From: Paulo Vital <pvital(a)linux.vnet.ibm.com>
Moving plugins directory to be part of src/wok development structure to make
easy develop, build, execute and test all plugins integrated with wok.
Signed-off-by: Paulo Vital <pvital(a)linux.vnet.ibm.com>
---
plugins/Makefile.am | 25 -
plugins/__init__.py | 18 -
plugins/kimchi/.gitignore | 37 -
plugins/kimchi/API.json | 836 -------
plugins/kimchi/INSTALL | 369 ---
plugins/kimchi/Makefile.am | 161 --
plugins/kimchi/README.md | 1 -
plugins/kimchi/VERSION | 1 -
plugins/kimchi/__init__.py | 21 -
plugins/kimchi/autogen.sh | 21 -
plugins/kimchi/build-aux/config.rpath | 672 ------
plugins/kimchi/build-aux/genChangelog | 25 -
plugins/kimchi/build-aux/pkg-version | 59 -
plugins/kimchi/config.py.in | 144 --
plugins/kimchi/config.rpath | 672 ------
plugins/kimchi/configure.ac | 119 -
plugins/kimchi/contrib/DEBIAN/Makefile.am | 17 -
plugins/kimchi/contrib/DEBIAN/control.in | 30 -
plugins/kimchi/contrib/Makefile.am | 34 -
plugins/kimchi/contrib/check_i18n.py | 82 -
plugins/kimchi/contrib/kimchi.spec.fedora.in | 119 -
plugins/kimchi/contrib/kimchi.spec.suse.in | 107 -
plugins/kimchi/contrib/make-deb.sh.in | 15 -
plugins/kimchi/control/Makefile.am | 27 -
plugins/kimchi/control/__init__.py | 26 -
plugins/kimchi/control/config.py | 57 -
plugins/kimchi/control/cpuinfo.py | 37 -
plugins/kimchi/control/debugreports.py | 61 -
plugins/kimchi/control/groups.py | 28 -
plugins/kimchi/control/host.py | 157 --
plugins/kimchi/control/interfaces.py | 46 -
plugins/kimchi/control/networks.py | 54 -
plugins/kimchi/control/peers.py | 29 -
plugins/kimchi/control/storagepools.py | 116 -
plugins/kimchi/control/storageservers.py | 60 -
plugins/kimchi/control/storagevolumes.py | 83 -
plugins/kimchi/control/templates.py | 58 -
plugins/kimchi/control/users.py | 35 -
plugins/kimchi/control/vm/Makefile.am | 26 -
plugins/kimchi/control/vm/__init__.py | 26 -
plugins/kimchi/control/vm/hostdevs.py | 43 -
plugins/kimchi/control/vm/ifaces.py | 45 -
plugins/kimchi/control/vm/snapshots.py | 58 -
plugins/kimchi/control/vm/storages.py | 45 -
plugins/kimchi/control/vms.py | 67 -
plugins/kimchi/disks.py | 196 --
plugins/kimchi/distroloader.py | 67 -
plugins/kimchi/distros.d/Makefile.am | 22 -
plugins/kimchi/distros.d/debian.json | 9 -
plugins/kimchi/distros.d/fedora.json | 30 -
plugins/kimchi/distros.d/gentoo.json | 9 -
plugins/kimchi/distros.d/opensuse.json | 23 -
plugins/kimchi/distros.d/ubuntu.json | 37 -
plugins/kimchi/docs/API.md | 1116 ---------
plugins/kimchi/docs/Makefile.am | 28 -
plugins/kimchi/docs/README-federation.md | 60 -
plugins/kimchi/docs/README.md | 247 --
plugins/kimchi/docs/kimchi-guest.png | Bin 192281 -> 0 bytes
plugins/kimchi/docs/kimchi-login.png | Bin 318041 -> 0 bytes
plugins/kimchi/docs/kimchi-templates.png | Bin 329678 -> 0 bytes
plugins/kimchi/i18n.py | 335 ---
plugins/kimchi/imageinfo.py | 72 -
plugins/kimchi/iscsi.py | 88 -
plugins/kimchi/isoinfo.py | 506 -----
plugins/kimchi/kimchi.conf | 37 -
plugins/kimchi/kvmusertests.py | 79 -
plugins/kimchi/m4/ac_python_module.m4 | 30 -
plugins/kimchi/m4/gettext.m4 | 383 ----
plugins/kimchi/m4/iconv.m4 | 214 --
plugins/kimchi/m4/intlmacosx.m4 | 51 -
plugins/kimchi/m4/lib-ld.m4 | 110 -
plugins/kimchi/m4/lib-link.m4 | 774 -------
plugins/kimchi/m4/lib-prefix.m4 | 224 --
plugins/kimchi/m4/nls.m4 | 32 -
plugins/kimchi/m4/po.m4 | 449 ----
plugins/kimchi/m4/progtest.m4 | 92 -
plugins/kimchi/mockmodel.py | 627 ------
plugins/kimchi/model/Makefile.am | 25 -
plugins/kimchi/model/__init__.py | 18 -
plugins/kimchi/model/config.py | 176 --
plugins/kimchi/model/cpuinfo.py | 126 --
plugins/kimchi/model/debugreports.py | 213 --
plugins/kimchi/model/diskutils.py | 75 -
plugins/kimchi/model/featuretests.py | 259 ---
plugins/kimchi/model/groups.py | 67 -
plugins/kimchi/model/host.py | 476 ----
plugins/kimchi/model/hostdev.py | 324 ---
plugins/kimchi/model/interfaces.py | 44 -
plugins/kimchi/model/libvirtconnection.py | 136 --
plugins/kimchi/model/libvirtstoragepool.py | 264 ---
plugins/kimchi/model/model.py | 52 -
plugins/kimchi/model/networks.py | 382 ----
plugins/kimchi/model/peers.py | 72 -
plugins/kimchi/model/storagepools.py | 490 ----
plugins/kimchi/model/storageservers.py | 81 -
plugins/kimchi/model/storagetargets.py | 122 -
plugins/kimchi/model/storagevolumes.py | 542 -----
plugins/kimchi/model/templates.py | 303 ---
plugins/kimchi/model/users.py | 90 -
plugins/kimchi/model/utils.py | 161 --
plugins/kimchi/model/vmhostdevs.py | 336 ---
plugins/kimchi/model/vmifaces.py | 186 --
plugins/kimchi/model/vms.py | 1307 -----------
plugins/kimchi/model/vmsnapshots.py | 204 --
plugins/kimchi/model/vmstorages.py | 252 ---
plugins/kimchi/netinfo.py | 216 --
plugins/kimchi/network.py | 62 -
plugins/kimchi/osinfo.py | 213 --
plugins/kimchi/po/LINGUAS | 11 -
plugins/kimchi/po/Makefile.in.in | 398 ----
plugins/kimchi/po/Makevars | 41 -
plugins/kimchi/po/POTFILES.in | 3 -
plugins/kimchi/po/de_DE.po | 2288 -------------------
plugins/kimchi/po/en_US.po | 2075 -----------------
plugins/kimchi/po/es_ES.po | 2305 -------------------
plugins/kimchi/po/fr_FR.po | 2338 -------------------
plugins/kimchi/po/gen-pot.in | 9 -
plugins/kimchi/po/it_IT.po | 2274 -------------------
plugins/kimchi/po/ja_JP.po | 2269 -------------------
plugins/kimchi/po/kimchi.pot | 2074 -----------------
plugins/kimchi/po/ko_KR.po | 2197 ------------------
plugins/kimchi/po/pt_BR.po | 2369 --------------------
plugins/kimchi/po/ru_RU.po | 2198 ------------------
plugins/kimchi/po/zh_CN.po | 2186 ------------------
plugins/kimchi/po/zh_TW.po | 2138 ------------------
plugins/kimchi/repositories.py | 529 -----
plugins/kimchi/root.py | 69 -
plugins/kimchi/scan.py | 89 -
plugins/kimchi/screenshot.py | 184 --
plugins/kimchi/swupdate.py | 263 ---
plugins/kimchi/template.conf | 47 -
plugins/kimchi/tests/Makefile.am | 50 -
plugins/kimchi/tests/iso_gen.py | 212 --
plugins/kimchi/tests/run_tests.sh.in | 55 -
plugins/kimchi/tests/test_authorization.py | 178 --
plugins/kimchi/tests/test_config.py.in | 267 ---
plugins/kimchi/tests/test_exception.py | 123 -
plugins/kimchi/tests/test_host.py | 206 --
plugins/kimchi/tests/test_mock_network.py | 73 -
plugins/kimchi/tests/test_mock_storagepool.py | 147 --
plugins/kimchi/tests/test_mock_storagevolume.py | 98 -
plugins/kimchi/tests/test_mockmodel.py | 141 --
plugins/kimchi/tests/test_model.py | 1248 -----------
plugins/kimchi/tests/test_model_network.py | 149 --
plugins/kimchi/tests/test_model_storagepool.py | 123 -
plugins/kimchi/tests/test_model_storagevolume.py | 280 ---
plugins/kimchi/tests/test_networkxml.py | 172 --
plugins/kimchi/tests/test_objectstore.py | 97 -
plugins/kimchi/tests/test_osinfo.py | 69 -
plugins/kimchi/tests/test_plugin.py | 126 --
plugins/kimchi/tests/test_rest.py | 1327 -----------
plugins/kimchi/tests/test_rollbackcontext.py | 99 -
plugins/kimchi/tests/test_server.py | 289 ---
plugins/kimchi/tests/test_storagepoolxml.py | 171 --
plugins/kimchi/tests/test_template.py | 387 ----
plugins/kimchi/tests/test_utils.py | 69 -
plugins/kimchi/tests/test_vmtemplate.py | 116 -
plugins/kimchi/tests/test_yumparser.py | 162 --
plugins/kimchi/tests/utils.py | 260 ---
plugins/kimchi/ui/Makefile.am | 20 -
plugins/kimchi/ui/config/Makefile.am | 22 -
plugins/kimchi/ui/config/tab-ext.xml | 38 -
plugins/kimchi/ui/css/Makefile.am | 26 -
plugins/kimchi/ui/css/theme-default/guest-edit.css | 424 ----
.../ui/css/theme-default/guest-storage-add.css | 81 -
plugins/kimchi/ui/css/theme-default/host.css | 287 ---
plugins/kimchi/ui/css/theme-default/icon.css | 106 -
plugins/kimchi/ui/css/theme-default/list.css | 326 ---
plugins/kimchi/ui/css/theme-default/network.css | 267 ---
plugins/kimchi/ui/css/theme-default/report-add.css | 37 -
.../kimchi/ui/css/theme-default/report-rename.css | 39 -
.../kimchi/ui/css/theme-default/repository-add.css | 42 -
.../ui/css/theme-default/repository-edit.css | 88 -
plugins/kimchi/ui/css/theme-default/storage.css | 550 -----
.../css/theme-default/storagepool-add-volume.css | 36 -
.../kimchi/ui/css/theme-default/template-edit.css | 175 --
plugins/kimchi/ui/css/theme-default/template.css | 85 -
.../kimchi/ui/css/theme-default/template_add.css | 317 ---
.../kimchi/ui/css/theme-default/template_list.css | 267 ---
plugins/kimchi/ui/images/Makefile.am | 22 -
plugins/kimchi/ui/images/icon-centos.png | Bin 4734 -> 0 bytes
plugins/kimchi/ui/images/icon-debian.png | Bin 4239 -> 0 bytes
plugins/kimchi/ui/images/icon-fedora.png | Bin 4449 -> 0 bytes
plugins/kimchi/ui/images/icon-gentoo.png | Bin 15307 -> 0 bytes
plugins/kimchi/ui/images/icon-opensuse.png | Bin 3046 -> 0 bytes
plugins/kimchi/ui/images/icon-ubuntu.png | Bin 4818 -> 0 bytes
plugins/kimchi/ui/images/icon-vm.png | Bin 2976 -> 0 bytes
plugins/kimchi/ui/images/theme-default/Makefile.am | 20 -
.../kimchi/ui/images/theme-default/ac22_pause.png | Bin 1219 -> 0 bytes
.../ui/images/theme-default/ac22_pause_grey.png | Bin 1175 -> 0 bytes
.../kimchi/ui/images/theme-default/ac24_resume.png | Bin 1341 -> 0 bytes
.../ui/images/theme-default/ac24_resume_grey.png | Bin 1282 -> 0 bytes
.../ui/images/theme-default/arrow-down-black.png | Bin 2942 -> 0 bytes
.../ui/images/theme-default/arrow-down-disable.png | Bin 472 -> 0 bytes
.../kimchi/ui/images/theme-default/arrow-down.png | Bin 537 -> 0 bytes
.../kimchi/ui/images/theme-default/arrow-up.png | Bin 510 -> 0 bytes
.../kimchi/ui/images/theme-default/arrow_out.png | Bin 3048 -> 0 bytes
plugins/kimchi/ui/images/theme-default/group.png | Bin 1703 -> 0 bytes
.../ui/images/theme-default/host-icon-sprite.png | Bin 1034 -> 0 bytes
.../kimchi/ui/images/theme-default/icon-back.png | Bin 244 -> 0 bytes
.../kimchi/ui/images/theme-default/icon-camera.png | Bin 4860 -> 0 bytes
.../kimchi/ui/images/theme-default/icon-design.png | Bin 4562 -> 0 bytes
.../kimchi/ui/images/theme-default/icon-detail.png | Bin 3079 -> 0 bytes
.../kimchi/ui/images/theme-default/icon-iso.png | Bin 4188 -> 0 bytes
.../kimchi/ui/images/theme-default/icon-list.png | Bin 2983 -> 0 bytes
.../kimchi/ui/images/theme-default/icon-load.png | Bin 3678 -> 0 bytes
.../kimchi/ui/images/theme-default/icon-local.png | Bin 425 -> 0 bytes
.../ui/images/theme-default/icon-power-down.png | Bin 4372 -> 0 bytes
.../ui/images/theme-default/icon-power-up.png | Bin 4367 -> 0 bytes
.../kimchi/ui/images/theme-default/icon-qcow2.png | Bin 4684 -> 0 bytes
.../kimchi/ui/images/theme-default/icon-raw.png | Bin 4679 -> 0 bytes
.../kimchi/ui/images/theme-default/icon-remote.png | Bin 1005 -> 0 bytes
.../kimchi/ui/images/theme-default/icon-reset.png | Bin 4576 -> 0 bytes
.../kimchi/ui/images/theme-default/icon-search.png | Bin 4197 -> 0 bytes
.../kimchi/ui/images/theme-default/icon-sort.png | Bin 3421 -> 0 bytes
.../kimchi/ui/images/theme-default/icon-tree.png | Bin 3526 -> 0 bytes
.../kimchi/ui/images/theme-default/icon-user.png | Bin 5366 -> 0 bytes
.../images/theme-default/icon-volume-default.png | Bin 4265 -> 0 bytes
.../images/theme-default/kimchi-loading15x15.gif | Bin 1653 -> 0 bytes
plugins/kimchi/ui/images/theme-default/loading.gif | Bin 2190 -> 0 bytes
plugins/kimchi/ui/images/theme-default/user.png | Bin 1322 -> 0 bytes
plugins/kimchi/ui/js/Makefile.am | 27 -
plugins/kimchi/ui/js/src/kimchi.api.js | 1355 -----------
plugins/kimchi/ui/js/src/kimchi.guest_add_main.js | 86 -
plugins/kimchi/ui/js/src/kimchi.guest_edit_main.js | 759 -------
plugins/kimchi/ui/js/src/kimchi.guest_main.js | 511 -----
.../kimchi/ui/js/src/kimchi.guest_media_main.js | 56 -
.../ui/js/src/kimchi.guest_storage_add.main.js | 199 --
plugins/kimchi/ui/js/src/kimchi.host.js | 858 -------
plugins/kimchi/ui/js/src/kimchi.main.js | 26 -
plugins/kimchi/ui/js/src/kimchi.network.js | 442 ----
plugins/kimchi/ui/js/src/kimchi.report_add_main.js | 72 -
.../kimchi/ui/js/src/kimchi.report_rename_main.js | 66 -
.../kimchi/ui/js/src/kimchi.repository_add_main.js | 96 -
.../ui/js/src/kimchi.repository_edit_main.js | 74 -
plugins/kimchi/ui/js/src/kimchi.storage_main.js | 428 ----
.../ui/js/src/kimchi.storagepool_add_main.js | 414 ----
.../js/src/kimchi.storagepool_add_volume_main.js | 179 --
.../kimchi/ui/js/src/kimchi.template_add_main.js | 441 ----
.../kimchi/ui/js/src/kimchi.template_edit_main.js | 343 ---
plugins/kimchi/ui/js/src/kimchi.template_main.js | 111 -
plugins/kimchi/ui/pages/Makefile.am | 22 -
plugins/kimchi/ui/pages/guest-add.html.tmpl | 98 -
plugins/kimchi/ui/pages/guest-edit.html.tmpl | 311 ---
.../kimchi/ui/pages/guest-storage-add.html.tmpl | 103 -
plugins/kimchi/ui/pages/guest.html.tmpl | 77 -
plugins/kimchi/ui/pages/guests.html.tmpl | 65 -
plugins/kimchi/ui/pages/help/Makefile.am | 34 -
plugins/kimchi/ui/pages/help/de_DE/Makefile.am | 23 -
plugins/kimchi/ui/pages/help/de_DE/guests.dita | 127 --
plugins/kimchi/ui/pages/help/de_DE/host.dita | 49 -
plugins/kimchi/ui/pages/help/de_DE/network.dita | 62 -
plugins/kimchi/ui/pages/help/de_DE/storage.dita | 86 -
plugins/kimchi/ui/pages/help/de_DE/templates.dita | 112 -
plugins/kimchi/ui/pages/help/dita-help.xsl | 26 -
plugins/kimchi/ui/pages/help/en_US/Makefile.am | 23 -
plugins/kimchi/ui/pages/help/en_US/guests.dita | 136 --
plugins/kimchi/ui/pages/help/en_US/host.dita | 70 -
plugins/kimchi/ui/pages/help/en_US/network.dita | 68 -
plugins/kimchi/ui/pages/help/en_US/storage.dita | 99 -
plugins/kimchi/ui/pages/help/en_US/templates.dita | 123 -
plugins/kimchi/ui/pages/help/es_ES/Makefile.am | 23 -
plugins/kimchi/ui/pages/help/es_ES/guests.dita | 120 -
plugins/kimchi/ui/pages/help/es_ES/host.dita | 49 -
plugins/kimchi/ui/pages/help/es_ES/network.dita | 61 -
plugins/kimchi/ui/pages/help/es_ES/storage.dita | 86 -
plugins/kimchi/ui/pages/help/es_ES/templates.dita | 111 -
plugins/kimchi/ui/pages/help/fr_FR/Makefile.am | 23 -
plugins/kimchi/ui/pages/help/fr_FR/guests.dita | 130 --
plugins/kimchi/ui/pages/help/fr_FR/host.dita | 68 -
plugins/kimchi/ui/pages/help/fr_FR/network.dita | 67 -
plugins/kimchi/ui/pages/help/fr_FR/storage.dita | 93 -
plugins/kimchi/ui/pages/help/fr_FR/templates.dita | 120 -
plugins/kimchi/ui/pages/help/it_IT/Makefile.am | 23 -
plugins/kimchi/ui/pages/help/it_IT/guests.dita | 123 -
plugins/kimchi/ui/pages/help/it_IT/host.dita | 51 -
plugins/kimchi/ui/pages/help/it_IT/network.dita | 63 -
plugins/kimchi/ui/pages/help/it_IT/storage.dita | 91 -
plugins/kimchi/ui/pages/help/it_IT/templates.dita | 115 -
plugins/kimchi/ui/pages/help/ja_JP/Makefile.am | 23 -
plugins/kimchi/ui/pages/help/ja_JP/guests.dita | 172 --
plugins/kimchi/ui/pages/help/ja_JP/host.dita | 70 -
plugins/kimchi/ui/pages/help/ja_JP/network.dita | 83 -
plugins/kimchi/ui/pages/help/ja_JP/storage.dita | 120 -
plugins/kimchi/ui/pages/help/ja_JP/templates.dita | 150 --
plugins/kimchi/ui/pages/help/kimchi.css | 208 --
plugins/kimchi/ui/pages/help/ko_KR/Makefile.am | 23 -
plugins/kimchi/ui/pages/help/ko_KR/guests.dita | 119 -
plugins/kimchi/ui/pages/help/ko_KR/host.dita | 47 -
plugins/kimchi/ui/pages/help/ko_KR/network.dita | 61 -
plugins/kimchi/ui/pages/help/ko_KR/storage.dita | 86 -
plugins/kimchi/ui/pages/help/ko_KR/templates.dita | 111 -
plugins/kimchi/ui/pages/help/pt_BR/Makefile.am | 23 -
plugins/kimchi/ui/pages/help/pt_BR/guests.dita | 137 --
plugins/kimchi/ui/pages/help/pt_BR/host.dita | 74 -
plugins/kimchi/ui/pages/help/pt_BR/network.dita | 72 -
plugins/kimchi/ui/pages/help/pt_BR/storage.dita | 102 -
plugins/kimchi/ui/pages/help/pt_BR/templates.dita | 127 --
plugins/kimchi/ui/pages/help/ru_RU/Makefile.am | 23 -
plugins/kimchi/ui/pages/help/ru_RU/guests.dita | 122 -
plugins/kimchi/ui/pages/help/ru_RU/host.dita | 48 -
plugins/kimchi/ui/pages/help/ru_RU/network.dita | 61 -
plugins/kimchi/ui/pages/help/ru_RU/storage.dita | 88 -
plugins/kimchi/ui/pages/help/ru_RU/templates.dita | 111 -
plugins/kimchi/ui/pages/help/zh_CN/Makefile.am | 23 -
plugins/kimchi/ui/pages/help/zh_CN/guests.dita | 118 -
plugins/kimchi/ui/pages/help/zh_CN/host.dita | 45 -
plugins/kimchi/ui/pages/help/zh_CN/network.dita | 61 -
plugins/kimchi/ui/pages/help/zh_CN/storage.dita | 84 -
plugins/kimchi/ui/pages/help/zh_CN/templates.dita | 111 -
plugins/kimchi/ui/pages/help/zh_TW/Makefile.am | 23 -
plugins/kimchi/ui/pages/help/zh_TW/guests.dita | 120 -
plugins/kimchi/ui/pages/help/zh_TW/host.dita | 50 -
plugins/kimchi/ui/pages/help/zh_TW/network.dita | 61 -
plugins/kimchi/ui/pages/help/zh_TW/storage.dita | 88 -
plugins/kimchi/ui/pages/help/zh_TW/templates.dita | 112 -
plugins/kimchi/ui/pages/host.html.tmpl | 177 --
plugins/kimchi/ui/pages/i18n.json.tmpl | 187 --
plugins/kimchi/ui/pages/network.html.tmpl | 133 --
plugins/kimchi/ui/pages/report-add.html.tmpl | 56 -
plugins/kimchi/ui/pages/report-rename.html.tmpl | 56 -
plugins/kimchi/ui/pages/repository-add.html.tmpl | 113 -
plugins/kimchi/ui/pages/repository-edit.html.tmpl | 117 -
plugins/kimchi/ui/pages/storage.html.tmpl | 143 --
.../ui/pages/storagepool-add-volume.html.tmpl | 79 -
plugins/kimchi/ui/pages/storagepool-add.html.tmpl | 186 --
plugins/kimchi/ui/pages/template-add.html.tmpl | 233 --
plugins/kimchi/ui/pages/template-edit.html.tmpl | 193 --
plugins/kimchi/ui/pages/templates.html.tmpl | 77 -
plugins/kimchi/ui/robots.txt | 2 -
plugins/kimchi/ui/spice-html5/Makefile.am | 25 -
plugins/kimchi/ui/spice-html5/atKeynames.js | 183 --
plugins/kimchi/ui/spice-html5/bitmap.js | 51 -
plugins/kimchi/ui/spice-html5/css/Makefile.am | 20 -
plugins/kimchi/ui/spice-html5/css/spice.css | 118 -
plugins/kimchi/ui/spice-html5/cursor.js | 110 -
plugins/kimchi/ui/spice-html5/display.js | 823 -------
plugins/kimchi/ui/spice-html5/enums.js | 324 ---
plugins/kimchi/ui/spice-html5/inputs.js | 280 ---
plugins/kimchi/ui/spice-html5/lz.js | 166 --
plugins/kimchi/ui/spice-html5/main.js | 231 --
plugins/kimchi/ui/spice-html5/pages/Makefile.am | 20 -
.../kimchi/ui/spice-html5/pages/spice_auto.html | 200 --
plugins/kimchi/ui/spice-html5/playback.js | 278 ---
plugins/kimchi/ui/spice-html5/png.js | 256 ---
plugins/kimchi/ui/spice-html5/quic.js | 1335 -----------
plugins/kimchi/ui/spice-html5/resize.js | 70 -
plugins/kimchi/ui/spice-html5/simulatecursor.js | 202 --
plugins/kimchi/ui/spice-html5/spicearraybuffer.js | 58 -
plugins/kimchi/ui/spice-html5/spiceconn.js | 460 ----
plugins/kimchi/ui/spice-html5/spicedataview.js | 120 -
plugins/kimchi/ui/spice-html5/spicemsg.js | 1047 ---------
plugins/kimchi/ui/spice-html5/spicetype.js | 473 ----
.../kimchi/ui/spice-html5/thirdparty/Makefile.am | 20 -
plugins/kimchi/ui/spice-html5/thirdparty/jsbn.js | 589 -----
plugins/kimchi/ui/spice-html5/thirdparty/prng4.js | 79 -
plugins/kimchi/ui/spice-html5/thirdparty/rng.js | 102 -
plugins/kimchi/ui/spice-html5/thirdparty/rsa.js | 146 --
plugins/kimchi/ui/spice-html5/thirdparty/sha1.js | 346 ---
plugins/kimchi/ui/spice-html5/ticket.js | 250 ---
plugins/kimchi/ui/spice-html5/utils.js | 265 ---
plugins/kimchi/ui/spice-html5/webm.js | 553 -----
plugins/kimchi/ui/spice-html5/wire.js | 123 -
plugins/kimchi/utils.py | 39 -
plugins/kimchi/vmtemplate.py | 431 ----
plugins/kimchi/vnc.py | 77 -
plugins/kimchi/xmlutils/Makefile.am | 25 -
plugins/kimchi/xmlutils/__init__.py | 18 -
plugins/kimchi/xmlutils/cpu.py | 60 -
plugins/kimchi/xmlutils/disk.py | 164 --
plugins/kimchi/xmlutils/graphics.py | 45 -
plugins/kimchi/xmlutils/interface.py | 61 -
plugins/kimchi/xmlutils/network.py | 122 -
plugins/kimchi/xmlutils/qemucmdline.py | 45 -
plugins/kimchi/yumparser.py | 283 ---
plugins/sample/API.json | 56 -
plugins/sample/Makefile.am | 29 -
plugins/sample/__init__.py | 97 -
plugins/sample/config.status | 1 -
plugins/sample/i18n.py | 40 -
plugins/sample/model.py | 131 --
plugins/sample/po/LINGUAS | 3 -
plugins/sample/po/Makefile.in.in | 400 ----
plugins/sample/po/Makevars | 41 -
plugins/sample/po/POTFILES.in | 2 -
plugins/sample/po/en_US.po | 21 -
plugins/sample/po/gen-pot | 9 -
plugins/sample/po/pt_BR.po | 24 -
plugins/sample/po/sample.pot | 21 -
plugins/sample/po/zh_CN.po | 24 -
plugins/sample/sample.conf.in | 27 -
plugins/sample/ui/Makefile.am | 22 -
plugins/sample/ui/config/Makefile.am | 21 -
plugins/sample/ui/config/tab-ext.xml | 17 -
plugins/sample/ui/css/.gitignore | 0
plugins/sample/ui/images/.gitignore | 0
plugins/sample/ui/js/.gitignore | 0
plugins/sample/ui/js/Makefile.am | 20 -
plugins/sample/ui/js/util.js | 33 -
plugins/sample/ui/libs/.gitignore | 0
plugins/sample/ui/pages/Makefile.am | 20 -
.../sample/ui/pages/help/en_US/sample-tab1.html | 1 -
.../sample/ui/pages/help/en_US/sample-tab2.html | 1 -
plugins/sample/ui/pages/i18n.json.tmpl | 26 -
plugins/sample/ui/pages/sample-tab1.html.tmpl | 30 -
plugins/sample/ui/pages/sample-tab2.html.tmpl | 30 -
src/wok/plugins/Makefile.am | 25 +
src/wok/plugins/__init__.py | 18 +
src/wok/plugins/kimchi/.gitignore | 37 +
src/wok/plugins/kimchi/API.json | 836 +++++++
src/wok/plugins/kimchi/INSTALL | 369 +++
src/wok/plugins/kimchi/Makefile.am | 161 ++
src/wok/plugins/kimchi/README.md | 1 +
src/wok/plugins/kimchi/VERSION | 1 +
src/wok/plugins/kimchi/__init__.py | 21 +
src/wok/plugins/kimchi/autogen.sh | 21 +
src/wok/plugins/kimchi/build-aux/config.rpath | 672 ++++++
src/wok/plugins/kimchi/build-aux/genChangelog | 25 +
src/wok/plugins/kimchi/build-aux/pkg-version | 59 +
src/wok/plugins/kimchi/config.py.in | 144 ++
src/wok/plugins/kimchi/config.rpath | 672 ++++++
src/wok/plugins/kimchi/configure.ac | 119 +
src/wok/plugins/kimchi/contrib/DEBIAN/Makefile.am | 17 +
src/wok/plugins/kimchi/contrib/DEBIAN/control.in | 30 +
src/wok/plugins/kimchi/contrib/Makefile.am | 34 +
src/wok/plugins/kimchi/contrib/check_i18n.py | 82 +
.../plugins/kimchi/contrib/kimchi.spec.fedora.in | 119 +
src/wok/plugins/kimchi/contrib/kimchi.spec.suse.in | 107 +
src/wok/plugins/kimchi/contrib/make-deb.sh.in | 15 +
src/wok/plugins/kimchi/control/Makefile.am | 27 +
src/wok/plugins/kimchi/control/__init__.py | 26 +
src/wok/plugins/kimchi/control/config.py | 57 +
src/wok/plugins/kimchi/control/cpuinfo.py | 37 +
src/wok/plugins/kimchi/control/debugreports.py | 61 +
src/wok/plugins/kimchi/control/groups.py | 28 +
src/wok/plugins/kimchi/control/host.py | 157 ++
src/wok/plugins/kimchi/control/interfaces.py | 46 +
src/wok/plugins/kimchi/control/networks.py | 54 +
src/wok/plugins/kimchi/control/peers.py | 29 +
src/wok/plugins/kimchi/control/storagepools.py | 116 +
src/wok/plugins/kimchi/control/storageservers.py | 60 +
src/wok/plugins/kimchi/control/storagevolumes.py | 83 +
src/wok/plugins/kimchi/control/templates.py | 58 +
src/wok/plugins/kimchi/control/users.py | 35 +
src/wok/plugins/kimchi/control/vm/Makefile.am | 26 +
src/wok/plugins/kimchi/control/vm/__init__.py | 26 +
src/wok/plugins/kimchi/control/vm/hostdevs.py | 43 +
src/wok/plugins/kimchi/control/vm/ifaces.py | 45 +
src/wok/plugins/kimchi/control/vm/snapshots.py | 58 +
src/wok/plugins/kimchi/control/vm/storages.py | 45 +
src/wok/plugins/kimchi/control/vms.py | 67 +
src/wok/plugins/kimchi/disks.py | 196 ++
src/wok/plugins/kimchi/distroloader.py | 67 +
src/wok/plugins/kimchi/distros.d/Makefile.am | 22 +
src/wok/plugins/kimchi/distros.d/debian.json | 9 +
src/wok/plugins/kimchi/distros.d/fedora.json | 30 +
src/wok/plugins/kimchi/distros.d/gentoo.json | 9 +
src/wok/plugins/kimchi/distros.d/opensuse.json | 23 +
src/wok/plugins/kimchi/distros.d/ubuntu.json | 37 +
src/wok/plugins/kimchi/docs/API.md | 1116 +++++++++
src/wok/plugins/kimchi/docs/Makefile.am | 28 +
src/wok/plugins/kimchi/docs/README-federation.md | 60 +
src/wok/plugins/kimchi/docs/README.md | 247 ++
src/wok/plugins/kimchi/docs/kimchi-guest.png | Bin 0 -> 192281 bytes
src/wok/plugins/kimchi/docs/kimchi-login.png | Bin 0 -> 318041 bytes
src/wok/plugins/kimchi/docs/kimchi-templates.png | Bin 0 -> 329678 bytes
src/wok/plugins/kimchi/i18n.py | 335 +++
src/wok/plugins/kimchi/imageinfo.py | 72 +
src/wok/plugins/kimchi/iscsi.py | 88 +
src/wok/plugins/kimchi/isoinfo.py | 506 +++++
src/wok/plugins/kimchi/kimchi.conf | 37 +
src/wok/plugins/kimchi/kvmusertests.py | 79 +
src/wok/plugins/kimchi/m4/ac_python_module.m4 | 30 +
src/wok/plugins/kimchi/m4/gettext.m4 | 383 ++++
src/wok/plugins/kimchi/m4/iconv.m4 | 214 ++
src/wok/plugins/kimchi/m4/intlmacosx.m4 | 51 +
src/wok/plugins/kimchi/m4/lib-ld.m4 | 110 +
src/wok/plugins/kimchi/m4/lib-link.m4 | 774 +++++++
src/wok/plugins/kimchi/m4/lib-prefix.m4 | 224 ++
src/wok/plugins/kimchi/m4/nls.m4 | 32 +
src/wok/plugins/kimchi/m4/po.m4 | 449 ++++
src/wok/plugins/kimchi/m4/progtest.m4 | 92 +
src/wok/plugins/kimchi/mockmodel.py | 627 ++++++
src/wok/plugins/kimchi/model/Makefile.am | 25 +
src/wok/plugins/kimchi/model/__init__.py | 18 +
src/wok/plugins/kimchi/model/config.py | 176 ++
src/wok/plugins/kimchi/model/cpuinfo.py | 126 ++
src/wok/plugins/kimchi/model/debugreports.py | 213 ++
src/wok/plugins/kimchi/model/diskutils.py | 75 +
src/wok/plugins/kimchi/model/featuretests.py | 259 +++
src/wok/plugins/kimchi/model/groups.py | 67 +
src/wok/plugins/kimchi/model/host.py | 476 ++++
src/wok/plugins/kimchi/model/hostdev.py | 324 +++
src/wok/plugins/kimchi/model/interfaces.py | 44 +
src/wok/plugins/kimchi/model/libvirtconnection.py | 136 ++
src/wok/plugins/kimchi/model/libvirtstoragepool.py | 264 +++
src/wok/plugins/kimchi/model/model.py | 52 +
src/wok/plugins/kimchi/model/networks.py | 382 ++++
src/wok/plugins/kimchi/model/peers.py | 72 +
src/wok/plugins/kimchi/model/storagepools.py | 490 ++++
src/wok/plugins/kimchi/model/storageservers.py | 81 +
src/wok/plugins/kimchi/model/storagetargets.py | 122 +
src/wok/plugins/kimchi/model/storagevolumes.py | 542 +++++
src/wok/plugins/kimchi/model/templates.py | 303 +++
src/wok/plugins/kimchi/model/users.py | 90 +
src/wok/plugins/kimchi/model/utils.py | 161 ++
src/wok/plugins/kimchi/model/vmhostdevs.py | 336 +++
src/wok/plugins/kimchi/model/vmifaces.py | 186 ++
src/wok/plugins/kimchi/model/vms.py | 1307 +++++++++++
src/wok/plugins/kimchi/model/vmsnapshots.py | 204 ++
src/wok/plugins/kimchi/model/vmstorages.py | 252 +++
src/wok/plugins/kimchi/netinfo.py | 216 ++
src/wok/plugins/kimchi/network.py | 62 +
src/wok/plugins/kimchi/osinfo.py | 213 ++
src/wok/plugins/kimchi/po/LINGUAS | 11 +
src/wok/plugins/kimchi/po/Makefile.in.in | 398 ++++
src/wok/plugins/kimchi/po/Makevars | 41 +
src/wok/plugins/kimchi/po/POTFILES.in | 3 +
src/wok/plugins/kimchi/po/de_DE.po | 2288 +++++++++++++++++++
src/wok/plugins/kimchi/po/en_US.po | 2075 +++++++++++++++++
src/wok/plugins/kimchi/po/es_ES.po | 2305 +++++++++++++++++++
src/wok/plugins/kimchi/po/fr_FR.po | 2338 +++++++++++++++++++
src/wok/plugins/kimchi/po/gen-pot.in | 9 +
src/wok/plugins/kimchi/po/it_IT.po | 2274 +++++++++++++++++++
src/wok/plugins/kimchi/po/ja_JP.po | 2269 +++++++++++++++++++
src/wok/plugins/kimchi/po/kimchi.pot | 2074 +++++++++++++++++
src/wok/plugins/kimchi/po/ko_KR.po | 2197 ++++++++++++++++++
src/wok/plugins/kimchi/po/pt_BR.po | 2369 ++++++++++++++++++++
src/wok/plugins/kimchi/po/ru_RU.po | 2198 ++++++++++++++++++
src/wok/plugins/kimchi/po/zh_CN.po | 2186 ++++++++++++++++++
src/wok/plugins/kimchi/po/zh_TW.po | 2138 ++++++++++++++++++
src/wok/plugins/kimchi/repositories.py | 529 +++++
src/wok/plugins/kimchi/root.py | 69 +
src/wok/plugins/kimchi/scan.py | 89 +
src/wok/plugins/kimchi/screenshot.py | 184 ++
src/wok/plugins/kimchi/swupdate.py | 263 +++
src/wok/plugins/kimchi/template.conf | 47 +
src/wok/plugins/kimchi/tests/Makefile.am | 50 +
src/wok/plugins/kimchi/tests/iso_gen.py | 212 ++
src/wok/plugins/kimchi/tests/run_tests.sh.in | 55 +
src/wok/plugins/kimchi/tests/test_authorization.py | 178 ++
src/wok/plugins/kimchi/tests/test_config.py.in | 267 +++
src/wok/plugins/kimchi/tests/test_exception.py | 123 +
src/wok/plugins/kimchi/tests/test_host.py | 206 ++
src/wok/plugins/kimchi/tests/test_mock_network.py | 73 +
.../plugins/kimchi/tests/test_mock_storagepool.py | 147 ++
.../kimchi/tests/test_mock_storagevolume.py | 98 +
src/wok/plugins/kimchi/tests/test_mockmodel.py | 141 ++
src/wok/plugins/kimchi/tests/test_model.py | 1248 +++++++++++
src/wok/plugins/kimchi/tests/test_model_network.py | 149 ++
.../plugins/kimchi/tests/test_model_storagepool.py | 123 +
.../kimchi/tests/test_model_storagevolume.py | 280 +++
src/wok/plugins/kimchi/tests/test_networkxml.py | 172 ++
src/wok/plugins/kimchi/tests/test_objectstore.py | 97 +
src/wok/plugins/kimchi/tests/test_osinfo.py | 69 +
src/wok/plugins/kimchi/tests/test_plugin.py | 126 ++
src/wok/plugins/kimchi/tests/test_rest.py | 1327 +++++++++++
.../plugins/kimchi/tests/test_rollbackcontext.py | 99 +
src/wok/plugins/kimchi/tests/test_server.py | 289 +++
.../plugins/kimchi/tests/test_storagepoolxml.py | 171 ++
src/wok/plugins/kimchi/tests/test_template.py | 387 ++++
src/wok/plugins/kimchi/tests/test_utils.py | 69 +
src/wok/plugins/kimchi/tests/test_vmtemplate.py | 116 +
src/wok/plugins/kimchi/tests/test_yumparser.py | 162 ++
src/wok/plugins/kimchi/tests/utils.py | 260 +++
src/wok/plugins/kimchi/ui/Makefile.am | 20 +
src/wok/plugins/kimchi/ui/config/Makefile.am | 22 +
src/wok/plugins/kimchi/ui/config/tab-ext.xml | 38 +
src/wok/plugins/kimchi/ui/css/Makefile.am | 26 +
.../kimchi/ui/css/theme-default/guest-edit.css | 424 ++++
.../ui/css/theme-default/guest-storage-add.css | 81 +
.../plugins/kimchi/ui/css/theme-default/host.css | 287 +++
.../plugins/kimchi/ui/css/theme-default/icon.css | 106 +
.../plugins/kimchi/ui/css/theme-default/list.css | 326 +++
.../kimchi/ui/css/theme-default/network.css | 267 +++
.../kimchi/ui/css/theme-default/report-add.css | 37 +
.../kimchi/ui/css/theme-default/report-rename.css | 39 +
.../kimchi/ui/css/theme-default/repository-add.css | 42 +
.../ui/css/theme-default/repository-edit.css | 88 +
.../kimchi/ui/css/theme-default/storage.css | 550 +++++
.../css/theme-default/storagepool-add-volume.css | 36 +
.../kimchi/ui/css/theme-default/template-edit.css | 175 ++
.../kimchi/ui/css/theme-default/template.css | 85 +
.../kimchi/ui/css/theme-default/template_add.css | 317 +++
.../kimchi/ui/css/theme-default/template_list.css | 267 +++
src/wok/plugins/kimchi/ui/images/Makefile.am | 22 +
src/wok/plugins/kimchi/ui/images/icon-centos.png | Bin 0 -> 4734 bytes
src/wok/plugins/kimchi/ui/images/icon-debian.png | Bin 0 -> 4239 bytes
src/wok/plugins/kimchi/ui/images/icon-fedora.png | Bin 0 -> 4449 bytes
src/wok/plugins/kimchi/ui/images/icon-gentoo.png | Bin 0 -> 15307 bytes
src/wok/plugins/kimchi/ui/images/icon-opensuse.png | Bin 0 -> 3046 bytes
src/wok/plugins/kimchi/ui/images/icon-ubuntu.png | Bin 0 -> 4818 bytes
src/wok/plugins/kimchi/ui/images/icon-vm.png | Bin 0 -> 2976 bytes
.../kimchi/ui/images/theme-default/Makefile.am | 20 +
.../kimchi/ui/images/theme-default/ac22_pause.png | Bin 0 -> 1219 bytes
.../ui/images/theme-default/ac22_pause_grey.png | Bin 0 -> 1175 bytes
.../kimchi/ui/images/theme-default/ac24_resume.png | Bin 0 -> 1341 bytes
.../ui/images/theme-default/ac24_resume_grey.png | Bin 0 -> 1282 bytes
.../ui/images/theme-default/arrow-down-black.png | Bin 0 -> 2942 bytes
.../ui/images/theme-default/arrow-down-disable.png | Bin 0 -> 472 bytes
.../kimchi/ui/images/theme-default/arrow-down.png | Bin 0 -> 537 bytes
.../kimchi/ui/images/theme-default/arrow-up.png | Bin 0 -> 510 bytes
.../kimchi/ui/images/theme-default/arrow_out.png | Bin 0 -> 3048 bytes
.../kimchi/ui/images/theme-default/group.png | Bin 0 -> 1703 bytes
.../ui/images/theme-default/host-icon-sprite.png | Bin 0 -> 1034 bytes
.../kimchi/ui/images/theme-default/icon-back.png | Bin 0 -> 244 bytes
.../kimchi/ui/images/theme-default/icon-camera.png | Bin 0 -> 4860 bytes
.../kimchi/ui/images/theme-default/icon-design.png | Bin 0 -> 4562 bytes
.../kimchi/ui/images/theme-default/icon-detail.png | Bin 0 -> 3079 bytes
.../kimchi/ui/images/theme-default/icon-iso.png | Bin 0 -> 4188 bytes
.../kimchi/ui/images/theme-default/icon-list.png | Bin 0 -> 2983 bytes
.../kimchi/ui/images/theme-default/icon-load.png | Bin 0 -> 3678 bytes
.../kimchi/ui/images/theme-default/icon-local.png | Bin 0 -> 425 bytes
.../ui/images/theme-default/icon-power-down.png | Bin 0 -> 4372 bytes
.../ui/images/theme-default/icon-power-up.png | Bin 0 -> 4367 bytes
.../kimchi/ui/images/theme-default/icon-qcow2.png | Bin 0 -> 4684 bytes
.../kimchi/ui/images/theme-default/icon-raw.png | Bin 0 -> 4679 bytes
.../kimchi/ui/images/theme-default/icon-remote.png | Bin 0 -> 1005 bytes
.../kimchi/ui/images/theme-default/icon-reset.png | Bin 0 -> 4576 bytes
.../kimchi/ui/images/theme-default/icon-search.png | Bin 0 -> 4197 bytes
.../kimchi/ui/images/theme-default/icon-sort.png | Bin 0 -> 3421 bytes
.../kimchi/ui/images/theme-default/icon-tree.png | Bin 0 -> 3526 bytes
.../kimchi/ui/images/theme-default/icon-user.png | Bin 0 -> 5366 bytes
.../images/theme-default/icon-volume-default.png | Bin 0 -> 4265 bytes
.../images/theme-default/kimchi-loading15x15.gif | Bin 0 -> 1653 bytes
.../kimchi/ui/images/theme-default/loading.gif | Bin 0 -> 2190 bytes
.../kimchi/ui/images/theme-default/user.png | Bin 0 -> 1322 bytes
src/wok/plugins/kimchi/ui/js/Makefile.am | 27 +
src/wok/plugins/kimchi/ui/js/src/kimchi.api.js | 1355 +++++++++++
.../kimchi/ui/js/src/kimchi.guest_add_main.js | 86 +
.../kimchi/ui/js/src/kimchi.guest_edit_main.js | 759 +++++++
.../plugins/kimchi/ui/js/src/kimchi.guest_main.js | 511 +++++
.../kimchi/ui/js/src/kimchi.guest_media_main.js | 56 +
.../ui/js/src/kimchi.guest_storage_add.main.js | 199 ++
src/wok/plugins/kimchi/ui/js/src/kimchi.host.js | 858 +++++++
src/wok/plugins/kimchi/ui/js/src/kimchi.main.js | 26 +
src/wok/plugins/kimchi/ui/js/src/kimchi.network.js | 442 ++++
.../kimchi/ui/js/src/kimchi.report_add_main.js | 72 +
.../kimchi/ui/js/src/kimchi.report_rename_main.js | 66 +
.../kimchi/ui/js/src/kimchi.repository_add_main.js | 96 +
.../ui/js/src/kimchi.repository_edit_main.js | 74 +
.../kimchi/ui/js/src/kimchi.storage_main.js | 428 ++++
.../ui/js/src/kimchi.storagepool_add_main.js | 414 ++++
.../js/src/kimchi.storagepool_add_volume_main.js | 179 ++
.../kimchi/ui/js/src/kimchi.template_add_main.js | 441 ++++
.../kimchi/ui/js/src/kimchi.template_edit_main.js | 343 +++
.../kimchi/ui/js/src/kimchi.template_main.js | 111 +
src/wok/plugins/kimchi/ui/pages/Makefile.am | 22 +
.../plugins/kimchi/ui/pages/guest-add.html.tmpl | 98 +
.../plugins/kimchi/ui/pages/guest-edit.html.tmpl | 311 +++
.../kimchi/ui/pages/guest-storage-add.html.tmpl | 103 +
src/wok/plugins/kimchi/ui/pages/guest.html.tmpl | 77 +
src/wok/plugins/kimchi/ui/pages/guests.html.tmpl | 65 +
src/wok/plugins/kimchi/ui/pages/help/Makefile.am | 34 +
.../plugins/kimchi/ui/pages/help/de_DE/Makefile.am | 23 +
.../plugins/kimchi/ui/pages/help/de_DE/guests.dita | 127 ++
.../plugins/kimchi/ui/pages/help/de_DE/host.dita | 49 +
.../kimchi/ui/pages/help/de_DE/network.dita | 62 +
.../kimchi/ui/pages/help/de_DE/storage.dita | 86 +
.../kimchi/ui/pages/help/de_DE/templates.dita | 112 +
src/wok/plugins/kimchi/ui/pages/help/dita-help.xsl | 26 +
.../plugins/kimchi/ui/pages/help/en_US/Makefile.am | 23 +
.../plugins/kimchi/ui/pages/help/en_US/guests.dita | 136 ++
.../plugins/kimchi/ui/pages/help/en_US/host.dita | 70 +
.../kimchi/ui/pages/help/en_US/network.dita | 68 +
.../kimchi/ui/pages/help/en_US/storage.dita | 99 +
.../kimchi/ui/pages/help/en_US/templates.dita | 123 +
.../plugins/kimchi/ui/pages/help/es_ES/Makefile.am | 23 +
.../plugins/kimchi/ui/pages/help/es_ES/guests.dita | 120 +
.../plugins/kimchi/ui/pages/help/es_ES/host.dita | 49 +
.../kimchi/ui/pages/help/es_ES/network.dita | 61 +
.../kimchi/ui/pages/help/es_ES/storage.dita | 86 +
.../kimchi/ui/pages/help/es_ES/templates.dita | 111 +
.../plugins/kimchi/ui/pages/help/fr_FR/Makefile.am | 23 +
.../plugins/kimchi/ui/pages/help/fr_FR/guests.dita | 130 ++
.../plugins/kimchi/ui/pages/help/fr_FR/host.dita | 68 +
.../kimchi/ui/pages/help/fr_FR/network.dita | 67 +
.../kimchi/ui/pages/help/fr_FR/storage.dita | 93 +
.../kimchi/ui/pages/help/fr_FR/templates.dita | 120 +
.../plugins/kimchi/ui/pages/help/it_IT/Makefile.am | 23 +
.../plugins/kimchi/ui/pages/help/it_IT/guests.dita | 123 +
.../plugins/kimchi/ui/pages/help/it_IT/host.dita | 51 +
.../kimchi/ui/pages/help/it_IT/network.dita | 63 +
.../kimchi/ui/pages/help/it_IT/storage.dita | 91 +
.../kimchi/ui/pages/help/it_IT/templates.dita | 115 +
.../plugins/kimchi/ui/pages/help/ja_JP/Makefile.am | 23 +
.../plugins/kimchi/ui/pages/help/ja_JP/guests.dita | 172 ++
.../plugins/kimchi/ui/pages/help/ja_JP/host.dita | 70 +
.../kimchi/ui/pages/help/ja_JP/network.dita | 83 +
.../kimchi/ui/pages/help/ja_JP/storage.dita | 120 +
.../kimchi/ui/pages/help/ja_JP/templates.dita | 150 ++
src/wok/plugins/kimchi/ui/pages/help/kimchi.css | 208 ++
.../plugins/kimchi/ui/pages/help/ko_KR/Makefile.am | 23 +
.../plugins/kimchi/ui/pages/help/ko_KR/guests.dita | 119 +
.../plugins/kimchi/ui/pages/help/ko_KR/host.dita | 47 +
.../kimchi/ui/pages/help/ko_KR/network.dita | 61 +
.../kimchi/ui/pages/help/ko_KR/storage.dita | 86 +
.../kimchi/ui/pages/help/ko_KR/templates.dita | 111 +
.../plugins/kimchi/ui/pages/help/pt_BR/Makefile.am | 23 +
.../plugins/kimchi/ui/pages/help/pt_BR/guests.dita | 137 ++
.../plugins/kimchi/ui/pages/help/pt_BR/host.dita | 74 +
.../kimchi/ui/pages/help/pt_BR/network.dita | 72 +
.../kimchi/ui/pages/help/pt_BR/storage.dita | 102 +
.../kimchi/ui/pages/help/pt_BR/templates.dita | 127 ++
.../plugins/kimchi/ui/pages/help/ru_RU/Makefile.am | 23 +
.../plugins/kimchi/ui/pages/help/ru_RU/guests.dita | 122 +
.../plugins/kimchi/ui/pages/help/ru_RU/host.dita | 48 +
.../kimchi/ui/pages/help/ru_RU/network.dita | 61 +
.../kimchi/ui/pages/help/ru_RU/storage.dita | 88 +
.../kimchi/ui/pages/help/ru_RU/templates.dita | 111 +
.../plugins/kimchi/ui/pages/help/zh_CN/Makefile.am | 23 +
.../plugins/kimchi/ui/pages/help/zh_CN/guests.dita | 118 +
.../plugins/kimchi/ui/pages/help/zh_CN/host.dita | 45 +
.../kimchi/ui/pages/help/zh_CN/network.dita | 61 +
.../kimchi/ui/pages/help/zh_CN/storage.dita | 84 +
.../kimchi/ui/pages/help/zh_CN/templates.dita | 111 +
.../plugins/kimchi/ui/pages/help/zh_TW/Makefile.am | 23 +
.../plugins/kimchi/ui/pages/help/zh_TW/guests.dita | 120 +
.../plugins/kimchi/ui/pages/help/zh_TW/host.dita | 50 +
.../kimchi/ui/pages/help/zh_TW/network.dita | 61 +
.../kimchi/ui/pages/help/zh_TW/storage.dita | 88 +
.../kimchi/ui/pages/help/zh_TW/templates.dita | 112 +
src/wok/plugins/kimchi/ui/pages/host.html.tmpl | 177 ++
src/wok/plugins/kimchi/ui/pages/i18n.json.tmpl | 187 ++
src/wok/plugins/kimchi/ui/pages/network.html.tmpl | 133 ++
.../plugins/kimchi/ui/pages/report-add.html.tmpl | 56 +
.../kimchi/ui/pages/report-rename.html.tmpl | 56 +
.../kimchi/ui/pages/repository-add.html.tmpl | 113 +
.../kimchi/ui/pages/repository-edit.html.tmpl | 117 +
src/wok/plugins/kimchi/ui/pages/storage.html.tmpl | 143 ++
.../ui/pages/storagepool-add-volume.html.tmpl | 79 +
.../kimchi/ui/pages/storagepool-add.html.tmpl | 186 ++
.../plugins/kimchi/ui/pages/template-add.html.tmpl | 233 ++
.../kimchi/ui/pages/template-edit.html.tmpl | 193 ++
.../plugins/kimchi/ui/pages/templates.html.tmpl | 77 +
src/wok/plugins/kimchi/ui/robots.txt | 2 +
src/wok/plugins/kimchi/ui/spice-html5/Makefile.am | 25 +
.../plugins/kimchi/ui/spice-html5/atKeynames.js | 183 ++
src/wok/plugins/kimchi/ui/spice-html5/bitmap.js | 51 +
.../plugins/kimchi/ui/spice-html5/css/Makefile.am | 20 +
.../plugins/kimchi/ui/spice-html5/css/spice.css | 118 +
src/wok/plugins/kimchi/ui/spice-html5/cursor.js | 110 +
src/wok/plugins/kimchi/ui/spice-html5/display.js | 823 +++++++
src/wok/plugins/kimchi/ui/spice-html5/enums.js | 324 +++
src/wok/plugins/kimchi/ui/spice-html5/inputs.js | 280 +++
src/wok/plugins/kimchi/ui/spice-html5/lz.js | 166 ++
src/wok/plugins/kimchi/ui/spice-html5/main.js | 231 ++
.../kimchi/ui/spice-html5/pages/Makefile.am | 20 +
.../kimchi/ui/spice-html5/pages/spice_auto.html | 200 ++
src/wok/plugins/kimchi/ui/spice-html5/playback.js | 278 +++
src/wok/plugins/kimchi/ui/spice-html5/png.js | 256 +++
src/wok/plugins/kimchi/ui/spice-html5/quic.js | 1335 +++++++++++
src/wok/plugins/kimchi/ui/spice-html5/resize.js | 70 +
.../kimchi/ui/spice-html5/simulatecursor.js | 202 ++
.../kimchi/ui/spice-html5/spicearraybuffer.js | 58 +
src/wok/plugins/kimchi/ui/spice-html5/spiceconn.js | 460 ++++
.../plugins/kimchi/ui/spice-html5/spicedataview.js | 120 +
src/wok/plugins/kimchi/ui/spice-html5/spicemsg.js | 1047 +++++++++
src/wok/plugins/kimchi/ui/spice-html5/spicetype.js | 473 ++++
.../kimchi/ui/spice-html5/thirdparty/Makefile.am | 20 +
.../kimchi/ui/spice-html5/thirdparty/jsbn.js | 589 +++++
.../kimchi/ui/spice-html5/thirdparty/prng4.js | 79 +
.../kimchi/ui/spice-html5/thirdparty/rng.js | 102 +
.../kimchi/ui/spice-html5/thirdparty/rsa.js | 146 ++
.../kimchi/ui/spice-html5/thirdparty/sha1.js | 346 +++
src/wok/plugins/kimchi/ui/spice-html5/ticket.js | 250 +++
src/wok/plugins/kimchi/ui/spice-html5/utils.js | 265 +++
src/wok/plugins/kimchi/ui/spice-html5/webm.js | 553 +++++
src/wok/plugins/kimchi/ui/spice-html5/wire.js | 123 +
src/wok/plugins/kimchi/utils.py | 39 +
src/wok/plugins/kimchi/vmtemplate.py | 431 ++++
src/wok/plugins/kimchi/vnc.py | 77 +
src/wok/plugins/kimchi/xmlutils/Makefile.am | 25 +
src/wok/plugins/kimchi/xmlutils/__init__.py | 18 +
src/wok/plugins/kimchi/xmlutils/cpu.py | 60 +
src/wok/plugins/kimchi/xmlutils/disk.py | 164 ++
src/wok/plugins/kimchi/xmlutils/graphics.py | 45 +
src/wok/plugins/kimchi/xmlutils/interface.py | 61 +
src/wok/plugins/kimchi/xmlutils/network.py | 122 +
src/wok/plugins/kimchi/xmlutils/qemucmdline.py | 45 +
src/wok/plugins/kimchi/yumparser.py | 283 +++
src/wok/plugins/sample/API.json | 56 +
src/wok/plugins/sample/Makefile.am | 29 +
src/wok/plugins/sample/__init__.py | 97 +
src/wok/plugins/sample/config.status | 1 +
src/wok/plugins/sample/i18n.py | 40 +
src/wok/plugins/sample/model.py | 131 ++
src/wok/plugins/sample/po/LINGUAS | 3 +
src/wok/plugins/sample/po/Makefile.in.in | 400 ++++
src/wok/plugins/sample/po/Makevars | 41 +
src/wok/plugins/sample/po/POTFILES.in | 2 +
src/wok/plugins/sample/po/en_US.po | 21 +
src/wok/plugins/sample/po/gen-pot | 9 +
src/wok/plugins/sample/po/pt_BR.po | 24 +
src/wok/plugins/sample/po/sample.pot | 21 +
src/wok/plugins/sample/po/zh_CN.po | 24 +
src/wok/plugins/sample/sample.conf.in | 27 +
src/wok/plugins/sample/ui/Makefile.am | 22 +
src/wok/plugins/sample/ui/config/Makefile.am | 21 +
src/wok/plugins/sample/ui/config/tab-ext.xml | 17 +
src/wok/plugins/sample/ui/css/.gitignore | 0
src/wok/plugins/sample/ui/images/.gitignore | 0
src/wok/plugins/sample/ui/js/.gitignore | 0
src/wok/plugins/sample/ui/js/Makefile.am | 20 +
src/wok/plugins/sample/ui/js/util.js | 33 +
src/wok/plugins/sample/ui/libs/.gitignore | 0
src/wok/plugins/sample/ui/pages/Makefile.am | 20 +
.../sample/ui/pages/help/en_US/sample-tab1.html | 1 +
.../sample/ui/pages/help/en_US/sample-tab2.html | 1 +
src/wok/plugins/sample/ui/pages/i18n.json.tmpl | 26 +
.../plugins/sample/ui/pages/sample-tab1.html.tmpl | 30 +
.../plugins/sample/ui/pages/sample-tab2.html.tmpl | 30 +
812 files changed, 82736 insertions(+), 82736 deletions(-)
delete mode 100644 plugins/Makefile.am
delete mode 100644 plugins/__init__.py
delete mode 100644 plugins/kimchi/.gitignore
delete mode 100644 plugins/kimchi/API.json
delete mode 100644 plugins/kimchi/INSTALL
delete mode 100644 plugins/kimchi/Makefile.am
delete mode 120000 plugins/kimchi/README.md
delete mode 100644 plugins/kimchi/VERSION
delete mode 100644 plugins/kimchi/__init__.py
delete mode 100755 plugins/kimchi/autogen.sh
delete mode 100644 plugins/kimchi/build-aux/config.rpath
delete mode 100755 plugins/kimchi/build-aux/genChangelog
delete mode 100755 plugins/kimchi/build-aux/pkg-version
delete mode 100644 plugins/kimchi/config.py.in
delete mode 100644 plugins/kimchi/config.rpath
delete mode 100644 plugins/kimchi/configure.ac
delete mode 100644 plugins/kimchi/contrib/DEBIAN/Makefile.am
delete mode 100644 plugins/kimchi/contrib/DEBIAN/control.in
delete mode 100644 plugins/kimchi/contrib/Makefile.am
delete mode 100755 plugins/kimchi/contrib/check_i18n.py
delete mode 100644 plugins/kimchi/contrib/kimchi.spec.fedora.in
delete mode 100644 plugins/kimchi/contrib/kimchi.spec.suse.in
delete mode 100644 plugins/kimchi/contrib/make-deb.sh.in
delete mode 100644 plugins/kimchi/control/Makefile.am
delete mode 100644 plugins/kimchi/control/__init__.py
delete mode 100644 plugins/kimchi/control/config.py
delete mode 100644 plugins/kimchi/control/cpuinfo.py
delete mode 100644 plugins/kimchi/control/debugreports.py
delete mode 100644 plugins/kimchi/control/groups.py
delete mode 100644 plugins/kimchi/control/host.py
delete mode 100644 plugins/kimchi/control/interfaces.py
delete mode 100644 plugins/kimchi/control/networks.py
delete mode 100644 plugins/kimchi/control/peers.py
delete mode 100644 plugins/kimchi/control/storagepools.py
delete mode 100644 plugins/kimchi/control/storageservers.py
delete mode 100644 plugins/kimchi/control/storagevolumes.py
delete mode 100644 plugins/kimchi/control/templates.py
delete mode 100644 plugins/kimchi/control/users.py
delete mode 100644 plugins/kimchi/control/vm/Makefile.am
delete mode 100644 plugins/kimchi/control/vm/__init__.py
delete mode 100644 plugins/kimchi/control/vm/hostdevs.py
delete mode 100644 plugins/kimchi/control/vm/ifaces.py
delete mode 100644 plugins/kimchi/control/vm/snapshots.py
delete mode 100644 plugins/kimchi/control/vm/storages.py
delete mode 100644 plugins/kimchi/control/vms.py
delete mode 100644 plugins/kimchi/disks.py
delete mode 100644 plugins/kimchi/distroloader.py
delete mode 100644 plugins/kimchi/distros.d/Makefile.am
delete mode 100644 plugins/kimchi/distros.d/debian.json
delete mode 100644 plugins/kimchi/distros.d/fedora.json
delete mode 100644 plugins/kimchi/distros.d/gentoo.json
delete mode 100644 plugins/kimchi/distros.d/opensuse.json
delete mode 100644 plugins/kimchi/distros.d/ubuntu.json
delete mode 100644 plugins/kimchi/docs/API.md
delete mode 100644 plugins/kimchi/docs/Makefile.am
delete mode 100644 plugins/kimchi/docs/README-federation.md
delete mode 100644 plugins/kimchi/docs/README.md
delete mode 100644 plugins/kimchi/docs/kimchi-guest.png
delete mode 100644 plugins/kimchi/docs/kimchi-login.png
delete mode 100644 plugins/kimchi/docs/kimchi-templates.png
delete mode 100644 plugins/kimchi/i18n.py
delete mode 100644 plugins/kimchi/imageinfo.py
delete mode 100644 plugins/kimchi/iscsi.py
delete mode 100644 plugins/kimchi/isoinfo.py
delete mode 100644 plugins/kimchi/kimchi.conf
delete mode 100644 plugins/kimchi/kvmusertests.py
delete mode 100644 plugins/kimchi/m4/ac_python_module.m4
delete mode 100644 plugins/kimchi/m4/gettext.m4
delete mode 100644 plugins/kimchi/m4/iconv.m4
delete mode 100644 plugins/kimchi/m4/intlmacosx.m4
delete mode 100644 plugins/kimchi/m4/lib-ld.m4
delete mode 100644 plugins/kimchi/m4/lib-link.m4
delete mode 100644 plugins/kimchi/m4/lib-prefix.m4
delete mode 100644 plugins/kimchi/m4/nls.m4
delete mode 100644 plugins/kimchi/m4/po.m4
delete mode 100644 plugins/kimchi/m4/progtest.m4
delete mode 100644 plugins/kimchi/mockmodel.py
delete mode 100644 plugins/kimchi/model/Makefile.am
delete mode 100644 plugins/kimchi/model/__init__.py
delete mode 100644 plugins/kimchi/model/config.py
delete mode 100644 plugins/kimchi/model/cpuinfo.py
delete mode 100644 plugins/kimchi/model/debugreports.py
delete mode 100644 plugins/kimchi/model/diskutils.py
delete mode 100644 plugins/kimchi/model/featuretests.py
delete mode 100644 plugins/kimchi/model/groups.py
delete mode 100644 plugins/kimchi/model/host.py
delete mode 100644 plugins/kimchi/model/hostdev.py
delete mode 100644 plugins/kimchi/model/interfaces.py
delete mode 100644 plugins/kimchi/model/libvirtconnection.py
delete mode 100644 plugins/kimchi/model/libvirtstoragepool.py
delete mode 100644 plugins/kimchi/model/model.py
delete mode 100644 plugins/kimchi/model/networks.py
delete mode 100644 plugins/kimchi/model/peers.py
delete mode 100644 plugins/kimchi/model/storagepools.py
delete mode 100644 plugins/kimchi/model/storageservers.py
delete mode 100644 plugins/kimchi/model/storagetargets.py
delete mode 100644 plugins/kimchi/model/storagevolumes.py
delete mode 100644 plugins/kimchi/model/templates.py
delete mode 100644 plugins/kimchi/model/users.py
delete mode 100644 plugins/kimchi/model/utils.py
delete mode 100644 plugins/kimchi/model/vmhostdevs.py
delete mode 100644 plugins/kimchi/model/vmifaces.py
delete mode 100644 plugins/kimchi/model/vms.py
delete mode 100644 plugins/kimchi/model/vmsnapshots.py
delete mode 100644 plugins/kimchi/model/vmstorages.py
delete mode 100644 plugins/kimchi/netinfo.py
delete mode 100644 plugins/kimchi/network.py
delete mode 100644 plugins/kimchi/osinfo.py
delete mode 100644 plugins/kimchi/po/LINGUAS
delete mode 100644 plugins/kimchi/po/Makefile.in.in
delete mode 100644 plugins/kimchi/po/Makevars
delete mode 100644 plugins/kimchi/po/POTFILES.in
delete mode 100644 plugins/kimchi/po/de_DE.po
delete mode 100644 plugins/kimchi/po/en_US.po
delete mode 100644 plugins/kimchi/po/es_ES.po
delete mode 100644 plugins/kimchi/po/fr_FR.po
delete mode 100644 plugins/kimchi/po/gen-pot.in
delete mode 100644 plugins/kimchi/po/it_IT.po
delete mode 100644 plugins/kimchi/po/ja_JP.po
delete mode 100755 plugins/kimchi/po/kimchi.pot
delete mode 100644 plugins/kimchi/po/ko_KR.po
delete mode 100644 plugins/kimchi/po/pt_BR.po
delete mode 100644 plugins/kimchi/po/ru_RU.po
delete mode 100644 plugins/kimchi/po/zh_CN.po
delete mode 100644 plugins/kimchi/po/zh_TW.po
delete mode 100644 plugins/kimchi/repositories.py
delete mode 100644 plugins/kimchi/root.py
delete mode 100644 plugins/kimchi/scan.py
delete mode 100644 plugins/kimchi/screenshot.py
delete mode 100644 plugins/kimchi/swupdate.py
delete mode 100644 plugins/kimchi/template.conf
delete mode 100644 plugins/kimchi/tests/Makefile.am
delete mode 100644 plugins/kimchi/tests/iso_gen.py
delete mode 100644 plugins/kimchi/tests/run_tests.sh.in
delete mode 100644 plugins/kimchi/tests/test_authorization.py
delete mode 100644 plugins/kimchi/tests/test_config.py.in
delete mode 100644 plugins/kimchi/tests/test_exception.py
delete mode 100644 plugins/kimchi/tests/test_host.py
delete mode 100644 plugins/kimchi/tests/test_mock_network.py
delete mode 100644 plugins/kimchi/tests/test_mock_storagepool.py
delete mode 100644 plugins/kimchi/tests/test_mock_storagevolume.py
delete mode 100644 plugins/kimchi/tests/test_mockmodel.py
delete mode 100644 plugins/kimchi/tests/test_model.py
delete mode 100644 plugins/kimchi/tests/test_model_network.py
delete mode 100644 plugins/kimchi/tests/test_model_storagepool.py
delete mode 100644 plugins/kimchi/tests/test_model_storagevolume.py
delete mode 100644 plugins/kimchi/tests/test_networkxml.py
delete mode 100644 plugins/kimchi/tests/test_objectstore.py
delete mode 100644 plugins/kimchi/tests/test_osinfo.py
delete mode 100644 plugins/kimchi/tests/test_plugin.py
delete mode 100644 plugins/kimchi/tests/test_rest.py
delete mode 100644 plugins/kimchi/tests/test_rollbackcontext.py
delete mode 100644 plugins/kimchi/tests/test_server.py
delete mode 100644 plugins/kimchi/tests/test_storagepoolxml.py
delete mode 100644 plugins/kimchi/tests/test_template.py
delete mode 100644 plugins/kimchi/tests/test_utils.py
delete mode 100644 plugins/kimchi/tests/test_vmtemplate.py
delete mode 100644 plugins/kimchi/tests/test_yumparser.py
delete mode 100644 plugins/kimchi/tests/utils.py
delete mode 100644 plugins/kimchi/ui/Makefile.am
delete mode 100644 plugins/kimchi/ui/config/Makefile.am
delete mode 100644 plugins/kimchi/ui/config/tab-ext.xml
delete mode 100644 plugins/kimchi/ui/css/Makefile.am
delete mode 100644 plugins/kimchi/ui/css/theme-default/guest-edit.css
delete mode 100644 plugins/kimchi/ui/css/theme-default/guest-storage-add.css
delete mode 100644 plugins/kimchi/ui/css/theme-default/host.css
delete mode 100644 plugins/kimchi/ui/css/theme-default/icon.css
delete mode 100644 plugins/kimchi/ui/css/theme-default/list.css
delete mode 100644 plugins/kimchi/ui/css/theme-default/network.css
delete mode 100644 plugins/kimchi/ui/css/theme-default/report-add.css
delete mode 100644 plugins/kimchi/ui/css/theme-default/report-rename.css
delete mode 100644 plugins/kimchi/ui/css/theme-default/repository-add.css
delete mode 100644 plugins/kimchi/ui/css/theme-default/repository-edit.css
delete mode 100644 plugins/kimchi/ui/css/theme-default/storage.css
delete mode 100644 plugins/kimchi/ui/css/theme-default/storagepool-add-volume.css
delete mode 100644 plugins/kimchi/ui/css/theme-default/template-edit.css
delete mode 100644 plugins/kimchi/ui/css/theme-default/template.css
delete mode 100644 plugins/kimchi/ui/css/theme-default/template_add.css
delete mode 100644 plugins/kimchi/ui/css/theme-default/template_list.css
delete mode 100644 plugins/kimchi/ui/images/Makefile.am
delete mode 100644 plugins/kimchi/ui/images/icon-centos.png
delete mode 100644 plugins/kimchi/ui/images/icon-debian.png
delete mode 100644 plugins/kimchi/ui/images/icon-fedora.png
delete mode 100644 plugins/kimchi/ui/images/icon-gentoo.png
delete mode 100644 plugins/kimchi/ui/images/icon-opensuse.png
delete mode 100644 plugins/kimchi/ui/images/icon-ubuntu.png
delete mode 100644 plugins/kimchi/ui/images/icon-vm.png
delete mode 100644 plugins/kimchi/ui/images/theme-default/Makefile.am
delete mode 100644 plugins/kimchi/ui/images/theme-default/ac22_pause.png
delete mode 100644 plugins/kimchi/ui/images/theme-default/ac22_pause_grey.png
delete mode 100644 plugins/kimchi/ui/images/theme-default/ac24_resume.png
delete mode 100644 plugins/kimchi/ui/images/theme-default/ac24_resume_grey.png
delete mode 100644 plugins/kimchi/ui/images/theme-default/arrow-down-black.png
delete mode 100644 plugins/kimchi/ui/images/theme-default/arrow-down-disable.png
delete mode 100644 plugins/kimchi/ui/images/theme-default/arrow-down.png
delete mode 100644 plugins/kimchi/ui/images/theme-default/arrow-up.png
delete mode 100644 plugins/kimchi/ui/images/theme-default/arrow_out.png
delete mode 100644 plugins/kimchi/ui/images/theme-default/group.png
delete mode 100644 plugins/kimchi/ui/images/theme-default/host-icon-sprite.png
delete mode 100644 plugins/kimchi/ui/images/theme-default/icon-back.png
delete mode 100644 plugins/kimchi/ui/images/theme-default/icon-camera.png
delete mode 100644 plugins/kimchi/ui/images/theme-default/icon-design.png
delete mode 100644 plugins/kimchi/ui/images/theme-default/icon-detail.png
delete mode 100644 plugins/kimchi/ui/images/theme-default/icon-iso.png
delete mode 100644 plugins/kimchi/ui/images/theme-default/icon-list.png
delete mode 100644 plugins/kimchi/ui/images/theme-default/icon-load.png
delete mode 100644 plugins/kimchi/ui/images/theme-default/icon-local.png
delete mode 100644 plugins/kimchi/ui/images/theme-default/icon-power-down.png
delete mode 100644 plugins/kimchi/ui/images/theme-default/icon-power-up.png
delete mode 100644 plugins/kimchi/ui/images/theme-default/icon-qcow2.png
delete mode 100644 plugins/kimchi/ui/images/theme-default/icon-raw.png
delete mode 100644 plugins/kimchi/ui/images/theme-default/icon-remote.png
delete mode 100644 plugins/kimchi/ui/images/theme-default/icon-reset.png
delete mode 100644 plugins/kimchi/ui/images/theme-default/icon-search.png
delete mode 100644 plugins/kimchi/ui/images/theme-default/icon-sort.png
delete mode 100644 plugins/kimchi/ui/images/theme-default/icon-tree.png
delete mode 100644 plugins/kimchi/ui/images/theme-default/icon-user.png
delete mode 100644 plugins/kimchi/ui/images/theme-default/icon-volume-default.png
delete mode 100644 plugins/kimchi/ui/images/theme-default/kimchi-loading15x15.gif
delete mode 100644 plugins/kimchi/ui/images/theme-default/loading.gif
delete mode 100644 plugins/kimchi/ui/images/theme-default/user.png
delete mode 100644 plugins/kimchi/ui/js/Makefile.am
delete mode 100644 plugins/kimchi/ui/js/src/kimchi.api.js
delete mode 100644 plugins/kimchi/ui/js/src/kimchi.guest_add_main.js
delete mode 100644 plugins/kimchi/ui/js/src/kimchi.guest_edit_main.js
delete mode 100644 plugins/kimchi/ui/js/src/kimchi.guest_main.js
delete mode 100644 plugins/kimchi/ui/js/src/kimchi.guest_media_main.js
delete mode 100644 plugins/kimchi/ui/js/src/kimchi.guest_storage_add.main.js
delete mode 100644 plugins/kimchi/ui/js/src/kimchi.host.js
delete mode 100644 plugins/kimchi/ui/js/src/kimchi.main.js
delete mode 100644 plugins/kimchi/ui/js/src/kimchi.network.js
delete mode 100644 plugins/kimchi/ui/js/src/kimchi.report_add_main.js
delete mode 100644 plugins/kimchi/ui/js/src/kimchi.report_rename_main.js
delete mode 100644 plugins/kimchi/ui/js/src/kimchi.repository_add_main.js
delete mode 100644 plugins/kimchi/ui/js/src/kimchi.repository_edit_main.js
delete mode 100644 plugins/kimchi/ui/js/src/kimchi.storage_main.js
delete mode 100644 plugins/kimchi/ui/js/src/kimchi.storagepool_add_main.js
delete mode 100644 plugins/kimchi/ui/js/src/kimchi.storagepool_add_volume_main.js
delete mode 100644 plugins/kimchi/ui/js/src/kimchi.template_add_main.js
delete mode 100644 plugins/kimchi/ui/js/src/kimchi.template_edit_main.js
delete mode 100644 plugins/kimchi/ui/js/src/kimchi.template_main.js
delete mode 100644 plugins/kimchi/ui/pages/Makefile.am
delete mode 100644 plugins/kimchi/ui/pages/guest-add.html.tmpl
delete mode 100644 plugins/kimchi/ui/pages/guest-edit.html.tmpl
delete mode 100644 plugins/kimchi/ui/pages/guest-storage-add.html.tmpl
delete mode 100644 plugins/kimchi/ui/pages/guest.html.tmpl
delete mode 100644 plugins/kimchi/ui/pages/guests.html.tmpl
delete mode 100644 plugins/kimchi/ui/pages/help/Makefile.am
delete mode 100644 plugins/kimchi/ui/pages/help/de_DE/Makefile.am
delete mode 100644 plugins/kimchi/ui/pages/help/de_DE/guests.dita
delete mode 100644 plugins/kimchi/ui/pages/help/de_DE/host.dita
delete mode 100644 plugins/kimchi/ui/pages/help/de_DE/network.dita
delete mode 100644 plugins/kimchi/ui/pages/help/de_DE/storage.dita
delete mode 100644 plugins/kimchi/ui/pages/help/de_DE/templates.dita
delete mode 100644 plugins/kimchi/ui/pages/help/dita-help.xsl
delete mode 100644 plugins/kimchi/ui/pages/help/en_US/Makefile.am
delete mode 100644 plugins/kimchi/ui/pages/help/en_US/guests.dita
delete mode 100644 plugins/kimchi/ui/pages/help/en_US/host.dita
delete mode 100644 plugins/kimchi/ui/pages/help/en_US/network.dita
delete mode 100644 plugins/kimchi/ui/pages/help/en_US/storage.dita
delete mode 100644 plugins/kimchi/ui/pages/help/en_US/templates.dita
delete mode 100644 plugins/kimchi/ui/pages/help/es_ES/Makefile.am
delete mode 100644 plugins/kimchi/ui/pages/help/es_ES/guests.dita
delete mode 100644 plugins/kimchi/ui/pages/help/es_ES/host.dita
delete mode 100644 plugins/kimchi/ui/pages/help/es_ES/network.dita
delete mode 100644 plugins/kimchi/ui/pages/help/es_ES/storage.dita
delete mode 100644 plugins/kimchi/ui/pages/help/es_ES/templates.dita
delete mode 100644 plugins/kimchi/ui/pages/help/fr_FR/Makefile.am
delete mode 100644 plugins/kimchi/ui/pages/help/fr_FR/guests.dita
delete mode 100644 plugins/kimchi/ui/pages/help/fr_FR/host.dita
delete mode 100644 plugins/kimchi/ui/pages/help/fr_FR/network.dita
delete mode 100644 plugins/kimchi/ui/pages/help/fr_FR/storage.dita
delete mode 100644 plugins/kimchi/ui/pages/help/fr_FR/templates.dita
delete mode 100644 plugins/kimchi/ui/pages/help/it_IT/Makefile.am
delete mode 100644 plugins/kimchi/ui/pages/help/it_IT/guests.dita
delete mode 100644 plugins/kimchi/ui/pages/help/it_IT/host.dita
delete mode 100644 plugins/kimchi/ui/pages/help/it_IT/network.dita
delete mode 100644 plugins/kimchi/ui/pages/help/it_IT/storage.dita
delete mode 100644 plugins/kimchi/ui/pages/help/it_IT/templates.dita
delete mode 100644 plugins/kimchi/ui/pages/help/ja_JP/Makefile.am
delete mode 100644 plugins/kimchi/ui/pages/help/ja_JP/guests.dita
delete mode 100644 plugins/kimchi/ui/pages/help/ja_JP/host.dita
delete mode 100644 plugins/kimchi/ui/pages/help/ja_JP/network.dita
delete mode 100644 plugins/kimchi/ui/pages/help/ja_JP/storage.dita
delete mode 100644 plugins/kimchi/ui/pages/help/ja_JP/templates.dita
delete mode 100644 plugins/kimchi/ui/pages/help/kimchi.css
delete mode 100644 plugins/kimchi/ui/pages/help/ko_KR/Makefile.am
delete mode 100644 plugins/kimchi/ui/pages/help/ko_KR/guests.dita
delete mode 100644 plugins/kimchi/ui/pages/help/ko_KR/host.dita
delete mode 100644 plugins/kimchi/ui/pages/help/ko_KR/network.dita
delete mode 100644 plugins/kimchi/ui/pages/help/ko_KR/storage.dita
delete mode 100644 plugins/kimchi/ui/pages/help/ko_KR/templates.dita
delete mode 100644 plugins/kimchi/ui/pages/help/pt_BR/Makefile.am
delete mode 100644 plugins/kimchi/ui/pages/help/pt_BR/guests.dita
delete mode 100644 plugins/kimchi/ui/pages/help/pt_BR/host.dita
delete mode 100644 plugins/kimchi/ui/pages/help/pt_BR/network.dita
delete mode 100644 plugins/kimchi/ui/pages/help/pt_BR/storage.dita
delete mode 100644 plugins/kimchi/ui/pages/help/pt_BR/templates.dita
delete mode 100644 plugins/kimchi/ui/pages/help/ru_RU/Makefile.am
delete mode 100644 plugins/kimchi/ui/pages/help/ru_RU/guests.dita
delete mode 100644 plugins/kimchi/ui/pages/help/ru_RU/host.dita
delete mode 100644 plugins/kimchi/ui/pages/help/ru_RU/network.dita
delete mode 100644 plugins/kimchi/ui/pages/help/ru_RU/storage.dita
delete mode 100644 plugins/kimchi/ui/pages/help/ru_RU/templates.dita
delete mode 100644 plugins/kimchi/ui/pages/help/zh_CN/Makefile.am
delete mode 100644 plugins/kimchi/ui/pages/help/zh_CN/guests.dita
delete mode 100644 plugins/kimchi/ui/pages/help/zh_CN/host.dita
delete mode 100644 plugins/kimchi/ui/pages/help/zh_CN/network.dita
delete mode 100644 plugins/kimchi/ui/pages/help/zh_CN/storage.dita
delete mode 100644 plugins/kimchi/ui/pages/help/zh_CN/templates.dita
delete mode 100644 plugins/kimchi/ui/pages/help/zh_TW/Makefile.am
delete mode 100644 plugins/kimchi/ui/pages/help/zh_TW/guests.dita
delete mode 100644 plugins/kimchi/ui/pages/help/zh_TW/host.dita
delete mode 100644 plugins/kimchi/ui/pages/help/zh_TW/network.dita
delete mode 100644 plugins/kimchi/ui/pages/help/zh_TW/storage.dita
delete mode 100644 plugins/kimchi/ui/pages/help/zh_TW/templates.dita
delete mode 100644 plugins/kimchi/ui/pages/host.html.tmpl
delete mode 100644 plugins/kimchi/ui/pages/i18n.json.tmpl
delete mode 100644 plugins/kimchi/ui/pages/network.html.tmpl
delete mode 100644 plugins/kimchi/ui/pages/report-add.html.tmpl
delete mode 100644 plugins/kimchi/ui/pages/report-rename.html.tmpl
delete mode 100644 plugins/kimchi/ui/pages/repository-add.html.tmpl
delete mode 100644 plugins/kimchi/ui/pages/repository-edit.html.tmpl
delete mode 100644 plugins/kimchi/ui/pages/storage.html.tmpl
delete mode 100644 plugins/kimchi/ui/pages/storagepool-add-volume.html.tmpl
delete mode 100644 plugins/kimchi/ui/pages/storagepool-add.html.tmpl
delete mode 100644 plugins/kimchi/ui/pages/template-add.html.tmpl
delete mode 100644 plugins/kimchi/ui/pages/template-edit.html.tmpl
delete mode 100644 plugins/kimchi/ui/pages/templates.html.tmpl
delete mode 100644 plugins/kimchi/ui/robots.txt
delete mode 100644 plugins/kimchi/ui/spice-html5/Makefile.am
delete mode 100644 plugins/kimchi/ui/spice-html5/atKeynames.js
delete mode 100644 plugins/kimchi/ui/spice-html5/bitmap.js
delete mode 100644 plugins/kimchi/ui/spice-html5/css/Makefile.am
delete mode 100644 plugins/kimchi/ui/spice-html5/css/spice.css
delete mode 100644 plugins/kimchi/ui/spice-html5/cursor.js
delete mode 100644 plugins/kimchi/ui/spice-html5/display.js
delete mode 100644 plugins/kimchi/ui/spice-html5/enums.js
delete mode 100644 plugins/kimchi/ui/spice-html5/inputs.js
delete mode 100644 plugins/kimchi/ui/spice-html5/lz.js
delete mode 100644 plugins/kimchi/ui/spice-html5/main.js
delete mode 100644 plugins/kimchi/ui/spice-html5/pages/Makefile.am
delete mode 100644 plugins/kimchi/ui/spice-html5/pages/spice_auto.html
delete mode 100644 plugins/kimchi/ui/spice-html5/playback.js
delete mode 100644 plugins/kimchi/ui/spice-html5/png.js
delete mode 100644 plugins/kimchi/ui/spice-html5/quic.js
delete mode 100644 plugins/kimchi/ui/spice-html5/resize.js
delete mode 100644 plugins/kimchi/ui/spice-html5/simulatecursor.js
delete mode 100644 plugins/kimchi/ui/spice-html5/spicearraybuffer.js
delete mode 100644 plugins/kimchi/ui/spice-html5/spiceconn.js
delete mode 100644 plugins/kimchi/ui/spice-html5/spicedataview.js
delete mode 100644 plugins/kimchi/ui/spice-html5/spicemsg.js
delete mode 100644 plugins/kimchi/ui/spice-html5/spicetype.js
delete mode 100644 plugins/kimchi/ui/spice-html5/thirdparty/Makefile.am
delete mode 100644 plugins/kimchi/ui/spice-html5/thirdparty/jsbn.js
delete mode 100644 plugins/kimchi/ui/spice-html5/thirdparty/prng4.js
delete mode 100644 plugins/kimchi/ui/spice-html5/thirdparty/rng.js
delete mode 100644 plugins/kimchi/ui/spice-html5/thirdparty/rsa.js
delete mode 100644 plugins/kimchi/ui/spice-html5/thirdparty/sha1.js
delete mode 100644 plugins/kimchi/ui/spice-html5/ticket.js
delete mode 100644 plugins/kimchi/ui/spice-html5/utils.js
delete mode 100644 plugins/kimchi/ui/spice-html5/webm.js
delete mode 100644 plugins/kimchi/ui/spice-html5/wire.js
delete mode 100644 plugins/kimchi/utils.py
delete mode 100644 plugins/kimchi/vmtemplate.py
delete mode 100644 plugins/kimchi/vnc.py
delete mode 100644 plugins/kimchi/xmlutils/Makefile.am
delete mode 100644 plugins/kimchi/xmlutils/__init__.py
delete mode 100644 plugins/kimchi/xmlutils/cpu.py
delete mode 100644 plugins/kimchi/xmlutils/disk.py
delete mode 100644 plugins/kimchi/xmlutils/graphics.py
delete mode 100644 plugins/kimchi/xmlutils/interface.py
delete mode 100644 plugins/kimchi/xmlutils/network.py
delete mode 100644 plugins/kimchi/xmlutils/qemucmdline.py
delete mode 100644 plugins/kimchi/yumparser.py
delete mode 100644 plugins/sample/API.json
delete mode 100644 plugins/sample/Makefile.am
delete mode 100644 plugins/sample/__init__.py
delete mode 120000 plugins/sample/config.status
delete mode 100644 plugins/sample/i18n.py
delete mode 100644 plugins/sample/model.py
delete mode 100644 plugins/sample/po/LINGUAS
delete mode 100644 plugins/sample/po/Makefile.in.in
delete mode 100644 plugins/sample/po/Makevars
delete mode 100644 plugins/sample/po/POTFILES.in
delete mode 100644 plugins/sample/po/en_US.po
delete mode 100755 plugins/sample/po/gen-pot
delete mode 100644 plugins/sample/po/pt_BR.po
delete mode 100644 plugins/sample/po/sample.pot
delete mode 100644 plugins/sample/po/zh_CN.po
delete mode 100644 plugins/sample/sample.conf.in
delete mode 100644 plugins/sample/ui/Makefile.am
delete mode 100644 plugins/sample/ui/config/Makefile.am
delete mode 100644 plugins/sample/ui/config/tab-ext.xml
delete mode 100644 plugins/sample/ui/css/.gitignore
delete mode 100644 plugins/sample/ui/images/.gitignore
delete mode 100644 plugins/sample/ui/js/.gitignore
delete mode 100644 plugins/sample/ui/js/Makefile.am
delete mode 100644 plugins/sample/ui/js/util.js
delete mode 100644 plugins/sample/ui/libs/.gitignore
delete mode 100644 plugins/sample/ui/pages/Makefile.am
delete mode 100644 plugins/sample/ui/pages/help/en_US/sample-tab1.html
delete mode 100644 plugins/sample/ui/pages/help/en_US/sample-tab2.html
delete mode 100644 plugins/sample/ui/pages/i18n.json.tmpl
delete mode 100644 plugins/sample/ui/pages/sample-tab1.html.tmpl
delete mode 100644 plugins/sample/ui/pages/sample-tab2.html.tmpl
create mode 100644 src/wok/plugins/Makefile.am
create mode 100644 src/wok/plugins/__init__.py
create mode 100644 src/wok/plugins/kimchi/.gitignore
create mode 100644 src/wok/plugins/kimchi/API.json
create mode 100644 src/wok/plugins/kimchi/INSTALL
create mode 100644 src/wok/plugins/kimchi/Makefile.am
create mode 120000 src/wok/plugins/kimchi/README.md
create mode 100644 src/wok/plugins/kimchi/VERSION
create mode 100644 src/wok/plugins/kimchi/__init__.py
create mode 100755 src/wok/plugins/kimchi/autogen.sh
create mode 100644 src/wok/plugins/kimchi/build-aux/config.rpath
create mode 100755 src/wok/plugins/kimchi/build-aux/genChangelog
create mode 100755 src/wok/plugins/kimchi/build-aux/pkg-version
create mode 100644 src/wok/plugins/kimchi/config.py.in
create mode 100644 src/wok/plugins/kimchi/config.rpath
create mode 100644 src/wok/plugins/kimchi/configure.ac
create mode 100644 src/wok/plugins/kimchi/contrib/DEBIAN/Makefile.am
create mode 100644 src/wok/plugins/kimchi/contrib/DEBIAN/control.in
create mode 100644 src/wok/plugins/kimchi/contrib/Makefile.am
create mode 100755 src/wok/plugins/kimchi/contrib/check_i18n.py
create mode 100644 src/wok/plugins/kimchi/contrib/kimchi.spec.fedora.in
create mode 100644 src/wok/plugins/kimchi/contrib/kimchi.spec.suse.in
create mode 100644 src/wok/plugins/kimchi/contrib/make-deb.sh.in
create mode 100644 src/wok/plugins/kimchi/control/Makefile.am
create mode 100644 src/wok/plugins/kimchi/control/__init__.py
create mode 100644 src/wok/plugins/kimchi/control/config.py
create mode 100644 src/wok/plugins/kimchi/control/cpuinfo.py
create mode 100644 src/wok/plugins/kimchi/control/debugreports.py
create mode 100644 src/wok/plugins/kimchi/control/groups.py
create mode 100644 src/wok/plugins/kimchi/control/host.py
create mode 100644 src/wok/plugins/kimchi/control/interfaces.py
create mode 100644 src/wok/plugins/kimchi/control/networks.py
create mode 100644 src/wok/plugins/kimchi/control/peers.py
create mode 100644 src/wok/plugins/kimchi/control/storagepools.py
create mode 100644 src/wok/plugins/kimchi/control/storageservers.py
create mode 100644 src/wok/plugins/kimchi/control/storagevolumes.py
create mode 100644 src/wok/plugins/kimchi/control/templates.py
create mode 100644 src/wok/plugins/kimchi/control/users.py
create mode 100644 src/wok/plugins/kimchi/control/vm/Makefile.am
create mode 100644 src/wok/plugins/kimchi/control/vm/__init__.py
create mode 100644 src/wok/plugins/kimchi/control/vm/hostdevs.py
create mode 100644 src/wok/plugins/kimchi/control/vm/ifaces.py
create mode 100644 src/wok/plugins/kimchi/control/vm/snapshots.py
create mode 100644 src/wok/plugins/kimchi/control/vm/storages.py
create mode 100644 src/wok/plugins/kimchi/control/vms.py
create mode 100644 src/wok/plugins/kimchi/disks.py
create mode 100644 src/wok/plugins/kimchi/distroloader.py
create mode 100644 src/wok/plugins/kimchi/distros.d/Makefile.am
create mode 100644 src/wok/plugins/kimchi/distros.d/debian.json
create mode 100644 src/wok/plugins/kimchi/distros.d/fedora.json
create mode 100644 src/wok/plugins/kimchi/distros.d/gentoo.json
create mode 100644 src/wok/plugins/kimchi/distros.d/opensuse.json
create mode 100644 src/wok/plugins/kimchi/distros.d/ubuntu.json
create mode 100644 src/wok/plugins/kimchi/docs/API.md
create mode 100644 src/wok/plugins/kimchi/docs/Makefile.am
create mode 100644 src/wok/plugins/kimchi/docs/README-federation.md
create mode 100644 src/wok/plugins/kimchi/docs/README.md
create mode 100644 src/wok/plugins/kimchi/docs/kimchi-guest.png
create mode 100644 src/wok/plugins/kimchi/docs/kimchi-login.png
create mode 100644 src/wok/plugins/kimchi/docs/kimchi-templates.png
create mode 100644 src/wok/plugins/kimchi/i18n.py
create mode 100644 src/wok/plugins/kimchi/imageinfo.py
create mode 100644 src/wok/plugins/kimchi/iscsi.py
create mode 100644 src/wok/plugins/kimchi/isoinfo.py
create mode 100644 src/wok/plugins/kimchi/kimchi.conf
create mode 100644 src/wok/plugins/kimchi/kvmusertests.py
create mode 100644 src/wok/plugins/kimchi/m4/ac_python_module.m4
create mode 100644 src/wok/plugins/kimchi/m4/gettext.m4
create mode 100644 src/wok/plugins/kimchi/m4/iconv.m4
create mode 100644 src/wok/plugins/kimchi/m4/intlmacosx.m4
create mode 100644 src/wok/plugins/kimchi/m4/lib-ld.m4
create mode 100644 src/wok/plugins/kimchi/m4/lib-link.m4
create mode 100644 src/wok/plugins/kimchi/m4/lib-prefix.m4
create mode 100644 src/wok/plugins/kimchi/m4/nls.m4
create mode 100644 src/wok/plugins/kimchi/m4/po.m4
create mode 100644 src/wok/plugins/kimchi/m4/progtest.m4
create mode 100644 src/wok/plugins/kimchi/mockmodel.py
create mode 100644 src/wok/plugins/kimchi/model/Makefile.am
create mode 100644 src/wok/plugins/kimchi/model/__init__.py
create mode 100644 src/wok/plugins/kimchi/model/config.py
create mode 100644 src/wok/plugins/kimchi/model/cpuinfo.py
create mode 100644 src/wok/plugins/kimchi/model/debugreports.py
create mode 100644 src/wok/plugins/kimchi/model/diskutils.py
create mode 100644 src/wok/plugins/kimchi/model/featuretests.py
create mode 100644 src/wok/plugins/kimchi/model/groups.py
create mode 100644 src/wok/plugins/kimchi/model/host.py
create mode 100644 src/wok/plugins/kimchi/model/hostdev.py
create mode 100644 src/wok/plugins/kimchi/model/interfaces.py
create mode 100644 src/wok/plugins/kimchi/model/libvirtconnection.py
create mode 100644 src/wok/plugins/kimchi/model/libvirtstoragepool.py
create mode 100644 src/wok/plugins/kimchi/model/model.py
create mode 100644 src/wok/plugins/kimchi/model/networks.py
create mode 100644 src/wok/plugins/kimchi/model/peers.py
create mode 100644 src/wok/plugins/kimchi/model/storagepools.py
create mode 100644 src/wok/plugins/kimchi/model/storageservers.py
create mode 100644 src/wok/plugins/kimchi/model/storagetargets.py
create mode 100644 src/wok/plugins/kimchi/model/storagevolumes.py
create mode 100644 src/wok/plugins/kimchi/model/templates.py
create mode 100644 src/wok/plugins/kimchi/model/users.py
create mode 100644 src/wok/plugins/kimchi/model/utils.py
create mode 100644 src/wok/plugins/kimchi/model/vmhostdevs.py
create mode 100644 src/wok/plugins/kimchi/model/vmifaces.py
create mode 100644 src/wok/plugins/kimchi/model/vms.py
create mode 100644 src/wok/plugins/kimchi/model/vmsnapshots.py
create mode 100644 src/wok/plugins/kimchi/model/vmstorages.py
create mode 100644 src/wok/plugins/kimchi/netinfo.py
create mode 100644 src/wok/plugins/kimchi/network.py
create mode 100644 src/wok/plugins/kimchi/osinfo.py
create mode 100644 src/wok/plugins/kimchi/po/LINGUAS
create mode 100644 src/wok/plugins/kimchi/po/Makefile.in.in
create mode 100644 src/wok/plugins/kimchi/po/Makevars
create mode 100644 src/wok/plugins/kimchi/po/POTFILES.in
create mode 100644 src/wok/plugins/kimchi/po/de_DE.po
create mode 100644 src/wok/plugins/kimchi/po/en_US.po
create mode 100644 src/wok/plugins/kimchi/po/es_ES.po
create mode 100644 src/wok/plugins/kimchi/po/fr_FR.po
create mode 100644 src/wok/plugins/kimchi/po/gen-pot.in
create mode 100644 src/wok/plugins/kimchi/po/it_IT.po
create mode 100644 src/wok/plugins/kimchi/po/ja_JP.po
create mode 100755 src/wok/plugins/kimchi/po/kimchi.pot
create mode 100644 src/wok/plugins/kimchi/po/ko_KR.po
create mode 100644 src/wok/plugins/kimchi/po/pt_BR.po
create mode 100644 src/wok/plugins/kimchi/po/ru_RU.po
create mode 100644 src/wok/plugins/kimchi/po/zh_CN.po
create mode 100644 src/wok/plugins/kimchi/po/zh_TW.po
create mode 100644 src/wok/plugins/kimchi/repositories.py
create mode 100644 src/wok/plugins/kimchi/root.py
create mode 100644 src/wok/plugins/kimchi/scan.py
create mode 100644 src/wok/plugins/kimchi/screenshot.py
create mode 100644 src/wok/plugins/kimchi/swupdate.py
create mode 100644 src/wok/plugins/kimchi/template.conf
create mode 100644 src/wok/plugins/kimchi/tests/Makefile.am
create mode 100644 src/wok/plugins/kimchi/tests/iso_gen.py
create mode 100644 src/wok/plugins/kimchi/tests/run_tests.sh.in
create mode 100644 src/wok/plugins/kimchi/tests/test_authorization.py
create mode 100644 src/wok/plugins/kimchi/tests/test_config.py.in
create mode 100644 src/wok/plugins/kimchi/tests/test_exception.py
create mode 100644 src/wok/plugins/kimchi/tests/test_host.py
create mode 100644 src/wok/plugins/kimchi/tests/test_mock_network.py
create mode 100644 src/wok/plugins/kimchi/tests/test_mock_storagepool.py
create mode 100644 src/wok/plugins/kimchi/tests/test_mock_storagevolume.py
create mode 100644 src/wok/plugins/kimchi/tests/test_mockmodel.py
create mode 100644 src/wok/plugins/kimchi/tests/test_model.py
create mode 100644 src/wok/plugins/kimchi/tests/test_model_network.py
create mode 100644 src/wok/plugins/kimchi/tests/test_model_storagepool.py
create mode 100644 src/wok/plugins/kimchi/tests/test_model_storagevolume.py
create mode 100644 src/wok/plugins/kimchi/tests/test_networkxml.py
create mode 100644 src/wok/plugins/kimchi/tests/test_objectstore.py
create mode 100644 src/wok/plugins/kimchi/tests/test_osinfo.py
create mode 100644 src/wok/plugins/kimchi/tests/test_plugin.py
create mode 100644 src/wok/plugins/kimchi/tests/test_rest.py
create mode 100644 src/wok/plugins/kimchi/tests/test_rollbackcontext.py
create mode 100644 src/wok/plugins/kimchi/tests/test_server.py
create mode 100644 src/wok/plugins/kimchi/tests/test_storagepoolxml.py
create mode 100644 src/wok/plugins/kimchi/tests/test_template.py
create mode 100644 src/wok/plugins/kimchi/tests/test_utils.py
create mode 100644 src/wok/plugins/kimchi/tests/test_vmtemplate.py
create mode 100644 src/wok/plugins/kimchi/tests/test_yumparser.py
create mode 100644 src/wok/plugins/kimchi/tests/utils.py
create mode 100644 src/wok/plugins/kimchi/ui/Makefile.am
create mode 100644 src/wok/plugins/kimchi/ui/config/Makefile.am
create mode 100644 src/wok/plugins/kimchi/ui/config/tab-ext.xml
create mode 100644 src/wok/plugins/kimchi/ui/css/Makefile.am
create mode 100644 src/wok/plugins/kimchi/ui/css/theme-default/guest-edit.css
create mode 100644 src/wok/plugins/kimchi/ui/css/theme-default/guest-storage-add.css
create mode 100644 src/wok/plugins/kimchi/ui/css/theme-default/host.css
create mode 100644 src/wok/plugins/kimchi/ui/css/theme-default/icon.css
create mode 100644 src/wok/plugins/kimchi/ui/css/theme-default/list.css
create mode 100644 src/wok/plugins/kimchi/ui/css/theme-default/network.css
create mode 100644 src/wok/plugins/kimchi/ui/css/theme-default/report-add.css
create mode 100644 src/wok/plugins/kimchi/ui/css/theme-default/report-rename.css
create mode 100644 src/wok/plugins/kimchi/ui/css/theme-default/repository-add.css
create mode 100644 src/wok/plugins/kimchi/ui/css/theme-default/repository-edit.css
create mode 100644 src/wok/plugins/kimchi/ui/css/theme-default/storage.css
create mode 100644
src/wok/plugins/kimchi/ui/css/theme-default/storagepool-add-volume.css
create mode 100644 src/wok/plugins/kimchi/ui/css/theme-default/template-edit.css
create mode 100644 src/wok/plugins/kimchi/ui/css/theme-default/template.css
create mode 100644 src/wok/plugins/kimchi/ui/css/theme-default/template_add.css
create mode 100644 src/wok/plugins/kimchi/ui/css/theme-default/template_list.css
create mode 100644 src/wok/plugins/kimchi/ui/images/Makefile.am
create mode 100644 src/wok/plugins/kimchi/ui/images/icon-centos.png
create mode 100644 src/wok/plugins/kimchi/ui/images/icon-debian.png
create mode 100644 src/wok/plugins/kimchi/ui/images/icon-fedora.png
create mode 100644 src/wok/plugins/kimchi/ui/images/icon-gentoo.png
create mode 100644 src/wok/plugins/kimchi/ui/images/icon-opensuse.png
create mode 100644 src/wok/plugins/kimchi/ui/images/icon-ubuntu.png
create mode 100644 src/wok/plugins/kimchi/ui/images/icon-vm.png
create mode 100644 src/wok/plugins/kimchi/ui/images/theme-default/Makefile.am
create mode 100644 src/wok/plugins/kimchi/ui/images/theme-default/ac22_pause.png
create mode 100644 src/wok/plugins/kimchi/ui/images/theme-default/ac22_pause_grey.png
create mode 100644 src/wok/plugins/kimchi/ui/images/theme-default/ac24_resume.png
create mode 100644 src/wok/plugins/kimchi/ui/images/theme-default/ac24_resume_grey.png
create mode 100644 src/wok/plugins/kimchi/ui/images/theme-default/arrow-down-black.png
create mode 100644 src/wok/plugins/kimchi/ui/images/theme-default/arrow-down-disable.png
create mode 100644 src/wok/plugins/kimchi/ui/images/theme-default/arrow-down.png
create mode 100644 src/wok/plugins/kimchi/ui/images/theme-default/arrow-up.png
create mode 100644 src/wok/plugins/kimchi/ui/images/theme-default/arrow_out.png
create mode 100644 src/wok/plugins/kimchi/ui/images/theme-default/group.png
create mode 100644 src/wok/plugins/kimchi/ui/images/theme-default/host-icon-sprite.png
create mode 100644 src/wok/plugins/kimchi/ui/images/theme-default/icon-back.png
create mode 100644 src/wok/plugins/kimchi/ui/images/theme-default/icon-camera.png
create mode 100644 src/wok/plugins/kimchi/ui/images/theme-default/icon-design.png
create mode 100644 src/wok/plugins/kimchi/ui/images/theme-default/icon-detail.png
create mode 100644 src/wok/plugins/kimchi/ui/images/theme-default/icon-iso.png
create mode 100644 src/wok/plugins/kimchi/ui/images/theme-default/icon-list.png
create mode 100644 src/wok/plugins/kimchi/ui/images/theme-default/icon-load.png
create mode 100644 src/wok/plugins/kimchi/ui/images/theme-default/icon-local.png
create mode 100644 src/wok/plugins/kimchi/ui/images/theme-default/icon-power-down.png
create mode 100644 src/wok/plugins/kimchi/ui/images/theme-default/icon-power-up.png
create mode 100644 src/wok/plugins/kimchi/ui/images/theme-default/icon-qcow2.png
create mode 100644 src/wok/plugins/kimchi/ui/images/theme-default/icon-raw.png
create mode 100644 src/wok/plugins/kimchi/ui/images/theme-default/icon-remote.png
create mode 100644 src/wok/plugins/kimchi/ui/images/theme-default/icon-reset.png
create mode 100644 src/wok/plugins/kimchi/ui/images/theme-default/icon-search.png
create mode 100644 src/wok/plugins/kimchi/ui/images/theme-default/icon-sort.png
create mode 100644 src/wok/plugins/kimchi/ui/images/theme-default/icon-tree.png
create mode 100644 src/wok/plugins/kimchi/ui/images/theme-default/icon-user.png
create mode 100644
src/wok/plugins/kimchi/ui/images/theme-default/icon-volume-default.png
create mode 100644
src/wok/plugins/kimchi/ui/images/theme-default/kimchi-loading15x15.gif
create mode 100644 src/wok/plugins/kimchi/ui/images/theme-default/loading.gif
create mode 100644 src/wok/plugins/kimchi/ui/images/theme-default/user.png
create mode 100644 src/wok/plugins/kimchi/ui/js/Makefile.am
create mode 100644 src/wok/plugins/kimchi/ui/js/src/kimchi.api.js
create mode 100644 src/wok/plugins/kimchi/ui/js/src/kimchi.guest_add_main.js
create mode 100644 src/wok/plugins/kimchi/ui/js/src/kimchi.guest_edit_main.js
create mode 100644 src/wok/plugins/kimchi/ui/js/src/kimchi.guest_main.js
create mode 100644 src/wok/plugins/kimchi/ui/js/src/kimchi.guest_media_main.js
create mode 100644 src/wok/plugins/kimchi/ui/js/src/kimchi.guest_storage_add.main.js
create mode 100644 src/wok/plugins/kimchi/ui/js/src/kimchi.host.js
create mode 100644 src/wok/plugins/kimchi/ui/js/src/kimchi.main.js
create mode 100644 src/wok/plugins/kimchi/ui/js/src/kimchi.network.js
create mode 100644 src/wok/plugins/kimchi/ui/js/src/kimchi.report_add_main.js
create mode 100644 src/wok/plugins/kimchi/ui/js/src/kimchi.report_rename_main.js
create mode 100644 src/wok/plugins/kimchi/ui/js/src/kimchi.repository_add_main.js
create mode 100644 src/wok/plugins/kimchi/ui/js/src/kimchi.repository_edit_main.js
create mode 100644 src/wok/plugins/kimchi/ui/js/src/kimchi.storage_main.js
create mode 100644 src/wok/plugins/kimchi/ui/js/src/kimchi.storagepool_add_main.js
create mode 100644
src/wok/plugins/kimchi/ui/js/src/kimchi.storagepool_add_volume_main.js
create mode 100644 src/wok/plugins/kimchi/ui/js/src/kimchi.template_add_main.js
create mode 100644 src/wok/plugins/kimchi/ui/js/src/kimchi.template_edit_main.js
create mode 100644 src/wok/plugins/kimchi/ui/js/src/kimchi.template_main.js
create mode 100644 src/wok/plugins/kimchi/ui/pages/Makefile.am
create mode 100644 src/wok/plugins/kimchi/ui/pages/guest-add.html.tmpl
create mode 100644 src/wok/plugins/kimchi/ui/pages/guest-edit.html.tmpl
create mode 100644 src/wok/plugins/kimchi/ui/pages/guest-storage-add.html.tmpl
create mode 100644 src/wok/plugins/kimchi/ui/pages/guest.html.tmpl
create mode 100644 src/wok/plugins/kimchi/ui/pages/guests.html.tmpl
create mode 100644 src/wok/plugins/kimchi/ui/pages/help/Makefile.am
create mode 100644 src/wok/plugins/kimchi/ui/pages/help/de_DE/Makefile.am
create mode 100644 src/wok/plugins/kimchi/ui/pages/help/de_DE/guests.dita
create mode 100644 src/wok/plugins/kimchi/ui/pages/help/de_DE/host.dita
create mode 100644 src/wok/plugins/kimchi/ui/pages/help/de_DE/network.dita
create mode 100644 src/wok/plugins/kimchi/ui/pages/help/de_DE/storage.dita
create mode 100644 src/wok/plugins/kimchi/ui/pages/help/de_DE/templates.dita
create mode 100644 src/wok/plugins/kimchi/ui/pages/help/dita-help.xsl
create mode 100644 src/wok/plugins/kimchi/ui/pages/help/en_US/Makefile.am
create mode 100644 src/wok/plugins/kimchi/ui/pages/help/en_US/guests.dita
create mode 100644 src/wok/plugins/kimchi/ui/pages/help/en_US/host.dita
create mode 100644 src/wok/plugins/kimchi/ui/pages/help/en_US/network.dita
create mode 100644 src/wok/plugins/kimchi/ui/pages/help/en_US/storage.dita
create mode 100644 src/wok/plugins/kimchi/ui/pages/help/en_US/templates.dita
create mode 100644 src/wok/plugins/kimchi/ui/pages/help/es_ES/Makefile.am
create mode 100644 src/wok/plugins/kimchi/ui/pages/help/es_ES/guests.dita
create mode 100644 src/wok/plugins/kimchi/ui/pages/help/es_ES/host.dita
create mode 100644 src/wok/plugins/kimchi/ui/pages/help/es_ES/network.dita
create mode 100644 src/wok/plugins/kimchi/ui/pages/help/es_ES/storage.dita
create mode 100644 src/wok/plugins/kimchi/ui/pages/help/es_ES/templates.dita
create mode 100644 src/wok/plugins/kimchi/ui/pages/help/fr_FR/Makefile.am
create mode 100644 src/wok/plugins/kimchi/ui/pages/help/fr_FR/guests.dita
create mode 100644 src/wok/plugins/kimchi/ui/pages/help/fr_FR/host.dita
create mode 100644 src/wok/plugins/kimchi/ui/pages/help/fr_FR/network.dita
create mode 100644 src/wok/plugins/kimchi/ui/pages/help/fr_FR/storage.dita
create mode 100644 src/wok/plugins/kimchi/ui/pages/help/fr_FR/templates.dita
create mode 100644 src/wok/plugins/kimchi/ui/pages/help/it_IT/Makefile.am
create mode 100644 src/wok/plugins/kimchi/ui/pages/help/it_IT/guests.dita
create mode 100644 src/wok/plugins/kimchi/ui/pages/help/it_IT/host.dita
create mode 100644 src/wok/plugins/kimchi/ui/pages/help/it_IT/network.dita
create mode 100644 src/wok/plugins/kimchi/ui/pages/help/it_IT/storage.dita
create mode 100644 src/wok/plugins/kimchi/ui/pages/help/it_IT/templates.dita
create mode 100644 src/wok/plugins/kimchi/ui/pages/help/ja_JP/Makefile.am
create mode 100644 src/wok/plugins/kimchi/ui/pages/help/ja_JP/guests.dita
create mode 100644 src/wok/plugins/kimchi/ui/pages/help/ja_JP/host.dita
create mode 100644 src/wok/plugins/kimchi/ui/pages/help/ja_JP/network.dita
create mode 100644 src/wok/plugins/kimchi/ui/pages/help/ja_JP/storage.dita
create mode 100644 src/wok/plugins/kimchi/ui/pages/help/ja_JP/templates.dita
create mode 100644 src/wok/plugins/kimchi/ui/pages/help/kimchi.css
create mode 100644 src/wok/plugins/kimchi/ui/pages/help/ko_KR/Makefile.am
create mode 100644 src/wok/plugins/kimchi/ui/pages/help/ko_KR/guests.dita
create mode 100644 src/wok/plugins/kimchi/ui/pages/help/ko_KR/host.dita
create mode 100644 src/wok/plugins/kimchi/ui/pages/help/ko_KR/network.dita
create mode 100644 src/wok/plugins/kimchi/ui/pages/help/ko_KR/storage.dita
create mode 100644 src/wok/plugins/kimchi/ui/pages/help/ko_KR/templates.dita
create mode 100644 src/wok/plugins/kimchi/ui/pages/help/pt_BR/Makefile.am
create mode 100644 src/wok/plugins/kimchi/ui/pages/help/pt_BR/guests.dita
create mode 100644 src/wok/plugins/kimchi/ui/pages/help/pt_BR/host.dita
create mode 100644 src/wok/plugins/kimchi/ui/pages/help/pt_BR/network.dita
create mode 100644 src/wok/plugins/kimchi/ui/pages/help/pt_BR/storage.dita
create mode 100644 src/wok/plugins/kimchi/ui/pages/help/pt_BR/templates.dita
create mode 100644 src/wok/plugins/kimchi/ui/pages/help/ru_RU/Makefile.am
create mode 100644 src/wok/plugins/kimchi/ui/pages/help/ru_RU/guests.dita
create mode 100644 src/wok/plugins/kimchi/ui/pages/help/ru_RU/host.dita
create mode 100644 src/wok/plugins/kimchi/ui/pages/help/ru_RU/network.dita
create mode 100644 src/wok/plugins/kimchi/ui/pages/help/ru_RU/storage.dita
create mode 100644 src/wok/plugins/kimchi/ui/pages/help/ru_RU/templates.dita
create mode 100644 src/wok/plugins/kimchi/ui/pages/help/zh_CN/Makefile.am
create mode 100644 src/wok/plugins/kimchi/ui/pages/help/zh_CN/guests.dita
create mode 100644 src/wok/plugins/kimchi/ui/pages/help/zh_CN/host.dita
create mode 100644 src/wok/plugins/kimchi/ui/pages/help/zh_CN/network.dita
create mode 100644 src/wok/plugins/kimchi/ui/pages/help/zh_CN/storage.dita
create mode 100644 src/wok/plugins/kimchi/ui/pages/help/zh_CN/templates.dita
create mode 100644 src/wok/plugins/kimchi/ui/pages/help/zh_TW/Makefile.am
create mode 100644 src/wok/plugins/kimchi/ui/pages/help/zh_TW/guests.dita
create mode 100644 src/wok/plugins/kimchi/ui/pages/help/zh_TW/host.dita
create mode 100644 src/wok/plugins/kimchi/ui/pages/help/zh_TW/network.dita
create mode 100644 src/wok/plugins/kimchi/ui/pages/help/zh_TW/storage.dita
create mode 100644 src/wok/plugins/kimchi/ui/pages/help/zh_TW/templates.dita
create mode 100644 src/wok/plugins/kimchi/ui/pages/host.html.tmpl
create mode 100644 src/wok/plugins/kimchi/ui/pages/i18n.json.tmpl
create mode 100644 src/wok/plugins/kimchi/ui/pages/network.html.tmpl
create mode 100644 src/wok/plugins/kimchi/ui/pages/report-add.html.tmpl
create mode 100644 src/wok/plugins/kimchi/ui/pages/report-rename.html.tmpl
create mode 100644 src/wok/plugins/kimchi/ui/pages/repository-add.html.tmpl
create mode 100644 src/wok/plugins/kimchi/ui/pages/repository-edit.html.tmpl
create mode 100644 src/wok/plugins/kimchi/ui/pages/storage.html.tmpl
create mode 100644 src/wok/plugins/kimchi/ui/pages/storagepool-add-volume.html.tmpl
create mode 100644 src/wok/plugins/kimchi/ui/pages/storagepool-add.html.tmpl
create mode 100644 src/wok/plugins/kimchi/ui/pages/template-add.html.tmpl
create mode 100644 src/wok/plugins/kimchi/ui/pages/template-edit.html.tmpl
create mode 100644 src/wok/plugins/kimchi/ui/pages/templates.html.tmpl
create mode 100644 src/wok/plugins/kimchi/ui/robots.txt
create mode 100644 src/wok/plugins/kimchi/ui/spice-html5/Makefile.am
create mode 100644 src/wok/plugins/kimchi/ui/spice-html5/atKeynames.js
create mode 100644 src/wok/plugins/kimchi/ui/spice-html5/bitmap.js
create mode 100644 src/wok/plugins/kimchi/ui/spice-html5/css/Makefile.am
create mode 100644 src/wok/plugins/kimchi/ui/spice-html5/css/spice.css
create mode 100644 src/wok/plugins/kimchi/ui/spice-html5/cursor.js
create mode 100644 src/wok/plugins/kimchi/ui/spice-html5/display.js
create mode 100644 src/wok/plugins/kimchi/ui/spice-html5/enums.js
create mode 100644 src/wok/plugins/kimchi/ui/spice-html5/inputs.js
create mode 100644 src/wok/plugins/kimchi/ui/spice-html5/lz.js
create mode 100644 src/wok/plugins/kimchi/ui/spice-html5/main.js
create mode 100644 src/wok/plugins/kimchi/ui/spice-html5/pages/Makefile.am
create mode 100644 src/wok/plugins/kimchi/ui/spice-html5/pages/spice_auto.html
create mode 100644 src/wok/plugins/kimchi/ui/spice-html5/playback.js
create mode 100644 src/wok/plugins/kimchi/ui/spice-html5/png.js
create mode 100644 src/wok/plugins/kimchi/ui/spice-html5/quic.js
create mode 100644 src/wok/plugins/kimchi/ui/spice-html5/resize.js
create mode 100644 src/wok/plugins/kimchi/ui/spice-html5/simulatecursor.js
create mode 100644 src/wok/plugins/kimchi/ui/spice-html5/spicearraybuffer.js
create mode 100644 src/wok/plugins/kimchi/ui/spice-html5/spiceconn.js
create mode 100644 src/wok/plugins/kimchi/ui/spice-html5/spicedataview.js
create mode 100644 src/wok/plugins/kimchi/ui/spice-html5/spicemsg.js
create mode 100644 src/wok/plugins/kimchi/ui/spice-html5/spicetype.js
create mode 100644 src/wok/plugins/kimchi/ui/spice-html5/thirdparty/Makefile.am
create mode 100644 src/wok/plugins/kimchi/ui/spice-html5/thirdparty/jsbn.js
create mode 100644 src/wok/plugins/kimchi/ui/spice-html5/thirdparty/prng4.js
create mode 100644 src/wok/plugins/kimchi/ui/spice-html5/thirdparty/rng.js
create mode 100644 src/wok/plugins/kimchi/ui/spice-html5/thirdparty/rsa.js
create mode 100644 src/wok/plugins/kimchi/ui/spice-html5/thirdparty/sha1.js
create mode 100644 src/wok/plugins/kimchi/ui/spice-html5/ticket.js
create mode 100644 src/wok/plugins/kimchi/ui/spice-html5/utils.js
create mode 100644 src/wok/plugins/kimchi/ui/spice-html5/webm.js
create mode 100644 src/wok/plugins/kimchi/ui/spice-html5/wire.js
create mode 100644 src/wok/plugins/kimchi/utils.py
create mode 100644 src/wok/plugins/kimchi/vmtemplate.py
create mode 100644 src/wok/plugins/kimchi/vnc.py
create mode 100644 src/wok/plugins/kimchi/xmlutils/Makefile.am
create mode 100644 src/wok/plugins/kimchi/xmlutils/__init__.py
create mode 100644 src/wok/plugins/kimchi/xmlutils/cpu.py
create mode 100644 src/wok/plugins/kimchi/xmlutils/disk.py
create mode 100644 src/wok/plugins/kimchi/xmlutils/graphics.py
create mode 100644 src/wok/plugins/kimchi/xmlutils/interface.py
create mode 100644 src/wok/plugins/kimchi/xmlutils/network.py
create mode 100644 src/wok/plugins/kimchi/xmlutils/qemucmdline.py
create mode 100644 src/wok/plugins/kimchi/yumparser.py
create mode 100644 src/wok/plugins/sample/API.json
create mode 100644 src/wok/plugins/sample/Makefile.am
create mode 100644 src/wok/plugins/sample/__init__.py
create mode 120000 src/wok/plugins/sample/config.status
create mode 100644 src/wok/plugins/sample/i18n.py
create mode 100644 src/wok/plugins/sample/model.py
create mode 100644 src/wok/plugins/sample/po/LINGUAS
create mode 100644 src/wok/plugins/sample/po/Makefile.in.in
create mode 100644 src/wok/plugins/sample/po/Makevars
create mode 100644 src/wok/plugins/sample/po/POTFILES.in
create mode 100644 src/wok/plugins/sample/po/en_US.po
create mode 100755 src/wok/plugins/sample/po/gen-pot
create mode 100644 src/wok/plugins/sample/po/pt_BR.po
create mode 100644 src/wok/plugins/sample/po/sample.pot
create mode 100644 src/wok/plugins/sample/po/zh_CN.po
create mode 100644 src/wok/plugins/sample/sample.conf.in
create mode 100644 src/wok/plugins/sample/ui/Makefile.am
create mode 100644 src/wok/plugins/sample/ui/config/Makefile.am
create mode 100644 src/wok/plugins/sample/ui/config/tab-ext.xml
create mode 100644 src/wok/plugins/sample/ui/css/.gitignore
create mode 100644 src/wok/plugins/sample/ui/images/.gitignore
create mode 100644 src/wok/plugins/sample/ui/js/.gitignore
create mode 100644 src/wok/plugins/sample/ui/js/Makefile.am
create mode 100644 src/wok/plugins/sample/ui/js/util.js
create mode 100644 src/wok/plugins/sample/ui/libs/.gitignore
create mode 100644 src/wok/plugins/sample/ui/pages/Makefile.am
create mode 100644 src/wok/plugins/sample/ui/pages/help/en_US/sample-tab1.html
create mode 100644 src/wok/plugins/sample/ui/pages/help/en_US/sample-tab2.html
create mode 100644 src/wok/plugins/sample/ui/pages/i18n.json.tmpl
create mode 100644 src/wok/plugins/sample/ui/pages/sample-tab1.html.tmpl
create mode 100644 src/wok/plugins/sample/ui/pages/sample-tab2.html.tmpl
diff --git a/plugins/Makefile.am b/plugins/Makefile.am
deleted file mode 100644
index 21a6ece..0000000
--- a/plugins/Makefile.am
+++ /dev/null
@@ -1,25 +0,0 @@
-#
-# Kimchi
-#
-# Copyright IBM Corp, 2013
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-
-SUBDIRS = sample
-
-plugins_PYTHON = \
- __init__.py
-
-pluginsdir = $(pythondir)/wok/plugins
diff --git a/plugins/__init__.py b/plugins/__init__.py
deleted file mode 100644
index 0539a76..0000000
--- a/plugins/__init__.py
+++ /dev/null
@@ -1,18 +0,0 @@
-#
-# Project Kimchi
-#
-# Copyright IBM, Corp. 2013-2014
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
diff --git a/plugins/kimchi/.gitignore b/plugins/kimchi/.gitignore
deleted file mode 100644
index 1dae610..0000000
--- a/plugins/kimchi/.gitignore
+++ /dev/null
@@ -1,37 +0,0 @@
-*.pyc
-*~
-i18n/mo/*
-log
-data
-mo
-autom4te.cache
-Makefile
-Makefile.in
-aclocal.m4
-build-aux/compile
-build-aux/config.guess
-build-aux/config.sub
-build-aux/install-sh
-build-aux/missing
-build-aux/py-compile
-configure
-config.log
-config.py
-config.status
-contrib/DEBIAN/control
-contrib/kimchi.spec.fedora
-contrib/kimchi.spec.suse
-contrib/make-deb.sh
-*.min.css
-*.min.js
-*.gmo
-stamp-po
-kimchi-*.tar.gz
-tests/run_tests.sh
-tests/test_config.py
-po/POTFILES
-po/gen-pot
-*.orig
-*.rej
-*.pem
-ui/pages/help/*/*.html
diff --git a/plugins/kimchi/API.json b/plugins/kimchi/API.json
deleted file mode 100644
index f1f58ff..0000000
--- a/plugins/kimchi/API.json
+++ /dev/null
@@ -1,836 +0,0 @@
-{
- "$schema": "http://json-schema.org/draft-03/schema#",
- "title": "Kimchi API",
- "description": "Json schema for Kimchi API",
- "type": "object",
- "kimchitype": {
- "graphics": {
- "description": "Configure graphics parameters for the new
VM",
- "type": "object",
- "properties": {
- "type": {
- "enum": ["spice", "vnc"],
- "error": "KCHVM0014E"
- },
- "listen": {
- "error": "KCHVM0015E",
- "type": [
- {
- "type": "string",
- "format": "ip-address"
- },
- {
- "type": "string",
- "format": "ipv6"
- }
- ]
- }
- }
- },
- "cpu_info": {
- "description": "Configure CPU specifics for a VM.",
- "type": "object",
- "properties": {
- "topology": {
- "description": "Configure the guest CPU
topology.",
- "type": "object",
- "properties": {
- "sockets": {
- "type": "integer",
- "required": true,
- "minimum": 1,
- "error": "KCHTMPL0026E"
- },
- "cores": {
- "type": "integer",
- "required": true,
- "minimum": 1,
- "error": "KCHTMPL0026E"
- },
- "threads": {
- "type": "integer",
- "required": true,
- "minimum": 1,
- "error": "KCHTMPL0026E"
- }
- }
- }
- }
- }
- },
- "properties": {
- "debugreports_create": {
- "type": "object",
- "error": "KCHDR0006E",
- "properties": {
- "name": {
- "description": "The name for the debug report
file.",
- "type": "string",
- "pattern": "^[_A-Za-z0-9-]*$",
- "error": "KCHDR0007E"
- }
- }
- },
- "debugreport_update": {
- "type": "object",
- "properties": {
- "name": {
- "description": "New name of debug report",
- "type": "string",
- "pattern": "^[_A-Za-z0-9-]*$",
- "error": "KCHDR0007E"
- }
- },
- "additionalProperties": false
- },
- "storagepools_create": {
- "type": "object",
- "error": "KCHPOOL0026E",
- "properties": {
- "name": {
- "description": "The name of the Storage Pool",
- "type": "string",
- "minLength": 1,
- "pattern": "^[^/]*$",
- "required": true,
- "error": "KCHPOOL0016E"
- },
- "type": {
- "description": "The type of the defined Storage
Pool",
- "type": "string",
- "pattern":
"^dir|netfs|logical|kimchi-iso|iscsi|scsi$",
- "required": true,
- "error": "KCHPOOL0017E"
- },
- "path": {
- "description": "The path of the defined Storage
Pool",
- "type": "string",
- "error": "KCHPOOL0018E"
- },
- "source": {
- "description": "Dictionary containing source
information of the pool",
- "type": "object",
- "properties": {
- "host": {
- "description": "IP or hostname of server for a
pool backed from a remote host",
- "type": "string",
- "error": "KCHPOOL0019E"
- },
- "path": {
- "description": "Export path on NFS server for
NFS pool",
- "type": "string",
- "error": "KCHPOOL0018E"
- },
- "devices": {
- "description": "Array of devices to be used in
the Storage Pool",
- "type": "array",
- "minItems": 1,
- "uniqueItems": true,
- "error": "KCHPOOL0021E",
- "items": {
- "description": "Full path of the block
device node",
- "type": "string",
- "error": "KCHPOOL0020E"
- }
- },
- "target": {
- "description": "Target IQN of an iSCSI
pool",
- "type": "string",
- "error": "KCHPOOL0022E"
- },
- "port": {
- "description": "Listening port of a remote
storage server",
- "type": "integer",
- "minimum": 1,
- "maximum": 65535,
- "error": "KCHPOOL0023E"
- },
- "adapter_name": {
- "description": "SCSI host name",
- "type": "string",
- "error": "KCHPOOL0030E"
- },
- "auth": {
- "description": "Storage back-end
authentication information",
- "type": "object",
- "properties": {
- "username": {
- "description": "Login username of the
iSCSI target",
- "type": "string",
- "error": "KCHPOOL0024E"
- },
- "password": {
- "description": "Login password of the
iSCSI target",
- "type": "string",
- "error": "KCHPOOL0025E"
- }
- }
- }
- }
- }
- }
- },
- "storagepool_update": {
- "type": "object",
- "properties": {
- "autostart": {
- "description": "Set autostart value of the
pool",
- "type": "boolean"
- },
- "disks": {
- "description": "List of disks/partitions to be
added",
- "type": "array",
- "items": { "type": "string" },
- "minItems": 1,
- "uniqueItems": true
- }
- },
- "additionalProperties": false
- },
- "storagevolumes_create": {
- "type": "object",
- "properties": {
- "name": {
- "description": "The name of the Storage Volume",
- "type": "string",
- "minLength": 1,
- "error": "KCHVOL0013E"
- },
- "capacity": {
- "description": "The total size (MiB) of the storage
volume",
- "type": "number",
- "minimum": 1,
- "error": "KCHVOL0020E"
- },
- "upload": {
- "description": "When the storage volume will be
uploaded",
- "type": "boolean",
- "error": "KCHVOL0025E"
- },
- "allocation": {
- "description": "The size(MiB) of allocation when
create the storage volume",
- "type": "number",
- "minimum": 1,
- "error": "KCHVOL0014E"
- },
- "format": {
- "description": "The format of the volume",
- "type": "string",
- "pattern":
"^(|bochs|cloop|cow|dmg|qcow|qcow2|qed|raw|vmdk|vpc)$",
- "error": "KCHVOL0015E"
- },
- "url": {
- "description": "The remote URL of the storage
volume",
- "type": "string",
- "pattern": "^(http|ftp)[s]?://",
- "error": "KCHVOL0021E"
- }
- }
- },
- "storagevolume_update": {
- "type": "object",
- "properties": {
- "chunk": {
- "description": "Upload storage volume chunk",
- "error": "KCHVOL0024E",
- "required": true
- },
- "chunk_size": {
- "description": "Chunk size of uploaded storage
volume",
- "type": "string",
- "error": "KCHVOL0024E",
- "required": true
- }
- },
- "additionalProperties": false
- },
- "vms_create": {
- "type": "object",
- "error": "KCHVM0016E",
- "properties": {
- "name": {
- "description": "The name of the new VM",
- "type": "string",
- "pattern": "^[^/]*$",
- "error": "KCHVM0011E"
- },
- "template": {
- "description": "The URI of a template to use when
building a VM",
- "type": "string",
- "pattern":
"^/plugins/kimchi/templates/(.*?)/?$",
- "required": true,
- "error": "KCHVM0012E"
- },
- "storagepool": {
- "description": "Assign a specefic Storage Pool to the
new VM",
- "type": "string",
- "pattern":
"^/plugins/kimchi/storagepools/[^/]+/?$",
- "error": "KCHVM0013E"
- },
- "graphics": { "$ref":
"#/kimchitype/graphics" }
- }
- },
- "vm_update": {
- "type": "object",
- "properties": {
- "name": {
- "description": "New name of VM",
- "type": "string",
- "pattern": "^[^/]*$",
- "minLength": 1,
- "error": "KCHVM0011E"
- },
- "users": {
- "description": "Array of users who have permission to
the VM",
- "type": "array",
- "uniqueItems": true,
- "error": "KCHVM0023E",
- "items": {
- "description": "User name",
- "type": "string",
- "error": "KCHVM0024E"
- }
- },
- "groups": {
- "description": "Array of groups who have permission to
the VM",
- "type": "array",
- "uniqueItems": true,
- "error": "KCHVM0025E",
- "items": {
- "description": "Group name",
- "type": "string",
- "error": "KCHVM0026E"
- }
- },
- "graphics": {
- "description": "Graphics information from
guest",
- "type": "object",
- "properties": {
- "passwd": {
- "description": "New graphics password.",
- "type": "string",
- "error": "KCHVM0031E"
- },
- "passwdValidTo": {
- "description": "Life time for the graphics
password.",
- "type": "number",
- "error": "KCHVM0032E"
- }
- }
- },
- "cpus": {
- "description": "The new number of virtual CPUs for the
VM",
- "type": "integer",
- "minimum": 1,
- "error": "KCHTMPL0012E"
- },
- "memory": {
- "description": "The new amount (MB) of memory for the
VM",
- "type": "integer",
- "minimum": 512,
- "error": "KCHTMPL0013E"
- }
- },
- "additionalProperties": false
- },
- "networks_create": {
- "type": "object",
- "error": "KCHNET0016E",
- "properties": {
- "name": {
- "description": "The name of the new network",
- "type": "string",
- "minLength": 1,
- "pattern": "^[^/\"]*$",
- "required": true,
- "error": "KCHNET0011E"
- },
- "connection": {
- "description": "Specifies how this network should be
connected to the other networks",
- "type": "string",
- "pattern": "^isolated|nat|bridge$",
- "required": true,
- "error": "KCHNET0012E"
- },
- "subnet": {
- "description": "Network segment in slash-separated
format with ip address and prefix or netmask",
- "type": "string",
- "error": "KCHNET0013E"
- },
- "interface": {
- "description": "The name of a network interface on the
host",
- "type": "string",
- "error": "KCHNET0014E"
- },
- "vlan_id": {
- "description": "Network's VLAN ID",
- "type": "integer",
- "maximum": 4094,
- "minimum": 1,
- "error": "KCHNET0015E"
- }
- }
- },
- "vmifaces_create": {
- "type": "object",
- "error": "KCHVMIF0007E",
- "properties": {
- "type": {
- "description": "The type of VM network interface that
libvirt supports",
- "type": "string",
- "pattern": "^network$",
- "required": true,
- "error": "KCHVMIF0004E"
- },
- "network": {
- "description": "the name of one available
network",
- "minLength": 1,
- "type": "string",
- "error": "KCHVMIF0005E"
- },
- "model": {
- "description": "model of emulated network interface
card",
- "type": "string",
- "pattern":
"^ne2k_pci|i82551|i82557b|i82559er|rtl8139|e1000|pcnet|virtio$",
- "error": "KCHVMIF0006E"
- },
- "mac": {
- "description": "Network Interface Card MAC
address",
- "type": "string",
- "pattern":
"(^$)|^(([0-9a-fA-F]{2}:){5}[0-9a-fA-F]{2}$)",
- "error": "KCHVMIF0010E"
- }
- }
- },
- "vmiface_update": {
- "type": "object",
- "error": "KCHVMIF0008E",
- "properties": {
- "mac": {
- "description": "Network Interface Card MAC
address",
- "type": "string",
- "pattern":
"^([0-9a-fA-F]{2}:){5}[0-9a-fA-F]{2}$",
- "error": "KCHVMIF0010E"
- }
- }
- },
- "templates_create": {
- "type": "object",
- "error": "KCHTMPL0016E",
- "properties": {
- "name": {
- "description": "The name of the template",
- "type": "string",
- "pattern": "^[^ ]+( +[^ ]+)*$",
- "minLength": 1,
- "error": "KCHTMPL0008E"
- },
- "icon": {
- "description": "The template icon path",
- "type": "string",
- "pattern": "^/plugins/kimchi/images/",
- "error": "KCHTMPL0009E"
- },
- "os_distro": {
- "description": "Distribution name of the Operating
System",
- "type": "string",
- "minLength": 1,
- "error": "KCHTMPL0010E"
- },
- "os_version": {
- "description": "Version of the Operating
System",
- "type": "string",
- "minLength": 1,
- "error": "KCHTMPL0011E"
- },
- "cpus": {
- "description": "Number of CPUs for the
template",
- "type": "integer",
- "minimum": 1,
- "error": "KCHTMPL0012E"
- },
- "memory": {
- "description": "Memory (MB) for the template",
- "type": "integer",
- "minimum": 512,
- "error": "KCHTMPL0013E"
- },
- "cdrom": {
- "description": "Path for cdrom",
- "type": "string",
- "pattern":
"^((/)|(http)[s]?:|[t]?(ftp)[s]?:)+.*$",
- "error": "KCHTMPL0014E"
- },
- "disks": {
- "description": "List of disks",
- "type": "array",
- "items": {
- "type": "object",
- "properties": {
- "index": {
- "description": "Index of the disk",
- "type": "integer",
- "minimum": 0
- },
- "size": {
- "description": "Size (GB) of the
disk",
- "type": "number",
- "minimum": 1,
- "error": "KCHTMPL0022E"
- },
- "base": {
- "description": "Base image of the
disk",
- "type": "string",
- "pattern": "^/.+$",
- "error": "KCHTMPL0023E"
- }
-
- }
- },
- "minItems": 1,
- "uniqueItems": true
- },
- "storagepool": {
- "description": "Location of the storage pool",
- "type": "string",
- "pattern":
"^/plugins/kimchi/storagepools/[^/]+/?$",
- "error": "KCHTMPL0015E"
- },
- "networks": {
- "description": "list of which networks will be
assigned to the new VM.",
- "type": "array",
- "items": { "type": "string" },
- "error": "KCHTMPL0017E"
- },
- "folder": {
- "description": "Folder",
- "type": "array",
- "items": { "type": "string" }
- },
- "graphics": { "$ref":
"#/kimchitype/graphics" },
- "cpu_info": { "$ref":
"#/kimchitype/cpu_info" }
- },
- "additionalProperties": false,
- "error": "KCHAPI0001E"
- },
- "storageservers_get_list": {
- "type": "object",
- "properties": {
- "_target_type": {
- "description": "List storage servers of given
type",
- "type": "string",
- "pattern": "^netfs|iscsi$"
- }
- },
- "additionalProperties": false,
- "error": "KCHAPI0001E"
- },
- "storagetargets_get_list": {
- "type": "object",
- "properties": {
- "_target_type": {
- "description": "List storage servers of given
type",
- "type": "string",
- "pattern": "^netfs|iscsi$"
- },
- "_server_port": {
- "description": "the port of iscsi storage
servers",
- "type": "string",
- "pattern": "^[0-9]{1,5}$"
- }
- },
- "additionalProperties": false,
- "error": "KCHAPI0001E"
- },
- "vmstorages_create": {
- "type": "object",
- "error": "KCHVMSTOR0012E",
- "properties": {
- "type": {
- "description": "The storage type",
- "type": "string",
- "pattern": "^cdrom|disk$",
- "required": true,
- "error": "KCHVMSTOR0002E"
- },
- "pool": {
- "description": "Storage pool name disk image locate
in",
- "type": "string",
- "minLength": 1,
- "error": "KCHVMSTOR0012E"
- },
- "vol": {
- "description": "Storage volume name of disk
image",
- "type": "string",
- "minLength": 1,
- "error": "KCHVMSTOR0012E"
- },
- "path": {
- "description": "Path of iso image file or disk mount
point",
- "type": "string",
- "pattern":
"^((/)|(http)[s]?:|[t]?(ftp)[s]?:)+.*$",
- "error": "KCHVMSTOR0003E"
- }
- }
- },
- "vmstorage_update": {
- "type": "object",
- "error": "KCHVMSTOR0013E",
- "properties": {
- "path": {
- "description": "Path of iso image file or disk mount
point",
- "type": "string",
- "pattern":
"^(|(/)|(http)[s]?:|[t]?(ftp)[s]?:)+.*$",
- "required": true,
- "error": "KCHVMSTOR0003E"
- }
- },
- "additionalProperties": false
- },
- "template_update": {
- "type": "object",
- "properties": {
- "name": {
- "description": "The name of the template",
- "type": "string",
- "pattern": "^[^ ]+( +[^ ]+)*$",
- "minLength": 1,
- "error": "KCHTMPL0008E"
- },
- "icon": {
- "description": "The template icon path",
- "type": "string",
- "pattern": "^/plugins/kimchi/images/",
- "error": "KCHTMPL0009E"
- },
- "os_distro": {
- "description": "Distribution name of the Operating
System",
- "type": "string",
- "minLength": 1,
- "error": "KCHTMPL0010E"
- },
- "os_version": {
- "description": "Version of the Operating
System",
- "type": "string",
- "minLength": 1,
- "error": "KCHTMPL0011E"
- },
- "cpus": {
- "description": "Number of CPUs for the
template",
- "type": "integer",
- "minimum": 1,
- "error": "KCHTMPL0012E"
- },
- "memory": {
- "description": "Memory (MB) for the template",
- "type": "integer",
- "minimum": 512,
- "error": "KCHTMPL0013E"
- },
- "cdrom": {
- "description": "Path for cdrom",
- "type": "string",
- "pattern":
"^((/)|(http)[s]?:|[t]?(ftp)[s]?:)+.*$",
- "error": "KCHTMPL0014E"
- },
- "disks": {
- "description": "List of disks",
- "type": "array",
- "items": {
- "type": "object",
- "properties": {
- "index": {
- "description": "Index of the disk",
- "type": "integer",
- "minimum": 0
- },
- "size": {
- "description": "Size (GB) of the
disk",
- "type": "integer",
- "minimum": 1,
- "error": "KCHTMPL0022E"
- },
- "format": {
- "description": "Type of the image of the
disk",
- "type": "string",
- "pattern":
"^(bochs|cloop|cow|dmg|qcow|qcow2|qed|raw|vmdk|vpc)$",
- "error": "KCHTMPL0027E"
- }
- }
- },
- "minItems": 1,
- "uniqueItems": true
- },
- "storagepool": {
- "description": "Location of the storage pool",
- "type": "string",
- "pattern":
"^/plugins/kimchi/storagepools/[^/]+/?$",
- "error": "KCHTMPL0015E"
- },
- "networks": {
- "description": "list of which networks will be
assigned to the new VM.",
- "type": "array",
- "items": { "type": "string" },
- "error": "KCHTMPL0017E"
- },
- "folder": {
- "description": "Folder",
- "type": "array",
- "items": { "type": "string" }
- },
- "graphics": { "$ref":
"#/kimchitype/graphics" },
- "cpu_info": { "$ref":
"#/kimchitype/cpu_info" }
- },
- "additionalProperties": false,
- "error": "KCHAPI0001E"
- },
- "repositories_create": {
- "type": "object",
- "properties": {
- "repo_id": {
- "description": "Repository ID used for YUM
repository.",
- "type": "string",
- "error": "KCHREPOS0001E"
- },
- "baseurl": {
- "description": "URL to the directory where the
repodata directory of a repository is located. Can be an http://, ftp:// or file://
URL.",
- "type": "string",
- "error": "KCHREPOS0002E"
- },
- "config": {
- "description": "Dictionary containing repository
configuration",
- "type": "object",
- "error": "KCHREPOS0003E",
- "properties": {
- "dist": {
- "description": "Distribution to DEB
repository",
- "type": "string",
- "error": "KCHREPOS0004E"
- },
- "comps": {
- "description": "List of components to DEB
repository",
- "type": "array",
- "error": "KCHREPOS0005E",
- "uniqueItems": true,
- "items": {
- "description": "Component name",
- "type": "string",
- "error": "KCHREPOS0006E"
- }
- },
- "repo_name": {
- "description": "YUM repository name",
- "type": "string",
- "error": "KCHREPOS0023E"
- },
- "mirrorlist": {
- "description": "URL to a file containing a
list of baseurls",
- "type": "string",
- "error": "KCHREPOS0007E"
- },
- "metalink": {
- "description": "URL to a metalink file for the
repomd.xml",
- "type": "string",
- "error": "KCHREPOS0029E"
- }
- }
- }
- },
- "additionalProperties": false,
- "error": "KCHAPI0001E"
- },
- "repository_update": {
- "type": "object",
- "properties": {
- "baseurl": {
- "description": "URL to the directory where the
repodata directory of a repository is located. Can be an http://, ftp:// or file://
URL.",
- "type": "string",
- "error": "KCHREPOS0002E"
- },
- "config": {
- "description": "Dictionary containing repository
configuration",
- "type": "object",
- "error": "KCHREPOS0003E",
- "properties": {
- "dist": {
- "description": "Distribution to DEB
repository",
- "type": "string",
- "error": "KCHREPOS0004E"
- },
- "comps": {
- "description": "List of components to DEB
repository",
- "type": "array",
- "error": "KCHREPOS0005E",
- "uniqueItems": true,
- "items": {
- "description": "Component name",
- "type": "string",
- "error": "KCHREPOS0006E"
- }
- },
- "repo_name": {
- "description": "Human-readable string
describing the YUM repository.",
- "type": "string",
- "error": "KCHREPOS0008E"
- },
- "mirrorlist": {
- "description": "URL to a file containing a
list of baseurls for YUM repository",
- "type": "string",
- "error": "KCHREPOS0007E"
- },
- "gpgcheck": {
- "description": "Indicates if a GPG signature
check on the packages gotten from repository should be performed.",
- "type": "boolean",
- "error": "KCHREPOS0009E"
- },
- "gpgkey": {
- "description": "URL pointing to the
ASCII-armored GPG key file for the repository.",
- "type": "string",
- "error": "KCHREPOS0010E"
- }
- }
- }
- },
- "additionalProperties": false,
- "error": "KCHAPI0001E"
- },
- "devices_get_list": {
- "type": "object",
- "properties": {
- "_cap": {
- "description": "List specific type of device",
- "type": "string",
- "pattern":
"^fc_host|net|pci|scsi|scsi_host|storage|system|usb|usb_device$",
- "error": "KCHDEVS0001E"
- },
- "_passthrough": {
- "description": "List only devices eligible to be
assigned to guest",
- "type": "string",
- "pattern": "^true|false$",
- "error": "KCHDEVS0002E"
- },
- "_passthrough_affected_by": {
- "description": "List the affected devices in the same
group of a certain device to be assigned to guest",
- "type": "string",
- "pattern": "^[_A-Za-z0-9-]+$",
- "error": "KCHDEVS0003E"
- }
- },
- "additionalProperties": false,
- "error": "KCHAPI0001E"
- },
- "vmhostdevs_create": {
- "type": "object",
- "properties": {
- "name": {
- "description": "Then name of the device to assign to
VM",
- "type": "string",
- "pattern": "^[_A-Za-z0-9-]+$",
- "required": true,
- "error": "KCHVMHDEV0004E"
- }
- },
- "error": "KCHAPI0001E"
- }
- }
-}
diff --git a/plugins/kimchi/INSTALL b/plugins/kimchi/INSTALL
deleted file mode 100644
index 63bf076..0000000
--- a/plugins/kimchi/INSTALL
+++ /dev/null
@@ -1,369 +0,0 @@
-Installation Instructions
-*************************
-
-Copyright (C) 1994-1996, 1999-2002, 2004-2011 Free Software Foundation,
-Inc.
-
- Copying and distribution of this file, with or without modification,
-are permitted in any medium without royalty provided the copyright
-notice and this notice are preserved. This file is offered as-is,
-without warranty of any kind.
-
-Basic Installation
-==================
-
- Briefly, the shell commands `./configure; make; make install' should
-configure, build, and install this package. The following
-more-detailed instructions are generic; see the `README' file for
-instructions specific to this package. Some packages provide this
-`INSTALL' file but do not implement all of the features documented
-below. The lack of an optional feature in a given package is not
-necessarily a bug. More recommendations for GNU packages can be found
-in *note Makefile Conventions: (standards)Makefile Conventions.
-
- The `configure' shell script attempts to guess correct values for
-various system-dependent variables used during compilation. It uses
-those values to create a `Makefile' in each directory of the package.
-It may also create one or more `.h' files containing system-dependent
-definitions. Finally, it creates a shell script `config.status' that
-you can run in the future to recreate the current configuration, and a
-file `config.log' containing compiler output (useful mainly for
-debugging `configure').
-
- It can also use an optional file (typically called `config.cache'
-and enabled with `--cache-file=config.cache' or simply `-C') that saves
-the results of its tests to speed up reconfiguring. Caching is
-disabled by default to prevent problems with accidental use of stale
-cache files.
-
- If you need to do unusual things to compile the package, please try
-to figure out how `configure' could check whether to do them, and mail
-diffs or instructions to the address given in the `README' so they can
-be considered for the next release. If you are using the cache, and at
-some point `config.cache' contains results you don't want to keep, you
-may remove or edit it.
-
- The file `configure.ac' (or `configure.in') is used to create
-`configure' by a program called `autoconf'. You need `configure.ac' if
-you want to change it or regenerate `configure' using a newer version
-of `autoconf'.
-
- The simplest way to compile this package is:
-
- 1. `cd' to the directory containing the package's source code and type
- `./configure' to configure the package for your system.
-
- Running `configure' might take a while. While running, it prints
- some messages telling which features it is checking for.
-
- 2. Type `make' to compile the package.
-
- 3. Optionally, type `make check' to run any self-tests that come with
- the package, generally using the just-built uninstalled binaries.
-
- 4. Type `make install' to install the programs and any data files and
- documentation. When installing into a prefix owned by root, it is
- recommended that the package be configured and built as a regular
- user, and only the `make install' phase executed with root
- privileges.
-
- 5. Optionally, type `make installcheck' to repeat any self-tests, but
- this time using the binaries in their final installed location.
- This target does not install anything. Running this target as a
- regular user, particularly if the prior `make install' required
- root privileges, verifies that the installation completed
- correctly.
-
- 6. You can remove the program binaries and object files from the
- source code directory by typing `make clean'. To also remove the
- files that `configure' created (so you can compile the package for
- a different kind of computer), type `make distclean'. There is
- also a `make maintainer-clean' target, but that is intended mainly
- for the package's developers. If you use it, you may have to get
- all sorts of other programs in order to regenerate files that came
- with the distribution.
-
- 7. Often, you can also type `make uninstall' to remove the installed
- files again. In practice, not all packages have tested that
- uninstallation works correctly, even though it is required by the
- GNU Coding Standards.
-
- 8. Some packages, particularly those that use Automake, provide `make
- distcheck', which can by used by developers to test that all other
- targets like `make install' and `make uninstall' work correctly.
- This target is generally not run by end users.
-
-Compilers and Options
-=====================
-
- Some systems require unusual options for compilation or linking that
-the `configure' script does not know about. Run `./configure --help'
-for details on some of the pertinent environment variables.
-
- You can give `configure' initial values for configuration parameters
-by setting variables in the command line or in the environment. Here
-is an example:
-
- ./configure CC=c99 CFLAGS=-g LIBS=-lposix
-
- *Note Defining Variables::, for more details.
-
-Compiling For Multiple Architectures
-====================================
-
- You can compile the package for more than one kind of computer at the
-same time, by placing the object files for each architecture in their
-own directory. To do this, you can use GNU `make'. `cd' to the
-directory where you want the object files and executables to go and run
-the `configure' script. `configure' automatically checks for the
-source code in the directory that `configure' is in and in `..'. This
-is known as a "VPATH" build.
-
- With a non-GNU `make', it is safer to compile the package for one
-architecture at a time in the source code directory. After you have
-installed the package for one architecture, use `make distclean' before
-reconfiguring for another architecture.
-
- On MacOS X 10.5 and later systems, you can create libraries and
-executables that work on multiple system types--known as "fat" or
-"universal" binaries--by specifying multiple `-arch' options to the
-compiler but only a single `-arch' option to the preprocessor. Like
-this:
-
- ./configure CC="gcc -arch i386 -arch x86_64 -arch ppc -arch ppc64" \
- CXX="g++ -arch i386 -arch x86_64 -arch ppc -arch ppc64" \
- CPP="gcc -E" CXXCPP="g++ -E"
-
- This is not guaranteed to produce working output in all cases, you
-may have to build one architecture at a time and combine the results
-using the `lipo' tool if you have problems.
-
-Installation Names
-==================
-
- By default, `make install' installs the package's commands under
-`/usr/local/bin', include files under `/usr/local/include', etc. You
-can specify an installation prefix other than `/usr/local' by giving
-`configure' the option `--prefix=PREFIX', where PREFIX must be an
-absolute file name.
-
- You can specify separate installation prefixes for
-architecture-specific files and architecture-independent files. If you
-pass the option `--exec-prefix=PREFIX' to `configure', the package uses
-PREFIX as the prefix for installing programs and libraries.
-Documentation and other data files still use the regular prefix.
-
- In addition, if you use an unusual directory layout you can give
-options like `--bindir=DIR' to specify different values for particular
-kinds of files. Run `configure --help' for a list of the directories
-you can set and what kinds of files go in them. In general, the
-default for these options is expressed in terms of `${prefix}', so that
-specifying just `--prefix' will affect all of the other directory
-specifications that were not explicitly provided.
-
- The most portable way to affect installation locations is to pass the
-correct locations to `configure'; however, many packages provide one or
-both of the following shortcuts of passing variable assignments to the
-`make install' command line to change installation locations without
-having to reconfigure or recompile.
-
- The first method involves providing an override variable for each
-affected directory. For example, `make install
-prefix=/alternate/directory' will choose an alternate location for all
-directory configuration variables that were expressed in terms of
-`${prefix}'. Any directories that were specified during `configure',
-but not in terms of `${prefix}', must each be overridden at install
-time for the entire installation to be relocated. The approach of
-makefile variable overrides for each directory variable is required by
-the GNU Coding Standards, and ideally causes no recompilation.
-However, some platforms have known limitations with the semantics of
-shared libraries that end up requiring recompilation when using this
-method, particularly noticeable in packages that use GNU Libtool.
-
- The second method involves providing the `DESTDIR' variable. For
-example, `make install DESTDIR=/alternate/directory' will prepend
-`/alternate/directory' before all installation names. The approach of
-`DESTDIR' overrides is not required by the GNU Coding Standards, and
-does not work on platforms that have drive letters. On the other hand,
-it does better at avoiding recompilation issues, and works well even
-when some directory options were not specified in terms of `${prefix}'
-at `configure' time.
-
-Optional Features
-=================
-
- If the package supports it, you can cause programs to be installed
-with an extra prefix or suffix on their names by giving `configure' the
-option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'.
-
- Some packages pay attention to `--enable-FEATURE' options to
-`configure', where FEATURE indicates an optional part of the package.
-They may also pay attention to `--with-PACKAGE' options, where PACKAGE
-is something like `gnu-as' or `x' (for the X Window System). The
-`README' should mention any `--enable-' and `--with-' options that the
-package recognizes.
-
- For packages that use the X Window System, `configure' can usually
-find the X include and library files automatically, but if it doesn't,
-you can use the `configure' options `--x-includes=DIR' and
-`--x-libraries=DIR' to specify their locations.
-
- Some packages offer the ability to configure how verbose the
-execution of `make' will be. For these packages, running `./configure
---enable-silent-rules' sets the default to minimal output, which can be
-overridden with `make V=1'; while running `./configure
---disable-silent-rules' sets the default to verbose, which can be
-overridden with `make V=0'.
-
-Particular systems
-==================
-
- On HP-UX, the default C compiler is not ANSI C compatible. If GNU
-CC is not installed, it is recommended to use the following options in
-order to use an ANSI C compiler:
-
- ./configure CC="cc -Ae -D_XOPEN_SOURCE=500"
-
-and if that doesn't work, install pre-built binaries of GCC for HP-UX.
-
- HP-UX `make' updates targets which have the same time stamps as
-their prerequisites, which makes it generally unusable when shipped
-generated files such as `configure' are involved. Use GNU `make'
-instead.
-
- On OSF/1 a.k.a. Tru64, some versions of the default C compiler cannot
-parse its `<wchar.h>' header file. The option `-nodtk' can be used as
-a workaround. If GNU CC is not installed, it is therefore recommended
-to try
-
- ./configure CC="cc"
-
-and if that doesn't work, try
-
- ./configure CC="cc -nodtk"
-
- On Solaris, don't put `/usr/ucb' early in your `PATH'. This
-directory contains several dysfunctional programs; working variants of
-these programs are available in `/usr/bin'. So, if you need `/usr/ucb'
-in your `PATH', put it _after_ `/usr/bin'.
-
- On Haiku, software installed for all users goes in `/boot/common',
-not `/usr/local'. It is recommended to use the following options:
-
- ./configure --prefix=/boot/common
-
-Specifying the System Type
-==========================
-
- There may be some features `configure' cannot figure out
-automatically, but needs to determine by the type of machine the package
-will run on. Usually, assuming the package is built to be run on the
-_same_ architectures, `configure' can figure that out, but if it prints
-a message saying it cannot guess the machine type, give it the
-`--build=TYPE' option. TYPE can either be a short name for the system
-type, such as `sun4', or a canonical name which has the form:
-
- CPU-COMPANY-SYSTEM
-
-where SYSTEM can have one of these forms:
-
- OS
- KERNEL-OS
-
- See the file `config.sub' for the possible values of each field. If
-`config.sub' isn't included in this package, then this package doesn't
-need to know the machine type.
-
- If you are _building_ compiler tools for cross-compiling, you should
-use the option `--target=TYPE' to select the type of system they will
-produce code for.
-
- If you want to _use_ a cross compiler, that generates code for a
-platform different from the build platform, you should specify the
-"host" platform (i.e., that on which the generated programs will
-eventually be run) with `--host=TYPE'.
-
-Sharing Defaults
-================
-
- If you want to set default values for `configure' scripts to share,
-you can create a site shell script called `config.site' that gives
-default values for variables like `CC', `cache_file', and `prefix'.
-`configure' looks for `PREFIX/share/config.site' if it exists, then
-`PREFIX/etc/config.site' if it exists. Or, you can set the
-`CONFIG_SITE' environment variable to the location of the site script.
-A warning: not all `configure' scripts look for a site script.
-
-Defining Variables
-==================
-
- Variables not defined in a site shell script can be set in the
-environment passed to `configure'. However, some packages may run
-configure again during the build, and the customized values of these
-variables may be lost. In order to avoid this problem, you should set
-them in the `configure' command line, using `VAR=value'. For example:
-
- ./configure CC=/usr/local2/bin/gcc
-
-causes the specified `gcc' to be used as the C compiler (unless it is
-overridden in the site shell script).
-
-Unfortunately, this technique does not work for `CONFIG_SHELL' due to
-an Autoconf bug. Until the bug is fixed you can use this workaround:
-
- CONFIG_SHELL=/bin/bash /bin/bash ./configure CONFIG_SHELL=/bin/bash
-
-`configure' Invocation
-======================
-
- `configure' recognizes the following options to control how it
-operates.
-
-`--help'
-`-h'
- Print a summary of all of the options to `configure', and exit.
-
-`--help=short'
-`--help=recursive'
- Print a summary of the options unique to this package's
- `configure', and exit. The `short' variant lists options used
- only in the top level, while the `recursive' variant lists options
- also present in any nested packages.
-
-`--version'
-`-V'
- Print the version of Autoconf used to generate the `configure'
- script, and exit.
-
-`--cache-file=FILE'
- Enable the cache: use and save the results of the tests in FILE,
- traditionally `config.cache'. FILE defaults to `/dev/null' to
- disable caching.
-
-`--config-cache'
-`-C'
- Alias for `--cache-file=config.cache'.
-
-`--quiet'
-`--silent'
-`-q'
- Do not print messages saying which checks are being made. To
- suppress all normal output, redirect it to `/dev/null' (any error
- messages will still be shown).
-
-`--srcdir=DIR'
- Look for the package's source code in directory DIR. Usually
- `configure' can determine that directory automatically.
-
-`--prefix=DIR'
- Use DIR as the installation prefix. *note Installation Names::
- for more details, including other options available for fine-tuning
- the installation locations.
-
-`--no-create'
-`-n'
- Run the configure checks, but stop before creating any output
- files.
-
-`configure' also accepts some other, not widely useful, options. Run
-`configure --help' for more details.
diff --git a/plugins/kimchi/Makefile.am b/plugins/kimchi/Makefile.am
deleted file mode 100644
index 49c835e..0000000
--- a/plugins/kimchi/Makefile.am
+++ /dev/null
@@ -1,161 +0,0 @@
-#
-# Kimchi
-#
-# Copyright IBM Corp, 2013
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-
-SUBDIRS = contrib control distros.d docs model po tests ui xmlutils
-
-kimchi_PYTHON = $(filter-out config.py, $(wildcard *.py))
-
-nodist_kimchi_PYTHON = config.py
-
-if WITH_SPICE
-WITH_SPICE=yes
-else
-WITH_SPICE=no
-endif
-
-wokdir = $(pythondir)/wok
-kimchidir = $(pythondir)/wok/plugins/kimchi
-
-confdir = $(sysconfdir)/wok/plugins.d
-dist_conf_DATA = kimchi.conf template.conf
-
-AUTOMAKE_OPTIONS = foreign
-
-ACLOCAL_AMFLAGS = --install -I m4
-
-EXTRA_DIST = \
- config.rpath \
- API.json \
- autogen.sh \
- COPYING.ASL2 \
- COPYING.LGPL \
- CONTRIBUTE.md \
- VERSION \
- build-aux/pkg-version \
- config.py.in \
- $(NULL)
-
-
-PEP8_BLACKLIST = *config.py,*i18n.py,*tests/test_config.py
-
-I18N_FILES = ./i18n.py \
- $(NULL)
-
-check-local:
- contrib/check_i18n.py $(I18N_FILES)
- find . -path './.git' -prune -type f -o \
- -name '*.py' -o -name '*.py.in' | xargs $(PYFLAKES) | \
- while read LINE; do echo "$$LINE"; false; done
-
- $(PEP8) --version
- $(PEP8) --filename '*.py,*.py.in' --exclude="$(PEP8_BLACKLIST)" .
-
-
-# Link built mo files in the source tree to enable use of translations from
-# within the source tree
-all-local:
- while read L && test -n "$$L"; do \
- dir=mo/$$L/LC_MESSAGES ; \
- $(MKDIR_P) $$dir ; \
- ln -sf ../../../po/$$L.gmo $$dir/kimchi.mo ; \
- done < po/LINGUAS
-
-do_substitution = \
- sed -e 's,[@]prefix[@],$(prefix),g' \
- -e 's,[@]datadir[@],$(datadir),g' \
- -e 's,[@]sysconfdir[@],$(sysconfdir),g' \
- -e 's,[@]localstatedir[@],$(localstatedir),g' \
- -e 's,[@]pkgdatadir[@],$(pkgdatadir),g' \
- -e 's,[@]wokdir[@],$(wokdir),g' \
- -e 's,[@]kimchidir[@],$(kimchidir),g' \
- -e 's,[@]kimchiversion[@],$(PACKAGE_VERSION),g' \
- -e 's,[@]kimchirelease[@],$(PACKAGE_RELEASE),g' \
- -e 's,[@]withspice[@],$(WITH_SPICE),g'
-
-config.py: config.py.in Makefile
- $(do_substitution) < $(srcdir)/config.py.in > config.py
-
-
-#
-# Packaging helpers
-#
-
-install-deb: install
- cp -R $(top_srcdir)/contrib/DEBIAN $(DESTDIR)/
- mkdir -p $(DESTDIR)/var/lib/kimchi/vnc-tokens
- mkdir -p $(DESTDIR)/var/lib/kimchi/debugreports
- mkdir -p $(DESTDIR)/var/lib/kimchi/screenshots
- mkdir -p $(DESTDIR)/var/lib/kimchi/isos
-
-
-deb: contrib/make-deb.sh
- $(top_srcdir)/contrib/make-deb.sh
-
-kimchi.spec: contrib/kimchi.spec.fedora contrib/kimchi.spec.suse
- @if test -e /etc/redhat-release; then \
- ln -sf contrib/kimchi.spec.fedora $@ ; \
- elif test -e /etc/SuSE-release; then \
- ln -sf contrib/kimchi.spec.suse $@ ; \
- else \
- echo "Unable to select a spec file for RPM build" ; \
- /bin/false ; \
- fi
-
-rpm: dist kimchi.spec
- $(MKDIR_P) rpm/BUILD rpm/RPMS rpm/SOURCES rpm/SPECS rpm/SRPMS
- cp $(top_srcdir)/kimchi.spec rpm/SPECS/kimchi.spec
- cp $(DIST_ARCHIVES) rpm/SOURCES
- rpmbuild -ba --define "_topdir `pwd`/rpm" rpm/SPECS/kimchi.spec
-
-fedora-rpm: contrib/kimchi.spec.fedora
- ln -sf contrib/kimchi.spec.fedora kimchi.spec
- $(MAKE) rpm
-
-suse-rpm: contrib/kimchi.spec.suse
- ln -sf contrib/kimchi.spec.suse kimchi.spec
- $(MAKE) rpm
-
-ChangeLog:
- @if test -d .git; then \
- $(top_srcdir)/build-aux/genChangelog --release > $@; \
- fi
-
-install-data-local:
- $(MKDIR_P) $(DESTDIR)$(kimchidir)
- $(INSTALL_DATA) API.json $(DESTDIR)$(kimchidir)/API.json
- mkdir -p $(DESTDIR)/var/lib/kimchi/vnc-tokens
- mkdir -p $(DESTDIR)/var/lib/kimchi/{debugreports,isos,screenshots}
-
-uninstall-local:
- $(RM) $(DESTDIR)$(kimchidir)/API.json
- $(RM) -rf $(DESTDIR)/var/lib/kimchi
-
-VERSION:
- @if test -d .git; then \
- git describe --abbrev=0 > $@; \
- fi
-
-.PHONY: deb install-deb rpm fedora-rpm suse-rpm ChangeLog VERSION
-
-
-clean-local:
- rm -rf mo rpm
-
-BUILT_SOURCES = config.py
-CLEANFILES = config.py kimchi.spec `find "$(top_srcdir)" -type f -name
"*.pyc" -print`
diff --git a/plugins/kimchi/README.md b/plugins/kimchi/README.md
deleted file mode 120000
index 0e01b43..0000000
--- a/plugins/kimchi/README.md
+++ /dev/null
@@ -1 +0,0 @@
-docs/README.md
\ No newline at end of file
diff --git a/plugins/kimchi/VERSION b/plugins/kimchi/VERSION
deleted file mode 100644
index bc80560..0000000
--- a/plugins/kimchi/VERSION
+++ /dev/null
@@ -1 +0,0 @@
-1.5.0
diff --git a/plugins/kimchi/__init__.py b/plugins/kimchi/__init__.py
deleted file mode 100644
index 9330044..0000000
--- a/plugins/kimchi/__init__.py
+++ /dev/null
@@ -1,21 +0,0 @@
-#
-# Project Kimchi
-#
-# Copyright IBM, Corp. 2013-2014
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-
-from root import KimchiRoot
-__all__ = [KimchiRoot]
diff --git a/plugins/kimchi/autogen.sh b/plugins/kimchi/autogen.sh
deleted file mode 100755
index 0f22dba..0000000
--- a/plugins/kimchi/autogen.sh
+++ /dev/null
@@ -1,21 +0,0 @@
-#!/bin/bash
-
-aclocal
-automake --add-missing
-autoreconf
-
-if [ ! -f "configure" ]; then
- echo "Failed to generate configure script. Check to make sure autoconf, "
- echo "automake, and other build dependencies are properly installed."
- exit 1
-fi
-
-if [ "x$1" == "x--system" ]; then
- ./configure --prefix=/usr --sysconfdir=/etc --localstatedir=/var
-else
- if [ $# -gt 0 ]; then
- ./configure $@
- else
- ./configure --prefix=/usr/local
- fi
-fi
diff --git a/plugins/kimchi/build-aux/config.rpath
b/plugins/kimchi/build-aux/config.rpath
deleted file mode 100644
index 17298f2..0000000
--- a/plugins/kimchi/build-aux/config.rpath
+++ /dev/null
@@ -1,672 +0,0 @@
-#! /bin/sh
-# Output a system dependent set of variables, describing how to set the
-# run time search path of shared libraries in an executable.
-#
-# Copyright 1996-2010 Free Software Foundation, Inc.
-# Taken from GNU libtool, 2001
-# Originally by Gordon Matzigkeit <gord(a)gnu.ai.mit.edu>, 1996
-#
-# This file is free software; the Free Software Foundation gives
-# unlimited permission to copy and/or distribute it, with or without
-# modifications, as long as this notice is preserved.
-#
-# The first argument passed to this file is the canonical host specification,
-# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM
-# or
-# CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM
-# The environment variables CC, GCC, LDFLAGS, LD, with_gnu_ld
-# should be set by the caller.
-#
-# The set of defined variables is at the end of this script.
-
-# Known limitations:
-# - On IRIX 6.5 with CC="cc", the run time search patch must not be longer
-# than 256 bytes, otherwise the compiler driver will dump core. The only
-# known workaround is to choose shorter directory names for the build
-# directory and/or the installation directory.
-
-# All known linkers require a `.a' archive for static linking (except MSVC,
-# which needs '.lib').
-libext=a
-shrext=.so
-
-host="$1"
-host_cpu=`echo "$host" | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
-host_vendor=`echo "$host" | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
-host_os=`echo "$host" | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
-
-# Code taken from libtool.m4's _LT_CC_BASENAME.
-
-for cc_temp in $CC""; do
- case $cc_temp in
- compile | *[\\/]compile | ccache | *[\\/]ccache ) ;;
- distcc | *[\\/]distcc | purify | *[\\/]purify ) ;;
- \-*) ;;
- *) break;;
- esac
-done
-cc_basename=`echo "$cc_temp" | sed -e 's%^.*/%%'`
-
-# Code taken from libtool.m4's _LT_COMPILER_PIC.
-
-wl=
-if test "$GCC" = yes; then
- wl='-Wl,'
-else
- case "$host_os" in
- aix*)
- wl='-Wl,'
- ;;
- darwin*)
- case $cc_basename in
- xlc*)
- wl='-Wl,'
- ;;
- esac
- ;;
- mingw* | cygwin* | pw32* | os2* | cegcc*)
- ;;
- hpux9* | hpux10* | hpux11*)
- wl='-Wl,'
- ;;
- irix5* | irix6* | nonstopux*)
- wl='-Wl,'
- ;;
- newsos6)
- ;;
- linux* | k*bsd*-gnu)
- case $cc_basename in
- ecc*)
- wl='-Wl,'
- ;;
- icc* | ifort*)
- wl='-Wl,'
- ;;
- lf95*)
- wl='-Wl,'
- ;;
- pgcc | pgf77 | pgf90)
- wl='-Wl,'
- ;;
- ccc*)
- wl='-Wl,'
- ;;
- como)
- wl='-lopt='
- ;;
- *)
- case `$CC -V 2>&1 | sed 5q` in
- *Sun\ C*)
- wl='-Wl,'
- ;;
- esac
- ;;
- esac
- ;;
- osf3* | osf4* | osf5*)
- wl='-Wl,'
- ;;
- rdos*)
- ;;
- solaris*)
- wl='-Wl,'
- ;;
- sunos4*)
- wl='-Qoption ld '
- ;;
- sysv4 | sysv4.2uw2* | sysv4.3*)
- wl='-Wl,'
- ;;
- sysv4*MP*)
- ;;
- sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*)
- wl='-Wl,'
- ;;
- unicos*)
- wl='-Wl,'
- ;;
- uts4*)
- ;;
- esac
-fi
-
-# Code taken from libtool.m4's _LT_LINKER_SHLIBS.
-
-hardcode_libdir_flag_spec=
-hardcode_libdir_separator=
-hardcode_direct=no
-hardcode_minus_L=no
-
-case "$host_os" in
- cygwin* | mingw* | pw32* | cegcc*)
- # FIXME: the MSVC++ port hasn't been tested in a loooong time
- # When not using gcc, we currently assume that we are using
- # Microsoft Visual C++.
- if test "$GCC" != yes; then
- with_gnu_ld=no
- fi
- ;;
- interix*)
- # we just hope/assume this is gcc and not c89 (= MSVC++)
- with_gnu_ld=yes
- ;;
- openbsd*)
- with_gnu_ld=no
- ;;
-esac
-
-ld_shlibs=yes
-if test "$with_gnu_ld" = yes; then
- # Set some defaults for GNU ld with shared library support. These
- # are reset later if shared libraries are not supported. Putting them
- # here allows them to be overridden if necessary.
- # Unlike libtool, we use -rpath here, not --rpath, since the documented
- # option of GNU ld is called -rpath, not --rpath.
- hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
- case "$host_os" in
- aix[3-9]*)
- # On AIX/PPC, the GNU linker is very broken
- if test "$host_cpu" != ia64; then
- ld_shlibs=no
- fi
- ;;
- amigaos*)
- hardcode_libdir_flag_spec='-L$libdir'
- hardcode_minus_L=yes
- # Samuel A. Falvo II <kc5tja(a)dolphin.openprojects.net> reports
- # that the semantics of dynamic libraries on AmigaOS, at least up
- # to version 4, is to share data among multiple programs linked
- # with the same dynamic library. Since this doesn't match the
- # behavior of shared libraries on other platforms, we cannot use
- # them.
- ld_shlibs=no
- ;;
- beos*)
- if $LD --help 2>&1 | grep ': supported targets:.* elf' >
/dev/null; then
- :
- else
- ld_shlibs=no
- fi
- ;;
- cygwin* | mingw* | pw32* | cegcc*)
- # hardcode_libdir_flag_spec is actually meaningless, as there is
- # no search path for DLLs.
- hardcode_libdir_flag_spec='-L$libdir'
- if $LD --help 2>&1 | grep 'auto-import' > /dev/null; then
- :
- else
- ld_shlibs=no
- fi
- ;;
- interix[3-9]*)
- hardcode_direct=no
- hardcode_libdir_flag_spec='${wl}-rpath,$libdir'
- ;;
- gnu* | linux* | k*bsd*-gnu)
- if $LD --help 2>&1 | grep ': supported targets:.* elf' >
/dev/null; then
- :
- else
- ld_shlibs=no
- fi
- ;;
- netbsd*)
- ;;
- solaris*)
- if $LD -v 2>&1 | grep 'BFD 2\.8' > /dev/null; then
- ld_shlibs=no
- elif $LD --help 2>&1 | grep ': supported targets:.* elf' >
/dev/null; then
- :
- else
- ld_shlibs=no
- fi
- ;;
- sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*)
- case `$LD -v 2>&1` in
- *\ [01].* | *\ 2.[0-9].* | *\ 2.1[0-5].*)
- ld_shlibs=no
- ;;
- *)
- if $LD --help 2>&1 | grep ': supported targets:.* elf' >
/dev/null; then
- hardcode_libdir_flag_spec='`test -z "$SCOABSPATH" &&
echo ${wl}-rpath,$libdir`'
- else
- ld_shlibs=no
- fi
- ;;
- esac
- ;;
- sunos4*)
- hardcode_direct=yes
- ;;
- *)
- if $LD --help 2>&1 | grep ': supported targets:.* elf' >
/dev/null; then
- :
- else
- ld_shlibs=no
- fi
- ;;
- esac
- if test "$ld_shlibs" = no; then
- hardcode_libdir_flag_spec=
- fi
-else
- case "$host_os" in
- aix3*)
- # Note: this linker hardcodes the directories in LIBPATH if there
- # are no directories specified by -L.
- hardcode_minus_L=yes
- if test "$GCC" = yes; then
- # Neither direct hardcoding nor static linking is supported with a
- # broken collect2.
- hardcode_direct=unsupported
- fi
- ;;
- aix[4-9]*)
- if test "$host_cpu" = ia64; then
- # On IA64, the linker does run time linking by default, so we don't
- # have to do anything special.
- aix_use_runtimelinking=no
- else
- aix_use_runtimelinking=no
- # Test if we are trying to use run time linking or normal
- # AIX style linking. If -brtl is somewhere in LDFLAGS, we
- # need to do runtime linking.
- case $host_os in aix4.[23]|aix4.[23].*|aix[5-9]*)
- for ld_flag in $LDFLAGS; do
- if (test $ld_flag = "-brtl" || test $ld_flag =
"-Wl,-brtl"); then
- aix_use_runtimelinking=yes
- break
- fi
- done
- ;;
- esac
- fi
- hardcode_direct=yes
- hardcode_libdir_separator=':'
- if test "$GCC" = yes; then
- case $host_os in aix4.[012]|aix4.[012].*)
- collect2name=`${CC} -print-prog-name=collect2`
- if test -f "$collect2name" && \
- strings "$collect2name" | grep resolve_lib_name >/dev/null
- then
- # We have reworked collect2
- :
- else
- # We have old collect2
- hardcode_direct=unsupported
- hardcode_minus_L=yes
- hardcode_libdir_flag_spec='-L$libdir'
- hardcode_libdir_separator=
- fi
- ;;
- esac
- fi
- # Begin _LT_AC_SYS_LIBPATH_AIX.
- echo 'int main () { return 0; }' > conftest.c
- ${CC} ${LDFLAGS} conftest.c -o conftest
- aix_libpath=`dump -H conftest 2>/dev/null | sed -n -e '/Import File
Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; }
-}'`
- if test -z "$aix_libpath"; then
- aix_libpath=`dump -HX64 conftest 2>/dev/null | sed -n -e '/Import File
Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; }
-}'`
- fi
- if test -z "$aix_libpath"; then
- aix_libpath="/usr/lib:/lib"
- fi
- rm -f conftest.c conftest
- # End _LT_AC_SYS_LIBPATH_AIX.
- if test "$aix_use_runtimelinking" = yes; then
-
hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath"
- else
- if test "$host_cpu" = ia64; then
- hardcode_libdir_flag_spec='${wl}-R $libdir:/usr/lib:/lib'
- else
-
hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath"
- fi
- fi
- ;;
- amigaos*)
- hardcode_libdir_flag_spec='-L$libdir'
- hardcode_minus_L=yes
- # see comment about different semantics on the GNU ld section
- ld_shlibs=no
- ;;
- bsdi[45]*)
- ;;
- cygwin* | mingw* | pw32* | cegcc*)
- # When not using gcc, we currently assume that we are using
- # Microsoft Visual C++.
- # hardcode_libdir_flag_spec is actually meaningless, as there is
- # no search path for DLLs.
- hardcode_libdir_flag_spec=' '
- libext=lib
- ;;
- darwin* | rhapsody*)
- hardcode_direct=no
- if test "$GCC" = yes ; then
- :
- else
- case $cc_basename in
- xlc*)
- ;;
- *)
- ld_shlibs=no
- ;;
- esac
- fi
- ;;
- dgux*)
- hardcode_libdir_flag_spec='-L$libdir'
- ;;
- freebsd1*)
- ld_shlibs=no
- ;;
- freebsd2.2*)
- hardcode_libdir_flag_spec='-R$libdir'
- hardcode_direct=yes
- ;;
- freebsd2*)
- hardcode_direct=yes
- hardcode_minus_L=yes
- ;;
- freebsd* | dragonfly*)
- hardcode_libdir_flag_spec='-R$libdir'
- hardcode_direct=yes
- ;;
- hpux9*)
- hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir'
- hardcode_libdir_separator=:
- hardcode_direct=yes
- # hardcode_minus_L: Not really in the search PATH,
- # but as the default location of the library.
- hardcode_minus_L=yes
- ;;
- hpux10*)
- if test "$with_gnu_ld" = no; then
- hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir'
- hardcode_libdir_separator=:
- hardcode_direct=yes
- # hardcode_minus_L: Not really in the search PATH,
- # but as the default location of the library.
- hardcode_minus_L=yes
- fi
- ;;
- hpux11*)
- if test "$with_gnu_ld" = no; then
- hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir'
- hardcode_libdir_separator=:
- case $host_cpu in
- hppa*64*|ia64*)
- hardcode_direct=no
- ;;
- *)
- hardcode_direct=yes
- # hardcode_minus_L: Not really in the search PATH,
- # but as the default location of the library.
- hardcode_minus_L=yes
- ;;
- esac
- fi
- ;;
- irix5* | irix6* | nonstopux*)
- hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
- hardcode_libdir_separator=:
- ;;
- netbsd*)
- hardcode_libdir_flag_spec='-R$libdir'
- hardcode_direct=yes
- ;;
- newsos6)
- hardcode_direct=yes
- hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
- hardcode_libdir_separator=:
- ;;
- openbsd*)
- if test -f /usr/libexec/ld.so; then
- hardcode_direct=yes
- if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test
"$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
- hardcode_libdir_flag_spec='${wl}-rpath,$libdir'
- else
- case "$host_os" in
- openbsd[01].* | openbsd2.[0-7] | openbsd2.[0-7].*)
- hardcode_libdir_flag_spec='-R$libdir'
- ;;
- *)
- hardcode_libdir_flag_spec='${wl}-rpath,$libdir'
- ;;
- esac
- fi
- else
- ld_shlibs=no
- fi
- ;;
- os2*)
- hardcode_libdir_flag_spec='-L$libdir'
- hardcode_minus_L=yes
- ;;
- osf3*)
- hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
- hardcode_libdir_separator=:
- ;;
- osf4* | osf5*)
- if test "$GCC" = yes; then
- hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
- else
- # Both cc and cxx compiler support -rpath directly
- hardcode_libdir_flag_spec='-rpath $libdir'
- fi
- hardcode_libdir_separator=:
- ;;
- solaris*)
- hardcode_libdir_flag_spec='-R$libdir'
- ;;
- sunos4*)
- hardcode_libdir_flag_spec='-L$libdir'
- hardcode_direct=yes
- hardcode_minus_L=yes
- ;;
- sysv4)
- case $host_vendor in
- sni)
- hardcode_direct=yes # is this really true???
- ;;
- siemens)
- hardcode_direct=no
- ;;
- motorola)
- hardcode_direct=no #Motorola manual says yes, but my tests say they lie
- ;;
- esac
- ;;
- sysv4.3*)
- ;;
- sysv4*MP*)
- if test -d /usr/nec; then
- ld_shlibs=yes
- fi
- ;;
- sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[01].[10]* | unixware7* |
sco3.2v5.0.[024]*)
- ;;
- sysv5* | sco3.2v5* | sco5v6*)
- hardcode_libdir_flag_spec='`test -z "$SCOABSPATH" && echo
${wl}-R,$libdir`'
- hardcode_libdir_separator=':'
- ;;
- uts4*)
- hardcode_libdir_flag_spec='-L$libdir'
- ;;
- *)
- ld_shlibs=no
- ;;
- esac
-fi
-
-# Check dynamic linker characteristics
-# Code taken from libtool.m4's _LT_SYS_DYNAMIC_LINKER.
-# Unlike libtool.m4, here we don't care about _all_ names of the library, but
-# only about the one the linker finds when passed -lNAME. This is the last
-# element of library_names_spec in libtool.m4, or possibly two of them if the
-# linker has special search rules.
-library_names_spec= # the last element of library_names_spec in libtool.m4
-libname_spec='lib$name'
-case "$host_os" in
- aix3*)
- library_names_spec='$libname.a'
- ;;
- aix[4-9]*)
- library_names_spec='$libname$shrext'
- ;;
- amigaos*)
- library_names_spec='$libname.a'
- ;;
- beos*)
- library_names_spec='$libname$shrext'
- ;;
- bsdi[45]*)
- library_names_spec='$libname$shrext'
- ;;
- cygwin* | mingw* | pw32* | cegcc*)
- shrext=.dll
- library_names_spec='$libname.dll.a $libname.lib'
- ;;
- darwin* | rhapsody*)
- shrext=.dylib
- library_names_spec='$libname$shrext'
- ;;
- dgux*)
- library_names_spec='$libname$shrext'
- ;;
- freebsd1*)
- ;;
- freebsd* | dragonfly*)
- case "$host_os" in
- freebsd[123]*)
- library_names_spec='$libname$shrext$versuffix' ;;
- *)
- library_names_spec='$libname$shrext' ;;
- esac
- ;;
- gnu*)
- library_names_spec='$libname$shrext'
- ;;
- hpux9* | hpux10* | hpux11*)
- case $host_cpu in
- ia64*)
- shrext=.so
- ;;
- hppa*64*)
- shrext=.sl
- ;;
- *)
- shrext=.sl
- ;;
- esac
- library_names_spec='$libname$shrext'
- ;;
- interix[3-9]*)
- library_names_spec='$libname$shrext'
- ;;
- irix5* | irix6* | nonstopux*)
- library_names_spec='$libname$shrext'
- case "$host_os" in
- irix5* | nonstopux*)
- libsuff= shlibsuff=
- ;;
- *)
- case $LD in
- *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ") libsuff=
shlibsuff= ;;
- *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ")
libsuff=32 shlibsuff=N32 ;;
- *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ") libsuff=64
shlibsuff=64 ;;
- *) libsuff= shlibsuff= ;;
- esac
- ;;
- esac
- ;;
- linux*oldld* | linux*aout* | linux*coff*)
- ;;
- linux* | k*bsd*-gnu)
- library_names_spec='$libname$shrext'
- ;;
- knetbsd*-gnu)
- library_names_spec='$libname$shrext'
- ;;
- netbsd*)
- library_names_spec='$libname$shrext'
- ;;
- newsos6)
- library_names_spec='$libname$shrext'
- ;;
- nto-qnx*)
- library_names_spec='$libname$shrext'
- ;;
- openbsd*)
- library_names_spec='$libname$shrext$versuffix'
- ;;
- os2*)
- libname_spec='$name'
- shrext=.dll
- library_names_spec='$libname.a'
- ;;
- osf3* | osf4* | osf5*)
- library_names_spec='$libname$shrext'
- ;;
- rdos*)
- ;;
- solaris*)
- library_names_spec='$libname$shrext'
- ;;
- sunos4*)
- library_names_spec='$libname$shrext$versuffix'
- ;;
- sysv4 | sysv4.3*)
- library_names_spec='$libname$shrext'
- ;;
- sysv4*MP*)
- library_names_spec='$libname$shrext'
- ;;
- sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*)
- library_names_spec='$libname$shrext'
- ;;
- uts4*)
- library_names_spec='$libname$shrext'
- ;;
-esac
-
-sed_quote_subst='s/\(["`$\\]\)/\\\1/g'
-escaped_wl=`echo "X$wl" | sed -e 's/^X//' -e
"$sed_quote_subst"`
-shlibext=`echo "$shrext" | sed -e 's,^\.,,'`
-escaped_libname_spec=`echo "X$libname_spec" | sed -e 's/^X//' -e
"$sed_quote_subst"`
-escaped_library_names_spec=`echo "X$library_names_spec" | sed -e
's/^X//' -e "$sed_quote_subst"`
-escaped_hardcode_libdir_flag_spec=`echo "X$hardcode_libdir_flag_spec" | sed -e
's/^X//' -e "$sed_quote_subst"`
-
-LC_ALL=C sed -e 's/^\([a-zA-Z0-9_]*\)=/acl_cv_\1=/' <<EOF
-
-# How to pass a linker flag through the compiler.
-wl="$escaped_wl"
-
-# Static library suffix (normally "a").
-libext="$libext"
-
-# Shared library suffix (normally "so").
-shlibext="$shlibext"
-
-# Format of library name prefix.
-libname_spec="$escaped_libname_spec"
-
-# Library names that the linker finds when passed -lNAME.
-library_names_spec="$escaped_library_names_spec"
-
-# Flag to hardcode \$libdir into a binary during linking.
-# This must work even if \$libdir does not exist.
-hardcode_libdir_flag_spec="$escaped_hardcode_libdir_flag_spec"
-
-# Whether we need a single -rpath flag with a separated argument.
-hardcode_libdir_separator="$hardcode_libdir_separator"
-
-# Set to yes if using DIR/libNAME.so during linking hardcodes DIR into the
-# resulting binary.
-hardcode_direct="$hardcode_direct"
-
-# Set to yes if using the -LDIR flag during linking hardcodes DIR into the
-# resulting binary.
-hardcode_minus_L="$hardcode_minus_L"
-
-EOF
diff --git a/plugins/kimchi/build-aux/genChangelog
b/plugins/kimchi/build-aux/genChangelog
deleted file mode 100755
index 803f24e..0000000
--- a/plugins/kimchi/build-aux/genChangelog
+++ /dev/null
@@ -1,25 +0,0 @@
-#!/bin/bash
-
-# This script is based on code from the Kandan project:
-#
https://github.com/kandanapp/kandan/blob/master/gen-changelog.sh
-
-echo "CHANGELOG"
-echo "========="
-echo
-git for-each-ref --sort='*authordate' --format='%(tag)' refs/tags | tac
|grep -v '^$' | while read TAG ; do
- if [ $NEXT ]; then
- echo "#### [$NEXT] ####"
- elif [ "$1" != "--release" ]; then
- echo "#### [Current] ####"
- else
- NEXT=$TAG
- continue
- fi
- GIT_PAGER=cat git log --pretty=format:" * [%h] %<(78,trunc)%s (%an)"
$TAG..$NEXT
- NEXT=$TAG
- echo; echo
-done
-FIRST=$(git for-each-ref --sort='*authordate' --format='%(tag)' refs/tags
| head -1)
-
-echo "#### [$FIRST] ####"
-GIT_PAGER=cat git log --pretty=format:" * [%h] %<(78,trunc)%s (%an)" $FIRST
diff --git a/plugins/kimchi/build-aux/pkg-version b/plugins/kimchi/build-aux/pkg-version
deleted file mode 100755
index 749cf6c..0000000
--- a/plugins/kimchi/build-aux/pkg-version
+++ /dev/null
@@ -1,59 +0,0 @@
-#!/bin/sh
-#
-# Copyright 2008-2012 Red Hat, Inc.
-#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-
-# tags and output versions:
-# - 4.9.0 => 4.9.0 (upstream clean)
-# - 4.9.0-1 => 4.9.0 (downstream clean)
-# - 4.9.0-2-g34e62f => 4.9.0 (upstream dirty)
-# - 4.9.0-1-2-g34e62f => 4.9.0 (downstream dirty)
-AWK_VERSION='
- BEGIN { FS="-" }
- /^[0-9]/ {
- print $1
- }'
-
-# tags and output releases:
-# - 4.9.0 => 0 (upstream clean)
-# - 4.9.0-1 => 1 (downstream clean)
-# - 4.9.0-2-g34e62f1 => 2.git34e62f1 (upstream dirty)
-# - 4.9.0-1-2-g34e62f1 => 1.2.git34e62f1 (downstream dirty)
-AWK_RELEASE='
- BEGIN { FS="-"; OFS="." }
- /^[0-9]/ {
- if (NF == 1) print 0
- else if (NF == 2) print $2
- else if (NF == 3) print $2, "git" substr($3, 2)
- else if (NF == 4) print $2, $3, "git" substr($4, 2)
- }'
-
-if [ ! -d .git ]; then
- PKG_VERSION=`cat VERSION`
-else
- PKG_VERSION=`git describe --tags --match "[0-9]*" || cat VERSION`
-fi
-
-if test "x$1" = "x--full"; then
- echo $PKG_VERSION | tr -d '[:space:]'
-elif test "x$1" = "x--version"; then
- echo $PKG_VERSION | awk "$AWK_VERSION" | tr -cd '[:alnum:].'
-elif test "x$1" = "x--release"; then
- echo $PKG_VERSION | awk "$AWK_RELEASE" | tr -cd '[:alnum:].'
-else
- echo "usage: $0 [--full|--version|--release]"
- exit 1
-fi
diff --git a/plugins/kimchi/config.py.in b/plugins/kimchi/config.py.in
deleted file mode 100644
index 6ae0ccd..0000000
--- a/plugins/kimchi/config.py.in
+++ /dev/null
@@ -1,144 +0,0 @@
-#
-# Project Kimchi
-#
-# Copyright IBM, Corp. 2013-2015
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-#
-
-import libvirt
-import os
-import platform
-import threading
-
-from wok.config import CACHEEXPIRES, PluginConfig, PluginPaths
-from wok.xmlutils.utils import xpath_get_text
-
-kimchiLock = threading.Lock()
-
-__with_spice__ = "@withspice@"
-
-# Storage pool constant for read-only pool types
-READONLY_POOL_TYPE = ['iscsi', 'scsi', 'mpath']
-
-
-def get_distros_store():
- return os.path.join(PluginPaths('kimchi').conf_dir, 'distros.d')
-
-
-def get_debugreports_path():
- return os.path.join(PluginPaths('kimchi').state_dir, 'debugreports')
-
-
-def get_screenshot_path():
- return os.path.join(PluginPaths('kimchi').state_dir, 'screenshots')
-
-
-def find_qemu_binary(find_emulator=False):
- try:
- connect = libvirt.open(None)
- except Exception, e:
- raise Exception("Unable to get qemu binary location: %s" % e)
- try:
- xml = connect.getCapabilities()
-
- # On Little Endian system, the qemu binary is
- # qemu-system-ppc64, not qemu-system-ppc64le as expected
- arch = platform.machine()
- if arch == "ppc64le":
- arch = "ppc64"
-
- if find_emulator:
- expr = "/capabilities/guest/arch[@name='%s']\
- /emulator" % arch
- else:
- expr = "/capabilities/guest/arch[@name='%s']\
- /domain[@type='kvm']/emulator" % arch
- res = xpath_get_text(xml, expr)
- location = res[0]
- except Exception, e:
- raise Exception("Unable to get qemu binary location: %s" % e)
- finally:
- connect.close()
- return location
-
-
-class KimchiPaths(PluginPaths):
-
- def __init__(self):
- super(KimchiPaths, self).__init__('kimchi')
- self.spice_file = os.path.join(self.ui_dir,
- 'spice-html5/pages/spice_auto.html')
-
- if __with_spice__ == 'yes':
- self.spice_dir = self.add_prefix('ui/spice-html5')
- elif os.path.exists('@datadir@/spice-html5'):
- self.spice_dir = '@datadir@/spice-html5'
- else:
- self.spice_dir = '/usr/share/spice-html5'
-
- if os.path.exists('@datadir@/novnc'):
- self.novnc_dir = '@datadir@/novnc'
- else:
- self.novnc_dir = '/usr/share/novnc'
-
- if self.installed:
- self.spice_css_file = os.path.join(self.spice_dir, 'spice.css')
- else:
- self.spice_css_file = os.path.join(self.spice_dir, 'css/spice.css')
-
-
-kimchiPaths = KimchiPaths()
-
-
-class KimchiConfig(PluginConfig):
- def __init__(self):
- super(KimchiConfig, self).__init__('kimchi')
-
- static_config = {
- '/novnc': {'type': 'dir',
- 'path': kimchiPaths.novnc_dir},
- '/spice-html5': {'type': 'dir',
- 'path': kimchiPaths.spice_dir},
- '/spice_auto.html': {'type': 'file',
- 'path': kimchiPaths.spice_file},
- '/spice-html5/spice.css': {'type': 'file',
- 'path': kimchiPaths.spice_css_file}}
-
- custom_config = {}
- for uri, data in static_config.iteritems():
- custom_config[uri] = {'tools.nocache.on': True,
- 'tools.wokauth.on': True}
- path = data['path']
- if data['type'] == 'dir':
- custom_config[uri].update({'tools.staticdir.on': True,
- 'tools.staticdir.dir': path})
- elif data['type'] == 'file':
- custom_config[uri].update({'tools.staticfile.on': True,
- 'tools.staticfile.filename': path})
-
- for dirname in ('css', 'js', 'images'):
- custom_config['/' + dirname] = {
- 'tools.staticdir.on': True,
- 'tools.staticdir.dir': os.path.join(kimchiPaths.ui_dir,
- dirname),
- 'tools.wokauth.on': False,
- 'tools.nocache.on': False}
- if dirname != 'images':
- custom_config['/' + dirname].update({
- 'tools.expires.on': True,
- 'tools.expires.secs': CACHEEXPIRES})
-
- self.update(custom_config)
diff --git a/plugins/kimchi/config.rpath b/plugins/kimchi/config.rpath
deleted file mode 100644
index 17298f2..0000000
--- a/plugins/kimchi/config.rpath
+++ /dev/null
@@ -1,672 +0,0 @@
-#! /bin/sh
-# Output a system dependent set of variables, describing how to set the
-# run time search path of shared libraries in an executable.
-#
-# Copyright 1996-2010 Free Software Foundation, Inc.
-# Taken from GNU libtool, 2001
-# Originally by Gordon Matzigkeit <gord(a)gnu.ai.mit.edu>, 1996
-#
-# This file is free software; the Free Software Foundation gives
-# unlimited permission to copy and/or distribute it, with or without
-# modifications, as long as this notice is preserved.
-#
-# The first argument passed to this file is the canonical host specification,
-# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM
-# or
-# CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM
-# The environment variables CC, GCC, LDFLAGS, LD, with_gnu_ld
-# should be set by the caller.
-#
-# The set of defined variables is at the end of this script.
-
-# Known limitations:
-# - On IRIX 6.5 with CC="cc", the run time search patch must not be longer
-# than 256 bytes, otherwise the compiler driver will dump core. The only
-# known workaround is to choose shorter directory names for the build
-# directory and/or the installation directory.
-
-# All known linkers require a `.a' archive for static linking (except MSVC,
-# which needs '.lib').
-libext=a
-shrext=.so
-
-host="$1"
-host_cpu=`echo "$host" | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
-host_vendor=`echo "$host" | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
-host_os=`echo "$host" | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
-
-# Code taken from libtool.m4's _LT_CC_BASENAME.
-
-for cc_temp in $CC""; do
- case $cc_temp in
- compile | *[\\/]compile | ccache | *[\\/]ccache ) ;;
- distcc | *[\\/]distcc | purify | *[\\/]purify ) ;;
- \-*) ;;
- *) break;;
- esac
-done
-cc_basename=`echo "$cc_temp" | sed -e 's%^.*/%%'`
-
-# Code taken from libtool.m4's _LT_COMPILER_PIC.
-
-wl=
-if test "$GCC" = yes; then
- wl='-Wl,'
-else
- case "$host_os" in
- aix*)
- wl='-Wl,'
- ;;
- darwin*)
- case $cc_basename in
- xlc*)
- wl='-Wl,'
- ;;
- esac
- ;;
- mingw* | cygwin* | pw32* | os2* | cegcc*)
- ;;
- hpux9* | hpux10* | hpux11*)
- wl='-Wl,'
- ;;
- irix5* | irix6* | nonstopux*)
- wl='-Wl,'
- ;;
- newsos6)
- ;;
- linux* | k*bsd*-gnu)
- case $cc_basename in
- ecc*)
- wl='-Wl,'
- ;;
- icc* | ifort*)
- wl='-Wl,'
- ;;
- lf95*)
- wl='-Wl,'
- ;;
- pgcc | pgf77 | pgf90)
- wl='-Wl,'
- ;;
- ccc*)
- wl='-Wl,'
- ;;
- como)
- wl='-lopt='
- ;;
- *)
- case `$CC -V 2>&1 | sed 5q` in
- *Sun\ C*)
- wl='-Wl,'
- ;;
- esac
- ;;
- esac
- ;;
- osf3* | osf4* | osf5*)
- wl='-Wl,'
- ;;
- rdos*)
- ;;
- solaris*)
- wl='-Wl,'
- ;;
- sunos4*)
- wl='-Qoption ld '
- ;;
- sysv4 | sysv4.2uw2* | sysv4.3*)
- wl='-Wl,'
- ;;
- sysv4*MP*)
- ;;
- sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*)
- wl='-Wl,'
- ;;
- unicos*)
- wl='-Wl,'
- ;;
- uts4*)
- ;;
- esac
-fi
-
-# Code taken from libtool.m4's _LT_LINKER_SHLIBS.
-
-hardcode_libdir_flag_spec=
-hardcode_libdir_separator=
-hardcode_direct=no
-hardcode_minus_L=no
-
-case "$host_os" in
- cygwin* | mingw* | pw32* | cegcc*)
- # FIXME: the MSVC++ port hasn't been tested in a loooong time
- # When not using gcc, we currently assume that we are using
- # Microsoft Visual C++.
- if test "$GCC" != yes; then
- with_gnu_ld=no
- fi
- ;;
- interix*)
- # we just hope/assume this is gcc and not c89 (= MSVC++)
- with_gnu_ld=yes
- ;;
- openbsd*)
- with_gnu_ld=no
- ;;
-esac
-
-ld_shlibs=yes
-if test "$with_gnu_ld" = yes; then
- # Set some defaults for GNU ld with shared library support. These
- # are reset later if shared libraries are not supported. Putting them
- # here allows them to be overridden if necessary.
- # Unlike libtool, we use -rpath here, not --rpath, since the documented
- # option of GNU ld is called -rpath, not --rpath.
- hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
- case "$host_os" in
- aix[3-9]*)
- # On AIX/PPC, the GNU linker is very broken
- if test "$host_cpu" != ia64; then
- ld_shlibs=no
- fi
- ;;
- amigaos*)
- hardcode_libdir_flag_spec='-L$libdir'
- hardcode_minus_L=yes
- # Samuel A. Falvo II <kc5tja(a)dolphin.openprojects.net> reports
- # that the semantics of dynamic libraries on AmigaOS, at least up
- # to version 4, is to share data among multiple programs linked
- # with the same dynamic library. Since this doesn't match the
- # behavior of shared libraries on other platforms, we cannot use
- # them.
- ld_shlibs=no
- ;;
- beos*)
- if $LD --help 2>&1 | grep ': supported targets:.* elf' >
/dev/null; then
- :
- else
- ld_shlibs=no
- fi
- ;;
- cygwin* | mingw* | pw32* | cegcc*)
- # hardcode_libdir_flag_spec is actually meaningless, as there is
- # no search path for DLLs.
- hardcode_libdir_flag_spec='-L$libdir'
- if $LD --help 2>&1 | grep 'auto-import' > /dev/null; then
- :
- else
- ld_shlibs=no
- fi
- ;;
- interix[3-9]*)
- hardcode_direct=no
- hardcode_libdir_flag_spec='${wl}-rpath,$libdir'
- ;;
- gnu* | linux* | k*bsd*-gnu)
- if $LD --help 2>&1 | grep ': supported targets:.* elf' >
/dev/null; then
- :
- else
- ld_shlibs=no
- fi
- ;;
- netbsd*)
- ;;
- solaris*)
- if $LD -v 2>&1 | grep 'BFD 2\.8' > /dev/null; then
- ld_shlibs=no
- elif $LD --help 2>&1 | grep ': supported targets:.* elf' >
/dev/null; then
- :
- else
- ld_shlibs=no
- fi
- ;;
- sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*)
- case `$LD -v 2>&1` in
- *\ [01].* | *\ 2.[0-9].* | *\ 2.1[0-5].*)
- ld_shlibs=no
- ;;
- *)
- if $LD --help 2>&1 | grep ': supported targets:.* elf' >
/dev/null; then
- hardcode_libdir_flag_spec='`test -z "$SCOABSPATH" &&
echo ${wl}-rpath,$libdir`'
- else
- ld_shlibs=no
- fi
- ;;
- esac
- ;;
- sunos4*)
- hardcode_direct=yes
- ;;
- *)
- if $LD --help 2>&1 | grep ': supported targets:.* elf' >
/dev/null; then
- :
- else
- ld_shlibs=no
- fi
- ;;
- esac
- if test "$ld_shlibs" = no; then
- hardcode_libdir_flag_spec=
- fi
-else
- case "$host_os" in
- aix3*)
- # Note: this linker hardcodes the directories in LIBPATH if there
- # are no directories specified by -L.
- hardcode_minus_L=yes
- if test "$GCC" = yes; then
- # Neither direct hardcoding nor static linking is supported with a
- # broken collect2.
- hardcode_direct=unsupported
- fi
- ;;
- aix[4-9]*)
- if test "$host_cpu" = ia64; then
- # On IA64, the linker does run time linking by default, so we don't
- # have to do anything special.
- aix_use_runtimelinking=no
- else
- aix_use_runtimelinking=no
- # Test if we are trying to use run time linking or normal
- # AIX style linking. If -brtl is somewhere in LDFLAGS, we
- # need to do runtime linking.
- case $host_os in aix4.[23]|aix4.[23].*|aix[5-9]*)
- for ld_flag in $LDFLAGS; do
- if (test $ld_flag = "-brtl" || test $ld_flag =
"-Wl,-brtl"); then
- aix_use_runtimelinking=yes
- break
- fi
- done
- ;;
- esac
- fi
- hardcode_direct=yes
- hardcode_libdir_separator=':'
- if test "$GCC" = yes; then
- case $host_os in aix4.[012]|aix4.[012].*)
- collect2name=`${CC} -print-prog-name=collect2`
- if test -f "$collect2name" && \
- strings "$collect2name" | grep resolve_lib_name >/dev/null
- then
- # We have reworked collect2
- :
- else
- # We have old collect2
- hardcode_direct=unsupported
- hardcode_minus_L=yes
- hardcode_libdir_flag_spec='-L$libdir'
- hardcode_libdir_separator=
- fi
- ;;
- esac
- fi
- # Begin _LT_AC_SYS_LIBPATH_AIX.
- echo 'int main () { return 0; }' > conftest.c
- ${CC} ${LDFLAGS} conftest.c -o conftest
- aix_libpath=`dump -H conftest 2>/dev/null | sed -n -e '/Import File
Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; }
-}'`
- if test -z "$aix_libpath"; then
- aix_libpath=`dump -HX64 conftest 2>/dev/null | sed -n -e '/Import File
Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; }
-}'`
- fi
- if test -z "$aix_libpath"; then
- aix_libpath="/usr/lib:/lib"
- fi
- rm -f conftest.c conftest
- # End _LT_AC_SYS_LIBPATH_AIX.
- if test "$aix_use_runtimelinking" = yes; then
-
hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath"
- else
- if test "$host_cpu" = ia64; then
- hardcode_libdir_flag_spec='${wl}-R $libdir:/usr/lib:/lib'
- else
-
hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath"
- fi
- fi
- ;;
- amigaos*)
- hardcode_libdir_flag_spec='-L$libdir'
- hardcode_minus_L=yes
- # see comment about different semantics on the GNU ld section
- ld_shlibs=no
- ;;
- bsdi[45]*)
- ;;
- cygwin* | mingw* | pw32* | cegcc*)
- # When not using gcc, we currently assume that we are using
- # Microsoft Visual C++.
- # hardcode_libdir_flag_spec is actually meaningless, as there is
- # no search path for DLLs.
- hardcode_libdir_flag_spec=' '
- libext=lib
- ;;
- darwin* | rhapsody*)
- hardcode_direct=no
- if test "$GCC" = yes ; then
- :
- else
- case $cc_basename in
- xlc*)
- ;;
- *)
- ld_shlibs=no
- ;;
- esac
- fi
- ;;
- dgux*)
- hardcode_libdir_flag_spec='-L$libdir'
- ;;
- freebsd1*)
- ld_shlibs=no
- ;;
- freebsd2.2*)
- hardcode_libdir_flag_spec='-R$libdir'
- hardcode_direct=yes
- ;;
- freebsd2*)
- hardcode_direct=yes
- hardcode_minus_L=yes
- ;;
- freebsd* | dragonfly*)
- hardcode_libdir_flag_spec='-R$libdir'
- hardcode_direct=yes
- ;;
- hpux9*)
- hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir'
- hardcode_libdir_separator=:
- hardcode_direct=yes
- # hardcode_minus_L: Not really in the search PATH,
- # but as the default location of the library.
- hardcode_minus_L=yes
- ;;
- hpux10*)
- if test "$with_gnu_ld" = no; then
- hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir'
- hardcode_libdir_separator=:
- hardcode_direct=yes
- # hardcode_minus_L: Not really in the search PATH,
- # but as the default location of the library.
- hardcode_minus_L=yes
- fi
- ;;
- hpux11*)
- if test "$with_gnu_ld" = no; then
- hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir'
- hardcode_libdir_separator=:
- case $host_cpu in
- hppa*64*|ia64*)
- hardcode_direct=no
- ;;
- *)
- hardcode_direct=yes
- # hardcode_minus_L: Not really in the search PATH,
- # but as the default location of the library.
- hardcode_minus_L=yes
- ;;
- esac
- fi
- ;;
- irix5* | irix6* | nonstopux*)
- hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
- hardcode_libdir_separator=:
- ;;
- netbsd*)
- hardcode_libdir_flag_spec='-R$libdir'
- hardcode_direct=yes
- ;;
- newsos6)
- hardcode_direct=yes
- hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
- hardcode_libdir_separator=:
- ;;
- openbsd*)
- if test -f /usr/libexec/ld.so; then
- hardcode_direct=yes
- if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test
"$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
- hardcode_libdir_flag_spec='${wl}-rpath,$libdir'
- else
- case "$host_os" in
- openbsd[01].* | openbsd2.[0-7] | openbsd2.[0-7].*)
- hardcode_libdir_flag_spec='-R$libdir'
- ;;
- *)
- hardcode_libdir_flag_spec='${wl}-rpath,$libdir'
- ;;
- esac
- fi
- else
- ld_shlibs=no
- fi
- ;;
- os2*)
- hardcode_libdir_flag_spec='-L$libdir'
- hardcode_minus_L=yes
- ;;
- osf3*)
- hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
- hardcode_libdir_separator=:
- ;;
- osf4* | osf5*)
- if test "$GCC" = yes; then
- hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
- else
- # Both cc and cxx compiler support -rpath directly
- hardcode_libdir_flag_spec='-rpath $libdir'
- fi
- hardcode_libdir_separator=:
- ;;
- solaris*)
- hardcode_libdir_flag_spec='-R$libdir'
- ;;
- sunos4*)
- hardcode_libdir_flag_spec='-L$libdir'
- hardcode_direct=yes
- hardcode_minus_L=yes
- ;;
- sysv4)
- case $host_vendor in
- sni)
- hardcode_direct=yes # is this really true???
- ;;
- siemens)
- hardcode_direct=no
- ;;
- motorola)
- hardcode_direct=no #Motorola manual says yes, but my tests say they lie
- ;;
- esac
- ;;
- sysv4.3*)
- ;;
- sysv4*MP*)
- if test -d /usr/nec; then
- ld_shlibs=yes
- fi
- ;;
- sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[01].[10]* | unixware7* |
sco3.2v5.0.[024]*)
- ;;
- sysv5* | sco3.2v5* | sco5v6*)
- hardcode_libdir_flag_spec='`test -z "$SCOABSPATH" && echo
${wl}-R,$libdir`'
- hardcode_libdir_separator=':'
- ;;
- uts4*)
- hardcode_libdir_flag_spec='-L$libdir'
- ;;
- *)
- ld_shlibs=no
- ;;
- esac
-fi
-
-# Check dynamic linker characteristics
-# Code taken from libtool.m4's _LT_SYS_DYNAMIC_LINKER.
-# Unlike libtool.m4, here we don't care about _all_ names of the library, but
-# only about the one the linker finds when passed -lNAME. This is the last
-# element of library_names_spec in libtool.m4, or possibly two of them if the
-# linker has special search rules.
-library_names_spec= # the last element of library_names_spec in libtool.m4
-libname_spec='lib$name'
-case "$host_os" in
- aix3*)
- library_names_spec='$libname.a'
- ;;
- aix[4-9]*)
- library_names_spec='$libname$shrext'
- ;;
- amigaos*)
- library_names_spec='$libname.a'
- ;;
- beos*)
- library_names_spec='$libname$shrext'
- ;;
- bsdi[45]*)
- library_names_spec='$libname$shrext'
- ;;
- cygwin* | mingw* | pw32* | cegcc*)
- shrext=.dll
- library_names_spec='$libname.dll.a $libname.lib'
- ;;
- darwin* | rhapsody*)
- shrext=.dylib
- library_names_spec='$libname$shrext'
- ;;
- dgux*)
- library_names_spec='$libname$shrext'
- ;;
- freebsd1*)
- ;;
- freebsd* | dragonfly*)
- case "$host_os" in
- freebsd[123]*)
- library_names_spec='$libname$shrext$versuffix' ;;
- *)
- library_names_spec='$libname$shrext' ;;
- esac
- ;;
- gnu*)
- library_names_spec='$libname$shrext'
- ;;
- hpux9* | hpux10* | hpux11*)
- case $host_cpu in
- ia64*)
- shrext=.so
- ;;
- hppa*64*)
- shrext=.sl
- ;;
- *)
- shrext=.sl
- ;;
- esac
- library_names_spec='$libname$shrext'
- ;;
- interix[3-9]*)
- library_names_spec='$libname$shrext'
- ;;
- irix5* | irix6* | nonstopux*)
- library_names_spec='$libname$shrext'
- case "$host_os" in
- irix5* | nonstopux*)
- libsuff= shlibsuff=
- ;;
- *)
- case $LD in
- *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ") libsuff=
shlibsuff= ;;
- *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ")
libsuff=32 shlibsuff=N32 ;;
- *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ") libsuff=64
shlibsuff=64 ;;
- *) libsuff= shlibsuff= ;;
- esac
- ;;
- esac
- ;;
- linux*oldld* | linux*aout* | linux*coff*)
- ;;
- linux* | k*bsd*-gnu)
- library_names_spec='$libname$shrext'
- ;;
- knetbsd*-gnu)
- library_names_spec='$libname$shrext'
- ;;
- netbsd*)
- library_names_spec='$libname$shrext'
- ;;
- newsos6)
- library_names_spec='$libname$shrext'
- ;;
- nto-qnx*)
- library_names_spec='$libname$shrext'
- ;;
- openbsd*)
- library_names_spec='$libname$shrext$versuffix'
- ;;
- os2*)
- libname_spec='$name'
- shrext=.dll
- library_names_spec='$libname.a'
- ;;
- osf3* | osf4* | osf5*)
- library_names_spec='$libname$shrext'
- ;;
- rdos*)
- ;;
- solaris*)
- library_names_spec='$libname$shrext'
- ;;
- sunos4*)
- library_names_spec='$libname$shrext$versuffix'
- ;;
- sysv4 | sysv4.3*)
- library_names_spec='$libname$shrext'
- ;;
- sysv4*MP*)
- library_names_spec='$libname$shrext'
- ;;
- sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*)
- library_names_spec='$libname$shrext'
- ;;
- uts4*)
- library_names_spec='$libname$shrext'
- ;;
-esac
-
-sed_quote_subst='s/\(["`$\\]\)/\\\1/g'
-escaped_wl=`echo "X$wl" | sed -e 's/^X//' -e
"$sed_quote_subst"`
-shlibext=`echo "$shrext" | sed -e 's,^\.,,'`
-escaped_libname_spec=`echo "X$libname_spec" | sed -e 's/^X//' -e
"$sed_quote_subst"`
-escaped_library_names_spec=`echo "X$library_names_spec" | sed -e
's/^X//' -e "$sed_quote_subst"`
-escaped_hardcode_libdir_flag_spec=`echo "X$hardcode_libdir_flag_spec" | sed -e
's/^X//' -e "$sed_quote_subst"`
-
-LC_ALL=C sed -e 's/^\([a-zA-Z0-9_]*\)=/acl_cv_\1=/' <<EOF
-
-# How to pass a linker flag through the compiler.
-wl="$escaped_wl"
-
-# Static library suffix (normally "a").
-libext="$libext"
-
-# Shared library suffix (normally "so").
-shlibext="$shlibext"
-
-# Format of library name prefix.
-libname_spec="$escaped_libname_spec"
-
-# Library names that the linker finds when passed -lNAME.
-library_names_spec="$escaped_library_names_spec"
-
-# Flag to hardcode \$libdir into a binary during linking.
-# This must work even if \$libdir does not exist.
-hardcode_libdir_flag_spec="$escaped_hardcode_libdir_flag_spec"
-
-# Whether we need a single -rpath flag with a separated argument.
-hardcode_libdir_separator="$hardcode_libdir_separator"
-
-# Set to yes if using DIR/libNAME.so during linking hardcodes DIR into the
-# resulting binary.
-hardcode_direct="$hardcode_direct"
-
-# Set to yes if using the -LDIR flag during linking hardcodes DIR into the
-# resulting binary.
-hardcode_minus_L="$hardcode_minus_L"
-
-EOF
diff --git a/plugins/kimchi/configure.ac b/plugins/kimchi/configure.ac
deleted file mode 100644
index adab45b..0000000
--- a/plugins/kimchi/configure.ac
+++ /dev/null
@@ -1,119 +0,0 @@
-#
-# Kimchi
-#
-# Copyright IBM Corp, 2013-2015
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-
-AC_INIT([kimchi], [m4_esyscmd([./build-aux/pkg-version --version])])
-
-AC_SUBST([PACKAGE_VERSION],
- [m4_esyscmd([./build-aux/pkg-version --version])])
-
-AC_SUBST([PACKAGE_RELEASE],
- [m4_esyscmd([./build-aux/pkg-version --release])])
-
-# Testing for version and release
-AS_IF([test "x$PACKAGE_VERSION" = x],
- AC_MSG_ERROR([package version not defined]))
-AS_IF([test "x$PACKAGE_RELEASE" = x],
- AC_MSG_ERROR([package release not defined]))
-
-AC_CONFIG_AUX_DIR([build-aux])
-AM_INIT_AUTOMAKE([-Wno-portability])
-AM_PATH_PYTHON([2.6])
-AC_PATH_PROG([PEP8], [pep8], [/usr/bin/pep8])
-AC_PYTHON_MODULE([unittest])
-AC_SUBST([HAVE_PYMOD_UNITTEST])
-AC_SUBST([PYTHON_VERSION])
-AM_GNU_GETTEXT([external])
-AM_GNU_GETTEXT_VERSION([0.10])
-AC_PATH_PROG([CHEETAH], [cheetah], [/usr/bin/cheetah])
-
-# Checking for pyflakes
-AC_PATH_PROG([PYFLAKES], [pyflakes])
-if test "x$PYFLAKES" = "x"; then
- AC_MSG_WARN([pyflakes not found])
-fi
-
-AC_ARG_ENABLE(
- [sample],
- [AS_HELP_STRING(
- [--enable-sample],
- [enable sample plugin @<:@default=no@:>@]
- )],
- ,
- [enable_sample="no"]
-)
-
-if test "${enable_sample}" = "yes"; then
-AC_SUBST([ENABLE_SAMPLE], [True])
-else
-AC_SUBST([ENABLE_SAMPLE], [False])
-fi
-
-AC_ARG_WITH(
- [spice-html5],
- [AS_HELP_STRING([--with-spice-html5],
- [Build Kimchi with spice-html5 @<:@default=no@:>@])],
- ,
- [with_spice_html5="no"]
-)
-AM_CONDITIONAL([WITH_SPICE], [test "x$with_spice_html5" = xyes])
-
-AC_CONFIG_FILES([
- po/Makefile.in
- po/gen-pot
- Makefile
- docs/Makefile
- distros.d/Makefile
- control/Makefile
- control/vm/Makefile
- model/Makefile
- ui/Makefile
- ui/config/Makefile
- ui/css/Makefile
- ui/images/Makefile
- ui/images/theme-default/Makefile
- ui/js/Makefile
- ui/spice-html5/Makefile
- ui/spice-html5/css/Makefile
- ui/spice-html5/pages/Makefile
- ui/spice-html5/thirdparty/Makefile
- ui/pages/Makefile
- ui/pages/help/Makefile
- ui/pages/help/en_US/Makefile
- ui/pages/help/de_DE/Makefile
- ui/pages/help/es_ES/Makefile
- ui/pages/help/fr_FR/Makefile
- ui/pages/help/it_IT/Makefile
- ui/pages/help/ja_JP/Makefile
- ui/pages/help/ko_KR/Makefile
- ui/pages/help/pt_BR/Makefile
- ui/pages/help/ru_RU/Makefile
- ui/pages/help/zh_CN/Makefile
- ui/pages/help/zh_TW/Makefile
- contrib/Makefile
- contrib/DEBIAN/Makefile
- contrib/DEBIAN/control
- contrib/kimchi.spec.fedora
- contrib/kimchi.spec.suse
- tests/Makefile
- xmlutils/Makefile
-],[
- chmod +x po/gen-pot
-])
-
-AC_OUTPUT
diff --git a/plugins/kimchi/contrib/DEBIAN/Makefile.am
b/plugins/kimchi/contrib/DEBIAN/Makefile.am
deleted file mode 100644
index ca89552..0000000
--- a/plugins/kimchi/contrib/DEBIAN/Makefile.am
+++ /dev/null
@@ -1,17 +0,0 @@
-# Copyright IBM Corp, 2013
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-
-CLEANFILES = control
diff --git a/plugins/kimchi/contrib/DEBIAN/control.in
b/plugins/kimchi/contrib/DEBIAN/control.in
deleted file mode 100644
index dc153d8..0000000
--- a/plugins/kimchi/contrib/DEBIAN/control.in
+++ /dev/null
@@ -1,30 +0,0 @@
-Package: @PACKAGE_NAME@
-Version: @PACKAGE_VERSION@
-Section: base
-Priority: optional
-Architecture: all
-Depends: wok,
- python-imaging,
- python-configobj,
- websockify,
- novnc,
- python-jsonschema (>= 1.3.0),
- python-libvirt,
- gettext,
- libvirt-bin,
- nfs-common,
- qemu-kvm,
- python-parted,
- python-psutil (>= 0.6.0),
- python-ethtool,
- sosreport,
- python-ipaddr,
- python-lxml,
- open-iscsi,
- python-guestfs,
- libguestfs-tools,
- spice-html5
-Build-Depends: libxslt,
- python-lxml
-Maintainer: Aline Manera <alinefm(a)br.ibm.com>
-Description: Kimchi web application
diff --git a/plugins/kimchi/contrib/Makefile.am b/plugins/kimchi/contrib/Makefile.am
deleted file mode 100644
index 5001191..0000000
--- a/plugins/kimchi/contrib/Makefile.am
+++ /dev/null
@@ -1,34 +0,0 @@
-# Copyright IBM Corp, 2013
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-
-SUBDIRS = DEBIAN
-
-EXTRA_DIST = \
- check_i18n.py \
- kimchi.spec.fedora.in \
- make-deb.sh.in \
- $(NULL)
-
-make-deb.sh: make-deb.sh.in $(top_builddir)/config.status
- $(AM_V_GEN)sed \
- -e 's|[@]PACKAGE_VERSION[@]|$(PACKAGE_VERSION)|g' \
- -e 's|[@]PACKAGE_RELEASE[@]|$(PACKAGE_RELEASE)|g' \
- < $< > $@-t && \
- chmod a+x $@-t && \
- mv $@-t $@
-BUILT_SOURCES = make-deb.sh
-
-CLEANFILES = kimchi.spec.fedora kimchi.spec.suse kimchi.spec make-deb.sh
diff --git a/plugins/kimchi/contrib/check_i18n.py b/plugins/kimchi/contrib/check_i18n.py
deleted file mode 100755
index 6a2603c..0000000
--- a/plugins/kimchi/contrib/check_i18n.py
+++ /dev/null
@@ -1,82 +0,0 @@
-#!/usr/bin/env python2
-#
-# Project Kimchi
-#
-# Copyright IBM, Corp. 2014-2015
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-
-import imp
-import os
-import re
-import sys
-
-
-# Match all conversion specifier with mapping key
-PATTERN = re.compile(r'''%\([^)]+\) # Mapping key
- [#0\-+]? # Conversion flags (optional)
- (\d+|\*)? # Minimum field width (optional)
- (\.(\d+|\*))? # Precision (optional)
- [lLh]? # Length modifier (optional)
- [cdeEfFgGioursxX%] # Conversion type''',
- re.VERBOSE)
-BAD_PATTERN = re.compile(r"%\([^)]*?\)")
-
-
-def load_i18n_module(i18nfile):
- path = os.path.dirname(i18nfile)
- mname = i18nfile.replace("/", "_").rstrip(".py")
- mobj = imp.find_module("i18n", [path])
- return imp.load_module(mname, *mobj)
-
-
-def check_string_formatting(messages):
- for k, v in messages.iteritems():
- if BAD_PATTERN.findall(PATTERN.sub(" ", v)):
- print "bad i18n string formatting:"
- print " %s: %s" % (k, v)
- exit(1)
-
-
-def check_obsolete_messages(path, messages):
- def find_message_key(path, k):
- for root, dirs, files in os.walk(path):
- for f in files:
- fname = os.path.join(root, f)
- if (not fname.endswith("i18n.py") and
fname.endswith(".py") or
- fname.endswith(".json")):
- with open(fname) as f:
- string = "".join(f.readlines())
- if k in string:
- return True
- return False
-
- for k in messages.iterkeys():
- if not find_message_key(path, k):
- print " %s is obsolete, it is no longer in use" % k
- exit(1)
-
-
-def main():
- print "Checking for invalid i18n string..."
- for f in sys.argv[1:]:
- messages = load_i18n_module(f).messages
- check_string_formatting(messages)
- check_obsolete_messages(os.path.dirname(f), messages)
- print "Checking for invalid i18n string successfully"
-
-
-if __name__ == '__main__':
- main()
diff --git a/plugins/kimchi/contrib/kimchi.spec.fedora.in
b/plugins/kimchi/contrib/kimchi.spec.fedora.in
deleted file mode 100644
index 0db3d7e..0000000
--- a/plugins/kimchi/contrib/kimchi.spec.fedora.in
+++ /dev/null
@@ -1,119 +0,0 @@
-Name: kimchi
-Version: @PACKAGE_VERSION@
-Release: @PACKAGE_RELEASE@%{?dist}
-Summary: Kimchi server application
-BuildRoot: %{_topdir}/BUILD/%{name}-%{version}-%{release}
-BuildArch: noarch
-Group: System Environment/Base
-License: LGPL/ASL2
-Source0: %{name}-%{version}.tar.gz
-Requires: wok
-Requires: qemu-kvm
-Requires: gettext
-Requires: libvirt
-Requires: libvirt-python
-Requires: libvirt-daemon-config-network
-Requires: python-websockify
-Requires: python-configobj
-Requires: novnc
-Requires: python-imaging
-Requires: pyparted
-Requires: python-psutil >= 0.6.0
-Requires: python-jsonschema >= 1.3.0
-Requires: python-ethtool
-Requires: sos
-Requires: python-ipaddr
-Requires: python-lxml
-Requires: nfs-utils
-Requires: iscsi-initiator-utils
-Requires: python-libguestfs
-Requires: libguestfs-tools
-BuildRequires: libxslt
-BuildRequires: python-lxml
-
-%if 0%{?rhel} >= 6 || 0%{?fedora} >= 19
-Requires: spice-html5
-%endif
-
-%if 0%{?fedora} >= 15 || 0%{?rhel} >= 7
-%global with_systemd 1
-%endif
-
-%if 0%{?rhel} == 6
-Requires: python-ordereddict
-Requires: python-imaging
-BuildRequires: python-unittest2
-%endif
-
-%description
-Web application to manage KVM/Qemu virtual machines
-
-
-%prep
-%setup
-
-
-%build
-%if 0%{?rhel} >= 6 || 0%{?fedora} >= 19
-%configure
-%else
-%configure --with-spice-html5
-%endif
-make
-
-
-%install
-rm -rf %{buildroot}
-make DESTDIR=%{buildroot} install
-
-
-%clean
-rm -rf $RPM_BUILD_ROOT
-
-%files
-%attr(-,root,root)
-%{python_sitelib}/wok/plugins/kimchi/*.py*
-%{python_sitelib}/wok/plugins/kimchi/control/*.py*
-%{python_sitelib}/wok/plugins/kimchi/control/vm/*.py*
-%{python_sitelib}/wok/plugins/kimchi/model/*.py*
-%{python_sitelib}/wok/plugins/kimchi/API.json
-%{python_sitelib}/wok/plugins/kimchi/
-%{_datadir}/kimchi/doc/API.md
-%{_datadir}/kimchi/doc/README.md
-%{_datadir}/kimchi/doc/README-federation.md
-%{_datadir}/kimchi/doc/kimchi-guest.png
-%{_datadir}/kimchi/doc/kimchi-templates.png
-%{_prefix}/share/locale/*/LC_MESSAGES/kimchi.mo
-%{_datadir}/wok/plugins/kimchi/ui/config/*.xml
-%{_datadir}/wok/plugins/kimchi/ui/
-%{_datadir}/wok/plugins/kimchi
-%{_sysconfdir}/wok/plugins.d/kimchi.conf
-%{_sysconfdir}/wok/plugins.d/template.conf
-%{_sysconfdir}/kimchi/distros.d/debian.json
-%{_sysconfdir}/kimchi/distros.d/fedora.json
-%{_sysconfdir}/kimchi/distros.d/opensuse.json
-%{_sysconfdir}/kimchi/distros.d/ubuntu.json
-%{_sysconfdir}/kimchi/distros.d/gentoo.json
-%{_sysconfdir}/kimchi/
-%{_sharedstatedir}/kimchi/debugreports/
-%{_sharedstatedir}/kimchi/isos/
-%{_sharedstatedir}/kimchi/screenshots/
-%{_sharedstatedir}/kimchi/vnc-tokens/
-%{_sharedstatedir}/kimchi/
-
-
-%changelog
-* Thu Jun 18 2015 Lucio Correia <luciojhc(a)linux.vnet.ibm.com> 1.6
-- Run kimchi as a plugin
-
-* Thu Feb 26 2015 Fr��d��ric Bonnard <frediz(a)linux.vnet.ibm.com> 1.4.0
-- Add man page for kimchid
-
-* Tue Feb 11 2014 Cr��stian Viana <vianac(a)linux.vnet.ibm.com> 1.1.0
-- Add help pages and XSLT dependency
-
-* Tue Jul 16 2013 Adam Litke <agl(a)us.ibm.com> 0.1.0-1
-- Adapted for autotools build
-
-* Thu Apr 04 2013 Aline Manera <alinefm(a)br.ibm.com> 0.0-1
-- First build
diff --git a/plugins/kimchi/contrib/kimchi.spec.suse.in
b/plugins/kimchi/contrib/kimchi.spec.suse.in
deleted file mode 100644
index e466961..0000000
--- a/plugins/kimchi/contrib/kimchi.spec.suse.in
+++ /dev/null
@@ -1,107 +0,0 @@
-Name: kimchi
-Version: @PACKAGE_VERSION@
-Release: @PACKAGE_RELEASE@%{?dist}
-Summary: Kimchi server application
-BuildRoot: %{_topdir}/BUILD/%{name}-%{version}-%{release}
-BuildArch: noarch
-Group: System Environment/Base
-License: LGPL/ASL2
-Source0: %{name}-%{version}.tar.gz
-Requires: wok
-Requires: kvm
-Requires: gettext-tools
-Requires: libvirt
-Requires: libvirt-python
-Requires: libvirt-daemon-config-network
-Requires: python-websockify
-Requires: python-configobj
-Requires: novnc
-Requires: python-imaging
-Requires: python-parted
-Requires: python-psutil >= 0.6.0
-Requires: python-jsonschema >= 1.3.0
-Requires: python-ethtool
-Requires: python-ipaddr
-Requires: python-lxml
-Requires: python-xml
-Requires: nfs-client
-Requires: open-iscsi
-Requires: python-libguestfs
-Requires: guestfs-tools
-BuildRequires: libxslt-tools
-BuildRequires: python-lxml
-
-%if 0%{?suse_version} == 1100
-Requires: python-ordereddict
-%endif
-
-%if 0%{?suse_version} > 1140
-%global with_systemd 1
-%endif
-
-%description
-Web application to manage KVM/Qemu virtual machines
-
-%prep
-%setup
-
-%build
-%configure --with-spice-html5
-make
-
-%install
-rm -rf %{buildroot}
-make DESTDIR=%{buildroot} install
-
-
-%clean
-rm -rf $RPM_BUILD_ROOT
-
-%files
-%attr(-,root,root)
-%{python_sitelib}/wok/plugins/kimchi/*.py*
-%{python_sitelib}/wok/plugins/kimchi/control/*.py*
-%{python_sitelib}/wok/plugins/kimchi/control/vm/*.py*
-%{python_sitelib}/wok/plugins/kimchi/model/*.py*
-%{python_sitelib}/wok/plugins/kimchi/API.json
-%{python_sitelib}/wok/plugins/kimchi/
-%{_datadir}/kimchi/doc/API.md
-%{_datadir}/kimchi/doc/README.md
-%{_datadir}/kimchi/doc/README-federation.md
-%{_datadir}/kimchi/doc/kimchi-guest.png
-%{_datadir}/kimchi/doc/kimchi-templates.png
-%{_prefix}/share/locale/*/LC_MESSAGES/kimchi.mo
-%{_datadir}/wok/plugins/kimchi/ui/config/*.xml
-%{_datadir}/wok/plugins/kimchi/ui/
-%{_datadir}/wok/plugins/kimchi
-%{_sysconfdir}/wok/plugins.d/kimchi.conf
-%{_sysconfdir}/wok/plugins.d/template.conf
-%{_sysconfdir}/kimchi/distros.d/debian.json
-%{_sysconfdir}/kimchi/distros.d/fedora.json
-%{_sysconfdir}/kimchi/distros.d/opensuse.json
-%{_sysconfdir}/kimchi/distros.d/ubuntu.json
-%{_sysconfdir}/kimchi/distros.d/gentoo.json
-%{_sysconfdir}/kimchi/
-%{_var}/lib/kimchi/debugreports/
-%{_var}/lib/kimchi/isos/
-%{_var}/lib/kimchi/screenshots/
-%{_var}/lib/kimchi/vnc-tokens/
-%{_var}/lib/kimchi/
-
-
-%changelog
-* Thu Jun 18 2015 Lucio Correia <luciojhc(a)linux.vnet.ibm.com> 1.6
-- Run kimchi as a plugin
-
-* Thu Feb 26 2015 Fr��d��ric Bonnard <frediz(a)linux.vnet.ibm.com> 1.4.0
-- Add man page for kimchid
-
-* Tue Feb 11 2014 Cr��stian Viana <vianac(a)linux.vnet.ibm.com> 1.1.0
-- Add help pages and XSLT dependency
-
-* Thu Jul 18 2013 Adam Litke <agl(a)us.ibm.com> 0.1.0-1
-- Adapted for autotools build
-- Split Suse and Fedora spec files
-
-* Thu Apr 04 2013 Aline Manera <alinefm(a)br.ibm.com> 0.0-1
-- First build
diff --git a/plugins/kimchi/contrib/make-deb.sh.in
b/plugins/kimchi/contrib/make-deb.sh.in
deleted file mode 100644
index 5a6e56a..0000000
--- a/plugins/kimchi/contrib/make-deb.sh.in
+++ /dev/null
@@ -1,15 +0,0 @@
-#!/bin/bash
-
-VERSION="@PACKAGE_VERSION@"
-RELEASE="@PACKAGE_RELEASE@"
-
-if [ ! -f configure ]; then
- echo "Please run this script from the top of the package tree"
- exit 1
-fi
-
-TMPDIR=`mktemp -d`
-
-make DESTDIR=$TMPDIR install-deb
-dpkg-deb -b $TMPDIR kimchi-${VERSION}-${RELEASE}.noarch.deb
-rm -rf $TMPDIR
diff --git a/plugins/kimchi/control/Makefile.am b/plugins/kimchi/control/Makefile.am
deleted file mode 100644
index 33118ca..0000000
--- a/plugins/kimchi/control/Makefile.am
+++ /dev/null
@@ -1,27 +0,0 @@
-#
-# Kimchi
-#
-# Copyright IBM Corp, 2013
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-
-SUBDIRS = vm
-
-control_PYTHON = *.py
-
-controldir = $(pythondir)/wok/plugins/kimchi/control
-
-install-data-local:
- $(MKDIR_P) $(DESTDIR)$(controldir)
diff --git a/plugins/kimchi/control/__init__.py b/plugins/kimchi/control/__init__.py
deleted file mode 100644
index 4ad9459..0000000
--- a/plugins/kimchi/control/__init__.py
+++ /dev/null
@@ -1,26 +0,0 @@
-#
-# Project Kimchi
-#
-# Copyright IBM, Corp. 2013-2014
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-
-import os
-
-
-from wok.control.utils import load_url_sub_node
-
-
-sub_nodes = load_url_sub_node(os.path.dirname(__file__), __name__)
diff --git a/plugins/kimchi/control/config.py b/plugins/kimchi/control/config.py
deleted file mode 100644
index 15df68f..0000000
--- a/plugins/kimchi/control/config.py
+++ /dev/null
@@ -1,57 +0,0 @@
-#
-# Project Kimchi
-#
-# Copyright IBM, Corp. 2013-2014
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-
-from wok.control.base import Collection, Resource
-from wok.control.utils import UrlSubNode
-
-
-@UrlSubNode("config")
-class Config(Resource):
- def __init__(self, model, id=None):
- super(Config, self).__init__(model, id)
- self.capabilities = Capabilities(self.model)
- self.distros = Distros(model)
-
- @property
- def data(self):
- return self.info
-
-
-class Capabilities(Resource):
- def __init__(self, model, id=None):
- super(Capabilities, self).__init__(model, id)
-
- @property
- def data(self):
- return self.info
-
-
-class Distros(Collection):
- def __init__(self, model):
- super(Distros, self).__init__(model)
- self.resource = Distro
-
-
-class Distro(Resource):
- def __init__(self, model, ident):
- super(Distro, self).__init__(model, ident)
-
- @property
- def data(self):
- return self.info
diff --git a/plugins/kimchi/control/cpuinfo.py b/plugins/kimchi/control/cpuinfo.py
deleted file mode 100644
index 31f316c..0000000
--- a/plugins/kimchi/control/cpuinfo.py
+++ /dev/null
@@ -1,37 +0,0 @@
-#
-# Project Kimchi
-#
-# Copyright IBM, Corp. 2014
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-
-
-from wok.control.base import Resource
-
-
-class CPUInfo(Resource):
- def __init__(self, model):
- super(CPUInfo, self).__init__(model)
- self.admin_methods = ['GET']
- self.role_key = 'host'
- self.uri_fmt = "/host/cpuinfo"
-
- @property
- def data(self):
- return {'threading_enabled': self.info['guest_threads_enabled'],
- 'sockets': self.info['sockets'],
- 'cores': self.info['cores_available'],
- 'threads_per_core': self.info['threads_per_core']
- }
diff --git a/plugins/kimchi/control/debugreports.py
b/plugins/kimchi/control/debugreports.py
deleted file mode 100644
index b5a3072..0000000
--- a/plugins/kimchi/control/debugreports.py
+++ /dev/null
@@ -1,61 +0,0 @@
-#
-# Project Kimchi
-#
-# Copyright IBM, Corp. 2013-2015
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-
-from wok.control.base import AsyncCollection, Resource
-from wok.control.utils import internal_redirect
-from wok.control.utils import UrlSubNode
-
-
-@UrlSubNode('debugreports', True)
-class DebugReports(AsyncCollection):
- def __init__(self, model):
- super(DebugReports, self).__init__(model)
- self.resource = DebugReport
- self.role_key = 'host'
- self.admin_methods = ['GET', 'POST']
-
- def _get_resources(self, filter_params):
- res_list = super(DebugReports, self)._get_resources(filter_params)
- return sorted(res_list, key=lambda x: x.data['time'], reverse=True)
-
-
-class DebugReport(Resource):
- def __init__(self, model, ident):
- super(DebugReport, self).__init__(model, ident)
- self.role_key = 'host'
- self.admin_methods = ['GET', 'PUT', 'POST']
- self.uri_fmt = '/debugreports/%s'
- self.content = DebugReportContent(model, ident)
-
- @property
- def data(self):
- return {'name': self.ident,
- 'uri': self.info['uri'],
- 'time': self.info['ctime']}
-
-
-class DebugReportContent(Resource):
- def __init__(self, model, ident):
- super(DebugReportContent, self).__init__(model, ident)
- self.role_key = 'host'
- self.admin_methods = ['GET']
-
- def get(self):
- self.lookup()
- raise internal_redirect(self.info['uri'])
diff --git a/plugins/kimchi/control/groups.py b/plugins/kimchi/control/groups.py
deleted file mode 100644
index 649ff09..0000000
--- a/plugins/kimchi/control/groups.py
+++ /dev/null
@@ -1,28 +0,0 @@
-#
-# Project Kimchi
-#
-# Copyright IBM, Corp. 2013-2014
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-
-from wok.control.base import SimpleCollection
-from wok.control.utils import UrlSubNode
-
-
-@UrlSubNode('groups', True)
-class Groups(SimpleCollection):
- def __init__(self, model):
- super(Groups, self).__init__(model)
- self.role_key = 'guests'
diff --git a/plugins/kimchi/control/host.py b/plugins/kimchi/control/host.py
deleted file mode 100644
index 0a40f1b..0000000
--- a/plugins/kimchi/control/host.py
+++ /dev/null
@@ -1,157 +0,0 @@
-#
-# Project Kimchi
-#
-# Copyright IBM, Corp. 2013-2015
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-
-from wok.control.base import Collection, Resource, SimpleCollection
-from wok.control.utils import UrlSubNode
-from wok.exception import NotFoundError
-
-from cpuinfo import CPUInfo
-
-
-@UrlSubNode('host', True)
-class Host(Resource):
- def __init__(self, model, id=None):
- super(Host, self).__init__(model, id)
- self.role_key = 'host'
- self.admin_methods = ['GET', 'POST']
- self.uri_fmt = '/host/%s'
- self.reboot = self.generate_action_handler('reboot')
- self.shutdown = self.generate_action_handler('shutdown')
- self.stats = HostStats(self.model)
- self.partitions = Partitions(self.model)
- self.devices = Devices(self.model)
- self.packagesupdate = PackagesUpdate(self.model)
- self.repositories = Repositories(self.model)
- self.swupdate = self.generate_action_handler_task('swupdate')
- self.cpuinfo = CPUInfo(self.model)
-
- @property
- def data(self):
- return self.info
-
-
-class HostStats(Resource):
- def __init__(self, model, id=None):
- super(HostStats, self).__init__(model, id)
- self.role_key = 'host'
- self.admin_methods = ['GET']
- self.history = HostStatsHistory(self.model)
-
- @property
- def data(self):
- return self.info
-
-
-class HostStatsHistory(Resource):
- @property
- def data(self):
- return self.info
-
-
-class Partitions(Collection):
- def __init__(self, model):
- super(Partitions, self).__init__(model)
- self.role_key = 'storage'
- self.admin_methods = ['GET']
- self.resource = Partition
-
- # Defining get_resources in order to return list of partitions in UI
- # sorted by their path
- def _get_resources(self, flag_filter):
- res_list = super(Partitions, self)._get_resources(flag_filter)
- res_list = filter(lambda x: x.info['available'], res_list)
- res_list.sort(key=lambda x: x.info['path'])
- return res_list
-
-
-class Partition(Resource):
- def __init__(self, model, id):
- self.role_key = 'storage'
- self.admin_methods = ['GET']
- super(Partition, self).__init__(model, id)
-
- @property
- def data(self):
- if not self.info['available']:
- raise NotFoundError("KCHPART0001E", {'name':
self.info['name']})
-
- return self.info
-
-
-class Devices(Collection):
- def __init__(self, model):
- super(Devices, self).__init__(model)
- self.resource = Device
-
-
-class VMHolders(SimpleCollection):
- def __init__(self, model, device_id):
- super(VMHolders, self).__init__(model)
- self.model_args = (device_id, )
-
-
-class Device(Resource):
- def __init__(self, model, id):
- super(Device, self).__init__(model, id)
- self.vm_holders = VMHolders(self.model, id)
-
- @property
- def data(self):
- return self.info
-
-
-class PackagesUpdate(Collection):
- def __init__(self, model):
- super(PackagesUpdate, self).__init__(model)
- self.role_key = 'host'
- self.admin_methods = ['GET']
- self.resource = PackageUpdate
-
-
-class PackageUpdate(Resource):
- def __init__(self, model, id=None):
- super(PackageUpdate, self).__init__(model, id)
- self.role_key = 'host'
- self.admin_methods = ['GET']
-
- @property
- def data(self):
- return self.info
-
-
-class Repositories(Collection):
- def __init__(self, model):
- super(Repositories, self).__init__(model)
- self.role_key = 'host'
- self.admin_methods = ['GET', 'POST']
- self.resource = Repository
-
-
-class Repository(Resource):
- def __init__(self, model, id):
- super(Repository, self).__init__(model, id)
- self.role_key = 'host'
- self.admin_methods = ['GET', 'PUT', 'POST',
'DELETE']
- self.uri_fmt = "/host/repositories/%s"
- self.enable = self.generate_action_handler('enable')
- self.disable = self.generate_action_handler('disable')
-
- @property
- def data(self):
- return self.info
diff --git a/plugins/kimchi/control/interfaces.py b/plugins/kimchi/control/interfaces.py
deleted file mode 100644
index d698b7a..0000000
--- a/plugins/kimchi/control/interfaces.py
+++ /dev/null
@@ -1,46 +0,0 @@
-#
-# Project Kimchi
-#
-# Copyright IBM, Corp. 2013-2014
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-
-from wok.control.base import Collection, Resource
-from wok.control.utils import UrlSubNode
-
-
-@UrlSubNode('interfaces', True)
-class Interfaces(Collection):
- def __init__(self, model):
- super(Interfaces, self).__init__(model)
- self.role_key = 'network'
- self.admin_methods = ['GET']
- self.resource = Interface
-
-
-class Interface(Resource):
- def __init__(self, model, ident):
- super(Interface, self).__init__(model, ident)
- self.role_key = 'network'
- self.admin_methods = ['GET']
- self.uri_fmt = "/interfaces/%s"
-
- @property
- def data(self):
- return {'name': self.ident,
- 'type': self.info['type'],
- 'ipaddr': self.info['ipaddr'],
- 'netmask': self.info['netmask'],
- 'status': self.info['status']}
diff --git a/plugins/kimchi/control/networks.py b/plugins/kimchi/control/networks.py
deleted file mode 100644
index fd92111..0000000
--- a/plugins/kimchi/control/networks.py
+++ /dev/null
@@ -1,54 +0,0 @@
-#
-# Project Kimchi
-#
-# Copyright IBM, Corp. 2013-2015
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-
-from wok.control.base import Collection, Resource
-from wok.control.utils import UrlSubNode
-
-
-@UrlSubNode('networks', True)
-class Networks(Collection):
- def __init__(self, model):
- super(Networks, self).__init__(model)
- self.role_key = 'network'
- self.admin_methods = ['POST']
- self.resource = Network
-
-
-class Network(Resource):
- def __init__(self, model, ident):
- super(Network, self).__init__(model, ident)
- self.role_key = 'network'
- self.admin_methods = ['PUT', 'POST', 'DELETE']
- self.uri_fmt = "/networks/%s"
- self.activate = self.generate_action_handler('activate')
- self.deactivate = self.generate_action_handler('deactivate',
- destructive=True)
-
- @property
- def data(self):
- return {'name': self.ident,
- 'vms': self.info['vms'],
- 'in_use': self.info['in_use'],
- 'autostart': self.info['autostart'],
- 'connection': self.info['connection'],
- 'interface': self.info['interface'],
- 'subnet': self.info['subnet'],
- 'dhcp': self.info['dhcp'],
- 'state': self.info['state'],
- 'persistent': self.info['persistent']}
diff --git a/plugins/kimchi/control/peers.py b/plugins/kimchi/control/peers.py
deleted file mode 100644
index 21e9f13..0000000
--- a/plugins/kimchi/control/peers.py
+++ /dev/null
@@ -1,29 +0,0 @@
-#
-# Project Kimchi
-#
-# Copyright IBM, Corp. 2014
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-
-from wok.control.base import SimpleCollection
-from wok.control.utils import UrlSubNode
-
-
-@UrlSubNode("peers", True)
-class Peers(SimpleCollection):
- def __init__(self, model):
- super(Peers, self).__init__(model)
- self.role_key = 'peers'
- self.admin_methods = ['GET']
diff --git a/plugins/kimchi/control/storagepools.py
b/plugins/kimchi/control/storagepools.py
deleted file mode 100644
index e5f264e..0000000
--- a/plugins/kimchi/control/storagepools.py
+++ /dev/null
@@ -1,116 +0,0 @@
-#
-# Project Kimchi
-#
-# Copyright IBM, Corp. 2013-2015
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-
-import cherrypy
-
-from wok.control.base import Collection, Resource
-from wok.control.utils import get_class_name, model_fn
-from wok.control.utils import validate_params
-from wok.control.utils import UrlSubNode
-
-from ..model.storagepools import ISO_POOL_NAME
-from storagevolumes import IsoVolumes, StorageVolumes
-
-
-@UrlSubNode('storagepools', True)
-class StoragePools(Collection):
- def __init__(self, model):
- super(StoragePools, self).__init__(model)
- self.role_key = 'storage'
- self.admin_methods = ['POST']
- self.resource = StoragePool
- isos = IsoPool(model)
- setattr(self, ISO_POOL_NAME, isos)
-
- def create(self, params, *args):
- try:
- create = getattr(self.model, model_fn(self, 'create'))
- except AttributeError:
- error = 'Create is not allowed for %s' % get_class_name(self)
- raise cherrypy.HTTPError(405, error)
-
- validate_params(params, self, 'create')
- args = self.model_args + [params]
- name = create(*args)
- args = self.resource_args + [name]
- res = self.resource(self.model, *args)
- resp = res.get()
-
- if 'task_id' in res.data:
- cherrypy.response.status = 202
- else:
- cherrypy.response.status = 201
-
- return resp
-
- def _get_resources(self, filter_params):
- try:
- res_list = super(StoragePools, self)._get_resources(filter_params)
- # Append reserved pools
- isos = getattr(self, ISO_POOL_NAME)
- isos.lookup()
- res_list.append(isos)
- except AttributeError:
- pass
-
- return res_list
-
-
-class StoragePool(Resource):
- def __init__(self, model, ident):
- super(StoragePool, self).__init__(model, ident)
- self.role_key = 'storage'
- self.admin_methods = ['PUT', 'POST', 'DELETE']
- self.uri_fmt = "/storagepools/%s"
- self.activate = self.generate_action_handler('activate')
- self.deactivate = self.generate_action_handler('deactivate',
- destructive=True)
- self.storagevolumes = StorageVolumes(self.model, ident)
-
- @property
- def data(self):
- res = {'name': self.ident,
- 'state': self.info['state'],
- 'capacity': self.info['capacity'],
- 'allocated': self.info['allocated'],
- 'available': self.info['available'],
- 'path': self.info['path'],
- 'source': self.info['source'],
- 'type': self.info['type'],
- 'nr_volumes': self.info['nr_volumes'],
- 'autostart': self.info['autostart'],
- 'persistent': self.info['persistent']}
-
- val = self.info.get('task_id')
- if val:
- res['task_id'] = val
-
- return res
-
-
-class IsoPool(Resource):
- def __init__(self, model):
- super(IsoPool, self).__init__(model, ISO_POOL_NAME)
- self.storagevolumes = IsoVolumes(self.model, ISO_POOL_NAME)
-
- @property
- def data(self):
- return {'name': self.ident,
- 'state': self.info['state'],
- 'type': self.info['type']}
diff --git a/plugins/kimchi/control/storageservers.py
b/plugins/kimchi/control/storageservers.py
deleted file mode 100644
index 654ab47..0000000
--- a/plugins/kimchi/control/storageservers.py
+++ /dev/null
@@ -1,60 +0,0 @@
-#
-# Project Kimchi
-#
-# Copyright IBM, Corp. 2014
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-
-from wok import template
-from wok.control.base import Collection, Resource
-from wok.control.utils import get_class_name, model_fn, UrlSubNode
-
-
-@UrlSubNode('storageservers', True)
-class StorageServers(Collection):
- def __init__(self, model):
- super(StorageServers, self).__init__(model)
- self.role_key = 'storage'
- self.admin_methods = ['GET']
- self.resource = StorageServer
-
-
-class StorageServer(Resource):
- def __init__(self, model, ident):
- super(StorageServer, self).__init__(model, ident)
- self.role_key = 'storage'
- self.admin_methods = ['GET']
- self.storagetargets = StorageTargets(self.model,
- self.ident.decode("utf-8"))
-
- @property
- def data(self):
- return self.info
-
-
-class StorageTargets(Collection):
- def __init__(self, model, server):
- super(StorageTargets, self).__init__(model)
- self.role_key = 'storage'
- self.admin_methods = ['GET']
- self.server = server
- self.resource_args = [self.server, ]
- self.model_args = [self.server, ]
-
- def get(self, filter_params):
- res_list = []
- get_list = getattr(self.model, model_fn(self, 'get_list'))
- res_list = get_list(*self.model_args, **filter_params)
- return template.render(get_class_name(self), res_list)
diff --git a/plugins/kimchi/control/storagevolumes.py
b/plugins/kimchi/control/storagevolumes.py
deleted file mode 100644
index bbe6627..0000000
--- a/plugins/kimchi/control/storagevolumes.py
+++ /dev/null
@@ -1,83 +0,0 @@
-#
-# Project Kimchi
-#
-# Copyright IBM, Corp. 2013-2015
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-
-from wok import template
-from wok.control.base import AsyncCollection, Collection, Resource
-from wok.control.utils import get_class_name, model_fn
-
-
-class StorageVolumes(AsyncCollection):
- def __init__(self, model, pool):
- super(StorageVolumes, self).__init__(model)
- self.resource = StorageVolume
- self.pool = pool
- self.resource_args = [self.pool, ]
- self.model_args = [self.pool, ]
-
- def filter_data(self, resources, fields_filter):
- # filter directory from storage volumes
- fields_filter.update({'type': ['file', 'block',
'network']})
- return super(StorageVolumes, self).filter_data(resources,
- fields_filter)
-
-
-class StorageVolume(Resource):
- def __init__(self, model, pool, ident):
- super(StorageVolume, self).__init__(model, ident)
- self.pool = pool
- self.ident = ident
- self.info = {}
- self.model_args = [self.pool, self.ident]
- self.uri_fmt = '/storagepools/%s/storagevolumes/%s'
- self.resize = self.generate_action_handler('resize', ['size'])
- self.wipe = self.generate_action_handler('wipe')
- self.clone = self.generate_action_handler_task('clone')
-
- @property
- def data(self):
- res = {'name': self.ident,
- 'type': self.info['type'],
- 'capacity': self.info['capacity'],
- 'allocation': self.info['allocation'],
- 'path': self.info['path'],
- 'used_by': self.info['used_by'],
- 'format': self.info['format']}
-
- for key in ('os_version', 'os_distro', 'bootable',
'base'):
- val = self.info.get(key)
- if val:
- res[key] = val
-
- return res
-
-
-class IsoVolumes(Collection):
- def __init__(self, model, pool):
- super(IsoVolumes, self).__init__(model)
- self.pool = pool
-
- def get(self, filter_params):
- res_list = []
- try:
- get_list = getattr(self.model, model_fn(self, 'get_list'))
- res_list = get_list(*self.model_args)
- except AttributeError:
- pass
-
- return template.render(get_class_name(self), res_list)
diff --git a/plugins/kimchi/control/templates.py b/plugins/kimchi/control/templates.py
deleted file mode 100644
index fc58815..0000000
--- a/plugins/kimchi/control/templates.py
+++ /dev/null
@@ -1,58 +0,0 @@
-#
-# Project Kimchi
-#
-# Copyright IBM, Corp. 2013-2015
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-
-from wok.control.base import Collection, Resource
-from wok.control.utils import UrlSubNode
-
-
-@UrlSubNode('templates', True)
-class Templates(Collection):
- def __init__(self, model):
- super(Templates, self).__init__(model)
- self.role_key = 'templates'
- self.admin_methods = ['GET', 'POST']
- self.resource = Template
-
-
-class Template(Resource):
- def __init__(self, model, ident):
- super(Template, self).__init__(model, ident)
- self.role_key = 'templates'
- self.admin_methods = ['PUT', 'POST', 'DELETE']
- self.uri_fmt = "/templates/%s"
- self.clone = self.generate_action_handler('clone')
-
- @property
- def data(self):
- return {
- 'name': self.ident,
- 'icon': self.info['icon'],
- 'invalid': self.info['invalid'],
- 'os_distro': self.info['os_distro'],
- 'os_version': self.info['os_version'],
- 'cpus': self.info['cpus'],
- 'memory': self.info['memory'],
- 'cdrom': self.info.get('cdrom', None),
- 'disks': self.info['disks'],
- 'storagepool': self.info['storagepool'],
- 'networks': self.info['networks'],
- 'folder': self.info.get('folder', []),
- 'graphics': self.info['graphics'],
- 'cpu_info': self.info.get('cpu_info')
- }
diff --git a/plugins/kimchi/control/users.py b/plugins/kimchi/control/users.py
deleted file mode 100644
index 756a2f7..0000000
--- a/plugins/kimchi/control/users.py
+++ /dev/null
@@ -1,35 +0,0 @@
-#
-# Project Kimchi
-#
-# Copyright IBM, Corp. 2013-2014
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-
-from wok.control.base import SimpleCollection
-from wok.control.utils import get_class_name, model_fn, UrlSubNode
-from wok.template import render
-
-
-@UrlSubNode('users', True)
-class Users(SimpleCollection):
- def __init__(self, model):
- super(Users, self).__init__(model)
- self.role_key = 'guests'
-
- def get(self, filter_params):
- res_list = []
- get_list = getattr(self.model, model_fn(self, 'get_list'))
- res_list = get_list(*self.model_args, **filter_params)
- return render(get_class_name(self), res_list)
diff --git a/plugins/kimchi/control/vm/Makefile.am
b/plugins/kimchi/control/vm/Makefile.am
deleted file mode 100644
index b17c68a..0000000
--- a/plugins/kimchi/control/vm/Makefile.am
+++ /dev/null
@@ -1,26 +0,0 @@
-#
-# Kimchi
-#
-# Copyright IBM Corp, 2013
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-
-
-vm_PYTHON = *.py
-
-vmdir = $(pythondir)/wok/plugins/kimchi/control/vm
-
-install-data-local:
- $(MKDIR_P) $(DESTDIR)$(vmdir)
diff --git a/plugins/kimchi/control/vm/__init__.py
b/plugins/kimchi/control/vm/__init__.py
deleted file mode 100644
index a311045..0000000
--- a/plugins/kimchi/control/vm/__init__.py
+++ /dev/null
@@ -1,26 +0,0 @@
-#
-# Project Kimchi
-#
-# Copyright IBM, Corp. 2014
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-
-import os
-
-
-from wok.control.utils import load_url_sub_node
-
-
-sub_nodes = load_url_sub_node(os.path.dirname(__file__), __name__)
diff --git a/plugins/kimchi/control/vm/hostdevs.py
b/plugins/kimchi/control/vm/hostdevs.py
deleted file mode 100644
index a43b9d8..0000000
--- a/plugins/kimchi/control/vm/hostdevs.py
+++ /dev/null
@@ -1,43 +0,0 @@
-#
-# Project Kimchi
-#
-# Copyright IBM, Corp. 2014
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-
-from wok.control.base import Collection, Resource
-from wok.control.utils import UrlSubNode
-
-
-@UrlSubNode("hostdevs")
-class VMHostDevs(Collection):
- def __init__(self, model, vmid):
- super(VMHostDevs, self).__init__(model)
- self.resource = VMHostDev
- self.vmid = vmid
- self.resource_args = [self.vmid, ]
- self.model_args = [self.vmid, ]
-
-
-class VMHostDev(Resource):
- def __init__(self, model, vmid, ident):
- super(VMHostDev, self).__init__(model, ident)
- self.vmid = vmid
- self.ident = ident
- self.model_args = [self.vmid, self.ident]
-
- @property
- def data(self):
- return self.info
diff --git a/plugins/kimchi/control/vm/ifaces.py b/plugins/kimchi/control/vm/ifaces.py
deleted file mode 100644
index ac957fd..0000000
--- a/plugins/kimchi/control/vm/ifaces.py
+++ /dev/null
@@ -1,45 +0,0 @@
-#
-# Project Kimchi
-#
-# Copyright IBM, Corp. 2014-2015
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-
-from wok.control.base import Collection, Resource
-from wok.control.utils import UrlSubNode
-
-
-@UrlSubNode("ifaces")
-class VMIfaces(Collection):
- def __init__(self, model, vm):
- super(VMIfaces, self).__init__(model)
- self.resource = VMIface
- self.vm = vm
- self.resource_args = [self.vm, ]
- self.model_args = [self.vm, ]
-
-
-class VMIface(Resource):
- def __init__(self, model, vm, ident):
- super(VMIface, self).__init__(model, ident)
- self.vm = vm
- self.ident = ident
- self.info = {}
- self.model_args = [self.vm, self.ident]
- self.uri_fmt = '/vms/%s/ifaces/%s'
-
- @property
- def data(self):
- return self.info
diff --git a/plugins/kimchi/control/vm/snapshots.py
b/plugins/kimchi/control/vm/snapshots.py
deleted file mode 100644
index dd17b85..0000000
--- a/plugins/kimchi/control/vm/snapshots.py
+++ /dev/null
@@ -1,58 +0,0 @@
-#
-# Project Kimchi
-#
-# Copyright IBM, Corp. 2014
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-
-from wok.control.base import AsyncCollection, Resource
-from wok.control.utils import UrlSubNode
-
-
-@UrlSubNode('snapshots')
-class VMSnapshots(AsyncCollection):
- def __init__(self, model, vm):
- super(VMSnapshots, self).__init__(model)
- self.resource = VMSnapshot
- self.vm = vm
- self.resource_args = [self.vm, ]
- self.model_args = [self.vm, ]
- self.current = CurrentVMSnapshot(model, vm)
-
-
-class VMSnapshot(Resource):
- def __init__(self, model, vm, ident):
- super(VMSnapshot, self).__init__(model, ident)
- self.vm = vm
- self.ident = ident
- self.model_args = [self.vm, self.ident]
- self.uri_fmt = '/vms/%s/snapshots/%s'
- self.revert = self.generate_action_handler('revert')
-
- @property
- def data(self):
- return self.info
-
-
-class CurrentVMSnapshot(Resource):
- def __init__(self, model, vm):
- super(CurrentVMSnapshot, self).__init__(model)
- self.vm = vm
- self.model_args = [self.vm]
- self.uri_fmt = '/vms/%s/snapshots/current'
-
- @property
- def data(self):
- return self.info
diff --git a/plugins/kimchi/control/vm/storages.py
b/plugins/kimchi/control/vm/storages.py
deleted file mode 100644
index f502caa..0000000
--- a/plugins/kimchi/control/vm/storages.py
+++ /dev/null
@@ -1,45 +0,0 @@
-#
-# Project Kimchi
-#
-# Copyright IBM, Corp. 2014-2015
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-
-from wok.control.base import Collection, Resource
-from wok.control.utils import UrlSubNode
-
-
-@UrlSubNode("storages")
-class VMStorages(Collection):
- def __init__(self, model, vm):
- super(VMStorages, self).__init__(model)
- self.resource = VMStorage
- self.vm = vm
- self.resource_args = [self.vm, ]
- self.model_args = [self.vm, ]
-
-
-class VMStorage(Resource):
- def __init__(self, model, vm, ident):
- super(VMStorage, self).__init__(model, ident)
- self.vm = vm
- self.ident = ident
- self.info = {}
- self.model_args = [self.vm, self.ident]
- self.uri_fmt = '/vms/%s/storages/%s'
-
- @property
- def data(self):
- return self.info
diff --git a/plugins/kimchi/control/vms.py b/plugins/kimchi/control/vms.py
deleted file mode 100644
index 858b23c..0000000
--- a/plugins/kimchi/control/vms.py
+++ /dev/null
@@ -1,67 +0,0 @@
-#
-# Project Kimchi
-#
-# Copyright IBM, Corp. 2013-2015
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-
-from wok.control.base import AsyncCollection, Resource
-from wok.control.utils import internal_redirect, UrlSubNode
-
-from vm import sub_nodes
-
-
-@UrlSubNode('vms', True)
-class VMs(AsyncCollection):
- def __init__(self, model):
- super(VMs, self).__init__(model)
- self.resource = VM
- self.role_key = 'guests'
- self.admin_methods = ['POST']
-
-
-class VM(Resource):
- def __init__(self, model, ident):
- super(VM, self).__init__(model, ident)
- self.role_key = 'guests'
- self.screenshot = VMScreenShot(model, ident)
- self.uri_fmt = '/vms/%s'
- for ident, node in sub_nodes.items():
- setattr(self, ident, node(model, self.ident))
- self.start = self.generate_action_handler('start')
- self.poweroff = self.generate_action_handler('poweroff',
- destructive=True)
- self.shutdown = self.generate_action_handler('shutdown',
- destructive=True)
- self.reset = self.generate_action_handler('reset',
- destructive=True)
- self.connect = self.generate_action_handler('connect')
- self.clone = self.generate_action_handler_task('clone')
- self.suspend = self.generate_action_handler('suspend')
- self.resume = self.generate_action_handler('resume')
-
- @property
- def data(self):
- return self.info
-
-
-class VMScreenShot(Resource):
- def __init__(self, model, ident):
- super(VMScreenShot, self).__init__(model, ident)
- self.role_key = 'guests'
-
- def get(self):
- self.lookup()
- raise internal_redirect(self.info)
diff --git a/plugins/kimchi/disks.py b/plugins/kimchi/disks.py
deleted file mode 100644
index eb40e3a..0000000
--- a/plugins/kimchi/disks.py
+++ /dev/null
@@ -1,196 +0,0 @@
-#
-# Project Kimchi
-#
-# Copyright IBM, Corp. 2013-2015
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-
-import os.path
-import re
-import subprocess
-from parted import Device as PDevice
-from parted import Disk as PDisk
-
-from wok.exception import OperationFailed
-from wok.utils import wok_log
-
-
-def _get_dev_node_path(maj_min):
- """ Returns device node path given the device number
'major:min' """
-
- dm_name = "/sys/dev/block/%s/dm/name" % maj_min
- if os.path.exists(dm_name):
- with open(dm_name) as dm_f:
- content = dm_f.read().rstrip('\n')
- return "/dev/mapper/" + content
-
- uevent = "/sys/dev/block/%s/uevent" % maj_min
- with open(uevent) as ueventf:
- content = ueventf.read()
-
- data = dict(re.findall(r'(\S+)=(".*?"|\S+)',
content.replace("\n", " ")))
-
- return "/dev/%s" % data["DEVNAME"]
-
-
-def _get_lsblk_devs(keys, devs=[]):
- lsblk = subprocess.Popen(
- ["lsblk", "-Pbo"] + [','.join(keys)] + devs,
- stdout=subprocess.PIPE, stderr=subprocess.PIPE)
- out, err = lsblk.communicate()
- if lsblk.returncode != 0:
- raise OperationFailed("KCHDISKS0001E", {'err': err})
-
- return _parse_lsblk_output(out, keys)
-
-
-def _get_dev_major_min(name):
- maj_min = None
-
- keys = ["NAME", "MAJ:MIN"]
- dev_list = _get_lsblk_devs(keys)
-
- for dev in dev_list:
- if dev['name'].split()[0] == name:
- maj_min = dev['maj:min']
- break
- else:
- raise OperationFailed("KCHDISKS0002E", {'device': name})
-
- return maj_min
-
-
-def _is_dev_leaf(devNodePath):
- try:
- # By default, lsblk prints a device information followed by children
- # device information
- childrenCount = len(
- _get_lsblk_devs(["NAME"], [devNodePath])) - 1
- except OperationFailed as e:
- # lsblk is known to fail on multipath devices
- # Assume these devices contain children
- wok_log.error(
- "Error getting device info for %s: %s", devNodePath, e)
- return False
-
- return childrenCount == 0
-
-
-def _is_dev_extended_partition(devType, devNodePath):
- if devType != 'part':
- return False
- diskPath = devNodePath.rstrip('0123456789')
- device = PDevice(diskPath)
- try:
- extended_part = PDisk(device).getExtendedPartition()
- except NotImplementedError as e:
- wok_log.warning(
- "Error getting extended partition info for dev %s type %s: %s",
- devNodePath, devType, e.message)
- # Treate disk with unsupported partiton table as if it does not
- # contain extended partitions.
- return False
- if extended_part and extended_part.path == devNodePath:
- return True
- return False
-
-
-def _parse_lsblk_output(output, keys):
- # output is on format key="value",
- # where key can be NAME, TYPE, FSTYPE, SIZE, MOUNTPOINT, etc
- lines = output.rstrip("\n").split("\n")
- r = []
- for line in lines:
- d = {}
- for key in keys:
- expression = r"%s=\".*?\"" % key
- match = re.search(expression, line)
- field = match.group()
- k, v = field.split('=', 1)
- d[k.lower()] = v[1:-1]
- r.append(d)
- return r
-
-
-def _get_vgname(devNodePath):
- """ Return volume group name of a physical volume. If the device node
path
- is not a physical volume, return empty string. """
- pvs = subprocess.Popen(
- ["pvs", "--unbuffered", "--nameprefixes",
"--noheadings",
- "-o", "vg_name", devNodePath],
- stdout=subprocess.PIPE, stderr=subprocess.PIPE)
- out, err = pvs.communicate()
- if pvs.returncode != 0:
- return ""
-
- return re.findall(r"LVM2_VG_NAME='([^\']*)'", out)[0]
-
-
-def _is_available(name, devtype, fstype, mountpoint, majmin):
- devNodePath = _get_dev_node_path(majmin)
- # Only list unmounted and unformated and leaf and (partition or disk)
- # leaf means a partition, a disk has no partition, or a disk not held
- # by any multipath device. Physical volume belongs to no volume group
- # is also listed. Extended partitions should not be listed.
- if (devtype in ['part', 'disk', 'mpath'] and
- fstype in ['', 'LVM2_member'] and
- mountpoint == "" and
- _get_vgname(devNodePath) == "" and
- _is_dev_leaf(devNodePath) and
- not _is_dev_extended_partition(devtype, devNodePath)):
- return True
- return False
-
-
-def get_partitions_names(check=False):
- names = set()
- keys = ["NAME", "TYPE", "FSTYPE",
"MOUNTPOINT", "MAJ:MIN"]
- # output is on format key="value",
- # where key can be NAME, TYPE, FSTYPE, MOUNTPOINT
- for dev in _get_lsblk_devs(keys):
- # split()[0] to avoid the second part of the name, after the
- # whiteline
- name = dev['name'].split()[0]
- if check and not _is_available(name, dev['type'], dev['fstype'],
- dev['mountpoint'],
dev['maj:min']):
- continue
- names.add(name)
-
- return list(names)
-
-
-def get_partition_details(name):
- majmin = _get_dev_major_min(name)
- dev_path = _get_dev_node_path(majmin)
-
- keys = ["TYPE", "FSTYPE", "SIZE",
"MOUNTPOINT"]
- try:
- dev = _get_lsblk_devs(keys, [dev_path])[0]
- except OperationFailed as e:
- wok_log.error(
- "Error getting partition info for %s: %s", name, e)
- return {}
-
- dev['available'] = _is_available(name, dev['type'],
dev['fstype'],
- dev['mountpoint'], majmin)
- if dev['mountpoint']:
- # Sometimes the mountpoint comes with [SWAP] or other
- # info which is not an actual mount point. Filtering it
- regexp = re.compile(r"\[.*\]")
- if regexp.search(dev['mountpoint']) is not None:
- dev['mountpoint'] = ''
- dev['path'] = dev_path
- dev['name'] = name
- return dev
diff --git a/plugins/kimchi/distroloader.py b/plugins/kimchi/distroloader.py
deleted file mode 100644
index 0032737..0000000
--- a/plugins/kimchi/distroloader.py
+++ /dev/null
@@ -1,67 +0,0 @@
-#
-# Project Kimchi
-#
-# Copyright IBM, Corp. 2013-2015
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-#
-
-import glob
-import json
-import os
-
-
-from wok.exception import NotFoundError, OperationFailed
-from wok.utils import wok_log
-
-import config
-
-
-ARCHS = {'x86_64': ['x86_64', 'amd64', 'i686',
'x86', 'i386'],
- 'amd64': ['x86_64', 'amd64', 'i686',
'x86', 'i386'],
- 'ppc64': ['ppc', 'ppc64'],
- 'ppc64le': ['ppc64', 'ppc64le']}
-
-
-class DistroLoader(object):
-
- def __init__(self, location=None):
- self.location = location or config.get_distros_store()
-
- def _get_json_info(self, fname):
- msg_args = {'filename': fname}
- if not os.path.isfile(fname):
- msg = "DistroLoader: failed to find distro file: %s" % fname
- wok_log.error(msg)
- raise NotFoundError("KCHDL0001E", msg_args)
- try:
- with open(fname) as f:
- data = json.load(f)
- return data
- except ValueError:
- msg = "DistroLoader: failed to parse distro file: %s" % fname
- wok_log.error(msg)
- raise OperationFailed("KCHDL0002E", msg_args)
-
- def get(self):
- arch_list = ARCHS.get(os.uname()[4])
- all_json_files = glob.glob("%s/%s" % (self.location,
"*.json"))
- distros = []
- for f in all_json_files:
- distros.extend(self._get_json_info(f))
-
- # Return all remote ISOs arch not found
- return dict([(distro['name'], distro) for distro in distros if
- (arch_list is None or distro['os_arch'] in arch_list)])
diff --git a/plugins/kimchi/distros.d/Makefile.am b/plugins/kimchi/distros.d/Makefile.am
deleted file mode 100644
index 684fe60..0000000
--- a/plugins/kimchi/distros.d/Makefile.am
+++ /dev/null
@@ -1,22 +0,0 @@
-#
-# Kimchi
-#
-# Copyright IBM Corp, 2013
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-
-distrosdir = $(sysconfdir)/kimchi/distros.d
-
-dist_distros_DATA = *.json
diff --git a/plugins/kimchi/distros.d/debian.json b/plugins/kimchi/distros.d/debian.json
deleted file mode 100644
index 5d6a313..0000000
--- a/plugins/kimchi/distros.d/debian.json
+++ /dev/null
@@ -1,9 +0,0 @@
-[
- {
- "name": "debian-Wheezy",
- "os_distro": "debian",
- "os_arch": "x86_64",
- "os_version": "7.7.0",
- "path":
"http://caesar.acc.umu.se/debian-cd/7.7.0/amd64/iso-cd/debian-7.7.0-amd64-netinst.iso"
- }
-]
diff --git a/plugins/kimchi/distros.d/fedora.json b/plugins/kimchi/distros.d/fedora.json
deleted file mode 100644
index bce72d6..0000000
--- a/plugins/kimchi/distros.d/fedora.json
+++ /dev/null
@@ -1,30 +0,0 @@
-[
- {
- "name": "Fedora 20",
- "os_distro": "fedora",
- "os_arch": "x86_64",
- "os_version": "20",
- "path":
"http://fedora.mirrors.tds.net/pub/fedora/releases/20/Live/x86_64/Fedora-Live-Desktop-x86_64-20-1.iso"
- },
- {
- "name": "Fedora 18 (PPC64)",
- "os_distro": "fedora",
- "os_arch": "ppc64",
- "os_version": "18",
- "path":
"http://mirrors.kernel.org/fedora-secondary/releases/18/Fedora/ppc64/iso/Fedora-18-ppc64-DVD.iso"
- },
- {
- "name": "Fedora 19 (PPC64)",
- "os_distro": "fedora",
- "os_arch": "ppc64",
- "os_version": "19",
- "path":
"http://mirrors.kernel.org/fedora-secondary/releases/19/Fedora/ppc64/iso/Fedora-19-ppc64-DVD.iso"
- },
- {
- "name": "Fedora 20 (PPC64)",
- "os_distro": "fedora",
- "os_arch": "ppc64",
- "os_version": "20",
- "path":
"http://mirrors.kernel.org/fedora-secondary/releases/20/Fedora/ppc64/iso/Fedora-20-ppc64-DVD.iso"
- }
-]
diff --git a/plugins/kimchi/distros.d/gentoo.json b/plugins/kimchi/distros.d/gentoo.json
deleted file mode 100644
index 2c0f012..0000000
--- a/plugins/kimchi/distros.d/gentoo.json
+++ /dev/null
@@ -1,9 +0,0 @@
-[
- {
- "name": "gentoo-20141204",
- "os_distro": "gentoo",
- "os_arch": "x86_64",
- "os_version": "20141204",
- "path":
"http://distfiles.gentoo.org/releases/amd64/autobuilds/current-iso/install-amd64-minimal-20141204.iso"
- }
-]
diff --git a/plugins/kimchi/distros.d/opensuse.json
b/plugins/kimchi/distros.d/opensuse.json
deleted file mode 100644
index f51de97..0000000
--- a/plugins/kimchi/distros.d/opensuse.json
+++ /dev/null
@@ -1,23 +0,0 @@
-[
- {
- "name": "opensuse-12.3",
- "os_distro": "opensuse",
- "os_arch": "x86_64",
- "os_version": "12.3",
- "path":
"http://suse.mirrors.tds.net/pub/opensuse/distribution/12.3/iso/openSUSE-12.3-DVD-x86_64.iso"
- },
- {
- "name": "opensuse-13.1",
- "os_distro": "opensuse",
- "os_arch": "x86_64",
- "os_version": "13.1",
- "path":
"http://suse.mirrors.tds.net/pub/opensuse/distribution/13.1/iso/openSUSE-13.1-DVD-x86_64.iso"
- },
- {
- "name": "opensuse-13.2",
- "os_distro": "opensuse",
- "os_arch": "x86_64",
- "os_version": "13.2",
- "path":
"http://suse.mirrors.tds.net/pub/opensuse/distribution/13.2/iso/openSUSE-13.2-DVD-x86_64.iso"
- }
-]
diff --git a/plugins/kimchi/distros.d/ubuntu.json b/plugins/kimchi/distros.d/ubuntu.json
deleted file mode 100644
index 161fbc8..0000000
--- a/plugins/kimchi/distros.d/ubuntu.json
+++ /dev/null
@@ -1,37 +0,0 @@
-[
- {
- "name": "Ubuntu 13.04 (Raring Ringtail)",
- "os_distro": "ubuntu",
- "os_arch": "x86_64",
- "os_version": "13.04",
- "path":
"http://ubuntu-releases.cs.umn.edu/13.04/ubuntu-13.04-desktop-amd64.iso"
- },
- {
- "name": "Ubuntu 13.10 (Saucy Salamander)",
- "os_distro": "ubuntu",
- "os_arch": "x86_64",
- "os_version": "13.10",
- "path":
"http://ubuntu-releases.cs.umn.edu/13.10/ubuntu-13.10-desktop-amd64.iso"
- },
- {
- "name": "Ubuntu Server 14.04 LE (Trusty Tahr)",
- "os_distro": "ubuntu",
- "os_arch": "ppc64",
- "os_version": "14.04",
- "path":
"http://cdimages.ubuntu.com/releases/14.04/release/ubuntu-14.04-server-ppc64el.iso"
- },
- {
- "name": "Ubuntu Server 14.04 LE (Trusty Tahr)",
- "os_distro": "ubuntu",
- "os_arch": "x86_64",
- "os_version": "14.04",
- "path":
"http://releases.ubuntu.com/14.04/ubuntu-14.04-desktop-amd64.iso"
- },
- {
- "name": "Ubuntu Server 14.10 (Utopic Unicorn)",
- "os_distro": "ubuntu",
- "os_arch": "x86_64",
- "os_version": "14.10",
- "path":
"http://releases.ubuntu.com/14.10/ubuntu-14.10-desktop-amd64.iso"
- }
-]
diff --git a/plugins/kimchi/docs/API.md b/plugins/kimchi/docs/API.md
deleted file mode 100644
index fca424c..0000000
--- a/plugins/kimchi/docs/API.md
+++ /dev/null
@@ -1,1116 +0,0 @@
-## Project Kimchi REST API Specification
-
-The Kimchi API provides all functionality to the application and may be used
-directly by external tools. In the following sections you will find the
-specification of all Collections and Resource types that are supported and the
-URIs where they can be accessed. In order to use the API effectively, please
-the following general conventions:
-
-* The **Content Type** of the API is JSON. When making HTTP requests to this
- API you should specify the following headers:
- * Accept: application/json
- * Content-type: application/json
-* A **Collection** is a group of Resources of a given type.
- * A **GET** request retrieves a list of summarized Resource representations
- This summary *may* include all or some of the Resource properties but
- *must* include a link to the full Resource representation.
- * A **POST** request will create a new Resource in the Collection. The set
- of Resource properties *must* be specified as a JSON object in the request
- body.
- * No other HTTP methods are supported for Collections
-* A **Resource** is a representation of a singular object in the API (eg.
- Virtual Machine).
- * A **GET** request retrieves the full Resource representation.
- * A **DELETE** request will delete the Resource. This request *may* contain
- a JSON object which specifies optional parameters.
- * A **PUT** request is used to modify the properties of a Resource (eg.
- Change the name of a Virtual Machine). This kind of request *must not*
- alter the live state of the Resource. Only *actions* may alter live state.
- * A **POST** request commits an *action* upon a Resource (eg. Start a
- Virtual Machine). This request is made to a URI relative to the Resource
- URI. Available *actions* are described within the *actions* property of a
- Resource representation. The request body *must* contain a JSON object
- which specifies parameters.
-* URIs begin with '/plugins/kimchi' to indicate the root of Kimchi plugin.
- * Variable segments in the URI begin with a ':' and should replaced with the
- appropriate resource identifier.
-
-### Collection: Virtual Machines
-
-**URI:** /plugins/kimchi/vms
-
-**Methods:**
-
-* **GET**: Retrieve a summarized list of all defined Virtual Machines
-* **POST**: Create a new Virtual Machine
- * name *(optional)*: The name of the VM. Used to identify the VM in this
- API. If omitted, a name will be chosen based on the template used.
- * persistent: If 'true', vm will persist after a Power Off or host reboot.
- All virtual machines created by Kimchi are persistent.
- * template: The URI of a Template to use when building the VM
- * storagepool *(optional)*: Assign a specific Storage Pool to the new VM
- * graphics *(optional)*: Specify the graphics paramenter for this vm
- * type: The type of graphics. It can be VNC or spice or None.
- * vnc: Graphical display using the Virtual Network
- Computing protocol
- * spice: Graphical display using the Simple Protocol for
- Independent Computing Environments
- * null: Graphics is disabled or type not supported
- * listen: The network which the vnc/spice server listens on.
-
-
-### Resource: Virtual Machine
-
-**URI:** /plugins/kimchi/vms/*:name*
-
-**Methods:**
-
-* **GET**: Retrieve the full description of a Virtual Machine
- * name: The name of the VM. Used to identify the VM in this API
- * state: Indicates the current state in the VM lifecycle
- * running: The VM is powered on
- * paused: The VMs virtual CPUs are paused
- * shutoff: The VM is powered off
- * stats: Virtual machine statistics:
- * cpu_utilization: A number between 0 and 100 which indicates the
- percentage of CPU utilization.
- * net_throughput: Expresses total network throughput for reads and
- writes across all virtual interfaces (kb/s).
- * net_throughput_peak: The highest recent value of 'net_throughput'.
- * io_throughput: Expresses the total IO throughput for reads and
- writes across all virtual disks (kb/s).
- * io_throughput_peak: The highest recent value of 'io_throughput'.
- * uuid: UUID of the VM.
- * memory: The amount of memory assigned to the VM (in MB)
- * cpus: The number of CPUs assigned to the VM
- * screenshot: A link to a recent capture of the screen in PNG format
- * icon: A link to an icon that represents the VM
- * graphics: A dict to show detail of VM graphics.
- * type: The type of graphics. It can be VNC or spice or None.
- * vnc: Graphical display using the Virtual Network
- Computing protocol
- * spice: Graphical display using the Simple Protocol for
- Independent Computing Environments
- * null: Graphics is disabled or type not supported
- * listen: The network which the vnc/spice server listens on.
- * port: The real port number of the graphics, vnc or spice. Users
- can use this port to connect to the vm with general vnc/spice
- clients.
- * passwd: console password
- * passwdValidTo: lifetime for the console password.
- * users: A list of system users who have permission to access the VM.
- Default is: empty (i.e. only root-users may access).
- * groups: A list of system groups whose users have permission to access
- the VM. Default is: empty (i.e. no groups given access).
-* **DELETE**: Remove the Virtual Machine
-* **PUT**: update the parameters of existed VM
- * name: New name for this VM (only applied for shutoff VM)
- * users: New list of system users.
- * groups: New list of system groups.
- * cpus: New number of virtual cpus for this VM (if VM is running, new value
- will take effect in next reboot)
- * memory: New amount of memory (MB) for this VM (if VM is running, new
- value will take effect in next reboot)
- * graphics: A dict to show detail of VM graphics.
- * passwd *(optional)*: console password. When omitted a random password
- willbe generated.
- * passwdValidTo *(optional)*: lifetime for the console password. When
- omitted the password will be valid just
- for 30 seconds.
-
-* **POST**: *See Virtual Machine Actions*
-
-**Actions (POST):**
-
-* start: Power on a VM
-* poweroff: Power off a VM forcefully. Note this action may produce undesirable
- results, for example unflushed disk cache in the guest.
-* shutdown: Shut down a VM graceful. This action issue shutdown request to guest.
- And the guest will react this request. Note the guest OS may ignore
- the request.
-* reset: Reset a VM immediately without the guest OS shutdown.
- It emulates the power reset button on a machine. Note that there is a
- risk of data loss caused by reset without the guest OS shutdown.
-* connect: Prepare the connection for spice or vnc
-
-* clone: Create a new VM identical to this VM. The new VM's name, UUID and
- network MAC addresses will be generated automatically. Each existing
- disks will be copied to a new volume in the same storage pool. If
- there is no available space on that storage pool to hold the new
- volume, it will be created on the pool 'default'. This action returns
- a Task.
-
-* suspend: Suspend an active domain. The process is frozen without further
- access to CPU resources and I/O but the memory used by the domain at
- the hypervisor level will stay allocated.
-
-* resume: Resume a suspended domain. The process is restarted from the state
- where it was frozen by calling "suspend".
-
-### Sub-resource: Virtual Machine Screenshot
-
-**URI:** /plugins/kimchi/vms/*:name*/screenshot
-
-Represents a snapshot of the Virtual Machine's primary monitor.
-
-**Methods:**
-
-* **GET**: Redirect to the latest screenshot of a Virtual Machine in PNG format
-
-
-### Sub-collection: Virtual Machine storages
-**URI:** /plugins/kimchi/vms/*:name*/storages
-* **GET**: Retrieve a summarized list of all storages of specified guest
-* **POST**: Attach a new storage or virtual drive to specified virtual machine.
- * type: The type of the storage (currently support 'cdrom' and
'disk').
- * path: Path of cdrom iso.
- * pool: Storage pool which disk image file locate in.
- * vol: Storage volume name of disk image.
-
-### Sub-resource: storage
-**URI:** /plugins/kimchi/vms/*:name*/storages/*:dev*
-* **GET**: Retrieve storage information
- * dev: The name of the storage in the vm.
- * type: The type of the storage (currently support 'cdrom' and
'disk').
- * path: Path of cdrom iso or disk image file.
- * bus: Bus type of disk attached.
-* **PUT**: Update storage information
- * path: Path of cdrom iso. Can not be blank. Now just support cdrom type.
-* **DELETE**: Remove the storage.
-
-**Actions (POST):**
-
-
-### Sub-collection: Virtual Machine Passthrough Devices
-**URI:** /plugins/kimchi/vms/*:name*/hostdevs
-* **GET**: Retrieve a summarized list of all directly assigned host device of
- specified guest.
-* **POST**: Directly assign a host device to guest.
- * name: The name of the host device to be assigned to vm.
-
-### Sub-resource: Device
-**URI:** /plugins/kimchi/vms/*:name*/hostdevs/*:dev*
-* **GET**: Retrieve assigned device information
- * name: The name of the assigned device.
- * type: The type of the assigned device.
-* **DELETE**: Detach the host device from VM.
-
-### Sub-collection: Virtual Machine Snapshots
-**URI:** /plugins/kimchi/vms/*:name*/snapshots
-* **POST**: Create a new snapshot on a VM.
- * name: The snapshot name (optional, defaults to a value based on the
- current time).
-* **GET**: Retrieve a list of snapshots on a VM.
-
-### Sub-resource: Snapshot
-**URI:** /plugins/kimchi/vms/*:name*/snapshots/*:snapshot*
-* **GET**: Retrieve snapshot information.
- * created: The time when the snapshot was created
- (in seconds, since the epoch).
- * name: The snapshot name.
- * parent: The name of the parent snapshot, or an empty string if there is
- no parent.
- * state: The corresponding domain's state when the snapshot was created.
-* **DELETE**: Delete snapshot. If the snapshot has any children, they will be
- merged automatically with the snapshot's parent.
-* **POST**: See "Snapshot actions (POST)"
-
-**Snapshot Actions (POST):**
-
-* revert: Revert the domain to the given snapshot.
-
-### Sub-resource: Current snapshot
-**URI:** /plugins/kimchi/vms/*:name*/snapshots/current
-* **GET**: Retrieve current snapshot information for the virtual machine.
-
-### Collection: Templates
-
-**URI:** /plugins/kimchi/templates
-
-**Methods:**
-
-* **GET**: Retrieve a summarized list of all defined Templates
-* **POST**: Create a new Template
- * name: The name of the Template. Used to identify the Template in this API
- * os_distro *(optional)*: The operating system distribution
- * os_version *(optional)*: The version of the operating system distribution
- * cpus *(optional)*: The number of CPUs assigned to the VM.
- Default is 1, unlees specifying a cpu topology. In that case, cpus
- will default to a product of the topology values (see cpu_info).
- * memory *(optional)*: The amount of memory assigned to the VM.
- Default is 1024M.
- * cdrom *(optional)*: A volume name or URI to an ISO image.
- * storagepool *(optional)*: URI of the storagepool.
- Default is '/storagepools/default'
- * networks *(optional)*: list of networks will be assigned to the new VM.
- Default is '[default]'
- * disks *(optional)*: An array of requested disks with the following optional fields
- (either *size* or *volume* must be specified):
- * index: The device index
- * size: The device size in GB
- * base: Base image of this disk
-
- * graphics *(optional)*: The graphics paramenters of this template
- * type: The type of graphics. It can be VNC or spice or None.
- * vnc: Graphical display using the Virtual Network
- Computing protocol
- * spice: Graphical display using the Simple Protocol for
- Independent Computing Environments
- * null: Graphics is disabled or type not supported
- * listen: The network which the vnc/spice server listens on.
- * cpu_info *(optional)*: CPU-specific information.
- * topology: Specify sockets, threads, and cores to run the virtual CPU
- threads on.
- All three are required in order to specify cpu topology.
- * sockets - The number of sockets to use.
- * cores - The number of cores per socket.
- * threads - The number of threads per core.
- If specifying both cpus and CPU topology, make sure cpus is
- equal to the product of sockets, cores, and threads.
-
-### Sub-Collection: Virtual Machine Network Interfaces
-
-**URI:** /plugins/kimchi/vms/*:name*/ifaces
-
-Represents all network interfaces attached to a Virtual Machine.
-
-**Methods:**
-
-* **GET**: Retrieve a summarized list of all network interfaces attached to a Virtual
Machine.
-
-* **POST**: attach a network interface to VM
- * model *(optional)*: model of emulated network interface card. It can be one of
these models:
- ne2k_pci, i82551, i82557b, i82559er, rtl8139, e1000, pcnet and virtio.
- When model is missing, libvirt will set 'rtl8139' as default value.
- * network *(optional)*: the name of resource network, it is required when the
- interface type is network.
- * type: The type of VM network interface that libvirt supports.
- Now kimchi just supports 'network' type.
-
-### Sub-Resource: Virtual Machine Network Interface
-
-**URI:** /plugins/kimchi/vms/*:name*/ifaces/*:mac*
-
-A interface represents available network interface on VM.
-
-**Methods:**
-
-* **GET**: Retrieve the full description of the VM network interface
- * bridge *(optional)*: the name of resource bridge, only be available when the
- interface type is bridge.
- * mac: Media Access Control Address of the VM interface.
- * model *(optional)*: model of emulated network interface card. It will be one of
these models:
- ne2k_pci, i82551, i82557b, i82559er, rtl8139, e1000, pcnet and virtio.
- * network *(optional)*: the name of resource network, only be available when the
- interface type is network.
- * type: The type of VM network interface that libvirt supports.
- It will be one of these types: 'network', 'bridge',
'user','ethernet',
- 'direct', 'hostdev', 'mcast', 'server' and
'client'.
-
-* **DELETE**: detach the network interface from VM
-
-* **PUT**: update the parameters of existing VM interface.
- * model *(optional)*: model of emulated network interface card. It will be one of
these models:
- ne2k_pci, i82551, i82557b, i82559er, rtl8139, e1000, pcnet and virtio.
- This change is only on the persisted VM configuration.
- * network *(optional)*: the name of resource network, only be available when the
- interface type is network.
- This change is on the active VM instance and persisted VM configuration.
-
-**Actions (POST):**
-
-*No actions defined*
-
-
-### Resource: Template
-
-**URI:** /plugins/kimchi/templates/*:name*
-
-**Methods:**
-
-* **GET**: Retrieve the full description of a Template
- * name: A name for this template
- * folder: A virtual path which can be used to organize Templates in a user
- interface. The format is an array of path components.
- * icon: A URI to a PNG image representing this template
- * os_distro: The operating system distribution
- * os_version: The version of the operating system distribution
- * cpus: The number of CPUs assigned to the VM
- * memory: The amount of memory assigned to the VM in the unit of MB
- * cdrom: A volume name or URI to an ISO image
- * storagepool: URI of the storagepool where template allocates vm storage.
- * networks *(optional)*: list of networks will be assigned to the new VM.
- * disks: An array of requested disks with the following optional fields
- (either *size* or *volume* must be specified):
- * index: The device index
- * size: The device size in GB
- * volume: A volume name that contains the initial disk contents
- * format: Format of the image. Valid formats: bochs, cloop, cow, dmg, qcow,
qcow2, qed, raw, vmdk, vpc.
- * graphics: A dict of graphics paramenters of this template
- * type: The type of graphics. It can be VNC or spice or None.
- * vnc: Graphical display using the Virtual Network
- Computing protocol
- * spice: Graphical display using the Simple Protocol for
- Independent Computing Environments
- * null: Graphics is disabled or type not supported
- * listen: The network which the vnc/spice server listens on.
- * invalid: A dict indicates which paramenters of this template are invalid.
- * networks *(optional)*: An array of invalid network names.
- * cdrom *(optional)*: An array of invalid cdrom names.
- * disks *(optional)*: An array of invalid volume names.
- * storagepools *(optional)*: An array of invalid storagepool names.
-
-* **DELETE**: Remove the Template
-* **POST**: *See Template Actions*
-* **PUT**: update the parameters of existed template
- * name: A name for this template
- * folder: A virtual path which can be used to organize Templates in the user
- interface. The format is an array of path components.
- * icon: A URI to a PNG image representing this template
- * os_distro: The operating system distribution
- * os_version: The version of the operating system distribution
- * cpus: The number of CPUs assigned to the VM
- * memory: The amount of memory assigned to the VM
- * cdrom: A volume name or URI to an ISO image
- * storagepool: URI of the storagepool where template allocates vm storage.
- * networks *(optional)*: list of networks will be assigned to the new VM.
- * disks: An array of requested disks with the following optional fields
- (either *size* or *volume* must be specified):
- * index: The device index
- * size: The device size in GB
- * volume: A volume name that contains the initial disk contents
- * format: Format of the image. Valid formats: bochs, cloop, cow, dmg, qcow,
qcow2, qed, raw, vmdk, vpc.
- * graphics *(optional)*: A dict of graphics paramenters of this template
- * type: The type of graphics. It can be VNC or spice or None.
- * vnc: Graphical display using the Virtual Network
- Computing protocol
- * spice: Graphical display using the Simple Protocol for
- Independent Computing Environments
- * null: Graphics is disabled or type not supported
- * listen: The network which the vnc/spice server listens on.
-
-**Actions (POST):**
-
-* clone: clone a template from an existing template with different name.
- It will provide a reasonable default name with "-cloneN" as suffix
- for the new clone template. The "N" means the number of clone times.
-
-### Collection: Storage Pools
-
-**URI:** /plugins/kimchi/storagepools
-
-**Methods:**
-
-* **GET**: Retrieve a summarized list of all defined Storage Pools
-* **POST**: Create a new Storage Pool
- * name: The name of the Storage Pool.
- * type: The type of the defined Storage Pool.
- Supported types: 'dir', 'kimchi-iso', 'netfs',
'logical', 'iscsi', 'scsi'
- * path: The path of the defined Storage Pool.
- For 'kimchi-iso' pool refers to targeted deep scan path.
- Pool types: 'dir', 'kimchi-iso'.
- * source: Dictionary containing source information of the pool.
- * host: IP or hostname of server for a pool backed from a remote host.
- Pool types: 'netfs', 'iscsi'.
- * path: Export path on NFS server for NFS pool.
- Pool types: 'netfs'.
- * devices: Array of devices to be used in the Storage Pool
- Pool types: 'logical'.
- * target: Target IQN of an iSCSI pool.
- Pool types: 'iscsi'.
- * port *(optional)*: Listening port of a remote storage server.
- Pool types: 'iscsi'.
- * auth *(optional)*: Storage back-end authentication information.
- Pool types: 'iscsi'.
- * username: Login username of the iSCSI target.
- * password: Login password of the iSCSI target.
- * adapter_name: SCSI host name.
-
-### Resource: Storage Pool
-
-**URI:** /plugins/kimchi/storagepools/*:name*
-
-**Methods:**
-
-* **GET**: Retrieve the full description of a Storage Pool
- * name: The name of the Storage Pool
- Used to identify the Storage Pool in this API
- 'kimchi_isos' is a reserved storage pool
- which aggregates all ISO images
- across all active storage pools into a single view.
- * state: Indicates the current state of the Storage Pool
- * active: The Storage Pool is ready for use
- * inactive: The Storage Pool is not available
- * path: The path of the defined Storage Pool
- * type: The type of the Storage Pool
- * capacity: The total space which can be used to store volumes
- The unit is Bytes
- * allocated: The amount of space which is being used to store volumes
- The unit is Bytes
- * available: Free space available for creating new volumes in the pool
- * nr_volumes: The number of storage volumes for active pools, 0 for inactive pools
- * autostart: Whether the storage pool will be enabled
- automatically when the system boots
- * persistent: True, when pool persist after a system reboot or be stopped.
- All storage pools created by Kimchi are persistent.
- * source: Source of the storage pool,
- * addr: mount address of this storage pool(for 'netfs' pool)
- * path: export path of this storage pool(for 'netfs' pool)
-
-* **PUT**: Set whether the Storage Pool should be enabled automatically when the
- system boots
- * autostart: Toggle the autostart flag of the VM. This flag sets whether
- the Storage Pool should be enabled automatically when the
- system boots
- * disks: Adds one or more disks to the pool (for 'logical' pool only)
-* **DELETE**: Remove the Storage Pool
-* **POST**: *See Storage Pool Actions*
-
-**Actions (POST):**
-
-* activate: Activate an inactive Storage Pool
-* deactivate: Deactivate an active Storage Pool
-
-### Collection: Storage Volumes
-
-**URI:** /plugins/kimchi/storagepools/*:poolname*/storagevolumes
-
-**Methods:**
-
-* **GET**: Retrieve a summarized list of all defined Storage Volumes
- in the defined Storage Pool
-* **POST**: Create a new Storage Volume in the Storage Pool
- The return resource is a task resource * See Resource: Task *
- Only one of 'capacity', 'url' can be specified.
- * name: The name of the Storage Volume
- * capacity: The total space which can be used to store volumes
- The unit is bytes
- * format: The format of the defined Storage Volume. Only used when creating
- a storage volume with 'capacity'.
- * upload: True to start an upload process. False, otherwise.
- Only used when creating a storage volume 'capacity' parameter.
- * file: File to be uploaded, passed through form data
-
-### Resource: Storage Volume
-
-**URI:** /plugins/kimchi/storagepools/*:poolname*/storagevolumes/*:name*
-
-**Methods:**
-
-* **GET**: Retrieve the full description of a Storage Volume
- * name: The name of the Storage Volume
- Used to identify the Storage Volume in this API
- * type: The type of the Storage Volume
- * capacity: The total space which can be used to store data
- The unit is Bytes
- * allocation: The amount of space which is being used to store data
- The unit is Bytes
- * format: The format of the file or volume
- * path: Full path of the volume on the host filesystem.
- * os_distro *(optional)*: os distribution of the volume, for iso volume only.
- * os_version *(optional)*: os version of the volume, for iso volume only.
- * bootable *(optional)*: True if iso image is bootable and not corrupted.
- * used_by: Name of vms which use this volume.
-
-* **DELETE**: Remove the Storage Volume
-* **POST**: *See Storage Volume Actions*
-* **PUT**: Upload storage volume chunk
- * chunk_size: Chunk size of the slice in Bytes.
- * chunk: Actual data of uploaded file
-
-**Actions (POST):**
-
-* resize: Resize a Storage Volume
- * size: resize the total space which can be used to store data
- The unit is bytes
-* wipe: Wipe a Storage Volume
-* clone: Clone a Storage Volume.
- * pool: The name of the destination pool (optional).
- * name: The new storage volume name (optional).
-
-
-### Collection: Interfaces
-
-**URI:** /plugins/kimchi/interfaces
-
-**Methods:**
-
-* **GET**: Retrieve a summarized list of current Interfaces
-
-### Resource: Interface
-
-**URI:** /plugins/kimchi/interfaces/*:name*
-
-A interface represents available interface on host.
-
-**Methods:**
-
-* **GET**: Retrieve the full description of the Interface
- * name: The name of the interface.
- * status: The current status of the Interface.
- * active: The interface is active.
- * inactive: The interface is inactive.
- * ipaddr: The ip address assigned to this interface in subnet.
- * netmask: Is used to divide an IP address into subnets and specify the
- networks available hosts
- * type: The net device type of the interface.
- * nic: Network interface controller that connects a computer to a
- computer network
- * vlan: A logical interface that represents a VLAN in all Layer 3
- activities the unit may participate in
- * bonding: The combination of network interfaces on one host for redundancy
- and/or increased throughput.
- * bridge: A network device that connects multiple network segments.
-
-* **POST**: *See Interface Actions*
-
-**Actions (POST):**
-
-*No actions defined*
-
-### Collection: Networks
-
-**URI:** /plugins/kimchi/networks
-
-**Methods:**
-
-* **GET**: Retrieve a summarized list of all defined Networks
-* **POST**: Create a new Network
- * name: The name of the Network
- * connection: Specifies how this network should be connected to the other
- networks visible to this host.
- * isolated: Create a private, isolated virtual network.
- * nat: Outgoing traffic will be routed through the host.
- * bridge: All traffic on this network will be bridged through the indicated
- interface.
- * subnet *(optional)*: Network segment in slash-separated format with ip address and
- prefix or netmask used to create nat network.
- * interface *(optional)*: The name of a network interface on the host.
- For bridge network, the interface can be a bridge or nic/bonding
- device.
- * vlan_id *(optional)*: VLAN tagging ID for the bridge network.
-
-### Resource: Network
-
-**URI:** /plugins/kimchi/networks/*:name*
-
-**Methods:**
-
-* **GET**: Retrieve the full description of a Network
- * name: The name of the Network
- Used to identify the Network in this API
- * state: Indicates the current state of the Network
- * active: The Network is ready for use
- * inactive: The Network is not available
- * autostart: Network autostart onboot
- * in_use: Indicates ('true') if some guest is attached to this network and
'false' otherwise.
- * vms: all vms attached to this network
- * subnet: Network segment in slash-separated format with ip address and prefix
- * dhcp: DHCP services on the virtual network is enabled.
- * start: start boundary of a pool of addresses to be provided to DHCP clients.
- * end: end boundary of a pool of addresses to be provided to DHCP clients.
- * connection: Specifies how this network should be connected to the other networks
- visible to this host.
- * isolated: A private, isolated virtual network.
- The VMs attached to it can not be reached by the systems
- outside of this network and vice versa.
- * nat: Outgoing traffic will be routed through the host.
- The VM attached to it will have internet access via the host but
- other computers will not be able to connect to the VM.
- * bridge: Aggregated Public Network.
- The VM that joines this network is seen as a peer on this network
- and it may offer network services such as HTTP or SSH.
- * interface: The name of a bridge network interface on the host. All traffic
- on this network will be bridged through the indicated interface.
- The interface is a bridge or ethernet/bonding device.
- * persistent: If 'true', network will persist after a system reboot or be
stopped.
- All networks created by Kimchi are persistent.
-
-* **DELETE**: Remove the Network
-* **POST**: *See Network Actions*
-
-**Actions (POST):**
-
-* activate: Activate an inactive Network
-* deactivate: Deactivate an active Network
-
-
-### Resource: Configuration
-
-**URI:** /plugins/kimchi/config
-
-Contains information about the application environment and configuration.
-
-**Methods:**
-
-* **GET**: Retrieve configuration information
- * display_proxy_port: Port for vnc and spice's websocket proxy to listen on
- * version: The version of the kimchi service
-* **POST**: *See Configuration Actions*
-
-**Actions (POST):**
-
-*No actions defined*
-
-### Resource: Capabilities
-
-**URI:** /plugins/kimchi/config/capabilities
-
-Contains information about the host capabilities: iso streaming, screenshot
-creation.
-
-**Methods:**
-
-* **GET**: Retrieve capabilities information
- * libvirt_stream_protocols: list of which network protocols are accepted
- for iso streaming by libvirt
- * qemu_spice: True, if QEMU supports Spice; False, otherwise
- * qemu_stream: True, if QEMU supports ISO streaming; False, otherwise
- * screenshot: True, if libvirt stream functionality can create screenshot
- file without problems; False, otherwise or None if the functionality was
- not tested yet
- * system_report_tool: True if the is some debug report tool installed on
- the system; False, otherwise.
- * update_tool: True if there is a compatible package manager for the
- system; False, otherwise
- * repo_mngt_tool: 'deb', 'yum' or None - when the repository
management
- tool is not identified
- * federation: 'on' if federation feature is enabled, 'off'
otherwise.
- * auth: authentication type, 'pam' and 'ldap' are supported.
-* **POST**: *See Configuration Actions*
-
-**Actions (POST):**
-
-*No actions defined*
-
-### Collection: Storage Servers
-
-**URI:** /plugins/kimchi/storageservers
-
-**Methods:**
-
-* **GET**: Retrieve a summarized list of used storage servers.
- * Parameters:
- * _target_type: Filter server list with given type, currently support
- 'netfs' and 'iscsi'.
-
-### Resource: Storage Server
-
-**URI:** /plugins/kimchi/storageservers/*:host*
-
-**Methods:**
-
-* **GET**: Retrieve description of a Storage Server
- * host: IP or host name of storage server
- * port: port of storage server, only for "iscsi"
-
-### Collection: Storage Targets
-
-**URI:** /plugins/kimchi/storageservers/*:name*/storagetargets
-
-**Methods:**
-
-* **GET**: Retrieve a list of available storage targets.
- * Parameters:
- * _target_type: Filter target list with given type, currently support
- 'netfs' and 'iscsi'.
- * _server_port: Filter target list with given server port,
- currently support 'iscsi'.
- * Response: A list with storage targets information.
- * host: IP or host name of storage server of this target.
- * target_type: Type of storage target, supported: 'nfs'.
- * target: Storage target path.
-
-### Collection: Distros
-
-**URI:** /plugins/kimchi/config/distros
-
-**Methods:**
-
-* **GET**: Retrieve a summarized list of all Distros
-
-### Resource: Distro
-
-**URI:** /plugins/kimchi/config/distros/*:name*
-
-Contains information about the OS distribution.
-
-**Methods:**
-
-* **GET**: Retrieve a OS distribution information.
- * name: The name of the Distro.
- * os_distro: The operating system distribution.
- * os_version: The version of the operating system distribution.
- * path: A URI to an ISO image.
-
-**Actions (POST):**
-
-*No actions defined*
-
-#### Collection: Debug Reports
-
-**URI:** /plugins/kimchi/debugreports
-
-**Methods:**
-
-* **GET**: Retrieve a summarized list of all available Debug Reports
-* **POST**: Create a new Debug Report. This POST method is different
- from the other ones. The return resource is a task resource which
- is identified by the url below
- * task resource. * See Resource: Task *
-
-### Resource: Debug Report
-
-**URI:** /plugins/kimchi/debugreports/*:name*
-
-A Debug Report is an archive of logs and other information about the host that
-is used to diagnose and debug problems. The exact format and contents are
-specific to the low level collection tool being used.
-
-**Methods:**
-
-* **GET**: Retrieve the full description of Debug Report
- * name: The debug report name used to identify the report
- * uri: The URI path to download a debug report
- * time: The time when the debug report is created
-
-* **PUT**: rename an existed debug report
- * name: The new name for this debug report
-
-* **DELETE**: Remove the Debug Report
- * name: The debug report name used to identify the report
-
-* **POST**: *See Debug Report Actions*
-
-**Actions (POST):**
-
-*No actions defined*
-
-### Sub-resource: Debug Report content
-
-**URI:** /plugins/kimchi/debugreports/*:name*/content
-
-It is the sub-resource of Debug Report and the client use it to get the real content
-of the Debug Report file from the server
-
-* **GET**: Retrieve the content of a Debug Report file
-
-**Actions (POST):**
-
-*No actions defined*
-
-### Resource: Host
-
-**URI:** /plugins/kimchi/host
-Contains information of host.
-
-**Methods:**
-
-* **GET**: Retrieve host static information
- * memory: Total size of host physical memory
- The unit is Bytes
- * cpu_model: The model name of host CPU
- * cpus: The number of online CPUs available on host
- * os_distro: The OS distribution that runs on host
- * os_version: The version of OS distribution
- * os_codename: The code name of OS distribution
-
-* **POST**: *See Host Actions*
-
-**Actions (POST):**
-
-* reboot: Restart the host machine.
- Only allowed if there is not vm running.
-* shutdown: Power off the host machine.
- Only allowed if there is not vm running.
-* swupdate: Start the update of packages in background and return a Task resource
- * task resource. * See Resource: Task *
-
-### Resource: Users
-
-**URI:** /plugins/kimchi/users
-List of available users.
-
-**Methods:**
-
-* **GET**: Retrieve list of available users.
- * Parameters:
- * _user_id: Validate whether user exists.
- Essential for 'ldap' authentication.
-
-### Resource: Groups
-
-**URI:** /plugins/kimchi/groups
-List of available groups.
-
-**Methods:**
-
-* **GET**: Retrieve list of available groups, only support 'pam' authentication.
-
-### Resource: HostStats
-
-**URI:** /plugins/kimchi/host/stats
-
-Contains the host sample data.
-
-**Methods:**
-
-* **GET**: Retrieve host sample data
- * cpu_utilization: A number between 0 and 100 which indicates the
- percentage of CPU utilization.
- * memory: memory statistics of host
- * total: Total amount of memory. The unit is Bytes.
- * free: The amount of memory left unused by the system. The unit is Bytes.
- * buffers: The amount of memory used for file buffers. The unit is Bytes.
- * cached: The amount of memory used as cache memory. The unit is Bytes.
- * avail: The total amount of buffer, cache and free memory. The unit is Bytes.
- * disk_read_rate: Expresses the total IO throughput for reads across
- all disks (B/s).
- * disk_write_rate: Expresses the total IO throughput for writes across
- all disks (B/s).
- * net_sent_rate: Expresses the total network throughput for writes across
- all interfaces (B/s).
- * net_recv_rate: Expresses the total network throughput for reads across
- all interfaces (B/s).
-
-* **POST**: *See HostStats Actions*
-
-**Actions (POST):**
-
-*No actions defined*
-
-### Resource: HostStats
-
-**URI:** /plugins/kimchi/host/cpuinfo
-
-The cores and sockets of a hosts's CPU. Useful when sizing VMs to take
-advantages of the perforamance benefits of SMT (Power) or Hyper-Threading (Intel).
-
-**Methods:**
-
-* **GET**: Retreives the sockets, cores, and threads values.
- * threading_enabled: Whether CPU topology is supported on this system.
- * sockets: The number of total sockets on a system.
- * cores: The total number of cores per socket.
- * threads_per_core: The threads per core.
-
-**Actions (PUT):**
-
-*No actions defined*
-
-**Actions (POST):**
-
-*No actions defined*
-
-
-### Resource: HostStatsHistory
-
-**URI:** /plugins/kimchi/host/stats/history
-
-It is the sub-resource of Host Stats and the client uses it to get the host
-stats history
-
-**Methods:**
-
-* **GET**: Retrieve host sample data history
- * cpu_utilization: CPU utilization history
- * memory: Memory statistics history
- * total: Total amount of memory. The unit is Bytes.
- * free: The amount of memory left unused by the system. The unit is Bytes.
- * buffers: The amount of memory used for file buffers. The unit is Bytes.
- * cached: The amount of memory used as cache memory. The unit is Bytes.
- * avail: The total amount of buffer, cache and free memory. The unit is Bytes.
- * disk_read_rate: IO throughput for reads history
- * disk_write_rate: IO throughput for writes history
- * net_sent_rate: Network throughput for writes history
- * net_recv_rate: Network throughput for reads history
-
-* **POST**: *See HostStatsHistory Actions*
-
-**Actions (POST):**
-
-*No actions defined*
-
-### Collection: Partitions
-
-**URI:** /plugins/kimchi/host/partitions
-
-**Methods:**
-
-* **GET**: Retrieves a detailed list of all partitions of the host.
-
-### Resource: Partition
-
-**URI:** /plugins/kimchi/host/partitions/*:name*
-
-**Methods:**
-
-* **GET**: Retrieve the description of a single Partition:
- * name: The name of the partition. Used to identify it in this API
- * path: The device path of this partition.
- * type: The type of the partition:
- * part: a standard partition
- * lvm: a partition that belongs to a lvm
- * fstype: The file system type of the partition
- * size: The total size of the partition, in bytes
- * mountpoint: If the partition is mounted, represents the mountpoint.
- Otherwise blank.
- * available: false, if the partition is in use by system; true, otherwise.
-
-### Collection: Devices
-
-**URI:** /plugins/kimchi/host/devices
-
-**Methods:**
-
-* **GET**: Retrieves list of host devices (Node Devices).
- * Parameters:
- * _cap: Filter node device list with given node device capability.
- To list Fibre Channel SCSI Host devices, use "_cap=fc_host".
- Other available values are "fc_host", "net",
"pci", "scsi",
- "storage", "system", "usb" and
"usb_device".
- * _passthrough: Filter devices eligible to be assigned to guest
- directly. Possible values are "ture" and
"false".
- * _passthrough_affected_by: Filter the affected devices in the same
- group of a certain directly assigned device.
- The value should be the name of a device.
-
-### Resource: Device
-
-**URI:** /plugins/kimchi/host/devices/*:name*
-
-**Methods:**
-
-* **GET**: Retrieve information of a single host device.
- * device_type: Type of the device, supported types are "net",
"pci", "scsi",
- "storage", "system", "usb" and
"usb_device".
- * name: The name of the device.
- * path: Path of device in sysfs.
- * parent: The name of the parent parent device.
- * adapter: Host adapter information of a "scsi_host" or "fc_host"
device.
- * type: The capability type of the scsi_host device (fc_host, vport_ops).
- * wwnn: The HBA Word Wide Node Name. Empty if pci device is not fc_host.
- * wwpn: The HBA Word Wide Port Name. Empty if pci device is not fc_host.
- * domain: Domain number of a "pci" device.
- * bus: Bus number of a "pci" device.
- * slot: Slot number of a "pci" device.
- * function: Function number of a "pci" device.
- * vendor: Vendor information of a "pci" device.
- * id: Vendor id of a "pci" device.
- * description: Vendor description of a "pci" device.
- * product: Product information of a "pci" device.
- * id: Product id of a "pci" device.
- * description: Product description of a "pci" device.
- * iommuGroup: IOMMU group number of a "pci" device. Would be None/null if
- host does not enable IOMMU support.
-
-
-### Sub-collection: VMs with the device assigned.
-**URI:** /plugins/kimchi/host/devices/*:name*/vmholders
-* **GET**: Retrieve a summarized list of all VMs holding the device.
-
-### Sub-resource: VM holder
-**URI:** /plugins/kimchi/host/devices/*:name*/vmholders/*:vm*
-* **GET**: Retrieve information of the VM which is holding the device
- * name: The name of the VM.
- * state: The power state of the VM. Could be "running" and
"shutdown".
-
-
-### Collection: Host Packages Update
-
-**URI:** /plugins/kimchi/host/packagesupdate
-
-Contains the information and action of packages update in the host.
-
-**Methods:**
-
-* **GET**: Retrieves a list of all packages to be updated in the host:
-
-### Resource: Host Package Update
-
-**URI:** /plugins/kimchi/host/packagesupdate/*:name*
-
-Contains the information for a specific package to be updated.
-
-**Methods:**
-
-* **GET**: Retrieves a full description of a package:
- * package_name: The name of the package to be updated
- * arch: The architecture of the package
- * version: The new version of the package
- * repository: The repository name from where package will be downloaded
-
-### Collection: Host Repositories
-
-**URI:** /plugins/kimchi/host/repositories
-
-**Methods:**
-
-* **GET**: Retrieve a summarized list of all repositories available
-* **POST**: Add a new repository
- * baseurl: URL to the repodata directory when "is_mirror" is false.
-Otherwise, it can be URL to the mirror system for YUM. Can be an
-http://, ftp:// or file:// URL.
- * repo_id *(optional)*: Unique YUM repository ID
- * config: A dictionary that contains specific data according to repository
- type.
- * repo_name *(optional)*: YUM Repository name
- * mirrorlist *(optional)*: Specifies a URL to a file containing a
- list of baseurls for YUM repository
- * dist: Distribution to DEB repository
- * comps *(optional)*: List of components to DEB repository
-
-### Resource: Repository
-
-**URI:** /plugins/kimchi/host/repositories/*:repo-id*
-
-**Methods:**
-
-* **GET**: Retrieve the full description of a Repository
- * repo_id: Unique repository name for each repository, one word.
- * baseurl: URL to the repodata directory when "is_mirror" is false.
-Otherwise, it can be URL to the mirror system for YUM. Can be an
-http://, ftp:// or file:// URL.
- * enabled: True, when repository is enabled; False, otherwise
- * config: A dictionary that contains specific data according to repository
- type.
- * repo_name: Human-readable string describing the YUM repository.
- * mirrorlist: Specifies a URL to a file containing a list of baseurls
- for YUM repository
- * gpgcheck: True, to enable GPG signature verification; False, otherwise.
- * gpgkey: URL pointing to the ASCII-armored GPG key file for the YUM
- repository.
- * dist: Distribution to DEB repository
- * comps: List of components to DEB repository
-
-* **DELETE**: Remove the Repository
-* **POST**: *See Repository Actions*
-* **PUT**: update the parameters of existing Repository
- * repo_id: Unique repository name for each repository, one word.
- * baseurl: URL to the repodata directory when "is_mirror" is false.
-Otherwise, it can be URL to the mirror system for YUM. Can be an
-http://, ftp:// or file:// URL.
- * config: A dictionary that contains specific data according to repository
- type.
- * repo_name: Human-readable string describing the YUM repository.
- * mirrorlist: Specifies a URL to a file containing a list of baseurls
- for YUM repository
- * gpgcheck: True, to enable GPG signature verification; False, otherwise.
- * gpgkey: URL pointing to the ASCII-armored GPG key file for the YUM
- repository.
- * dist: Distribution to DEB repository
- * comps: List of components to DEB repository
-
-**Actions (POST):**
-
-* enable: Enable the Repository as package source
-* disable: Disable the Repository as package source
-
-### Collection: Peers
-
-**URI:** /plugins/kimchi/peers
-
-**Methods:**
-
-* **GET**: Return the list of Kimchi peers in the same network
- (It uses openSLP for discovering)
diff --git a/plugins/kimchi/docs/Makefile.am b/plugins/kimchi/docs/Makefile.am
deleted file mode 100644
index 679aa18..0000000
--- a/plugins/kimchi/docs/Makefile.am
+++ /dev/null
@@ -1,28 +0,0 @@
-#
-# Kimchi
-#
-# Copyright IBM Corp, 2013
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-
-docdir = $(datadir)/kimchi/doc
-
-dist_doc_DATA = \
- API.md \
- README.md \
- README-federation.md \
- kimchi-guest.png \
- kimchi-templates.png \
- $(NULL)
diff --git a/plugins/kimchi/docs/README-federation.md
b/plugins/kimchi/docs/README-federation.md
deleted file mode 100644
index c184f4f..0000000
--- a/plugins/kimchi/docs/README-federation.md
+++ /dev/null
@@ -1,60 +0,0 @@
-Kimchi Project - Federation Feature
-===================================
-
-Federation feature is a Kimchi mechanism to discover Wok peers in the same
-network. It uses openSLP tool (
http://www.openslp.org/) to register and find Wok
-servers.
-
-By default this feature is disabled on Wok as it is not critical for KVM
-virtualization and requires additional software installation.
-
-To enable it, do the following:
-
-1. Install openslp and openslp-server rpm packages,
- or install slpd and slptool deb packages.
-
-2. openSLP uses port 427 (UDP) and port 427 (TCP) so make sure to open those
- ports in your firewall configuration
-
- For system using firewalld, do:
- sudo firewall-cmd --permanent --add-port=427/udp
- sudo firewall-cmd --permanent --add-port=427/tcp
- sudo firewall-cmd --reload
-
- For openSUSE systems, do:
- sudo /sbin/SuSEfirewall2 open EXT TCP 427
- sudo /sbin/SuSEfirewall2 open EXT UDP 427
-
- For system using iptables, do:
- sudo iptables -A INPUT -p tcp --dport 427 -j ACCEPT
- sudo iptables -A INPUT -p udp --dport 427 -j ACCEPT
-
-3. In addition to the openSLP ports, you also need to allow multicast in the
- firewall configuration
-
- For system using firewalld, do:
- sudo firewall-cmd --direct --add-rule ipv4 filter INPUT 0 -s <subnet> -j ACCEPT
-
- For openSUSE systems, do:
- Add the subnet to the trusted networks listed on FW_TRUSTED_NETS in
- /etc/sysconfig/SuSEfirewall2 file.
- Make sure to restart /sbin/SuSEfirewall2 after modifying /etc/sysconfig/SuSEfirewall2
-
- For system using iptables, do:
- sudo iptables -A INPUT -s <subnet> -j ACCEPT
-
-4. Start slpd service and make sure it is up while running Wok
- sudo service slpd start
-
-5. Enable federation on Wok by editing the /etc/wok/wok.conf file:
-
- federation = on
-
-6. Then start Wok service
- sudo service wokd start
-
-The Wok server will be registered on openSLP on server starting up and will
-be found by other Wok peers (with federation feature enabled) in the same
-network.
-
-Enjoy!
diff --git a/plugins/kimchi/docs/README.md b/plugins/kimchi/docs/README.md
deleted file mode 100644
index f400333..0000000
--- a/plugins/kimchi/docs/README.md
+++ /dev/null
@@ -1,247 +0,0 @@
-Kimchi Project
-==============
-
-Kimchi is an HTML5 based management tool for KVM. It is designed to make it as
-easy as possible to get started with KVM and create your first guest.
-
-Kimchi runs as a Wok plugin. Wok runs as a daemon on the hypervisor host.
-
-Kimchi manages KVM guests through libvirt. The management interface is accessed
-over the web using a browser that supports HTML5.
-
-Browser Support
-===============
-Desktop Browser Support:
------------------------
-* **Internet Explorer:** IE9+
-* **Chrome:** Current-1 version
-* **Firefox:** Current-1 version Firefox 24ESR
-* **Safari:** Current-1 version
-* **Opera:** Current-1 version
-
-Mobile Browser Support:
------------------------
-* **Safari iOS:** Current-1 version
-* **Android Browser** Current-1 version
-
-Current-1 version denotes that we support the current stable version of the
-browser and the version that preceded it. For example, if the current version of
-a browser is 24.x, we support the 24.x and 23.x versions.This does not mean that
-kimchi cannot be used in other browsers, however, functionality and appearance
-may be diminished and we may not be able to provide support for any problems you
-find.
-
-Hypervisor Distro Support
-=========================
-
-Kimchi and Wok might run on any GNU/Linux distribution that meets the conditions
-described on the 'Getting Started' section below.
-
-The Kimchi community makes an effort to test it with the latest versions of
-Fedora, RHEL, OpenSuSe, and Ubuntu.
-
-Getting Started
-===============
-
-Install Dependencies
---------------------
-
-**For fedora and RHEL:**
-
- $ sudo yum install gcc make autoconf automake gettext-devel git \
- python-cherrypy python-cheetah libvirt-python \
- libvirt libvirt-daemon-config-network python-imaging \
- PyPAM m2crypto python-jsonschema rpm-build \
- qemu-kvm python-psutil python-ethtool sos \
- python-ipaddr python-ldap python-lxml nfs-utils \
- iscsi-initiator-utils libxslt pyparted nginx \
- python-libguestfs libguestfs-tools python-websockify \
- novnc spice-html5 python-configobj
-
- # If using RHEL, install the following additional packages:
- $ sudo yum install python-unittest2 python-ordereddict
-
- # Restart libvirt to allow configuration changes to take effect
- $ sudo service libvirtd restart
-
- Packages version requirement:
- python-psutil >= 0.6.0
-
- # These dependencies are only required if you want to run the tests:
- $ sudo yum install pyflakes python-pep8 python-requests
-
-*Note for RHEL users*: Some of the above packages are located in the Red Hat
-EPEL repositories. See
-[this
FAQ](http://fedoraproject.org/wiki/EPEL#How_can_I_use_these_extra_package...
-for more information on how to configure your system to access this repository.
-
-And for RHEL7 systems, you also need to subscribe to the "RHEL Server
Optional"
-channel at RHN Classic or Red Hat Satellite.
-
-**For debian:**
-
- $ sudo apt-get install gcc make autoconf automake gettext git \
- python-cherrypy3 python-cheetah python-libvirt \
- libvirt-bin python-imaging python-configobj \
- python-pam python-m2crypto python-jsonschema \
- qemu-kvm libtool python-psutil python-ethtool \
- sosreport python-ipaddr python-ldap \
- python-lxml nfs-common open-iscsi lvm2 xsltproc \
- python-parted nginx python-guestfs libguestfs-tools \
- websockify novnc spice-html5
-
- Packages version requirement:
- python-jsonschema >= 1.3.0
- python-psutil >= 0.6.0
-
- # These dependencies are only required if you want to run the tests:
- $ sudo apt-get install pep8 pyflakes python-requests
-
-**For openSUSE:**
-
- $ sudo zypper install gcc make autoconf automake gettext-tools git \
- python-CherryPy python-Cheetah libvirt-python \
- libvirt libvirt-daemon-config-network python-pam \
- python-imaging python-M2Crypto python-jsonschema \
- rpm-build kvm python-psutil python-ethtool \
- python-ipaddr python-ldap python-lxml nfs-client \
- open-iscsi libxslt-tools python-xml python-parted \
- nginx python-libguestfs python-configobj \
- guestfs-tools python-websockify novnc
-
- Packages version requirement:
- python-psutil >= 0.6.0
-
- # These dependencies are only required if you want to run the tests:
- $ sudo zypper install python-pyflakes python-pep8 python-requests
-
-*Note for openSUSE users*: Some of the above packages are located in different
-openSUSE repositories. See
-[this
FAQ](http://download.opensuse.org/repositories/home:GRNET:synnefo/) for
-python-parted; and
-[this
FAQ](http://download.opensuse.org/repositories/systemsmanagement:/spacewa...
-for python-ethtool to get the correct repository based on your openSUSE version. And
-[this
FAQ](http://en.opensuse.org/SDB:Add_package_repositories) for more
-information on how configure your system to access this repository.
-
-Build and Install
------------------
-
- Wok:
- $ ./autogen.sh --system
-
- $ make
- $ sudo make install # Optional if running from the source tree
-
-
- Kimchi:
- $ cd plugins/kimchi
-
- For openSUSE 13.1:
- $ ./autogen.sh --with-spice-html5
-
- Otherwise:
- $ ./autogen.sh --system
-
- $ make
- $ sudo make install # Optional if running from the source tree
-
-Run
----
-
- $ sudo wokd --host=0.0.0.0
-
-If you cannot access Wok, take a look at these 2 points:
-
-1. Firewall
-Wok uses by default the ports 8000, 8001 and 64667. To allow incoming connections:
-
- For system using firewalld, do:
- sudo firewall-cmd --add-port=8000/tcp --permanent
- sudo firewall-cmd --add-port=8001/tcp --permanent
- sudo firewall-cmd --add-port=64667/tcp --permanent
- sudo firewall-cmd --reload
-
- For openSUSE systems, do:
- sudo /sbin/SuSEfirewall2 open EXT TCP 8000
- sudo /sbin/SuSEfirewall2 open EXT TCP 8001
- sudo /sbin/SuSEfirewall2 open EXT TCP 64667
-
- For system using iptables, do:
- sudo iptables -A INPUT -p tcp --dport 8000 -j ACCEPT
- sudo iptables -A INPUT -p tcp --dport 8001 -j ACCEPT
- sudo iptables -A INPUT -p tcp --dport 64667 -j ACCEPT
-
- Don't forget to correctly save the rules.
-
-
-2. SELinux
-Allow httpd_t context for Wok web server:
-
- semanage permissive -a httpd_t
-
-
-Test
-----
-
- $ cd plugins/kimchi
- $ make check-local # check for i18n and formatting errors
- $ sudo make check
-
-After all tests are executed, a summary will be displayed containing any
-errors/failures which might have occurred.
-
-Usage
------
-
-Connect your browser to
https://localhost:8001. You should see a screen like:
-
-![Wok Login Screen](/docs/kimchi-login.png)
-
-Wok uses PAM to authenticate users so you can log in with the same username
-and password that you would use to log in to the machine itself. Once logged in
-you will see a screen like:
-
-![Kimchi Guest View](/docs/kimchi-guest.png)
-
-This shows you the list of running guests including a live screenshot of
-the guest session. You can use the action buttons to shutdown the guests
-or connect to the display in a new window.
-
-To create a new guest, click on the "+" button in the upper right corner.
-In Kimchi, all guest creation is done through templates.
-
-You can view or modify templates by clicking on the Templates link in the
-top navigation bar.
-
-The template screen looks like:
-
-![Kimchi Template View](/docs/kimchi-templates.png)
-
-From this view, you can change the parameters of a template or create a
-new template using the "+" button in the upper right corner.
-
-To create a template, you need an ISO on your host or using remote one.
-If you are willing to use your own ISO, please copy it to out of box storage
-pool (default path is: /var/lib/kimchi/isos).
-
-Known Issues
-------------
-
-1. When you are using NFS as storage pool, check the nfs export path permission
-is configured as:
- (1) export path need to be squashed as kvm gid and libvirt uid:
- /my_export_path *(all_squash,anongid=<kvm-gid>,
anonuid=<libvirt-uid>,rw,sync)
- So that root user can create volume with right user/group.
- (2) Chown of export path as libvirt user, group as kvm group,
- In order to make sure all mapped user can get into the mount point.
-
-Participating
--------------
-
-All patches are sent through our mailing list hosted by oVirt. More
-information can be found at:
-
-https://github.com/kimchi-project/kimchi/wiki/Communications
-
-Patches should be sent using git-send-email to kimchi-devel(a)ovirt.org.
diff --git a/plugins/kimchi/docs/kimchi-guest.png b/plugins/kimchi/docs/kimchi-guest.png
deleted file mode 100644
index 2ec8fea930b71c0e03a40700d79c4bbb63bf54e6..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001
literal 192281
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
P00000NkvXXu0mjf{F7R-
diff --git a/plugins/kimchi/docs/kimchi-login.png b/plugins/kimchi/docs/kimchi-login.png
deleted file mode 100644
index 66387fd70adebc3b20b9520974a127ea7faa52ac..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001
literal 318041
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%0A&`9-9b?c>R2A
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⪼mDSr{tK2+EhOBG_{{`e&G
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
NOI8XjSt(%@^gj?LcDMil
diff --git a/plugins/kimchi/docs/kimchi-templates.png
b/plugins/kimchi/docs/kimchi-templates.png
deleted file mode 100644
index ca3ba585b02668de97015bdd9ec4af64265592bd..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001
literal 329678
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%0Ad3dx|<q`n;0ZSQ(k06~bLzVbUVbpXVB!PYn
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ⅅOnbhWduq*EF?|q_xg7h<I
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⪻gYAy<i$*4^-X7~$4F9lRG_zXCwb
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
kbi{8Dx<
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�#jfNGR9ga5FKn
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
IM6N<$f~8PYD*ylh
diff --git a/plugins/kimchi/i18n.py b/plugins/kimchi/i18n.py
deleted file mode 100644
index 253f00d..0000000
--- a/plugins/kimchi/i18n.py
+++ /dev/null
@@ -1,335 +0,0 @@
-#
-# Project Kimchi
-#
-# Copyright IBM, Corp. 2014-2015
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-
-import gettext
-
-_ = gettext.gettext
-
-
-messages = {
- "KCHAPI0001E": _("Unknown parameter %(value)s"),
-
- "KCHASYNC0003E": _("Timeout of %(seconds)s seconds expired while
running task '%(task)s."),
-
- "KCHAUTH0004E": _("User %(user_id)s not found with given LDAP
settings."),
-
- "KCHDEVS0001E": _('Unknown "_cap" specified'),
- "KCHDEVS0002E": _('"_passthrough" should be "true"
or "false"'),
- "KCHDEVS0003E": _('"_passthrough_affected_by" should be a
device name string'),
-
- "KCHDISKS0001E": _("Error while getting block devices. Details:
%(err)s"),
- "KCHDISKS0002E": _("Error while getting block device information for
%(device)s."),
-
- "KCHDL0001E": _("Unable to find distro file: %(filename)s"),
- "KCHDL0002E": _("Unable to parse distro file: %(filename)s. Make sure,
it is a JSON file."),
-
- "KCHISCSI0001E": _("Unable to login to iSCSI host target %(portal)s.
Details: %(err)s"),
- "KCHISCSI0002E": _("Unable to login to iSCSI host %(host)s target
%(target)s"),
-
- "KCHISO0001E": _("Unable to find ISO file %(filename)s"),
- "KCHISO0002E": _("The ISO file %(filename)s is not bootable"),
- "KCHISO0003E": _("The ISO file %(filename)s does not have a valid El
Torito boot record"),
- "KCHISO0004E": _("Invalid El Torito validation entry in ISO
%(filename)s"),
- "KCHISO0005E": _("Invalid El Torito boot indicator in ISO
%(filename)s"),
- "KCHISO0006E": _("Unexpected volume type for primary volume in ISO
%(filename)s"),
- "KCHISO0007E": _("Bad format while reading volume descriptor in ISO
%(filename)s"),
- "KCHISO0008E": _("The hypervisor doesn't have permission to use
this ISO %(filename)s. "
- "Consider moving it under /var/lib/libvirt, or set the search
permission "
- "to file access control lists for '%(user)s' user if
possible, or add the "
- "'%(user)s' to the ISO path group, or (not recommended)
'chmod -R o+x 'path_to_iso'."
- "Details: %(err)s" ),
-
- "KCHIMG0001E": _("An error occurred when probing image OS
information."),
- "KCHIMG0002E": _("No OS information found in given image."),
- "KCHIMG0003E": _("Unable to read image file %(filename)s"),
- "KCHIMG0004E": _("Image file must be an existing file on system.
%(filename)s is not a valid input."),
-
- "KCHVM0001E": _("Virtual machine %(name)s already exists"),
- "KCHVM0002E": _("Virtual machine %(name)s does not exist"),
- "KCHVM0003E": _("Unable to rename virtual machine %(name)s. The name
%(new_name)s is already in use or the virtual machine is not powered off."),
- "KCHVM0004E": _("Unable to retrieve screenshot for stopped virtual
machine %(name)s"),
- "KCHVM0005E": _("Remote ISO image is not supported by this
server."),
- "KCHVM0006E": _("Screenshot is not supported on virtual machine
%(name)s"),
- "KCHVM0007E": _("Unable to create virtual machine %(name)s. Details:
%(err)s"),
- "KCHVM0008E": _("Unable to update virtual machine %(name)s. Details:
%(err)s"),
- "KCHVM0009E": _("Unable to retrieve virtual machine %(name)s. Details:
%(err)s"),
- "KCHVM0010E": _("Unable to connect to powered off virtual machine
%(name)s."),
- "KCHVM0011E": _("Virtual machine name must be a string without slashes
(/)"),
- "KCHVM0012E": _("Invalid template URI %(value)s specified for virtual
machine"),
- "KCHVM0013E": _("Invalid storage pool URI %(value)s specified for
virtual machine"),
- "KCHVM0014E": _("Supported virtual machine graphics are Spice or
VNC"),
- "KCHVM0015E": _("Graphics address to listen on must be IPv4 or
IPv6"),
- "KCHVM0016E": _("Specify a template to create a virtual machine
from"),
- "KCHVM0019E": _("Unable to start virtual machine %(name)s. Details:
%(err)s"),
- "KCHVM0020E": _("Unable to power off virtual machine %(name)s.
Details: %(err)s"),
- "KCHVM0021E": _("Unable to delete virtual machine %(name)s. Details:
%(err)s"),
- "KCHVM0022E": _("Unable to reset virtual machine %(name)s. Details:
%(err)s"),
- "KCHVM0023E": _("User name list must be an array"),
- "KCHVM0024E": _("User name must be a string"),
- "KCHVM0025E": _("Group name list must be an array"),
- "KCHVM0026E": _("Group name must be a string"),
- "KCHVM0027E": _("User(s) '%(users)s' do not exist"),
- "KCHVM0028E": _("Group(s) '%(groups)s' do not exist"),
- "KCHVM0029E": _("Unable to shutdown virtual machine %(name)s. Details:
%(err)s"),
- "KCHVM0030E": _("Unable to get access metadata of virtual machine
%(name)s. Details: %(err)s"),
- "KCHVM0031E": _("The guest console password must be a string."),
- "KCHVM0032E": _("The life time for the guest console password must be
a number."),
- "KCHVM0033E": _("Virtual machine '%(name)s' must be stopped
before cloning it."),
- "KCHVM0034E": _("Insufficient disk space to clone virtual machine
'%(name)s'"),
- "KCHVM0035E": _("Unable to clone VM '%(name)s'. Details:
%(err)s"),
- "KCHVM0036E": _("Invalid operation for non-persistent virtual machine
%(name)s"),
- "KCHVM0037E": _("Cannot suspend VM '%(name)s' because it is
not running."),
- "KCHVM0038E": _("Unable to suspend VM '%(name)s'. Details:
%(err)s"),
- "KCHVM0039E": _("Cannot resume VM '%(name)s' because it is not
paused."),
- "KCHVM0040E": _("Unable to resume VM '%(name)s'. Details:
%(err)s"),
- "KCHVM0041E": _("Memory assigned is higher then the maximum allowed in
the host."),
- "KCHVM0042E": _("VM '%(name)s' does not support live memory
update. Update the memory with the machine offline to enable this feature."),
- "KCHVM0043E": _("Only increase memory is allowed in active
VMs"),
- "KCHVM0044E": _("For live memory update, new memory value must be
equal old memory value plus multiples of 1024 Mib"),
- "KCHVM0045E": _("There are not enough free slots of 1024 Mib in the
guest."),
- "KCHVM0046E": _("Host's libvirt version does not support memory
devices. Libvirt must be >= 1.2.14"),
- "KCHVM0047E": _("Error attaching memory device. Details:
%(error)s"),
-
- "KCHVMHDEV0001E": _("VM %(vmid)s does not contain directly assigned
host device %(dev_name)s."),
- "KCHVMHDEV0002E": _("The host device %(dev_name)s is not allowed to
directly assign to VM."),
- "KCHVMHDEV0003E": _("No IOMMU groups found. Host PCI pass through
needs IOMMU group to function correctly. "
- "Please enable Intel VT-d or AMD IOMMU in your BIOS, then
verify the Kernel is compiled with IOMMU support. "
- "For Intel CPU, add intel_iommu=on to your Kernel parameter
in /boot/grub2/grub.conf. "
- "For AMD CPU, add iommu=pt iommu=1."),
- "KCHVMHDEV0004E": _('"name" should be a device name
string'),
- "KCHVMHDEV0005E": _('The device %(name)s is probably in use by the
host. Unable to attach it to the guest.'),
-
- "KCHVMIF0001E": _("Interface %(iface)s does not exist in virtual
machine %(name)s"),
- "KCHVMIF0002E": _("Network %(network)s specified for virtual machine
%(name)s does not exist"),
- "KCHVMIF0004E": _("Supported virtual machine interfaces type is only
network"),
- "KCHVMIF0005E": _("Network name for virtual machine interface must be
a string"),
- "KCHVMIF0006E": _("Invalid network model card specified for virtual
machine interface"),
- "KCHVMIF0007E": _("Specify type and network to add a new virtual
machine interface"),
- "KCHVMIF0008E": _("MAC Address must respect this format
FF:FF:FF:FF:FF:FF"),
- "KCHVMIF0009E": _("MAC Address %(mac)s already exists in virtual
machine %(name)s"),
- "KCHVMIF0010E": _("Invalid MAC Address"),
- "KCHVMIF0011E": _("Cannot change MAC address of a running virtual
machine"),
-
- "KCHTMPL0001E": _("Template %(name)s already exists"),
- "KCHTMPL0003E": _("Network '%(network)s' specified for
template %(template)s does not exist"),
- "KCHTMPL0004E": _("Storage pool %(pool)s specified for template
%(template)s does not exist"),
- "KCHTMPL0005E": _("Storage pool %(pool)s specified for template
%(template)s is not active"),
- "KCHTMPL0006E": _("Invalid parameter '%(param)s' specified for
CDROM."),
- "KCHTMPL0007E": _("Network %(network)s specified for template
%(template)s is not active"),
- "KCHTMPL0008E": _("Template name must be a string"),
- "KCHTMPL0009E": _("Template icon must be a path to the image"),
- "KCHTMPL0010E": _("Template distribution must be a string"),
- "KCHTMPL0011E": _("Template distribution version must be a
string"),
- "KCHTMPL0012E": _("The number of CPUs must be an integer greater than
0"),
- "KCHTMPL0013E": _("Amount of memory (MB) must be an integer greater
than 512"),
- "KCHTMPL0014E": _("Template CDROM must be a local or remote ISO
file"),
- "KCHTMPL0015E": _("Invalid storage pool URI %(value)s specified for
template"),
- "KCHTMPL0016E": _("Specify an ISO image as CDROM or a base image to
create a template"),
- "KCHTMPL0017E": _("All networks for the template must be specified in
a list."),
- "KCHTMPL0018E": _("Specify a volume to a template when storage pool is
iSCSI or SCSI"),
- "KCHTMPL0019E": _("The volume %(volume)s is not in storage pool
%(pool)s"),
- "KCHTMPL0020E": _("Unable to create template due error:
%(err)s"),
- "KCHTMPL0021E": _("Unable to delete template due error:
%(err)s"),
- "KCHTMPL0022E": _("Disk size must be an integer greater than
1GB."),
- "KCHTMPL0023E": _("Template base image must be a valid local image
file"),
- "KCHTMPL0024E": _("Cannot identify base image %(path)s format"),
- "KCHTMPL0025E": _("When specifying CPU topology, VCPUs must be a
product of sockets, cores, and threads."),
- "KCHTMPL0026E": _("When specifying CPU topology, each element must be
an integer greater than zero."),
- "KCHTMPL0027E": _("Invalid disk image format. Valid formats: bochs,
cloop, cow, dmg, qcow, qcow2, qed, raw, vmdk, vpc."),
-
- "KCHPOOL0001E": _("Storage pool %(name)s already exists"),
- "KCHPOOL0002E": _("Storage pool %(name)s does not exist"),
- "KCHPOOL0004E": _("Specify %(item)s in order to create the storage
pool %(name)s"),
- "KCHPOOL0005E": _("Unable to delete active storage pool
%(name)s"),
- "KCHPOOL0006E": _("Unable to list storage pools. Details:
%(err)s"),
- "KCHPOOL0007E": _("Unable to create storage pool %(name)s. Details:
%(err)s"),
- "KCHPOOL0008E": _("Unable to get number of storage volumes in storage
pool %(name)s. Details: %(err)s"),
- "KCHPOOL0009E": _("Unable to activate storage pool %(name)s. Details:
%(err)s"),
- "KCHPOOL0010E": _("Unable to deactivate storage pool %(name)s.
Details: %(err)s"),
- "KCHPOOL0011E": _("Unable to delete storage pool %(name)s. Details:
%(err)s"),
- "KCHPOOL0012E": _("Unable to create NFS Pool as export path %(path)s
may block during mount"),
- "KCHPOOL0013E": _("Unable to create NFS Pool as export path %(path)s
mount failed"),
- "KCHPOOL0014E": _("Unsupported storage pool type: %(type)s"),
- "KCHPOOL0015E": _("Error while retrieving storage pool XML to
%(pool)s"),
- "KCHPOOL0016E": _("Storage pool name must be a string without slashes
(/)"),
- "KCHPOOL0017E": _("Supported storage pool types are dir, netfs,
logical, iscsi, isci and kimchi-iso"),
- "KCHPOOL0018E": _("Storage pool path must be a string"),
- "KCHPOOL0019E": _("Storage pool host must be a IP or hostname"),
- "KCHPOOL0020E": _("Storage pool device must be the absolute path to
the block device"),
- "KCHPOOL0021E": _("Storage pool devices parameter must be a
list"),
- "KCHPOOL0022E": _("Target IQN of an iSCSI pool must be a
string"),
- "KCHPOOL0023E": _("Port of a remote storage server must be an integer
between 1 and 65535"),
- "KCHPOOL0024E": _("iSCSI target username must be a string"),
- "KCHPOOL0025E": _("iSCSI target password must be a string"),
- "KCHPOOL0026E": _("Specify name and type to create a storage
pool"),
- "KCHPOOL0027E": _("%(disk)s is not a valid disk/partition. Could not
add it to the pool %(pool)s."),
- "KCHPOOL0028E": _("Unable to extend logical pool %(pool)s. Details:
%(err)s"),
- "KCHPOOL0029E": _("The parameter disks only can be updated for logical
storage pool."),
- "KCHPOOL0030E": _("The SCSI host adapter name must be a
string."),
- "KCHPOOL0031E": _("The storage pool kimchi_isos is reserved for
internal use"),
- "KCHPOOL0032E": _("Unable to activate NFS storage pool %(name)s. NFS
server %(server)s is unreachable."),
- "KCHPOOL0033E": _("Unable to deactivate NFS storage pool %(name)s. NFS
server %(server)s is unreachable."),
- "KCHPOOL0034E": _("Unable to deactivate pool %(name)s as it is
associated with some templates"),
- "KCHPOOL0035E": _("Unable to delete pool %(name)s as it is associated
with some templates"),
- "KCHPOOL0036E": _("A volume group named '%(name)s' already
exists. Please, choose another name to create the logical pool."),
- "KCHPOOL0037E": _("Unable to update database with deep scan
information due error: %(err)s"),
-
- "KCHVOL0001E": _("Storage volume %(name)s already exists"),
- "KCHVOL0002E": _("Storage volume %(name)s does not exist in storage
pool %(pool)s"),
- "KCHVOL0003E": _("Unable to create storage volume %(volume)s because
storage pool %(pool)s is not active"),
- "KCHVOL0004E": _("Specify %(item)s in order to create storage volume
%(volume)s"),
- "KCHVOL0006E": _("Unable to list storage volumes because storage pool
%(pool)s is not active"),
- "KCHVOL0007E": _("Unable to create storage volume %(name)s in storage
pool %(pool)s. Details: %(err)s"),
- "KCHVOL0008E": _("Unable to list storage volumes in storage pool
%(pool)s. Details: %(err)s"),
- "KCHVOL0009E": _("Unable to wipe storage volumes %(name)s. Details:
%(err)s"),
- "KCHVOL0010E": _("Unable to delete storage volume %(name)s. Details:
%(err)s"),
- "KCHVOL0011E": _("Unable to resize storage volume %(name)s. Details:
%(err)s"),
- "KCHVOL0012E": _("Storage type %(type)s does not support volume create
and delete"),
- "KCHVOL0013E": _("Storage volume name must be a string"),
- "KCHVOL0014E": _("Storage volume allocation must be an integer
number"),
- "KCHVOL0015E": _("Storage volume format not supported. Valid formats:
bochs, cloop, cow, dmg, qcow, qcow2, qed, raw, vmdk, vpc."),
- "KCHVOL0016E": _("Storage volume requires a volume name"),
- "KCHVOL0017E": _("Unable to update database with storage volume
information due error: %(err)s"),
- "KCHVOL0018E": _("Only one of parameter %(param)s can be
specified"),
- "KCHVOL0019E": _("Create volume from %(param)s is not
supported"),
- "KCHVOL0020E": _("Storage volume capacity must be an integer
number."),
- "KCHVOL0021E": _("Storage volume URL must be http://, https://, ftp://
or ftps://."),
- "KCHVOL0022E": _("Unable to access file %(url)s. Please, check
it."),
- "KCHVOL0023E": _("Unable to clone storage volume '%(name)s' in
pool '%(pool)s'. Details: %(err)s"),
- "KCHVOL0024E": _("Specify chunk data and its size to upload a
file."),
- "KCHVOL0025E": _("In order to upload a storage volume, specify the
'upload' parameter."),
- "KCHVOL0026E": _("Unable to upload chunk data as it does not match
with requested chunk size."),
- "KCHVOL0027E": _("The storage volume %(vol)s is not under an upload
process."),
- "KCHVOL0028E": _("The upload chunk data will exceed the storage volume
size."),
- "KCHVOL0029E": _("Unable to upload chunk data to storage volume.
Details: %(err)s."),
-
- "KCHIFACE0001E": _("Interface %(name)s does not exist"),
-
- "KCHNET0001E": _("Network %(name)s already exists"),
- "KCHNET0002E": _("Network %(name)s does not exist"),
- "KCHNET0003E": _("Subnet %(subnet)s specified for network %(network)s
is not valid."),
- "KCHNET0004E": _("Specify a network interface to create bridged
network %(name)s"),
- "KCHNET0005E": _("Unable to delete active network %(name)s"),
- "KCHNET0006E": _("Interface %(iface)s specified for network
%(network)s is already in use"),
- "KCHNET0007E": _("Interface should be bare NIC, bonding or bridge
device."),
- "KCHNET0008E": _("Unable to create network %(name)s. Details:
%(err)s"),
- "KCHNET0009E": _("Unable to find a free IP address for network
'%(name)s'"),
- "KCHNET0010E": _("The interface %(iface)s already exists."),
- "KCHNET0011E": _("Network name must be a string without slashes (/) or
quotes (\")"),
- "KCHNET0012E": _("Supported network types are isolated, NAT and
bridge"),
- "KCHNET0013E": _("Network subnet must be a string with IP address and
prefix or netmask"),
- "KCHNET0014E": _("Network interface must be a string"),
- "KCHNET0015E": _("Network VLAN ID must be an integer between 1 and
4094"),
- "KCHNET0016E": _("Specify name and type to create a Network"),
- "KCHNET0017E": _("Unable to delete network %(name)s. There are some
virtual machines %(vms)s and/or templates linked to this network."),
- "KCHNET0018E": _("Unable to deactivate network %(name)s. There are
some virtual machines %(vms)s and/or templates linked to this network."),
- "KCHNET0019E": _("Bridge device %(name)s can not be the trunk device
of a VLAN."),
- "KCHNET0020E": _("Failed to activate interface %(iface)s:
%(err)s."),
- "KCHNET0021E": _("Failed to activate interface %(iface)s. Please check
the physical link status."),
- "KCHNET0022E": _("Failed to start network %(name)s. Details:
%(err)s"),
-
- "KCHDR0001E": _("Debug report %(name)s does not exist"),
- "KCHDR0002E": _("Debug report tool not found in system"),
- "KCHDR0003E": _("Unable to create debug report %(name)s. Details:
%(err)s."),
- "KCHDR0004E": _("Can not find any debug report with the given name
%(name)s"),
- "KCHDR0005E": _("Unable to generate debug report %(name)s. Details:
%(err)s"),
- "KCHDR0006E": _("You should give a name for the debug report
file."),
- "KCHDR0007E": _("Debug report name must be a string. Only letters,
digits, underscore ('_') and hyphen ('-') are allowed."),
- "KCHDR0008E": _("The debug report with specified name
\"%(name)s\" already exists. Please use another one."),
-
- "KCHSR0001E": _("Storage server %(server)s was not used by
Kimchi"),
-
- "KCHDISTRO0001E": _("Distro '%(name)s' does not exist"),
-
- "KCHPART0001E": _("Partition %(name)s does not exist in the
host"),
-
- "KCHHOST0001E": _("Unable to shutdown host machine as there are
running virtual machines"),
- "KCHHOST0002E": _("Unable to reboot host machine as there are running
virtual machines"),
- "KCHHOST0003E": _("Node device '%(name)s' not found"),
- "KCHHOST0004E": _("Conflicting flag filters specified."),
-
- "KCHPKGUPD0001E": _("No packages marked for update"),
- "KCHPKGUPD0002E": _("Package %(name)s is not marked to be
updated."),
- "KCHPKGUPD0003E": _("Error while getting packages marked to be
updated. Details: %(err)s"),
- "KCHPKGUPD0004E": _("There is no compatible package manager for this
system."),
-
- "KCHUTILS0003E": _("Unable to choose a virtual machine name"),
-
- "KCHVMSTOR0002E": _("Invalid storage type. Types supported:
'cdrom', 'disk'"),
- "KCHVMSTOR0003E": _("The path '%(value)s' is not a valid
local/remote path for the device"),
- "KCHVMSTOR0006E": _("Only CDROM path can be update."),
- "KCHVMSTOR0007E": _("The storage device %(dev_name)s does not exist in
the virtual machine %(vm_name)s"),
- "KCHVMSTOR0008E": _("Error while creating new storage device:
%(error)s"),
- "KCHVMSTOR0009E": _("Error while updating storage device:
%(error)s"),
- "KCHVMSTOR0010E": _("Error while removing storage device:
%(error)s"),
- "KCHVMSTOR0011E": _("Do not support IDE device hot plug"),
- "KCHVMSTOR0012E": _("Specify type and path or type and pool/volume to
add a new virtual machine disk"),
- "KCHVMSTOR0013E": _("Specify path to update virtual machine
disk"),
- "KCHVMSTOR0014E": _("Controller type %(type)s limitation of %(limit)s
devices reached"),
- "KCHVMSTOR0015E": _("Cannot retrieve disk path information for given
pool/volume: %(error)s"),
- "KCHVMSTOR0016E": _("Volume already in use by other virtual
machine."),
- "KCHVMSTOR0017E": _("Only one of path or pool/volume can be specified
to add a new virtual machine disk"),
- "KCHVMSTOR0018E": _("Volume chosen with format %(format)s does not fit
in the storage type %(type)s"),
-
- "KCHREPOS0001E": _("YUM Repository ID must be one word only
string."),
- "KCHREPOS0002E": _("Repository URL must be an http://, ftp:// or
file:// URL."),
- "KCHREPOS0003E": _("Repository configuration is a dictionary with
specific values according to repository type."),
- "KCHREPOS0004E": _("Distribution to DEB repository must be a
string"),
- "KCHREPOS0005E": _("Components to DEB repository must be listed in a
array"),
- "KCHREPOS0006E": _("Components to DEB repository must be a
string"),
- "KCHREPOS0007E": _("Mirror list to repository must be a
string"),
- "KCHREPOS0008E": _("YUM Repository name must be string."),
- "KCHREPOS0009E": _("GPG check must be a boolean value."),
- "KCHREPOS0010E": _("GPG key must be a URL pointing to the
ASCII-armored file."),
- "KCHREPOS0011E": _("Could not update repository %(repo_id)s."),
- "KCHREPOS0012E": _("Repository %(repo_id)s does not exist."),
- "KCHREPOS0013E": _("Specify repository base URL, mirror list or
metalink in order to create or update a YUM repository."),
- "KCHREPOS0014E": _("Repository management tool was not recognized for
your system."),
- "KCHREPOS0015E": _("Repository %(repo_id)s is already
enabled."),
- "KCHREPOS0016E": _("Repository %(repo_id)s is already
disabled."),
- "KCHREPOS0017E": _("Could not remove repository %(repo_id)s."),
- "KCHREPOS0018E": _("Could not write repository configuration file
%(repo_file)s"),
- "KCHREPOS0019E": _("Specify repository distribution in order to create
a DEB repository."),
- "KCHREPOS0020E": _("Could not enable repository %(repo_id)s."),
- "KCHREPOS0021E": _("Could not disable repository %(repo_id)s."),
- "KCHREPOS0022E": _("YUM Repository ID already exists"),
- "KCHREPOS0023E": _("YUM Repository name must be a string"),
- "KCHREPOS0024E": _("Unable to list repositories. Details:
'%(err)s'"),
- "KCHREPOS0025E": _("Unable to retrieve repository information.
Details: '%(err)s'"),
- "KCHREPOS0026E": _("Unable to add repository. Details:
'%(err)s'"),
- "KCHREPOS0027E": _("Unable to remove repository. Details:
'%(err)s'"),
- "KCHREPOS0028E": _("Configuration items: '%(items)s' are not
supported by repository manager"),
- "KCHREPOS0029E": _("Repository metalink must be an http://, ftp:// or
file:// URL."),
- "KCHREPOS0030E": _("Cannot specify mirrorlist and metalink at the same
time."),
-
- "KCHSNAP0001E": _("Virtual machine '%(vm)s' must be stopped
before creating a snapshot of it."),
- "KCHSNAP0002E": _("Unable to create snapshot '%(name)s' on
virtual machine '%(vm)s'. Details: %(err)s"),
- "KCHSNAP0003E": _("Snapshot '%(name)s' does not exist on
virtual machine '%(vm)s'."),
- "KCHSNAP0004E": _("Unable to retrieve snapshot '%(name)s' on
virtual machine '%(vm)s'. Details: %(err)s"),
- "KCHSNAP0005E": _("Unable to list snapshots on virtual machine
'%(vm)s'. Details: %(err)s"),
- "KCHSNAP0006E": _("Unable to delete snapshot '%(name)s' on
virtual machine '%(vm)s'. Details: %(err)s"),
- "KCHSNAP0008E": _("Unable to retrieve current snapshot of virtual
machine '%(vm)s'. Details: %(err)s"),
- "KCHSNAP0009E": _("Unable to revert virtual machine '%(vm)s'
to snapshot '%(name)s'. Details: %(err)s"),
- "KCHSNAP0010E": _("Unable to create snapshot of virtual machine
'%(vm)s' because it contains a disk with format '%(format)s'; only
'qcow2' is supported."),
-
- "KCHCPUINF0001E": _("The number of vCPUs is too large for this
system."),
- "KCHCPUINF0002E": _("Invalid vCPU/topology combination."),
- "KCHCPUINF0003E": _("This host (or current configuration) does not
allow CPU topology."),
-
-}
diff --git a/plugins/kimchi/imageinfo.py b/plugins/kimchi/imageinfo.py
deleted file mode 100644
index 8a22495..0000000
--- a/plugins/kimchi/imageinfo.py
+++ /dev/null
@@ -1,72 +0,0 @@
-#
-# Kimchi
-#
-# Copyright IBM, Corp. 2014
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-
-import guestfs
-import json
-import os
-import sys
-
-from wok.exception import ImageFormatError, InvalidParameter, TimeoutExpired
-from wok.utils import run_command, wok_log
-
-
-def probe_img_info(path):
- cmd = ["qemu-img", "info", "--output=json", path]
- info = dict()
- try:
- out = run_command(cmd, 10)[0]
- except TimeoutExpired:
- wok_log.warning("Cannot decide format of base img %s", path)
- return None
-
- info = json.loads(out)
- info['virtual-size'] = info['virtual-size'] >> 30
- info['actual-size'] = info['actual-size'] >> 30
- return info
-
-
-def probe_image(image_path):
- if not os.path.isfile(image_path):
- raise InvalidParameter("KCHIMG0004E", {'filename':
image_path})
-
- if not os.access(image_path, os.R_OK):
- raise ImageFormatError("KCHIMG0003E", {'filename':
image_path})
-
- g = guestfs.GuestFS(python_return_dict=True)
- g.add_drive_opts(image_path, readonly=1)
- g.launch()
-
- try:
- roots = g.inspect_os()
- except:
- raise ImageFormatError("KCHIMG0001E")
-
- if len(roots) == 0:
- raise ImageFormatError("KCHIMG0002E")
-
- for root in roots:
- version = "%d.%d" % (g.inspect_get_major_version(root),
- g.inspect_get_minor_version(root))
- distro = "%s" % (g.inspect_get_distro(root))
-
- return (distro, version)
-
-
-if __name__ == '__main__':
- print probe_image(sys.argv[1])
diff --git a/plugins/kimchi/iscsi.py b/plugins/kimchi/iscsi.py
deleted file mode 100644
index 02886ac..0000000
--- a/plugins/kimchi/iscsi.py
+++ /dev/null
@@ -1,88 +0,0 @@
-#
-# Project Kimchi
-#
-# Copyright IBM, Corp. 2014
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301USA
-
-import subprocess
-
-
-from wok.exception import OperationFailed
-
-
-class TargetClient(object):
- def __init__(self, target, host, port=None, auth=None):
- self.portal = host + ("" if port is None else ":%s" % port)
- self.target = target
- self.auth = auth
- self.targetCmd = ['iscsiadm', '--mode', 'node',
'--targetname',
- self.target, '--portal', self.portal]
-
- def _update_db(self, Name, Value):
- self._run_cmd(['--op=update', '--name', Name, '--value',
Value])
-
- def _update_auth(self):
- if self.auth is None:
- items = (('node.session.auth.authmethod', 'None'),
- ('node.session.auth.username', ''),
- ('node.session.auth.password', ''))
- else:
- items = (('node.session.auth.authmethod', 'CHAP'),
- ('node.session.auth.username',
self.auth['username']),
- ('node.session.auth.password',
self.auth['password']))
- for name, value in items:
- self._update_db(name, value)
-
- def _run_cmd(self, cmd):
- iscsiadm = subprocess.Popen(
- self.targetCmd + cmd,
- stdout=subprocess.PIPE, stderr=subprocess.PIPE)
- out, err = iscsiadm.communicate()
- if iscsiadm.returncode != 0:
- msg_args = {'portal': self.portal, 'err': err}
- raise OperationFailed("KCHISCSI0001E", msg_args)
- return out
-
- def _discover(self):
- iscsiadm = subprocess.Popen(
- ['iscsiadm', '--mode', 'discovery', '--type',
'sendtargets',
- '--portal', self.portal],
- stdout=subprocess.PIPE, stderr=subprocess.PIPE)
- out, err = iscsiadm.communicate()
- if iscsiadm.returncode != 0:
- msg_args = {'portal': self.portal, 'err': err}
- raise OperationFailed("KCHISCSI0001E", msg_args)
- return out
-
- def _run_op(self, op):
- self._run_cmd(['--' + op])
-
- def login(self):
- self._discover()
- self._update_auth()
- self._run_op('login')
-
- def logout(self):
- self._run_op('logout')
-
- def validate(self):
- try:
- self.login()
- except OperationFailed:
- return False
-
- self.logout()
- return True
diff --git a/plugins/kimchi/isoinfo.py b/plugins/kimchi/isoinfo.py
deleted file mode 100644
index 8de6885..0000000
--- a/plugins/kimchi/isoinfo.py
+++ /dev/null
@@ -1,506 +0,0 @@
-#
-# Project Kimchi
-#
-# Copyright IBM, Corp. 2013-2015
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-
-import contextlib
-import glob
-import os
-import platform
-import re
-import stat
-import struct
-import sys
-import urllib2
-
-
-from wok.exception import IsoFormatError
-from wok.utils import check_url_path, wok_log
-
-
-iso_dir = [
- ##
- # Portions of this data from libosinfo:
http://libosinfo.org/
- #
- # Each tuple has the following three members:
- # Distro ID: Nickname for the distro or OS family
- # Distro Version: A function or string that provides a specific version
- # given a regular expression match on the volume id string
- # Regular Expression: A regex to match against the ISO Volume ID
- ##
- ('openbsd', lambda m: m.group(2),
- ('OpenBSD/(i386|amd64) (\d+\.\d+) Install CD')),
- ('centos', lambda m: m.group(1),
- ('CentOS_(\d+\.\d+)_Final')),
- ('windows', '2000',
- ('W2AFPP|SP1AFPP|SP2AFPP|YRMAFPP|ZRMAFPP|W2AOEM|SP1AOEM|SP2AOEM' +
- '|YRMAOEM|ZRMAOEM|W2ASEL|SP2ASEL|W2SFPP|SP1SFPP|SP2SFPP|YRMSFPP' +
- '|ZRMSFPP|W2SOEM|W2SOEM|SP1SOEM|SP2SOEM|YRMSOEM|ZRMSOEM|W2SSEL' +
- '|SP2SSEL|W2PFPP|SP1PFPP|SP2PFPP|YRMPFPP|ZRMPFPP|W2POEM|SP1POEM' +
- '|SP2POEM|YRMPOEM|ZRMPOEM|W2PSEL|SP2PSEL|W2PCCP|WIN2000|W2K_SP4')),
- ('windows', 'xp',
- ('WXPFPP|WXHFPP|WXPCCP|WXHCCP|WXPOEM|WXHOEM|WXPVOL|WXPEVL|XRMPFPP' +
- '|XRMHFPP|XRMPCCP|XRMHCCP|XRMPOEM|XRMHOEM|XRMPVOL|XRMSD2|X1APFPP' +
- '|X1AHFPP|X1APCCP|X1APCCP|X1AHCCP|X1APOEM|X1AHOEM|X1APVOL|VRMPFPP' +
- '|VRMHFPP|VRMPCCP|VRMHCCP|VRMPOEM|VRMHOEM|VRMPVOL|VRMSD2|VX2PFPP' +
- '|VX2HFPP|VX2PCCP|VX2HCCP|VX2POEM|VX2HOEM|VX2PRMFPP|VX2PVOL|GRTMUPD' +
- '|GRTMPFPP|GRTMPRMFPP|GRTMHFPP|GRTMHKFPP|GRTMHKNFPP|GRTMHRMFPP' +
- '|GRTMPOEM|GRTMHOEM|GRTMPVOL|GRTMPKNVOL|GRTMPKVOL|GRTMPRMVOL' +
- '|MX2PFPP|MRMSD2|ARMPXFPP|ARMPXCCP|ARMPXOEM|ARMPXVOL|AX2PXCFPP' +
- '|AX2PXFPP|NRMPIFPP')),
- ('windows', '2003',
- ('ARMECHK|ARMEVOL|ARMSVOL|ARMWVOL|ARMEEVL|ARMSEVL|ARMWEVL|ARMEOEM' +
- '|ARMDOEM|ARMSOEM|ARMWOEM|ARMEFPP|ARMDFPP|ARMSFPP|ARMWFPP|NRMECHK' +
- '|NRMEVOL|NRMSVOL|NRMWVOL|NRMEEVL|NRMSEVL|NRMWEVL|NRMEOEM|NRMDOEM' +
- '|NRMSOEM|NRMWOEM|NRMEFPP|NRMDFPP|NRMSFPP|NRMSFPP|CRMSVOL|CRMSXVOL' +
- '|BRMEVOL|BX2DVOL|ARMEEVL|BRMEEVL|CR0SP2|ARMEICHK|ARMEIFPP|ARMEIEVL' +
- '|ARMEIOEM|ARMDIOEM|ARMEXFPP|ARMDFPP|ARMSXFPP|CR0SPX2|NRMEICHK' +
- '|NRMEIFPP|NRMDIFPP|NRMEIOEM|NRMDIOEM|NRMEIVOL|NRMEIEVL|BRMEXVOL' +
- '|BX2DXVOL|ARMEIFPP|CR0SPI2')),
- ('windows', '2003r2',
- ('CRMEFPP|CRMSFPP|CR0SCD2|CR0ECD2|BX2SFPP|BX2EFPP|BRMECD2FRE' +
- '|BRMSCD2FRE|CRMEXFPP|CRMSXFPP|CR0SCD2X|CR0ECD2X|BX2SXFPP|BX2EXFPP' +
- '|BRMECD2XFRE|BRMSCD2XFRE|CRMDVOL|CRMDXVOL')),
- ('windows', '2008',
- ('KRTMSVOL|KRTMSCHK|KRMWVOL|KRMSVOL|KRTMSXVOL|KRTMSXCHK|KRMWXVOL' +
- '|KRMSXVOL')),
- ('windows', '2008r2',
- ('GRMSXVOL|GRMSXFRER|GRMSHXVOL|GRMSIAIVOL|SRVHPCR2')),
- ('windows', 'vista',
- ('FB1EVOL|LRMCFRE|FRTMBVOL|FRMBVOL|FRMEVOL|FB1EXVOL|LRMCXFRE' +
- '|FRTMBXVOL|FRMBXVOL|FRMEXVOL|LRMEVOL|LRMEXVOL')),
- ('windows', '7',
- ('GRMCULFRER|GSP1RMCNPRFRER|GSP1RMCNULFRER|GSP1RMCULFRER' +
- '|GSP1RMCPRFRER|GRMCENVOL|GRMCNENVOL|GRMCPRFRER|GSP1RMCPRVOL' +
- '|GRMCULXFRER|GSP1RMCPRXFRER|GSP1RMCNHPXFRER|GRMCHPXFRER|GRMCXCHK' +
- '|GSP1RMCENXVOL|GRMCENXVOL|GRMCNENXVOL|GRMCPRXFRER|GSP1RMCPRXVOL')),
- ('windows', '8',
- ('HB1_CCPA_X86FRE|HRM_CCSA_X86FRE|HRM_CCSA_X86CHK|HRM_CCSNA_X86CHK' +
- '|HRM_CCSNA_X86FRE|HRM_CENA_X86FREV|HRM_CENA_X86CHKV' +
- '|HRM_CENNA_X86FREV|HRM_CENNA_X86CHKV|HRM_CPRA_X86FREV' +
- '|HRM_CPRNA_X86FREV|HB1_CCPA_X64FRE|HRM_CCSA_X64FRE' +
- '|HRM_CCSA_X64CHK|HRM_CCSNA_X64FRE|HRM_CCSNA_X64CHK' +
- '|HRM_CENNA_X64FREV|HRM_CENNA_X64CHKV|HRM_CENA_X64FREV' +
- '|HRM_CENA_X64CHKV|HRM_CPRA_X64FREV|HRM_CPRNA_X64FREV')),
- ('sles', '10', 'SLES10|SUSE-Linux-Enterprise-Server.001'),
- ('sles', '11', 'SUSE_SLES-11-0-0'),
- ('sles', '12', 'SLE-12'),
- ('sles', lambda m: "11sp%s" % m.group(1),
'SLES-11-SP(\d+)'),
- ('opensuse', lambda m: m.group(1), 'openSUSE[ -](\d+\.\d+)'),
- ('opensuse', '11.1', 'SU1110.001'),
- ('opensuse', '11.3',
- 'openSUSE-DVD-i586-Build0702..001|openSUSE-DVD-x86_64.0702..001'),
- ('opensuse', '11.4',
- 'openSUSE-DVD-i586-Build0024|openSUSE-DVD-x86_640024'),
- ('opensuse', '12.1',
- 'openSUSE-DVD-i586-Build0039|openSUSE-DVD-x86_640039'),
- ('opensuse', '12.2',
- 'openSUSE-DVD-i586-Build0167|openSUSE-DVD-x86_640167'),
- ('rhel', '4.8', 'RHEL/4-U8'),
- ('rhel', lambda m: m.group(2), 'RHEL(-LE)?[_/-](\d+\.\d+)'),
- ('debian', lambda m: m.group(1), 'Debian (\d+\.\d+)'),
- ('ubuntu', lambda m: m.group(2), '[Uu]buntu(-Server)? (\d+\.\d+)'),
- ('fedora', lambda m: m.group(1), 'Fedora[ -](\d+)'),
- ('fedora', lambda m: m.group(1), 'Fedora.*-(\d+)-'),
- ('gentoo', lambda m: m.group(1), 'Gentoo Linux \w+ (\d+)'),
- ('powerkvm', 'live_cd', 'POWERKVM_LIVECD'),
- ('arch', lambda m: m.group(1), 'ARCH_(\d+)'),
-]
-
-
-class IsoImage(object):
- """
- Scan an iso9660 image to extract the Volume ID and check for boot-ability
-
- ISO-9660 specification:
-
http://www.ecma-international.org/publications/standards/Ecma-119.htm
-
- El-Torito specification:
-
http://download.intel.com/support/motherboards/desktop/sb/specscdrom.pdf
- """
- SECTOR_SIZE = 2048
- VOL_DESC = struct.Struct("=B5sBB32s32s")
- EL_TORITO_BOOT_RECORD = struct.Struct("=B5sB32s32sI")
- EL_TORITO_VALIDATION_ENTRY = struct.Struct("=BBH24sHBB")
- EL_TORITO_BOOT_ENTRY = struct.Struct("=BBHBBHL20x")
- # Path table info starting in ISO9660 offset 132. We force little
- # endian byte order (the '<' sign) because Power systems can run on
- # both.
- # First int is path table size, next 4 bytes are discarded (it is
- # the same info but in big endian) and next int is the location.
- PATH_TABLE_SIZE_LOC = struct.Struct("<I 4s I")
-
- def __init__(self, path):
- self.path = path
- self.remote = self._is_iso_remote()
- self.volume_id = None
- self.bootable = False
- self._scan()
-
- def _is_iso_remote(self):
- if os.path.exists(self.path):
- st_mode = os.stat(self.path).st_mode
- if stat.S_ISREG(st_mode) or stat.S_ISBLK(st_mode):
- return False
-
- if check_url_path(self.path):
- return True
-
- raise IsoFormatError("KCHISO0001E", {'filename': self.path})
-
- def probe(self):
- if not self.bootable:
- raise IsoFormatError("KCHISO0002E", {'filename':
self.path})
-
- matcher = Matcher(self.volume_id)
-
- for d, v, regex in iso_dir:
- if matcher.search(regex):
- distro = d
- if hasattr(v, '__call__'):
- version = v(matcher)
- else:
- version = v
- return (distro, version)
-
- msg = "probe_iso: Unable to identify ISO %s with Volume ID: %s"
- wok_log.debug(msg, self.path, self.volume_id)
-
- return ('unknown', 'unknown')
-
- def _unpack(self, s, data):
- return s.unpack(data[:s.size])
-
- def _scan_el_torito(self, data):
- """
- Search the Volume Descriptor Table for an El Torito boot record. If
- found, the boot record will provide a link to a boot catalogue. The
- first entry in the boot catalogue is a validation entry. The next
- entry contains the default boot entry. The default boot entry will
- indicate whether the image is considered bootable.
- """
- vd_type = -1
- for i in xrange(1, 4):
- fmt = IsoImage.EL_TORITO_BOOT_RECORD
- ptr = i * IsoImage.SECTOR_SIZE
- tmp_data = data[ptr:ptr + fmt.size]
- if len(tmp_data) < fmt.size:
- return
-
- (vd_type, vd_ident, vd_ver,
- et_ident, pad0, boot_cat) = self._unpack(fmt, tmp_data)
- if vd_type == 255: # Volume record terminator
- return
- if vd_type == 0: # Found El-Torito Boot Record
- break
- if not et_ident.startswith('EL TORITO SPECIFICATION'):
- raise IsoFormatError("KCHISO0003E",
- {'filename': self.path})
-
- offset = IsoImage.SECTOR_SIZE * boot_cat
- size = IsoImage.EL_TORITO_VALIDATION_ENTRY.size + \
- IsoImage.EL_TORITO_BOOT_ENTRY.size
- data = self._get_iso_data(offset, size)
-
- fmt = IsoImage.EL_TORITO_VALIDATION_ENTRY
- tmp_data = data[0:fmt.size]
- ptr = fmt.size
- (hdr_id, platform_id, pad0,
- ident, csum, key55, keyAA) = self._unpack(fmt, tmp_data)
- if key55 != 0x55 or keyAA != 0xaa:
- raise IsoFormatError("KCHISO0004E",
- {'filename': self.path})
-
- fmt = IsoImage.EL_TORITO_BOOT_ENTRY
- tmp_data = data[ptr:ptr + fmt.size]
- (boot, media_type, load_seg, sys_type,
- pad0, sectors, load_rba) = self._unpack(fmt, tmp_data)
- if boot == 0x88:
- self.bootable = True
- elif boot == 0:
- self.bootable = False
- else:
- raise IsoFormatError("KCHISO0005E",
- {'filename': self.path})
-
- def _scan_ppc(self):
- """
- PowerPC firmware does not use the conventional El Torito boot
- specification. Instead, it looks for a file '/ppc/bootinfo.txt'
- which contains boot information. A PPC image is bootable if
- this file exists in the filesystem [1].
-
- To detect if a PPC ISO is bootable, we could simply mount the
- ISO and search for the boot file as we would with any other
- file in the filesystem. We can also look for the boot file
- searching byte by byte the ISO image. This is possible because
- the PPC ISO image follows the ISO9660 standard [2]. Mounting
- the ISO requires extra resources and it takes longer than
- searching the image data, thus we chose the latter approach
- in this code.
-
- To locate a file we must access the Path Table, which contains
- the records of all the directories in the ISO. After locating
- the directory/subdirectory that contains the file, we access
- the Directory Record to find it.
-
-
- .. [1]
https://www.ibm.com/developerworks/community/wikis/home?\
-lang=en#!/wiki/W51a7ffcf4dfd_4b40_9d82_446ebc23c550/page/PowerLinux\
-%20Boot%20howto
- .. [2]
http://wiki.osdev.org/ISO_9660
- """
-
- # To locate any file we must access the Path Table, which
- # contains the records of all the directories in the ISO.
- # ISO9660 dictates that the Path Table location information
- # is at offset 132, inside the Primary Volume Descriptor,
- # after the SystemArea (16*SECTOR_SIZE).
- #
- # In the Path table info we're forcing little endian byte
- # order (the '<' sign) because Power systems can run on
- # both.
- #
- # First int is path table size, next 4 bytes are discarded (it is
- # the same info but in big endian) and next int is the location.
- PATH_TABLE_LOC_OFFSET = 16 * IsoImage.SECTOR_SIZE + 132
- PATH_TABLE_SIZE_LOC = struct.Struct("<I 4s I")
-
- path_table_loc_data = self._get_iso_data(PATH_TABLE_LOC_OFFSET,
- PATH_TABLE_SIZE_LOC.size)
- path_size, unused, path_loc = self._unpack(PATH_TABLE_SIZE_LOC,
- path_table_loc_data)
- # Fetch the Path Table using location and size found above
- path_table_offset = path_loc * IsoImage.SECTOR_SIZE
- path_table_data = self._get_iso_data(path_table_offset, path_size)
-
- # Loop inside the path table to find the directory 'ppc'.
- # The contents of the registers are:
- # - length of the directory identifier (1 byte)
- # - extended attribute record length (1 byte)
- # - location of directory register (4 bytes)
- # - directory number of parent dir (2 bytes)
- # - directory name (size varies according to length)
- # - padding field - 1 byte if the length is odd, not present if even
- DIR_NAMELEN_LOCATION_PARENT = struct.Struct("<B B I H")
- dir_struct_size = DIR_NAMELEN_LOCATION_PARENT.size
- i = 0
- while i < path_size:
- dir_data = path_table_data[i: i+dir_struct_size]
- i += dir_struct_size
- # We won't use the Extended Attribute Record
- dir_namelen, unused, dir_loc, dir_parent = \
- self._unpack(DIR_NAMELEN_LOCATION_PARENT, dir_data)
- if dir_parent == 1:
- # read the dir name using the namelen
- dir_name = path_table_data[i: i+dir_namelen].rstrip()
- if dir_name.lower() == 'ppc':
- # stop searching, dir was found
- break
- # Need to consider the optional padding field as well
- i += dir_namelen + dir_namelen % 2
-
- if i > path_size:
- # Didn't find the '/ppc' directory. ISO is not bootable.
- self.bootable = False
- return
-
- # Get the 'ppc' directory record using 'dir_loc'.
- ppc_dir_offset = dir_loc * IsoImage.SECTOR_SIZE
-
- # We need to find the sector size of this dir entry. The
- # size of the File Section is located 10 bytes after
- # the dir location.
- DIR_SIZE_FMT = struct.Struct("<10sI")
- data = self._get_iso_data(ppc_dir_offset, DIR_SIZE_FMT.size)
- unused, dir_size = self._unpack(DIR_SIZE_FMT, data)
- # If the dir is in the middle of a sector, the sector is
- # padded zero and won't be utilized. We need to round up
- # the result
- dir_sectorsize = dir_size / IsoImage.SECTOR_SIZE
- if dir_size % IsoImage.SECTOR_SIZE:
- dir_sectorsize += 1
-
- # Fixed-size directory record fields:
- # - length of directory record (1 byte)
- # - extended attr. record length (1 byte)
- # - location of extend in both-endian format (8 bytes)
- # - data length (size of extend) in both-endian (8 bytes)
- # - recording date and time (7 bytes)
- # - file flags (1 byte)
- # - file unit size interleaved (1 byte)
- # - interleave gap size (1 byte)
- # - volume sequence number (4 bytes)
- # - length of file identifier (1 byte)
- #
- # Of all these fields, we will use only 3 of them, 'ignoring'
- # 30 bytes total.
- STATIC_DIR_RECORD_FMT = struct.Struct("<B 24s B 6s B")
- static_rec_size = STATIC_DIR_RECORD_FMT.size
-
- # Maximum offset possible of all the records of this directory
- DIR_REC_MAX = ppc_dir_offset + dir_sectorsize*IsoImage.SECTOR_SIZE
- # Max size of a given directory record
- MAX_DIR_SIZE = 255
- # Name of the boot file
- BOOT_FILE_NAME = "bootinfo.txt"
-
- # Loop until one of the following happens:
- # - boot file is found
- # - end of directory record listing for the 'ppc' dir
- while ppc_dir_offset < DIR_REC_MAX:
- record_data = self._get_iso_data(ppc_dir_offset, MAX_DIR_SIZE)
- dir_rec_len, unused, file_flags, unused2, file_name_len = \
- self._unpack(STATIC_DIR_RECORD_FMT, record_data)
-
- # if dir_rec_len = 0, increment offset (skip the
- # dir_rec_len byte) and continue the loop
- if dir_rec_len == 0:
- ppc_dir_offset += 1
- continue
-
- # Get filename of the file/dir we're at.
- filename = record_data[static_rec_size:
- static_rec_size + file_name_len].rstrip()
- # The second bit of the file_flags indicate if this record
- # is a directory.
- if BOOT_FILE_NAME in filename.lower() and (file_flags & 2) != 1:
- self.bootable = True
- return
-
- # Update offset and keep looking. There is a padding here
- # if the length of the file identifier is EVEN.
- padding = 0
- if not file_name_len % 2:
- padding = 1
- ppc_dir_offset += dir_rec_len + padding
- # If reached this point the file wasn't found = not bootable
- self.bootable = False
-
- def _scan_primary_vol(self, data):
- """
- Scan one sector for a Primary Volume Descriptor and extract the
- Volume ID from the table
- """
- primary_vol_data = data[0: -1]
- info = self._unpack(IsoImage.VOL_DESC, primary_vol_data)
- (vd_type, vd_ident, vd_ver, pad0, sys_id, vol_id) = info
- if vd_type != 1:
- raise IsoFormatError("KCHISO0006E", {'filename':
self.path})
- if vd_ident != 'CD001' or vd_ver != 1:
- raise IsoFormatError("KCHISO0007E", {'filename':
self.path})
- if vol_id.strip() == 'RED_HAT':
- # Some RHEL ISO images store the infomation of volume id in the
- # location of volume set id mistakenly.
- self.volume_id = self._get_volume_set_id(data)
- else:
- self.volume_id = vol_id
-
- def _get_volume_set_id(self, data):
- # The index is picked from ISO-9660 specification.
- return data[190: 318]
-
- def _get_iso_data(self, offset, size):
- if self.remote:
- request = urllib2.Request(self.path)
- range_header = "bytes=%d-%d" % (offset, offset + size - 1)
- request.add_header("range", range_header)
- with contextlib.closing(urllib2.urlopen(request)) as response:
- data = response.read()
- else:
- with open(self.path) as fd:
- fd.seek(offset)
- data = fd.read(size)
-
- return data
-
- def _scan(self):
- offset = 16 * IsoImage.SECTOR_SIZE
- size = 4 * IsoImage.SECTOR_SIZE
- data = self._get_iso_data(offset, size)
- if len(data) < 2 * IsoImage.SECTOR_SIZE:
- return
-
- self._scan_primary_vol(data)
- if platform.machine().startswith('ppc'):
- self._scan_ppc()
- else:
- self._scan_el_torito(data)
-
-
-class Matcher(object):
- """
- Simple utility class to assist with matching a given string against a
- series of regular expressions.
- """
- def __init__(self, matchstring):
- self.matchstring = matchstring
-
- def search(self, regex):
- self.lastmatch = re.search(regex, self.matchstring)
- return bool(self.lastmatch)
-
- def group(self, num):
- return self.lastmatch.group(num)
-
-
-def probe_iso(status_helper, params):
- loc = params['path'].encode("utf-8")
- updater = params['updater']
- ignore = False
- ignore_list = params.get('ignore_list', [])
-
- def update_result(iso, ret):
- path = os.path.abspath(iso) if os.path.isfile(iso) else iso
- updater({'path': path, 'distro': ret[0], 'version':
ret[1]})
-
- if os.path.isdir(loc):
- for root, dirs, files in os.walk(loc):
- for dir_name in ignore_list:
- if root in glob.glob(dir_name):
- ignore = True
- break
- if ignore:
- ignore = False
- continue
- for name in files:
- if not name.lower().endswith('.iso'):
- continue
- iso = os.path.join(root, name)
- try:
- iso_img = IsoImage(iso)
- ret = iso_img.probe()
- update_result(iso, ret)
- except:
- continue
- else:
- iso_img = IsoImage(loc)
- ret = iso_img.probe()
- update_result(loc, ret)
-
- if status_helper is not None:
- status_helper('', True)
-
-
-if __name__ == '__main__':
- iso_list = []
-
- def updater(iso_info):
- iso_list.append(iso_info)
-
- probe_iso(None, dict(path=sys.argv[1], updater=updater))
- print iso_list
diff --git a/plugins/kimchi/kimchi.conf b/plugins/kimchi/kimchi.conf
deleted file mode 100644
index 1bf78e4..0000000
--- a/plugins/kimchi/kimchi.conf
+++ /dev/null
@@ -1,37 +0,0 @@
-[wok]
-enable = True
-plugin_class = "KimchiRoot"
-uri = "/plugins/kimchi"
-extra_auth_api_class = "control.sub_nodes"
-
-[/]
-tools.trailing_slash.on = False
-request.methods_with_bodies = ('POST', 'PUT')
-tools.nocache.on = True
-tools.proxy.on = True
-tools.sessions.on = True
-tools.sessions.name = 'wok'
-tools.sessions.secure = True
-tools.sessions.httponly = True
-tools.sessions.locking = 'explicit'
-tools.sessions.storage_type = 'ram'
-tools.sessions.timeout = 10
-tools.wokauth.on = True
-
-[/data/screenshots]
-tools.staticdir.on = True
-tools.staticdir.dir = wok.config.PluginPaths('kimchi').state_dir +
'/screenshots'
-tools.nocache.on = False
-
-[/data/debugreports]
-tools.staticdir.on = True
-tools.staticdir.dir = wok.config.PluginPaths('kimchi').state_dir +
'/debugreports'
-tools.nocache.on = False
-tools.wokauth.on = True
-tools.staticdir.content_types = {'xz': 'application/x-xz'}
-
-[/help]
-tools.staticdir.on = True
-tools.staticdir.dir = wok.config.PluginPaths('kimchi').ui_dir +
'/pages/help'
-tools.nocache.on = True
-
diff --git a/plugins/kimchi/kvmusertests.py b/plugins/kimchi/kvmusertests.py
deleted file mode 100644
index 35350d8..0000000
--- a/plugins/kimchi/kvmusertests.py
+++ /dev/null
@@ -1,79 +0,0 @@
-# Project Kimchi
-#
-# Copyright IBM, Corp. 2014-2015
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-
-import libvirt
-import platform
-import psutil
-import threading
-
-
-from wok.rollbackcontext import RollbackContext
-
-KVMUSERTEST_VM_NAME = "KVMUSERTEST_VM"
-
-
-class UserTests(object):
- SIMPLE_VM_XML = """
- <domain type='kvm'>
- <name>%(name)s</name>
- <memory unit='KiB'>262144</memory>
- <os>
- <type arch='%(arch)s'>hvm</type>
- <boot dev='hd'/>
- </os>
- </domain>"""
- lock = threading.Lock()
- user = None
-
- @classmethod
- def probe_user(cls):
- with cls.lock:
- if cls.user:
- return cls.user
-
- arch = 'ppc64' if platform.machine() == 'ppc64le' \
- else platform.machine()
-
- xml = cls.SIMPLE_VM_XML % {'name': KVMUSERTEST_VM_NAME, 'arch':
arch}
-
- with RollbackContext() as rollback:
- with cls.lock:
- conn = libvirt.open(None)
- rollback.prependDefer(conn.close)
- f = libvirt.VIR_DOMAIN_START_AUTODESTROY
- dom = conn.createXML(xml, flags=f)
- rollback.prependDefer(dom.destroy)
- filename = '/var/run/libvirt/qemu/%s.pid' % KVMUSERTEST_VM_NAME
- with open(filename) as f:
- pidStr = f.read()
- p = psutil.Process(int(pidStr))
-
- # bug fix #357
- # in psutil 2.0 and above versions, username will be a method,
- # not a string
- if callable(p.username):
- cls.user = p.username()
- else:
- cls.user = p.username
-
- return cls.user
-
-
-if __name__ == '__main__':
- ut = UserTests()
- print ut.probe_user()
diff --git a/plugins/kimchi/m4/ac_python_module.m4
b/plugins/kimchi/m4/ac_python_module.m4
deleted file mode 100644
index 32b9d72..0000000
--- a/plugins/kimchi/m4/ac_python_module.m4
+++ /dev/null
@@ -1,30 +0,0 @@
-dnl @synopsis AC_PYTHON_MODULE(modname[, fatal])
-dnl
-dnl Checks for Python module.
-dnl
-dnl If fatal is non-empty then absence of a module will trigger an
-dnl error.
-dnl
-dnl @category InstalledPackages
-dnl @author Andrew Collier <colliera(a)nu.ac.za>.
-dnl @version 2004-07-14
-dnl @license AllPermissive
-
-AC_DEFUN([AC_PYTHON_MODULE],[
- AC_MSG_CHECKING(python module: $1)
- python -c "import $1" 2>/dev/null
- if test $? -eq 0;
- then
- AC_MSG_RESULT(yes)
- eval AS_TR_CPP(HAVE_PYMOD_$1)=yes
- else
- AC_MSG_RESULT(no)
- eval AS_TR_CPP(HAVE_PYMOD_$1)=no
- #
- if test -n "$2"
- then
- AC_MSG_ERROR(failed to find required module $1)
- exit 1
- fi
- fi
-])
diff --git a/plugins/kimchi/m4/gettext.m4 b/plugins/kimchi/m4/gettext.m4
deleted file mode 100644
index f84e6a5..0000000
--- a/plugins/kimchi/m4/gettext.m4
+++ /dev/null
@@ -1,383 +0,0 @@
-# gettext.m4 serial 63 (gettext-0.18)
-dnl Copyright (C) 1995-2010 Free Software Foundation, Inc.
-dnl This file is free software; the Free Software Foundation
-dnl gives unlimited permission to copy and/or distribute it,
-dnl with or without modifications, as long as this notice is preserved.
-dnl
-dnl This file can can be used in projects which are not available under
-dnl the GNU General Public License or the GNU Library General Public
-dnl License but which still want to provide support for the GNU gettext
-dnl functionality.
-dnl Please note that the actual code of the GNU gettext library is covered
-dnl by the GNU Library General Public License, and the rest of the GNU
-dnl gettext package package is covered by the GNU General Public License.
-dnl They are *not* in the public domain.
-
-dnl Authors:
-dnl Ulrich Drepper <drepper(a)cygnus.com>, 1995-2000.
-dnl Bruno Haible <haible(a)clisp.cons.org>, 2000-2006, 2008-2010.
-
-dnl Macro to add for using GNU gettext.
-
-dnl Usage: AM_GNU_GETTEXT([INTLSYMBOL], [NEEDSYMBOL], [INTLDIR]).
-dnl INTLSYMBOL can be one of 'external', 'no-libtool',
'use-libtool'. The
-dnl default (if it is not specified or empty) is 'no-libtool'.
-dnl INTLSYMBOL should be 'external' for packages with no intl directory,
-dnl and 'no-libtool' or 'use-libtool' for packages with an intl
directory.
-dnl If INTLSYMBOL is 'use-libtool', then a libtool library
-dnl $(top_builddir)/intl/libintl.la will be created (shared and/or static,
-dnl depending on --{enable,disable}-{shared,static} and on the presence of
-dnl AM-DISABLE-SHARED). If INTLSYMBOL is 'no-libtool', a static library
-dnl $(top_builddir)/intl/libintl.a will be created.
-dnl If NEEDSYMBOL is specified and is 'need-ngettext', then GNU gettext
-dnl implementations (in libc or libintl) without the ngettext() function
-dnl will be ignored. If NEEDSYMBOL is specified and is
-dnl 'need-formatstring-macros', then GNU gettext implementations that
don't
-dnl support the ISO C 99 <inttypes.h> formatstring macros will be ignored.
-dnl INTLDIR is used to find the intl libraries. If empty,
-dnl the value `$(top_builddir)/intl/' is used.
-dnl
-dnl The result of the configuration is one of three cases:
-dnl 1) GNU gettext, as included in the intl subdirectory, will be compiled
-dnl and used.
-dnl Catalog format: GNU --> install in $(datadir)
-dnl Catalog extension: .mo after installation, .gmo in source tree
-dnl 2) GNU gettext has been found in the system's C library.
-dnl Catalog format: GNU --> install in $(datadir)
-dnl Catalog extension: .mo after installation, .gmo in source tree
-dnl 3) No internationalization, always use English msgid.
-dnl Catalog format: none
-dnl Catalog extension: none
-dnl If INTLSYMBOL is 'external', only cases 2 and 3 can occur.
-dnl The use of .gmo is historical (it was needed to avoid overwriting the
-dnl GNU format catalogs when building on a platform with an X/Open gettext),
-dnl but we keep it in order not to force irrelevant filename changes on the
-dnl maintainers.
-dnl
-AC_DEFUN([AM_GNU_GETTEXT],
-[
- dnl Argument checking.
- ifelse([$1], [], , [ifelse([$1], [external], , [ifelse([$1], [no-libtool], ,
[ifelse([$1], [use-libtool], ,
- [errprint([ERROR: invalid first argument to AM_GNU_GETTEXT
-])])])])])
- ifelse(ifelse([$1], [], [old])[]ifelse([$1], [no-libtool], [old]), [old],
- [AC_DIAGNOSE([obsolete], [Use of AM_GNU_GETTEXT without [external] argument is
deprecated.])])
- ifelse([$2], [], , [ifelse([$2], [need-ngettext], , [ifelse([$2],
[need-formatstring-macros], ,
- [errprint([ERROR: invalid second argument to AM_GNU_GETTEXT
-])])])])
- define([gt_included_intl],
- ifelse([$1], [external],
- ifdef([AM_GNU_GETTEXT_][INTL_SUBDIR], [yes], [no]),
- [yes]))
- define([gt_libtool_suffix_prefix], ifelse([$1], [use-libtool], [l], []))
- gt_NEEDS_INIT
- AM_GNU_GETTEXT_NEED([$2])
-
- AC_REQUIRE([AM_PO_SUBDIRS])dnl
- ifelse(gt_included_intl, yes, [
- AC_REQUIRE([AM_INTL_SUBDIR])dnl
- ])
-
- dnl Prerequisites of AC_LIB_LINKFLAGS_BODY.
- AC_REQUIRE([AC_LIB_PREPARE_PREFIX])
- AC_REQUIRE([AC_LIB_RPATH])
-
- dnl Sometimes libintl requires libiconv, so first search for libiconv.
- dnl Ideally we would do this search only after the
- dnl if test "$USE_NLS" = "yes"; then
- dnl if { eval "gt_val=\$$gt_func_gnugettext_libc"; test
"$gt_val" != "yes"; }; then
- dnl tests. But if configure.in invokes AM_ICONV after AM_GNU_GETTEXT
- dnl the configure script would need to contain the same shell code
- dnl again, outside any 'if'. There are two solutions:
- dnl - Invoke AM_ICONV_LINKFLAGS_BODY here, outside any 'if'.
- dnl - Control the expansions in more detail using AC_PROVIDE_IFELSE.
- dnl Since AC_PROVIDE_IFELSE is only in autoconf >= 2.52 and not
- dnl documented, we avoid it.
- ifelse(gt_included_intl, yes, , [
- AC_REQUIRE([AM_ICONV_LINKFLAGS_BODY])
- ])
-
- dnl Sometimes, on MacOS X, libintl requires linking with CoreFoundation.
- gt_INTL_MACOSX
-
- dnl Set USE_NLS.
- AC_REQUIRE([AM_NLS])
-
- ifelse(gt_included_intl, yes, [
- BUILD_INCLUDED_LIBINTL=no
- USE_INCLUDED_LIBINTL=no
- ])
- LIBINTL=
- LTLIBINTL=
- POSUB=
-
- dnl Add a version number to the cache macros.
- case " $gt_needs " in
- *" need-formatstring-macros "*) gt_api_version=3 ;;
- *" need-ngettext "*) gt_api_version=2 ;;
- *) gt_api_version=1 ;;
- esac
- gt_func_gnugettext_libc="gt_cv_func_gnugettext${gt_api_version}_libc"
- gt_func_gnugettext_libintl="gt_cv_func_gnugettext${gt_api_version}_libintl"
-
- dnl If we use NLS figure out what method
- if test "$USE_NLS" = "yes"; then
- gt_use_preinstalled_gnugettext=no
- ifelse(gt_included_intl, yes, [
- AC_MSG_CHECKING([whether included gettext is requested])
- AC_ARG_WITH([included-gettext],
- [ --with-included-gettext use the GNU gettext library included here],
- nls_cv_force_use_gnu_gettext=$withval,
- nls_cv_force_use_gnu_gettext=no)
- AC_MSG_RESULT([$nls_cv_force_use_gnu_gettext])
-
- nls_cv_use_gnu_gettext="$nls_cv_force_use_gnu_gettext"
- if test "$nls_cv_force_use_gnu_gettext" != "yes"; then
- ])
- dnl User does not insist on using GNU NLS library. Figure out what
- dnl to use. If GNU gettext is available we use this. Else we have
- dnl to fall back to GNU NLS library.
-
- if test $gt_api_version -ge 3; then
- gt_revision_test_code='
-#ifndef __GNU_GETTEXT_SUPPORTED_REVISION
-#define __GNU_GETTEXT_SUPPORTED_REVISION(major) ((major) == 0 ? 0 : -1)
-#endif
-changequote(,)dnl
-typedef int array [2 * (__GNU_GETTEXT_SUPPORTED_REVISION(0) >= 1) - 1];
-changequote([,])dnl
-'
- else
- gt_revision_test_code=
- fi
- if test $gt_api_version -ge 2; then
- gt_expression_test_code=' + * ngettext ("", "",
0)'
- else
- gt_expression_test_code=
- fi
-
- AC_CACHE_CHECK([for GNU gettext in libc], [$gt_func_gnugettext_libc],
- [AC_TRY_LINK([#include <libintl.h>
-$gt_revision_test_code
-extern int _nl_msg_cat_cntr;
-extern int *_nl_domain_bindings;],
- [bindtextdomain ("", "");
-return * gettext ("")$gt_expression_test_code + _nl_msg_cat_cntr +
*_nl_domain_bindings],
- [eval "$gt_func_gnugettext_libc=yes"],
- [eval "$gt_func_gnugettext_libc=no"])])
-
- if { eval "gt_val=\$$gt_func_gnugettext_libc"; test "$gt_val"
!= "yes"; }; then
- dnl Sometimes libintl requires libiconv, so first search for libiconv.
- ifelse(gt_included_intl, yes, , [
- AM_ICONV_LINK
- ])
- dnl Search for libintl and define LIBINTL, LTLIBINTL and INCINTL
- dnl accordingly. Don't use AC_LIB_LINKFLAGS_BODY([intl],[iconv])
- dnl because that would add "-liconv" to LIBINTL and LTLIBINTL
- dnl even if libiconv doesn't exist.
- AC_LIB_LINKFLAGS_BODY([intl])
- AC_CACHE_CHECK([for GNU gettext in libintl],
- [$gt_func_gnugettext_libintl],
- [gt_save_CPPFLAGS="$CPPFLAGS"
- CPPFLAGS="$CPPFLAGS $INCINTL"
- gt_save_LIBS="$LIBS"
- LIBS="$LIBS $LIBINTL"
- dnl Now see whether libintl exists and does not depend on libiconv.
- AC_TRY_LINK([#include <libintl.h>
-$gt_revision_test_code
-extern int _nl_msg_cat_cntr;
-extern
-#ifdef __cplusplus
-"C"
-#endif
-const char *_nl_expand_alias (const char *);],
- [bindtextdomain ("", "");
-return * gettext ("")$gt_expression_test_code + _nl_msg_cat_cntr +
*_nl_expand_alias ("")],
- [eval "$gt_func_gnugettext_libintl=yes"],
- [eval "$gt_func_gnugettext_libintl=no"])
- dnl Now see whether libintl exists and depends on libiconv.
- if { eval "gt_val=\$$gt_func_gnugettext_libintl"; test
"$gt_val" != yes; } && test -n "$LIBICONV"; then
- LIBS="$LIBS $LIBICONV"
- AC_TRY_LINK([#include <libintl.h>
-$gt_revision_test_code
-extern int _nl_msg_cat_cntr;
-extern
-#ifdef __cplusplus
-"C"
-#endif
-const char *_nl_expand_alias (const char *);],
- [bindtextdomain ("", "");
-return * gettext ("")$gt_expression_test_code + _nl_msg_cat_cntr +
*_nl_expand_alias ("")],
- [LIBINTL="$LIBINTL $LIBICONV"
- LTLIBINTL="$LTLIBINTL $LTLIBICONV"
- eval "$gt_func_gnugettext_libintl=yes"
- ])
- fi
- CPPFLAGS="$gt_save_CPPFLAGS"
- LIBS="$gt_save_LIBS"])
- fi
-
- dnl If an already present or preinstalled GNU gettext() is found,
- dnl use it. But if this macro is used in GNU gettext, and GNU
- dnl gettext is already preinstalled in libintl, we update this
- dnl libintl. (Cf. the install rule in intl/Makefile.in.)
- if { eval "gt_val=\$$gt_func_gnugettext_libc"; test "$gt_val"
= "yes"; } \
- || { { eval "gt_val=\$$gt_func_gnugettext_libintl"; test
"$gt_val" = "yes"; } \
- && test "$PACKAGE" != gettext-runtime \
- && test "$PACKAGE" != gettext-tools; }; then
- gt_use_preinstalled_gnugettext=yes
- else
- dnl Reset the values set by searching for libintl.
- LIBINTL=
- LTLIBINTL=
- INCINTL=
- fi
-
- ifelse(gt_included_intl, yes, [
- if test "$gt_use_preinstalled_gnugettext" != "yes"; then
- dnl GNU gettext is not found in the C library.
- dnl Fall back on included GNU gettext library.
- nls_cv_use_gnu_gettext=yes
- fi
- fi
-
- if test "$nls_cv_use_gnu_gettext" = "yes"; then
- dnl Mark actions used to generate GNU NLS library.
- BUILD_INCLUDED_LIBINTL=yes
- USE_INCLUDED_LIBINTL=yes
-
LIBINTL="ifelse([$3],[],\${top_builddir}/intl,[$3])/libintl.[]gt_libtool_suffix_prefix[]a
$LIBICONV $LIBTHREAD"
-
LTLIBINTL="ifelse([$3],[],\${top_builddir}/intl,[$3])/libintl.[]gt_libtool_suffix_prefix[]a
$LTLIBICONV $LTLIBTHREAD"
- LIBS=`echo " $LIBS " | sed -e 's/ -lintl / /' -e 's/^
//' -e 's/ $//'`
- fi
-
- CATOBJEXT=
- if test "$gt_use_preinstalled_gnugettext" = "yes" \
- || test "$nls_cv_use_gnu_gettext" = "yes"; then
- dnl Mark actions to use GNU gettext tools.
- CATOBJEXT=.gmo
- fi
- ])
-
- if test -n "$INTL_MACOSX_LIBS"; then
- if test "$gt_use_preinstalled_gnugettext" = "yes" \
- || test "$nls_cv_use_gnu_gettext" = "yes"; then
- dnl Some extra flags are needed during linking.
- LIBINTL="$LIBINTL $INTL_MACOSX_LIBS"
- LTLIBINTL="$LTLIBINTL $INTL_MACOSX_LIBS"
- fi
- fi
-
- if test "$gt_use_preinstalled_gnugettext" = "yes" \
- || test "$nls_cv_use_gnu_gettext" = "yes"; then
- AC_DEFINE([ENABLE_NLS], [1],
- [Define to 1 if translation of program messages to the user's native
language
- is requested.])
- else
- USE_NLS=no
- fi
- fi
-
- AC_MSG_CHECKING([whether to use NLS])
- AC_MSG_RESULT([$USE_NLS])
- if test "$USE_NLS" = "yes"; then
- AC_MSG_CHECKING([where the gettext function comes from])
- if test "$gt_use_preinstalled_gnugettext" = "yes"; then
- if { eval "gt_val=\$$gt_func_gnugettext_libintl"; test
"$gt_val" = "yes"; }; then
- gt_source="external libintl"
- else
- gt_source="libc"
- fi
- else
- gt_source="included intl directory"
- fi
- AC_MSG_RESULT([$gt_source])
- fi
-
- if test "$USE_NLS" = "yes"; then
-
- if test "$gt_use_preinstalled_gnugettext" = "yes"; then
- if { eval "gt_val=\$$gt_func_gnugettext_libintl"; test
"$gt_val" = "yes"; }; then
- AC_MSG_CHECKING([how to link with libintl])
- AC_MSG_RESULT([$LIBINTL])
- AC_LIB_APPENDTOVAR([CPPFLAGS], [$INCINTL])
- fi
-
- dnl For backward compatibility. Some packages may be using this.
- AC_DEFINE([HAVE_GETTEXT], [1],
- [Define if the GNU gettext() function is already present or preinstalled.])
- AC_DEFINE([HAVE_DCGETTEXT], [1],
- [Define if the GNU dcgettext() function is already present or preinstalled.])
- fi
-
- dnl We need to process the po/ directory.
- POSUB=po
- fi
-
- ifelse(gt_included_intl, yes, [
- dnl If this is used in GNU gettext we have to set BUILD_INCLUDED_LIBINTL
- dnl to 'yes' because some of the testsuite requires it.
- if test "$PACKAGE" = gettext-runtime || test "$PACKAGE" =
gettext-tools; then
- BUILD_INCLUDED_LIBINTL=yes
- fi
-
- dnl Make all variables we use known to autoconf.
- AC_SUBST([BUILD_INCLUDED_LIBINTL])
- AC_SUBST([USE_INCLUDED_LIBINTL])
- AC_SUBST([CATOBJEXT])
-
- dnl For backward compatibility. Some configure.ins may be using this.
- nls_cv_header_intl=
- nls_cv_header_libgt=
-
- dnl For backward compatibility. Some Makefiles may be using this.
- DATADIRNAME=share
- AC_SUBST([DATADIRNAME])
-
- dnl For backward compatibility. Some Makefiles may be using this.
- INSTOBJEXT=.mo
- AC_SUBST([INSTOBJEXT])
-
- dnl For backward compatibility. Some Makefiles may be using this.
- GENCAT=gencat
- AC_SUBST([GENCAT])
-
- dnl For backward compatibility. Some Makefiles may be using this.
- INTLOBJS=
- if test "$USE_INCLUDED_LIBINTL" = yes; then
- INTLOBJS="\$(GETTOBJS)"
- fi
- AC_SUBST([INTLOBJS])
-
- dnl Enable libtool support if the surrounding package wishes it.
- INTL_LIBTOOL_SUFFIX_PREFIX=gt_libtool_suffix_prefix
- AC_SUBST([INTL_LIBTOOL_SUFFIX_PREFIX])
- ])
-
- dnl For backward compatibility. Some Makefiles may be using this.
- INTLLIBS="$LIBINTL"
- AC_SUBST([INTLLIBS])
-
- dnl Make all documented variables known to autoconf.
- AC_SUBST([LIBINTL])
- AC_SUBST([LTLIBINTL])
- AC_SUBST([POSUB])
-])
-
-
-dnl gt_NEEDS_INIT ensures that the gt_needs variable is initialized.
-m4_define([gt_NEEDS_INIT],
-[
- m4_divert_text([DEFAULTS], [gt_needs=])
- m4_define([gt_NEEDS_INIT], [])
-])
-
-
-dnl Usage: AM_GNU_GETTEXT_NEED([NEEDSYMBOL])
-AC_DEFUN([AM_GNU_GETTEXT_NEED],
-[
- m4_divert_text([INIT_PREPARE], [gt_needs="$gt_needs $1"])
-])
-
-
-dnl Usage: AM_GNU_GETTEXT_VERSION([gettext-version])
-AC_DEFUN([AM_GNU_GETTEXT_VERSION], [])
diff --git a/plugins/kimchi/m4/iconv.m4 b/plugins/kimchi/m4/iconv.m4
deleted file mode 100644
index e2041b9..0000000
--- a/plugins/kimchi/m4/iconv.m4
+++ /dev/null
@@ -1,214 +0,0 @@
-# iconv.m4 serial 11 (gettext-0.18.1)
-dnl Copyright (C) 2000-2002, 2007-2010 Free Software Foundation, Inc.
-dnl This file is free software; the Free Software Foundation
-dnl gives unlimited permission to copy and/or distribute it,
-dnl with or without modifications, as long as this notice is preserved.
-
-dnl From Bruno Haible.
-
-AC_DEFUN([AM_ICONV_LINKFLAGS_BODY],
-[
- dnl Prerequisites of AC_LIB_LINKFLAGS_BODY.
- AC_REQUIRE([AC_LIB_PREPARE_PREFIX])
- AC_REQUIRE([AC_LIB_RPATH])
-
- dnl Search for libiconv and define LIBICONV, LTLIBICONV and INCICONV
- dnl accordingly.
- AC_LIB_LINKFLAGS_BODY([iconv])
-])
-
-AC_DEFUN([AM_ICONV_LINK],
-[
- dnl Some systems have iconv in libc, some have it in libiconv (OSF/1 and
- dnl those with the standalone portable GNU libiconv installed).
- AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles
-
- dnl Search for libiconv and define LIBICONV, LTLIBICONV and INCICONV
- dnl accordingly.
- AC_REQUIRE([AM_ICONV_LINKFLAGS_BODY])
-
- dnl Add $INCICONV to CPPFLAGS before performing the following checks,
- dnl because if the user has installed libiconv and not disabled its use
- dnl via --without-libiconv-prefix, he wants to use it. The first
- dnl AC_TRY_LINK will then fail, the second AC_TRY_LINK will succeed.
- am_save_CPPFLAGS="$CPPFLAGS"
- AC_LIB_APPENDTOVAR([CPPFLAGS], [$INCICONV])
-
- AC_CACHE_CHECK([for iconv], [am_cv_func_iconv], [
- am_cv_func_iconv="no, consider installing GNU libiconv"
- am_cv_lib_iconv=no
- AC_TRY_LINK([#include <stdlib.h>
-#include <iconv.h>],
- [iconv_t cd = iconv_open("","");
- iconv(cd,NULL,NULL,NULL,NULL);
- iconv_close(cd);],
- [am_cv_func_iconv=yes])
- if test "$am_cv_func_iconv" != yes; then
- am_save_LIBS="$LIBS"
- LIBS="$LIBS $LIBICONV"
- AC_TRY_LINK([#include <stdlib.h>
-#include <iconv.h>],
- [iconv_t cd = iconv_open("","");
- iconv(cd,NULL,NULL,NULL,NULL);
- iconv_close(cd);],
- [am_cv_lib_iconv=yes]
- [am_cv_func_iconv=yes])
- LIBS="$am_save_LIBS"
- fi
- ])
- if test "$am_cv_func_iconv" = yes; then
- AC_CACHE_CHECK([for working iconv], [am_cv_func_iconv_works], [
- dnl This tests against bugs in AIX 5.1, HP-UX 11.11, Solaris 10.
- am_save_LIBS="$LIBS"
- if test $am_cv_lib_iconv = yes; then
- LIBS="$LIBS $LIBICONV"
- fi
- AC_TRY_RUN([
-#include <iconv.h>
-#include <string.h>
-int main ()
-{
- /* Test against AIX 5.1 bug: Failures are not distinguishable from successful
- returns. */
- {
- iconv_t cd_utf8_to_88591 = iconv_open ("ISO8859-1", "UTF-8");
- if (cd_utf8_to_88591 != (iconv_t)(-1))
- {
- static const char input[] = "\342\202\254"; /* EURO SIGN */
- char buf[10];
- const char *inptr = input;
- size_t inbytesleft = strlen (input);
- char *outptr = buf;
- size_t outbytesleft = sizeof (buf);
- size_t res = iconv (cd_utf8_to_88591,
- (char **) &inptr, &inbytesleft,
- &outptr, &outbytesleft);
- if (res == 0)
- return 1;
- }
- }
- /* Test against Solaris 10 bug: Failures are not distinguishable from
- successful returns. */
- {
- iconv_t cd_ascii_to_88591 = iconv_open ("ISO8859-1", "646");
- if (cd_ascii_to_88591 != (iconv_t)(-1))
- {
- static const char input[] = "\263";
- char buf[10];
- const char *inptr = input;
- size_t inbytesleft = strlen (input);
- char *outptr = buf;
- size_t outbytesleft = sizeof (buf);
- size_t res = iconv (cd_ascii_to_88591,
- (char **) &inptr, &inbytesleft,
- &outptr, &outbytesleft);
- if (res == 0)
- return 1;
- }
- }
-#if 0 /* This bug could be worked around by the caller. */
- /* Test against HP-UX 11.11 bug: Positive return value instead of 0. */
- {
- iconv_t cd_88591_to_utf8 = iconv_open ("utf8", "iso88591");
- if (cd_88591_to_utf8 != (iconv_t)(-1))
- {
- static const char input[] = "\304rger mit b\366sen B\374bchen ohne
Augenma\337";
- char buf[50];
- const char *inptr = input;
- size_t inbytesleft = strlen (input);
- char *outptr = buf;
- size_t outbytesleft = sizeof (buf);
- size_t res = iconv (cd_88591_to_utf8,
- (char **) &inptr, &inbytesleft,
- &outptr, &outbytesleft);
- if ((int)res > 0)
- return 1;
- }
- }
-#endif
- /* Test against HP-UX 11.11 bug: No converter from EUC-JP to UTF-8 is
- provided. */
- if (/* Try standardized names. */
- iconv_open ("UTF-8", "EUC-JP") == (iconv_t)(-1)
- /* Try IRIX, OSF/1 names. */
- && iconv_open ("UTF-8", "eucJP") == (iconv_t)(-1)
- /* Try AIX names. */
- && iconv_open ("UTF-8", "IBM-eucJP") == (iconv_t)(-1)
- /* Try HP-UX names. */
- && iconv_open ("utf8", "eucJP") == (iconv_t)(-1))
- return 1;
- return 0;
-}], [am_cv_func_iconv_works=yes], [am_cv_func_iconv_works=no],
- [case "$host_os" in
- aix* | hpux*) am_cv_func_iconv_works="guessing no" ;;
- *) am_cv_func_iconv_works="guessing yes" ;;
- esac])
- LIBS="$am_save_LIBS"
- ])
- case "$am_cv_func_iconv_works" in
- *no) am_func_iconv=no am_cv_lib_iconv=no ;;
- *) am_func_iconv=yes ;;
- esac
- else
- am_func_iconv=no am_cv_lib_iconv=no
- fi
- if test "$am_func_iconv" = yes; then
- AC_DEFINE([HAVE_ICONV], [1],
- [Define if you have the iconv() function and it works.])
- fi
- if test "$am_cv_lib_iconv" = yes; then
- AC_MSG_CHECKING([how to link with libiconv])
- AC_MSG_RESULT([$LIBICONV])
- else
- dnl If $LIBICONV didn't lead to a usable library, we don't need $INCICONV
- dnl either.
- CPPFLAGS="$am_save_CPPFLAGS"
- LIBICONV=
- LTLIBICONV=
- fi
- AC_SUBST([LIBICONV])
- AC_SUBST([LTLIBICONV])
-])
-
-dnl Define AM_ICONV using AC_DEFUN_ONCE for Autoconf >= 2.64, in order to
-dnl avoid warnings like
-dnl "warning: AC_REQUIRE: `AM_ICONV' was expanded before it was required".
-dnl This is tricky because of the way 'aclocal' is implemented:
-dnl - It requires defining an auxiliary macro whose name ends in AC_DEFUN.
-dnl Otherwise aclocal's initial scan pass would miss the macro definition.
-dnl - It requires a line break inside the AC_DEFUN_ONCE and AC_DEFUN expansions.
-dnl Otherwise aclocal would emit many "Use of uninitialized value $1"
-dnl warnings.
-m4_define([gl_iconv_AC_DEFUN],
- m4_version_prereq([2.64],
- [[AC_DEFUN_ONCE(
- [$1], [$2])]],
- [[AC_DEFUN(
- [$1], [$2])]]))
-gl_iconv_AC_DEFUN([AM_ICONV],
-[
- AM_ICONV_LINK
- if test "$am_cv_func_iconv" = yes; then
- AC_MSG_CHECKING([for iconv declaration])
- AC_CACHE_VAL([am_cv_proto_iconv], [
- AC_TRY_COMPILE([
-#include <stdlib.h>
-#include <iconv.h>
-extern
-#ifdef __cplusplus
-"C"
-#endif
-#if defined(__STDC__) || defined(__cplusplus)
-size_t iconv (iconv_t cd, char * *inbuf, size_t *inbytesleft, char * *outbuf, size_t
*outbytesleft);
-#else
-size_t iconv();
-#endif
-], [], [am_cv_proto_iconv_arg1=""],
[am_cv_proto_iconv_arg1="const"])
- am_cv_proto_iconv="extern size_t iconv (iconv_t cd, $am_cv_proto_iconv_arg1
char * *inbuf, size_t *inbytesleft, char * *outbuf, size_t *outbytesleft);"])
- am_cv_proto_iconv=`echo "[$]am_cv_proto_iconv" | tr -s ' ' | sed -e
's/( /(/'`
- AC_MSG_RESULT([
- $am_cv_proto_iconv])
- AC_DEFINE_UNQUOTED([ICONV_CONST], [$am_cv_proto_iconv_arg1],
- [Define as const if the declaration of iconv() needs const.])
- fi
-])
diff --git a/plugins/kimchi/m4/intlmacosx.m4 b/plugins/kimchi/m4/intlmacosx.m4
deleted file mode 100644
index dd91025..0000000
--- a/plugins/kimchi/m4/intlmacosx.m4
+++ /dev/null
@@ -1,51 +0,0 @@
-# intlmacosx.m4 serial 3 (gettext-0.18)
-dnl Copyright (C) 2004-2010 Free Software Foundation, Inc.
-dnl This file is free software; the Free Software Foundation
-dnl gives unlimited permission to copy and/or distribute it,
-dnl with or without modifications, as long as this notice is preserved.
-dnl
-dnl This file can can be used in projects which are not available under
-dnl the GNU General Public License or the GNU Library General Public
-dnl License but which still want to provide support for the GNU gettext
-dnl functionality.
-dnl Please note that the actual code of the GNU gettext library is covered
-dnl by the GNU Library General Public License, and the rest of the GNU
-dnl gettext package package is covered by the GNU General Public License.
-dnl They are *not* in the public domain.
-
-dnl Checks for special options needed on MacOS X.
-dnl Defines INTL_MACOSX_LIBS.
-AC_DEFUN([gt_INTL_MACOSX],
-[
- dnl Check for API introduced in MacOS X 10.2.
- AC_CACHE_CHECK([for CFPreferencesCopyAppValue],
- [gt_cv_func_CFPreferencesCopyAppValue],
- [gt_save_LIBS="$LIBS"
- LIBS="$LIBS -Wl,-framework -Wl,CoreFoundation"
- AC_TRY_LINK([#include <CoreFoundation/CFPreferences.h>],
- [CFPreferencesCopyAppValue(NULL, NULL)],
- [gt_cv_func_CFPreferencesCopyAppValue=yes],
- [gt_cv_func_CFPreferencesCopyAppValue=no])
- LIBS="$gt_save_LIBS"])
- if test $gt_cv_func_CFPreferencesCopyAppValue = yes; then
- AC_DEFINE([HAVE_CFPREFERENCESCOPYAPPVALUE], [1],
- [Define to 1 if you have the MacOS X function CFPreferencesCopyAppValue in the
CoreFoundation framework.])
- fi
- dnl Check for API introduced in MacOS X 10.3.
- AC_CACHE_CHECK([for CFLocaleCopyCurrent], [gt_cv_func_CFLocaleCopyCurrent],
- [gt_save_LIBS="$LIBS"
- LIBS="$LIBS -Wl,-framework -Wl,CoreFoundation"
- AC_TRY_LINK([#include <CoreFoundation/CFLocale.h>], [CFLocaleCopyCurrent();],
- [gt_cv_func_CFLocaleCopyCurrent=yes],
- [gt_cv_func_CFLocaleCopyCurrent=no])
- LIBS="$gt_save_LIBS"])
- if test $gt_cv_func_CFLocaleCopyCurrent = yes; then
- AC_DEFINE([HAVE_CFLOCALECOPYCURRENT], [1],
- [Define to 1 if you have the MacOS X function CFLocaleCopyCurrent in the
CoreFoundation framework.])
- fi
- INTL_MACOSX_LIBS=
- if test $gt_cv_func_CFPreferencesCopyAppValue = yes || test
$gt_cv_func_CFLocaleCopyCurrent = yes; then
- INTL_MACOSX_LIBS="-Wl,-framework -Wl,CoreFoundation"
- fi
- AC_SUBST([INTL_MACOSX_LIBS])
-])
diff --git a/plugins/kimchi/m4/lib-ld.m4 b/plugins/kimchi/m4/lib-ld.m4
deleted file mode 100644
index ebb3052..0000000
--- a/plugins/kimchi/m4/lib-ld.m4
+++ /dev/null
@@ -1,110 +0,0 @@
-# lib-ld.m4 serial 4 (gettext-0.18)
-dnl Copyright (C) 1996-2003, 2009-2010 Free Software Foundation, Inc.
-dnl This file is free software; the Free Software Foundation
-dnl gives unlimited permission to copy and/or distribute it,
-dnl with or without modifications, as long as this notice is preserved.
-
-dnl Subroutines of libtool.m4,
-dnl with replacements s/AC_/AC_LIB/ and s/lt_cv/acl_cv/ to avoid collision
-dnl with libtool.m4.
-
-dnl From libtool-1.4. Sets the variable with_gnu_ld to yes or no.
-AC_DEFUN([AC_LIB_PROG_LD_GNU],
-[AC_CACHE_CHECK([if the linker ($LD) is GNU ld], [acl_cv_prog_gnu_ld],
-[# I'd rather use --version here, but apparently some GNU ld's only accept -v.
-case `$LD -v 2>&1 </dev/null` in
-*GNU* | *'with BFD'*)
- acl_cv_prog_gnu_ld=yes ;;
-*)
- acl_cv_prog_gnu_ld=no ;;
-esac])
-with_gnu_ld=$acl_cv_prog_gnu_ld
-])
-
-dnl From libtool-1.4. Sets the variable LD.
-AC_DEFUN([AC_LIB_PROG_LD],
-[AC_ARG_WITH([gnu-ld],
-[ --with-gnu-ld assume the C compiler uses GNU ld [default=no]],
-test "$withval" = no || with_gnu_ld=yes, with_gnu_ld=no)
-AC_REQUIRE([AC_PROG_CC])dnl
-AC_REQUIRE([AC_CANONICAL_HOST])dnl
-# Prepare PATH_SEPARATOR.
-# The user is always right.
-if test "${PATH_SEPARATOR+set}" != set; then
- echo "#! /bin/sh" >conf$$.sh
- echo "exit 0" >>conf$$.sh
- chmod +x conf$$.sh
- if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then
- PATH_SEPARATOR=';'
- else
- PATH_SEPARATOR=:
- fi
- rm -f conf$$.sh
-fi
-ac_prog=ld
-if test "$GCC" = yes; then
- # Check if gcc -print-prog-name=ld gives a path.
- AC_MSG_CHECKING([for ld used by GCC])
- case $host in
- *-*-mingw*)
- # gcc leaves a trailing carriage return which upsets mingw
- ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;;
- *)
- ac_prog=`($CC -print-prog-name=ld) 2>&5` ;;
- esac
- case $ac_prog in
- # Accept absolute paths.
- [[\\/]* | [A-Za-z]:[\\/]*)]
- [re_direlt='/[^/][^/]*/\.\./']
- # Canonicalize the path of ld
- ac_prog=`echo $ac_prog| sed 's%\\\\%/%g'`
- while echo $ac_prog | grep "$re_direlt" > /dev/null 2>&1; do
- ac_prog=`echo $ac_prog| sed "s%$re_direlt%/%"`
- done
- test -z "$LD" && LD="$ac_prog"
- ;;
- "")
- # If it fails, then pretend we aren't using GCC.
- ac_prog=ld
- ;;
- *)
- # If it is relative, then search for the first ld in PATH.
- with_gnu_ld=unknown
- ;;
- esac
-elif test "$with_gnu_ld" = yes; then
- AC_MSG_CHECKING([for GNU ld])
-else
- AC_MSG_CHECKING([for non-GNU ld])
-fi
-AC_CACHE_VAL([acl_cv_path_LD],
-[if test -z "$LD"; then
- IFS="${IFS= }"; ac_save_ifs="$IFS";
IFS="${IFS}${PATH_SEPARATOR-:}"
- for ac_dir in $PATH; do
- test -z "$ac_dir" && ac_dir=.
- if test -f "$ac_dir/$ac_prog" || test -f
"$ac_dir/$ac_prog$ac_exeext"; then
- acl_cv_path_LD="$ac_dir/$ac_prog"
- # Check to see if the program is GNU ld. I'd rather use --version,
- # but apparently some GNU ld's only accept -v.
- # Break only if it was the GNU/non-GNU ld that we prefer.
- case `"$acl_cv_path_LD" -v 2>&1 < /dev/null` in
- *GNU* | *'with BFD'*)
- test "$with_gnu_ld" != no && break ;;
- *)
- test "$with_gnu_ld" != yes && break ;;
- esac
- fi
- done
- IFS="$ac_save_ifs"
-else
- acl_cv_path_LD="$LD" # Let the user override the test with a path.
-fi])
-LD="$acl_cv_path_LD"
-if test -n "$LD"; then
- AC_MSG_RESULT([$LD])
-else
- AC_MSG_RESULT([no])
-fi
-test -z "$LD" && AC_MSG_ERROR([no acceptable ld found in \$PATH])
-AC_LIB_PROG_LD_GNU
-])
diff --git a/plugins/kimchi/m4/lib-link.m4 b/plugins/kimchi/m4/lib-link.m4
deleted file mode 100644
index c73bd8e..0000000
--- a/plugins/kimchi/m4/lib-link.m4
+++ /dev/null
@@ -1,774 +0,0 @@
-# lib-link.m4 serial 21 (gettext-0.18)
-dnl Copyright (C) 2001-2010 Free Software Foundation, Inc.
-dnl This file is free software; the Free Software Foundation
-dnl gives unlimited permission to copy and/or distribute it,
-dnl with or without modifications, as long as this notice is preserved.
-
-dnl From Bruno Haible.
-
-AC_PREREQ([2.54])
-
-dnl AC_LIB_LINKFLAGS(name [, dependencies]) searches for libname and
-dnl the libraries corresponding to explicit and implicit dependencies.
-dnl Sets and AC_SUBSTs the LIB${NAME} and LTLIB${NAME} variables and
-dnl augments the CPPFLAGS variable.
-dnl Sets and AC_SUBSTs the LIB${NAME}_PREFIX variable to nonempty if libname
-dnl was found in ${LIB${NAME}_PREFIX}/$acl_libdirstem.
-AC_DEFUN([AC_LIB_LINKFLAGS],
-[
- AC_REQUIRE([AC_LIB_PREPARE_PREFIX])
- AC_REQUIRE([AC_LIB_RPATH])
- pushdef([Name],[translit([$1],[./-], [___])])
- pushdef([NAME],[translit([$1],[abcdefghijklmnopqrstuvwxyz./-],
- [ABCDEFGHIJKLMNOPQRSTUVWXYZ___])])
- AC_CACHE_CHECK([how to link with lib[]$1], [ac_cv_lib[]Name[]_libs], [
- AC_LIB_LINKFLAGS_BODY([$1], [$2])
- ac_cv_lib[]Name[]_libs="$LIB[]NAME"
- ac_cv_lib[]Name[]_ltlibs="$LTLIB[]NAME"
- ac_cv_lib[]Name[]_cppflags="$INC[]NAME"
- ac_cv_lib[]Name[]_prefix="$LIB[]NAME[]_PREFIX"
- ])
- LIB[]NAME="$ac_cv_lib[]Name[]_libs"
- LTLIB[]NAME="$ac_cv_lib[]Name[]_ltlibs"
- INC[]NAME="$ac_cv_lib[]Name[]_cppflags"
- LIB[]NAME[]_PREFIX="$ac_cv_lib[]Name[]_prefix"
- AC_LIB_APPENDTOVAR([CPPFLAGS], [$INC]NAME)
- AC_SUBST([LIB]NAME)
- AC_SUBST([LTLIB]NAME)
- AC_SUBST([LIB]NAME[_PREFIX])
- dnl Also set HAVE_LIB[]NAME so that AC_LIB_HAVE_LINKFLAGS can reuse the
- dnl results of this search when this library appears as a dependency.
- HAVE_LIB[]NAME=yes
- popdef([NAME])
- popdef([Name])
-])
-
-dnl AC_LIB_HAVE_LINKFLAGS(name, dependencies, includes, testcode, [missing-message])
-dnl searches for libname and the libraries corresponding to explicit and
-dnl implicit dependencies, together with the specified include files and
-dnl the ability to compile and link the specified testcode. The missing-message
-dnl defaults to 'no' and may contain additional hints for the user.
-dnl If found, it sets and AC_SUBSTs HAVE_LIB${NAME}=yes and the LIB${NAME}
-dnl and LTLIB${NAME} variables and augments the CPPFLAGS variable, and
-dnl #defines HAVE_LIB${NAME} to 1. Otherwise, it sets and AC_SUBSTs
-dnl HAVE_LIB${NAME}=no and LIB${NAME} and LTLIB${NAME} to empty.
-dnl Sets and AC_SUBSTs the LIB${NAME}_PREFIX variable to nonempty if libname
-dnl was found in ${LIB${NAME}_PREFIX}/$acl_libdirstem.
-AC_DEFUN([AC_LIB_HAVE_LINKFLAGS],
-[
- AC_REQUIRE([AC_LIB_PREPARE_PREFIX])
- AC_REQUIRE([AC_LIB_RPATH])
- pushdef([Name],[translit([$1],[./-], [___])])
- pushdef([NAME],[translit([$1],[abcdefghijklmnopqrstuvwxyz./-],
- [ABCDEFGHIJKLMNOPQRSTUVWXYZ___])])
-
- dnl Search for lib[]Name and define LIB[]NAME, LTLIB[]NAME and INC[]NAME
- dnl accordingly.
- AC_LIB_LINKFLAGS_BODY([$1], [$2])
-
- dnl Add $INC[]NAME to CPPFLAGS before performing the following checks,
- dnl because if the user has installed lib[]Name and not disabled its use
- dnl via --without-lib[]Name-prefix, he wants to use it.
- ac_save_CPPFLAGS="$CPPFLAGS"
- AC_LIB_APPENDTOVAR([CPPFLAGS], [$INC]NAME)
-
- AC_CACHE_CHECK([for lib[]$1], [ac_cv_lib[]Name], [
- ac_save_LIBS="$LIBS"
- dnl If $LIB[]NAME contains some -l options, add it to the end of LIBS,
- dnl because these -l options might require -L options that are present in
- dnl LIBS. -l options benefit only from the -L options listed before it.
- dnl Otherwise, add it to the front of LIBS, because it may be a static
- dnl library that depends on another static library that is present in LIBS.
- dnl Static libraries benefit only from the static libraries listed after
- dnl it.
- case " $LIB[]NAME" in
- *" -l"*) LIBS="$LIBS $LIB[]NAME" ;;
- *) LIBS="$LIB[]NAME $LIBS" ;;
- esac
- AC_TRY_LINK([$3], [$4],
- [ac_cv_lib[]Name=yes],
- [ac_cv_lib[]Name='m4_if([$5], [], [no], [[$5]])'])
- LIBS="$ac_save_LIBS"
- ])
- if test "$ac_cv_lib[]Name" = yes; then
- HAVE_LIB[]NAME=yes
- AC_DEFINE([HAVE_LIB]NAME, 1, [Define if you have the lib][$1 library.])
- AC_MSG_CHECKING([how to link with lib[]$1])
- AC_MSG_RESULT([$LIB[]NAME])
- else
- HAVE_LIB[]NAME=no
- dnl If $LIB[]NAME didn't lead to a usable library, we don't need
- dnl $INC[]NAME either.
- CPPFLAGS="$ac_save_CPPFLAGS"
- LIB[]NAME=
- LTLIB[]NAME=
- LIB[]NAME[]_PREFIX=
- fi
- AC_SUBST([HAVE_LIB]NAME)
- AC_SUBST([LIB]NAME)
- AC_SUBST([LTLIB]NAME)
- AC_SUBST([LIB]NAME[_PREFIX])
- popdef([NAME])
- popdef([Name])
-])
-
-dnl Determine the platform dependent parameters needed to use rpath:
-dnl acl_libext,
-dnl acl_shlibext,
-dnl acl_hardcode_libdir_flag_spec,
-dnl acl_hardcode_libdir_separator,
-dnl acl_hardcode_direct,
-dnl acl_hardcode_minus_L.
-AC_DEFUN([AC_LIB_RPATH],
-[
- dnl Tell automake >= 1.10 to complain if config.rpath is missing.
- m4_ifdef([AC_REQUIRE_AUX_FILE], [AC_REQUIRE_AUX_FILE([config.rpath])])
- AC_REQUIRE([AC_PROG_CC]) dnl we use $CC, $GCC, $LDFLAGS
- AC_REQUIRE([AC_LIB_PROG_LD]) dnl we use $LD, $with_gnu_ld
- AC_REQUIRE([AC_CANONICAL_HOST]) dnl we use $host
- AC_REQUIRE([AC_CONFIG_AUX_DIR_DEFAULT]) dnl we use $ac_aux_dir
- AC_CACHE_CHECK([for shared library run path origin], [acl_cv_rpath], [
- CC="$CC" GCC="$GCC" LDFLAGS="$LDFLAGS"
LD="$LD" with_gnu_ld="$with_gnu_ld" \
- ${CONFIG_SHELL-/bin/sh} "$ac_aux_dir/config.rpath" "$host" >
conftest.sh
- . ./conftest.sh
- rm -f ./conftest.sh
- acl_cv_rpath=done
- ])
- wl="$acl_cv_wl"
- acl_libext="$acl_cv_libext"
- acl_shlibext="$acl_cv_shlibext"
- acl_libname_spec="$acl_cv_libname_spec"
- acl_library_names_spec="$acl_cv_library_names_spec"
- acl_hardcode_libdir_flag_spec="$acl_cv_hardcode_libdir_flag_spec"
- acl_hardcode_libdir_separator="$acl_cv_hardcode_libdir_separator"
- acl_hardcode_direct="$acl_cv_hardcode_direct"
- acl_hardcode_minus_L="$acl_cv_hardcode_minus_L"
- dnl Determine whether the user wants rpath handling at all.
- AC_ARG_ENABLE([rpath],
- [ --disable-rpath do not hardcode runtime library paths],
- :, enable_rpath=yes)
-])
-
-dnl AC_LIB_FROMPACKAGE(name, package)
-dnl declares that libname comes from the given package. The configure file
-dnl will then not have a --with-libname-prefix option but a
-dnl --with-package-prefix option. Several libraries can come from the same
-dnl package. This declaration must occur before an AC_LIB_LINKFLAGS or similar
-dnl macro call that searches for libname.
-AC_DEFUN([AC_LIB_FROMPACKAGE],
-[
- pushdef([NAME],[translit([$1],[abcdefghijklmnopqrstuvwxyz./-],
- [ABCDEFGHIJKLMNOPQRSTUVWXYZ___])])
- define([acl_frompackage_]NAME, [$2])
- popdef([NAME])
- pushdef([PACK],[$2])
- pushdef([PACKUP],[translit(PACK,[abcdefghijklmnopqrstuvwxyz./-],
- [ABCDEFGHIJKLMNOPQRSTUVWXYZ___])])
- define([acl_libsinpackage_]PACKUP,
- m4_ifdef([acl_libsinpackage_]PACKUP, [acl_libsinpackage_]PACKUP[[, ]],)[lib$1])
- popdef([PACKUP])
- popdef([PACK])
-])
-
-dnl AC_LIB_LINKFLAGS_BODY(name [, dependencies]) searches for libname and
-dnl the libraries corresponding to explicit and implicit dependencies.
-dnl Sets the LIB${NAME}, LTLIB${NAME} and INC${NAME} variables.
-dnl Also, sets the LIB${NAME}_PREFIX variable to nonempty if libname was found
-dnl in ${LIB${NAME}_PREFIX}/$acl_libdirstem.
-AC_DEFUN([AC_LIB_LINKFLAGS_BODY],
-[
- AC_REQUIRE([AC_LIB_PREPARE_MULTILIB])
- pushdef([NAME],[translit([$1],[abcdefghijklmnopqrstuvwxyz./-],
- [ABCDEFGHIJKLMNOPQRSTUVWXYZ___])])
- pushdef([PACK],[m4_ifdef([acl_frompackage_]NAME, [acl_frompackage_]NAME, lib[$1])])
- pushdef([PACKUP],[translit(PACK,[abcdefghijklmnopqrstuvwxyz./-],
- [ABCDEFGHIJKLMNOPQRSTUVWXYZ___])])
- pushdef([PACKLIBS],[m4_ifdef([acl_frompackage_]NAME, [acl_libsinpackage_]PACKUP,
lib[$1])])
- dnl Autoconf >= 2.61 supports dots in --with options.
-
pushdef([P_A_C_K],[m4_if(m4_version_compare(m4_defn([m4_PACKAGE_VERSION]),[2.61]),[-1],[translit(PACK,[.],[_])],PACK)])
- dnl By default, look in $includedir and $libdir.
- use_additional=yes
- AC_LIB_WITH_FINAL_PREFIX([
- eval additional_includedir=\"$includedir\"
- eval additional_libdir=\"$libdir\"
- ])
- AC_ARG_WITH(P_A_C_K[-prefix],
-[[ --with-]]P_A_C_K[[-prefix[=DIR] search for ]PACKLIBS[ in DIR/include and DIR/lib
- --without-]]P_A_C_K[[-prefix don't search for ]PACKLIBS[ in includedir and
libdir]],
-[
- if test "X$withval" = "Xno"; then
- use_additional=no
- else
- if test "X$withval" = "X"; then
- AC_LIB_WITH_FINAL_PREFIX([
- eval additional_includedir=\"$includedir\"
- eval additional_libdir=\"$libdir\"
- ])
- else
- additional_includedir="$withval/include"
- additional_libdir="$withval/$acl_libdirstem"
- if test "$acl_libdirstem2" != "$acl_libdirstem" \
- && ! test -d "$withval/$acl_libdirstem"; then
- additional_libdir="$withval/$acl_libdirstem2"
- fi
- fi
- fi
-])
- dnl Search the library and its dependencies in $additional_libdir and
- dnl $LDFLAGS. Using breadth-first-seach.
- LIB[]NAME=
- LTLIB[]NAME=
- INC[]NAME=
- LIB[]NAME[]_PREFIX=
- dnl HAVE_LIB${NAME} is an indicator that LIB${NAME}, LTLIB${NAME} have been
- dnl computed. So it has to be reset here.
- HAVE_LIB[]NAME=
- rpathdirs=
- ltrpathdirs=
- names_already_handled=
- names_next_round='$1 $2'
- while test -n "$names_next_round"; do
- names_this_round="$names_next_round"
- names_next_round=
- for name in $names_this_round; do
- already_handled=
- for n in $names_already_handled; do
- if test "$n" = "$name"; then
- already_handled=yes
- break
- fi
- done
- if test -z "$already_handled"; then
- names_already_handled="$names_already_handled $name"
- dnl See if it was already located by an earlier AC_LIB_LINKFLAGS
- dnl or AC_LIB_HAVE_LINKFLAGS call.
- uppername=`echo "$name" | sed -e
'y|abcdefghijklmnopqrstuvwxyz./-|ABCDEFGHIJKLMNOPQRSTUVWXYZ___|'`
- eval value=\"\$HAVE_LIB$uppername\"
- if test -n "$value"; then
- if test "$value" = yes; then
- eval value=\"\$LIB$uppername\"
- test -z "$value" || LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+
}$value"
- eval value=\"\$LTLIB$uppername\"
- test -z "$value" || LTLIB[]NAME="${LTLIB[]NAME}${LTLIB[]NAME:+
}$value"
- else
- dnl An earlier call to AC_LIB_HAVE_LINKFLAGS has determined
- dnl that this library doesn't exist. So just drop it.
- :
- fi
- else
- dnl Search the library lib$name in $additional_libdir and $LDFLAGS
- dnl and the already constructed $LIBNAME/$LTLIBNAME.
- found_dir=
- found_la=
- found_so=
- found_a=
- eval libname=\"$acl_libname_spec\" # typically: libname=lib$name
- if test -n "$acl_shlibext"; then
- shrext=".$acl_shlibext" # typically: shrext=.so
- else
- shrext=
- fi
- if test $use_additional = yes; then
- dir="$additional_libdir"
- dnl The same code as in the loop below:
- dnl First look for a shared library.
- if test -n "$acl_shlibext"; then
- if test -f "$dir/$libname$shrext"; then
- found_dir="$dir"
- found_so="$dir/$libname$shrext"
- else
- if test "$acl_library_names_spec" =
'$libname$shrext$versuffix'; then
- ver=`(cd "$dir" && \
- for f in "$libname$shrext".*; do echo "$f";
done \
- | sed -e "s,^$libname$shrext\\\\.,," \
- | sort -t '.' -n -r -k1,1 -k2,2 -k3,3 -k4,4 -k5,5 \
- | sed 1q ) 2>/dev/null`
- if test -n "$ver" && test -f
"$dir/$libname$shrext.$ver"; then
- found_dir="$dir"
- found_so="$dir/$libname$shrext.$ver"
- fi
- else
- eval library_names=\"$acl_library_names_spec\"
- for f in $library_names; do
- if test -f "$dir/$f"; then
- found_dir="$dir"
- found_so="$dir/$f"
- break
- fi
- done
- fi
- fi
- fi
- dnl Then look for a static library.
- if test "X$found_dir" = "X"; then
- if test -f "$dir/$libname.$acl_libext"; then
- found_dir="$dir"
- found_a="$dir/$libname.$acl_libext"
- fi
- fi
- if test "X$found_dir" != "X"; then
- if test -f "$dir/$libname.la"; then
- found_la="$dir/$libname.la"
- fi
- fi
- fi
- if test "X$found_dir" = "X"; then
- for x in $LDFLAGS $LTLIB[]NAME; do
- AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"])
- case "$x" in
- -L*)
- dir=`echo "X$x" | sed -e 's/^X-L//'`
- dnl First look for a shared library.
- if test -n "$acl_shlibext"; then
- if test -f "$dir/$libname$shrext"; then
- found_dir="$dir"
- found_so="$dir/$libname$shrext"
- else
- if test "$acl_library_names_spec" =
'$libname$shrext$versuffix'; then
- ver=`(cd "$dir" && \
- for f in "$libname$shrext".*; do echo
"$f"; done \
- | sed -e "s,^$libname$shrext\\\\.,," \
- | sort -t '.' -n -r -k1,1 -k2,2 -k3,3 -k4,4 -k5,5
\
- | sed 1q ) 2>/dev/null`
- if test -n "$ver" && test -f
"$dir/$libname$shrext.$ver"; then
- found_dir="$dir"
- found_so="$dir/$libname$shrext.$ver"
- fi
- else
- eval library_names=\"$acl_library_names_spec\"
- for f in $library_names; do
- if test -f "$dir/$f"; then
- found_dir="$dir"
- found_so="$dir/$f"
- break
- fi
- done
- fi
- fi
- fi
- dnl Then look for a static library.
- if test "X$found_dir" = "X"; then
- if test -f "$dir/$libname.$acl_libext"; then
- found_dir="$dir"
- found_a="$dir/$libname.$acl_libext"
- fi
- fi
- if test "X$found_dir" != "X"; then
- if test -f "$dir/$libname.la"; then
- found_la="$dir/$libname.la"
- fi
- fi
- ;;
- esac
- if test "X$found_dir" != "X"; then
- break
- fi
- done
- fi
- if test "X$found_dir" != "X"; then
- dnl Found the library.
- LTLIB[]NAME="${LTLIB[]NAME}${LTLIB[]NAME:+ }-L$found_dir -l$name"
- if test "X$found_so" != "X"; then
- dnl Linking with a shared library. We attempt to hardcode its
- dnl directory into the executable's runpath, unless it's the
- dnl standard /usr/lib.
- if test "$enable_rpath" = no \
- || test "X$found_dir" = "X/usr/$acl_libdirstem" \
- || test "X$found_dir" = "X/usr/$acl_libdirstem2";
then
- dnl No hardcoding is needed.
- LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$found_so"
- else
- dnl Use an explicit option to hardcode DIR into the resulting
- dnl binary.
- dnl Potentially add DIR to ltrpathdirs.
- dnl The ltrpathdirs will be appended to $LTLIBNAME at the end.
- haveit=
- for x in $ltrpathdirs; do
- if test "X$x" = "X$found_dir"; then
- haveit=yes
- break
- fi
- done
- if test -z "$haveit"; then
- ltrpathdirs="$ltrpathdirs $found_dir"
- fi
- dnl The hardcoding into $LIBNAME is system dependent.
- if test "$acl_hardcode_direct" = yes; then
- dnl Using DIR/libNAME.so during linking hardcodes DIR into the
- dnl resulting binary.
- LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$found_so"
- else
- if test -n "$acl_hardcode_libdir_flag_spec" && test
"$acl_hardcode_minus_L" = no; then
- dnl Use an explicit option to hardcode DIR into the resulting
- dnl binary.
- LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$found_so"
- dnl Potentially add DIR to rpathdirs.
- dnl The rpathdirs will be appended to $LIBNAME at the end.
- haveit=
- for x in $rpathdirs; do
- if test "X$x" = "X$found_dir"; then
- haveit=yes
- break
- fi
- done
- if test -z "$haveit"; then
- rpathdirs="$rpathdirs $found_dir"
- fi
- else
- dnl Rely on "-L$found_dir".
- dnl But don't add it if it's already contained in the
LDFLAGS
- dnl or the already constructed $LIBNAME
- haveit=
- for x in $LDFLAGS $LIB[]NAME; do
- AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"])
- if test "X$x" = "X-L$found_dir"; then
- haveit=yes
- break
- fi
- done
- if test -z "$haveit"; then
- LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }-L$found_dir"
- fi
- if test "$acl_hardcode_minus_L" != no; then
- dnl FIXME: Not sure whether we should use
- dnl "-L$found_dir -l$name" or "-L$found_dir
$found_so"
- dnl here.
- LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$found_so"
- else
- dnl We cannot use $acl_hardcode_runpath_var and LD_RUN_PATH
- dnl here, because this doesn't fit in flags passed to the
- dnl compiler. So give up. No hardcoding. This affects only
- dnl very old systems.
- dnl FIXME: Not sure whether we should use
- dnl "-L$found_dir -l$name" or "-L$found_dir
$found_so"
- dnl here.
- LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }-l$name"
- fi
- fi
- fi
- fi
- else
- if test "X$found_a" != "X"; then
- dnl Linking with a static library.
- LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$found_a"
- else
- dnl We shouldn't come here, but anyway it's good to have a
- dnl fallback.
- LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }-L$found_dir -l$name"
- fi
- fi
- dnl Assume the include files are nearby.
- additional_includedir=
- case "$found_dir" in
- */$acl_libdirstem | */$acl_libdirstem/)
- basedir=`echo "X$found_dir" | sed -e 's,^X,,' -e
"s,/$acl_libdirstem/"'*$,,'`
- if test "$name" = '$1'; then
- LIB[]NAME[]_PREFIX="$basedir"
- fi
- additional_includedir="$basedir/include"
- ;;
- */$acl_libdirstem2 | */$acl_libdirstem2/)
- basedir=`echo "X$found_dir" | sed -e 's,^X,,' -e
"s,/$acl_libdirstem2/"'*$,,'`
- if test "$name" = '$1'; then
- LIB[]NAME[]_PREFIX="$basedir"
- fi
- additional_includedir="$basedir/include"
- ;;
- esac
- if test "X$additional_includedir" != "X"; then
- dnl Potentially add $additional_includedir to $INCNAME.
- dnl But don't add it
- dnl 1. if it's the standard /usr/include,
- dnl 2. if it's /usr/local/include and we are using GCC on Linux,
- dnl 3. if it's already present in $CPPFLAGS or the already
- dnl constructed $INCNAME,
- dnl 4. if it doesn't exist as a directory.
- if test "X$additional_includedir" != "X/usr/include";
then
- haveit=
- if test "X$additional_includedir" =
"X/usr/local/include"; then
- if test -n "$GCC"; then
- case $host_os in
- linux* | gnu* | k*bsd*-gnu) haveit=yes;;
- esac
- fi
- fi
- if test -z "$haveit"; then
- for x in $CPPFLAGS $INC[]NAME; do
- AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"])
- if test "X$x" = "X-I$additional_includedir";
then
- haveit=yes
- break
- fi
- done
- if test -z "$haveit"; then
- if test -d "$additional_includedir"; then
- dnl Really add $additional_includedir to $INCNAME.
- INC[]NAME="${INC[]NAME}${INC[]NAME:+
}-I$additional_includedir"
- fi
- fi
- fi
- fi
- fi
- dnl Look for dependencies.
- if test -n "$found_la"; then
- dnl Read the .la file. It defines the variables
- dnl dlname, library_names, old_library, dependency_libs, current,
- dnl age, revision, installed, dlopen, dlpreopen, libdir.
- save_libdir="$libdir"
- case "$found_la" in
- */* | *\\*) . "$found_la" ;;
- *) . "./$found_la" ;;
- esac
- libdir="$save_libdir"
- dnl We use only dependency_libs.
- for dep in $dependency_libs; do
- case "$dep" in
- -L*)
- additional_libdir=`echo "X$dep" | sed -e
's/^X-L//'`
- dnl Potentially add $additional_libdir to $LIBNAME and $LTLIBNAME.
- dnl But don't add it
- dnl 1. if it's the standard /usr/lib,
- dnl 2. if it's /usr/local/lib and we are using GCC on Linux,
- dnl 3. if it's already present in $LDFLAGS or the already
- dnl constructed $LIBNAME,
- dnl 4. if it doesn't exist as a directory.
- if test "X$additional_libdir" !=
"X/usr/$acl_libdirstem" \
- && test "X$additional_libdir" !=
"X/usr/$acl_libdirstem2"; then
- haveit=
- if test "X$additional_libdir" =
"X/usr/local/$acl_libdirstem" \
- || test "X$additional_libdir" =
"X/usr/local/$acl_libdirstem2"; then
- if test -n "$GCC"; then
- case $host_os in
- linux* | gnu* | k*bsd*-gnu) haveit=yes;;
- esac
- fi
- fi
- if test -z "$haveit"; then
- haveit=
- for x in $LDFLAGS $LIB[]NAME; do
- AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"])
- if test "X$x" = "X-L$additional_libdir";
then
- haveit=yes
- break
- fi
- done
- if test -z "$haveit"; then
- if test -d "$additional_libdir"; then
- dnl Really add $additional_libdir to $LIBNAME.
- LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+
}-L$additional_libdir"
- fi
- fi
- haveit=
- for x in $LDFLAGS $LTLIB[]NAME; do
- AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"])
- if test "X$x" = "X-L$additional_libdir";
then
- haveit=yes
- break
- fi
- done
- if test -z "$haveit"; then
- if test -d "$additional_libdir"; then
- dnl Really add $additional_libdir to $LTLIBNAME.
- LTLIB[]NAME="${LTLIB[]NAME}${LTLIB[]NAME:+
}-L$additional_libdir"
- fi
- fi
- fi
- fi
- ;;
- -R*)
- dir=`echo "X$dep" | sed -e 's/^X-R//'`
- if test "$enable_rpath" != no; then
- dnl Potentially add DIR to rpathdirs.
- dnl The rpathdirs will be appended to $LIBNAME at the end.
- haveit=
- for x in $rpathdirs; do
- if test "X$x" = "X$dir"; then
- haveit=yes
- break
- fi
- done
- if test -z "$haveit"; then
- rpathdirs="$rpathdirs $dir"
- fi
- dnl Potentially add DIR to ltrpathdirs.
- dnl The ltrpathdirs will be appended to $LTLIBNAME at the end.
- haveit=
- for x in $ltrpathdirs; do
- if test "X$x" = "X$dir"; then
- haveit=yes
- break
- fi
- done
- if test -z "$haveit"; then
- ltrpathdirs="$ltrpathdirs $dir"
- fi
- fi
- ;;
- -l*)
- dnl Handle this in the next round.
- names_next_round="$names_next_round "`echo
"X$dep" | sed -e 's/^X-l//'`
- ;;
- *.la)
- dnl Handle this in the next round. Throw away the .la's
- dnl directory; it is already contained in a preceding -L
- dnl option.
- names_next_round="$names_next_round "`echo
"X$dep" | sed -e 's,^X.*/,,' -e 's,^lib,,' -e
's,\.la$,,'`
- ;;
- *)
- dnl Most likely an immediate library name.
- LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$dep"
- LTLIB[]NAME="${LTLIB[]NAME}${LTLIB[]NAME:+ }$dep"
- ;;
- esac
- done
- fi
- else
- dnl Didn't find the library; assume it is in the system directories
- dnl known to the linker and runtime loader. (All the system
- dnl directories known to the linker should also be known to the
- dnl runtime loader, otherwise the system is severely misconfigured.)
- LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }-l$name"
- LTLIB[]NAME="${LTLIB[]NAME}${LTLIB[]NAME:+ }-l$name"
- fi
- fi
- fi
- done
- done
- if test "X$rpathdirs" != "X"; then
- if test -n "$acl_hardcode_libdir_separator"; then
- dnl Weird platform: only the last -rpath option counts, the user must
- dnl pass all path elements in one option. We can arrange that for a
- dnl single library, but not when more than one $LIBNAMEs are used.
- alldirs=
- for found_dir in $rpathdirs; do
-
alldirs="${alldirs}${alldirs:+$acl_hardcode_libdir_separator}$found_dir"
- done
- dnl Note: acl_hardcode_libdir_flag_spec uses $libdir and $wl.
- acl_save_libdir="$libdir"
- libdir="$alldirs"
- eval flag=\"$acl_hardcode_libdir_flag_spec\"
- libdir="$acl_save_libdir"
- LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$flag"
- else
- dnl The -rpath options are cumulative.
- for found_dir in $rpathdirs; do
- acl_save_libdir="$libdir"
- libdir="$found_dir"
- eval flag=\"$acl_hardcode_libdir_flag_spec\"
- libdir="$acl_save_libdir"
- LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$flag"
- done
- fi
- fi
- if test "X$ltrpathdirs" != "X"; then
- dnl When using libtool, the option that works for both libraries and
- dnl executables is -R. The -R options are cumulative.
- for found_dir in $ltrpathdirs; do
- LTLIB[]NAME="${LTLIB[]NAME}${LTLIB[]NAME:+ }-R$found_dir"
- done
- fi
- popdef([P_A_C_K])
- popdef([PACKLIBS])
- popdef([PACKUP])
- popdef([PACK])
- popdef([NAME])
-])
-
-dnl AC_LIB_APPENDTOVAR(VAR, CONTENTS) appends the elements of CONTENTS to VAR,
-dnl unless already present in VAR.
-dnl Works only for CPPFLAGS, not for LIB* variables because that sometimes
-dnl contains two or three consecutive elements that belong together.
-AC_DEFUN([AC_LIB_APPENDTOVAR],
-[
- for element in [$2]; do
- haveit=
- for x in $[$1]; do
- AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"])
- if test "X$x" = "X$element"; then
- haveit=yes
- break
- fi
- done
- if test -z "$haveit"; then
- [$1]="${[$1]}${[$1]:+ }$element"
- fi
- done
-])
-
-dnl For those cases where a variable contains several -L and -l options
-dnl referring to unknown libraries and directories, this macro determines the
-dnl necessary additional linker options for the runtime path.
-dnl AC_LIB_LINKFLAGS_FROM_LIBS([LDADDVAR], [LIBSVALUE], [USE-LIBTOOL])
-dnl sets LDADDVAR to linker options needed together with LIBSVALUE.
-dnl If USE-LIBTOOL evaluates to non-empty, linking with libtool is assumed,
-dnl otherwise linking without libtool is assumed.
-AC_DEFUN([AC_LIB_LINKFLAGS_FROM_LIBS],
-[
- AC_REQUIRE([AC_LIB_RPATH])
- AC_REQUIRE([AC_LIB_PREPARE_MULTILIB])
- $1=
- if test "$enable_rpath" != no; then
- if test -n "$acl_hardcode_libdir_flag_spec" && test
"$acl_hardcode_minus_L" = no; then
- dnl Use an explicit option to hardcode directories into the resulting
- dnl binary.
- rpathdirs=
- next=
- for opt in $2; do
- if test -n "$next"; then
- dir="$next"
- dnl No need to hardcode the standard /usr/lib.
- if test "X$dir" != "X/usr/$acl_libdirstem" \
- && test "X$dir" != "X/usr/$acl_libdirstem2";
then
- rpathdirs="$rpathdirs $dir"
- fi
- next=
- else
- case $opt in
- -L) next=yes ;;
- -L*) dir=`echo "X$opt" | sed -e 's,^X-L,,'`
- dnl No need to hardcode the standard /usr/lib.
- if test "X$dir" != "X/usr/$acl_libdirstem" \
- && test "X$dir" !=
"X/usr/$acl_libdirstem2"; then
- rpathdirs="$rpathdirs $dir"
- fi
- next= ;;
- *) next= ;;
- esac
- fi
- done
- if test "X$rpathdirs" != "X"; then
- if test -n ""$3""; then
- dnl libtool is used for linking. Use -R options.
- for dir in $rpathdirs; do
- $1="${$1}${$1:+ }-R$dir"
- done
- else
- dnl The linker is used for linking directly.
- if test -n "$acl_hardcode_libdir_separator"; then
- dnl Weird platform: only the last -rpath option counts, the user
- dnl must pass all path elements in one option.
- alldirs=
- for dir in $rpathdirs; do
-
alldirs="${alldirs}${alldirs:+$acl_hardcode_libdir_separator}$dir"
- done
- acl_save_libdir="$libdir"
- libdir="$alldirs"
- eval flag=\"$acl_hardcode_libdir_flag_spec\"
- libdir="$acl_save_libdir"
- $1="$flag"
- else
- dnl The -rpath options are cumulative.
- for dir in $rpathdirs; do
- acl_save_libdir="$libdir"
- libdir="$dir"
- eval flag=\"$acl_hardcode_libdir_flag_spec\"
- libdir="$acl_save_libdir"
- $1="${$1}${$1:+ }$flag"
- done
- fi
- fi
- fi
- fi
- fi
- AC_SUBST([$1])
-])
diff --git a/plugins/kimchi/m4/lib-prefix.m4 b/plugins/kimchi/m4/lib-prefix.m4
deleted file mode 100644
index 1601cea..0000000
--- a/plugins/kimchi/m4/lib-prefix.m4
+++ /dev/null
@@ -1,224 +0,0 @@
-# lib-prefix.m4 serial 7 (gettext-0.18)
-dnl Copyright (C) 2001-2005, 2008-2010 Free Software Foundation, Inc.
-dnl This file is free software; the Free Software Foundation
-dnl gives unlimited permission to copy and/or distribute it,
-dnl with or without modifications, as long as this notice is preserved.
-
-dnl From Bruno Haible.
-
-dnl AC_LIB_ARG_WITH is synonymous to AC_ARG_WITH in autoconf-2.13, and
-dnl similar to AC_ARG_WITH in autoconf 2.52...2.57 except that is doesn't
-dnl require excessive bracketing.
-ifdef([AC_HELP_STRING],
-[AC_DEFUN([AC_LIB_ARG_WITH], [AC_ARG_WITH([$1],[[$2]],[$3],[$4])])],
-[AC_DEFUN([AC_][LIB_ARG_WITH], [AC_ARG_WITH([$1],[$2],[$3],[$4])])])
-
-dnl AC_LIB_PREFIX adds to the CPPFLAGS and LDFLAGS the flags that are needed
-dnl to access previously installed libraries. The basic assumption is that
-dnl a user will want packages to use other packages he previously installed
-dnl with the same --prefix option.
-dnl This macro is not needed if only AC_LIB_LINKFLAGS is used to locate
-dnl libraries, but is otherwise very convenient.
-AC_DEFUN([AC_LIB_PREFIX],
-[
- AC_BEFORE([$0], [AC_LIB_LINKFLAGS])
- AC_REQUIRE([AC_PROG_CC])
- AC_REQUIRE([AC_CANONICAL_HOST])
- AC_REQUIRE([AC_LIB_PREPARE_MULTILIB])
- AC_REQUIRE([AC_LIB_PREPARE_PREFIX])
- dnl By default, look in $includedir and $libdir.
- use_additional=yes
- AC_LIB_WITH_FINAL_PREFIX([
- eval additional_includedir=\"$includedir\"
- eval additional_libdir=\"$libdir\"
- ])
- AC_LIB_ARG_WITH([lib-prefix],
-[ --with-lib-prefix[=DIR] search for libraries in DIR/include and DIR/lib
- --without-lib-prefix don't search for libraries in includedir and libdir],
-[
- if test "X$withval" = "Xno"; then
- use_additional=no
- else
- if test "X$withval" = "X"; then
- AC_LIB_WITH_FINAL_PREFIX([
- eval additional_includedir=\"$includedir\"
- eval additional_libdir=\"$libdir\"
- ])
- else
- additional_includedir="$withval/include"
- additional_libdir="$withval/$acl_libdirstem"
- fi
- fi
-])
- if test $use_additional = yes; then
- dnl Potentially add $additional_includedir to $CPPFLAGS.
- dnl But don't add it
- dnl 1. if it's the standard /usr/include,
- dnl 2. if it's already present in $CPPFLAGS,
- dnl 3. if it's /usr/local/include and we are using GCC on Linux,
- dnl 4. if it doesn't exist as a directory.
- if test "X$additional_includedir" != "X/usr/include"; then
- haveit=
- for x in $CPPFLAGS; do
- AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"])
- if test "X$x" = "X-I$additional_includedir"; then
- haveit=yes
- break
- fi
- done
- if test -z "$haveit"; then
- if test "X$additional_includedir" = "X/usr/local/include";
then
- if test -n "$GCC"; then
- case $host_os in
- linux* | gnu* | k*bsd*-gnu) haveit=yes;;
- esac
- fi
- fi
- if test -z "$haveit"; then
- if test -d "$additional_includedir"; then
- dnl Really add $additional_includedir to $CPPFLAGS.
- CPPFLAGS="${CPPFLAGS}${CPPFLAGS:+ }-I$additional_includedir"
- fi
- fi
- fi
- fi
- dnl Potentially add $additional_libdir to $LDFLAGS.
- dnl But don't add it
- dnl 1. if it's the standard /usr/lib,
- dnl 2. if it's already present in $LDFLAGS,
- dnl 3. if it's /usr/local/lib and we are using GCC on Linux,
- dnl 4. if it doesn't exist as a directory.
- if test "X$additional_libdir" != "X/usr/$acl_libdirstem"; then
- haveit=
- for x in $LDFLAGS; do
- AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"])
- if test "X$x" = "X-L$additional_libdir"; then
- haveit=yes
- break
- fi
- done
- if test -z "$haveit"; then
- if test "X$additional_libdir" =
"X/usr/local/$acl_libdirstem"; then
- if test -n "$GCC"; then
- case $host_os in
- linux*) haveit=yes;;
- esac
- fi
- fi
- if test -z "$haveit"; then
- if test -d "$additional_libdir"; then
- dnl Really add $additional_libdir to $LDFLAGS.
- LDFLAGS="${LDFLAGS}${LDFLAGS:+ }-L$additional_libdir"
- fi
- fi
- fi
- fi
- fi
-])
-
-dnl AC_LIB_PREPARE_PREFIX creates variables acl_final_prefix,
-dnl acl_final_exec_prefix, containing the values to which $prefix and
-dnl $exec_prefix will expand at the end of the configure script.
-AC_DEFUN([AC_LIB_PREPARE_PREFIX],
-[
- dnl Unfortunately, prefix and exec_prefix get only finally determined
- dnl at the end of configure.
- if test "X$prefix" = "XNONE"; then
- acl_final_prefix="$ac_default_prefix"
- else
- acl_final_prefix="$prefix"
- fi
- if test "X$exec_prefix" = "XNONE"; then
- acl_final_exec_prefix='${prefix}'
- else
- acl_final_exec_prefix="$exec_prefix"
- fi
- acl_save_prefix="$prefix"
- prefix="$acl_final_prefix"
- eval acl_final_exec_prefix=\"$acl_final_exec_prefix\"
- prefix="$acl_save_prefix"
-])
-
-dnl AC_LIB_WITH_FINAL_PREFIX([statement]) evaluates statement, with the
-dnl variables prefix and exec_prefix bound to the values they will have
-dnl at the end of the configure script.
-AC_DEFUN([AC_LIB_WITH_FINAL_PREFIX],
-[
- acl_save_prefix="$prefix"
- prefix="$acl_final_prefix"
- acl_save_exec_prefix="$exec_prefix"
- exec_prefix="$acl_final_exec_prefix"
- $1
- exec_prefix="$acl_save_exec_prefix"
- prefix="$acl_save_prefix"
-])
-
-dnl AC_LIB_PREPARE_MULTILIB creates
-dnl - a variable acl_libdirstem, containing the basename of the libdir, either
-dnl "lib" or "lib64" or "lib/64",
-dnl - a variable acl_libdirstem2, as a secondary possible value for
-dnl acl_libdirstem, either the same as acl_libdirstem or "lib/sparcv9" or
-dnl "lib/amd64".
-AC_DEFUN([AC_LIB_PREPARE_MULTILIB],
-[
- dnl There is no formal standard regarding lib and lib64.
- dnl On glibc systems, the current practice is that on a system supporting
- dnl 32-bit and 64-bit instruction sets or ABIs, 64-bit libraries go under
- dnl $prefix/lib64 and 32-bit libraries go under $prefix/lib. We determine
- dnl the compiler's default mode by looking at the compiler's library search
- dnl path. If at least one of its elements ends in /lib64 or points to a
- dnl directory whose absolute pathname ends in /lib64, we assume a 64-bit ABI.
- dnl Otherwise we use the default, namely "lib".
- dnl On Solaris systems, the current practice is that on a system supporting
- dnl 32-bit and 64-bit instruction sets or ABIs, 64-bit libraries go under
- dnl $prefix/lib/64 (which is a symlink to either $prefix/lib/sparcv9 or
- dnl $prefix/lib/amd64) and 32-bit libraries go under $prefix/lib.
- AC_REQUIRE([AC_CANONICAL_HOST])
- acl_libdirstem=lib
- acl_libdirstem2=
- case "$host_os" in
- solaris*)
- dnl See Solaris 10 Software Developer Collection > Solaris 64-bit
Developer's Guide > The Development Environment
- dnl <
http://docs.sun.com/app/docs/doc/816-5138/dev-env?l=en&a=view>.
- dnl "Portable Makefiles should refer to any library directories using the 64
symbolic link."
- dnl But we want to recognize the sparcv9 or amd64 subdirectory also if the
- dnl symlink is missing, so we set acl_libdirstem2 too.
- AC_CACHE_CHECK([for 64-bit host], [gl_cv_solaris_64bit],
- [AC_EGREP_CPP([sixtyfour bits], [
-#ifdef _LP64
-sixtyfour bits
-#endif
- ], [gl_cv_solaris_64bit=yes], [gl_cv_solaris_64bit=no])
- ])
- if test $gl_cv_solaris_64bit = yes; then
- acl_libdirstem=lib/64
- case "$host_cpu" in
- sparc*) acl_libdirstem2=lib/sparcv9 ;;
- i*86 | x86_64) acl_libdirstem2=lib/amd64 ;;
- esac
- fi
- ;;
- *)
- searchpath=`(LC_ALL=C $CC -print-search-dirs) 2>/dev/null | sed -n -e
's,^libraries: ,,p' | sed -e 's,^=,,'`
- if test -n "$searchpath"; then
- acl_save_IFS="${IFS= }"; IFS=":"
- for searchdir in $searchpath; do
- if test -d "$searchdir"; then
- case "$searchdir" in
- */lib64/ | */lib64 ) acl_libdirstem=lib64 ;;
- */../ | */.. )
- # Better ignore directories of this form. They are misleading.
- ;;
- *) searchdir=`cd "$searchdir" && pwd`
- case "$searchdir" in
- */lib64 ) acl_libdirstem=lib64 ;;
- esac ;;
- esac
- fi
- done
- IFS="$acl_save_IFS"
- fi
- ;;
- esac
- test -n "$acl_libdirstem2" || acl_libdirstem2="$acl_libdirstem"
-])
diff --git a/plugins/kimchi/m4/nls.m4 b/plugins/kimchi/m4/nls.m4
deleted file mode 100644
index 003704c..0000000
--- a/plugins/kimchi/m4/nls.m4
+++ /dev/null
@@ -1,32 +0,0 @@
-# nls.m4 serial 5 (gettext-0.18)
-dnl Copyright (C) 1995-2003, 2005-2006, 2008-2010 Free Software Foundation,
-dnl Inc.
-dnl This file is free software; the Free Software Foundation
-dnl gives unlimited permission to copy and/or distribute it,
-dnl with or without modifications, as long as this notice is preserved.
-dnl
-dnl This file can can be used in projects which are not available under
-dnl the GNU General Public License or the GNU Library General Public
-dnl License but which still want to provide support for the GNU gettext
-dnl functionality.
-dnl Please note that the actual code of the GNU gettext library is covered
-dnl by the GNU Library General Public License, and the rest of the GNU
-dnl gettext package package is covered by the GNU General Public License.
-dnl They are *not* in the public domain.
-
-dnl Authors:
-dnl Ulrich Drepper <drepper(a)cygnus.com>, 1995-2000.
-dnl Bruno Haible <haible(a)clisp.cons.org>, 2000-2003.
-
-AC_PREREQ([2.50])
-
-AC_DEFUN([AM_NLS],
-[
- AC_MSG_CHECKING([whether NLS is requested])
- dnl Default is enabled NLS
- AC_ARG_ENABLE([nls],
- [ --disable-nls do not use Native Language Support],
- USE_NLS=$enableval, USE_NLS=yes)
- AC_MSG_RESULT([$USE_NLS])
- AC_SUBST([USE_NLS])
-])
diff --git a/plugins/kimchi/m4/po.m4 b/plugins/kimchi/m4/po.m4
deleted file mode 100644
index 8bc921d..0000000
--- a/plugins/kimchi/m4/po.m4
+++ /dev/null
@@ -1,449 +0,0 @@
-# po.m4 serial 17 (gettext-0.18)
-dnl Copyright (C) 1995-2010 Free Software Foundation, Inc.
-dnl This file is free software; the Free Software Foundation
-dnl gives unlimited permission to copy and/or distribute it,
-dnl with or without modifications, as long as this notice is preserved.
-dnl
-dnl This file can can be used in projects which are not available under
-dnl the GNU General Public License or the GNU Library General Public
-dnl License but which still want to provide support for the GNU gettext
-dnl functionality.
-dnl Please note that the actual code of the GNU gettext library is covered
-dnl by the GNU Library General Public License, and the rest of the GNU
-dnl gettext package package is covered by the GNU General Public License.
-dnl They are *not* in the public domain.
-
-dnl Authors:
-dnl Ulrich Drepper <drepper(a)cygnus.com>, 1995-2000.
-dnl Bruno Haible <haible(a)clisp.cons.org>, 2000-2003.
-
-AC_PREREQ([2.50])
-
-dnl Checks for all prerequisites of the po subdirectory.
-AC_DEFUN([AM_PO_SUBDIRS],
-[
- AC_REQUIRE([AC_PROG_MAKE_SET])dnl
- AC_REQUIRE([AC_PROG_INSTALL])dnl
- AC_REQUIRE([AC_PROG_MKDIR_P])dnl defined by autoconf
- AC_REQUIRE([AM_NLS])dnl
-
- dnl Release version of the gettext macros. This is used to ensure that
- dnl the gettext macros and po/Makefile.in.in are in sync.
- AC_SUBST([GETTEXT_MACRO_VERSION], [0.18])
-
- dnl Perform the following tests also if --disable-nls has been given,
- dnl because they are needed for "make dist" to work.
-
- dnl Search for GNU msgfmt in the PATH.
- dnl The first test excludes Solaris msgfmt and early GNU msgfmt versions.
- dnl The second test excludes FreeBSD msgfmt.
- AM_PATH_PROG_WITH_TEST(MSGFMT, msgfmt,
- [$ac_dir/$ac_word --statistics /dev/null >&]AS_MESSAGE_LOG_FD[ 2>&1
&&
- (if $ac_dir/$ac_word --statistics /dev/null 2>&1 >/dev/null | grep usage
>/dev/null; then exit 1; else exit 0; fi)],
- :)
- AC_PATH_PROG([GMSGFMT], [gmsgfmt], [$MSGFMT])
-
- dnl Test whether it is GNU msgfmt >= 0.15.
-changequote(,)dnl
- case `$MSGFMT --version | sed 1q | sed -e 's,^[^0-9]*,,'` in
- '' | 0.[0-9] | 0.[0-9].* | 0.1[0-4] | 0.1[0-4].*) MSGFMT_015=: ;;
- *) MSGFMT_015=$MSGFMT ;;
- esac
-changequote([,])dnl
- AC_SUBST([MSGFMT_015])
-changequote(,)dnl
- case `$GMSGFMT --version | sed 1q | sed -e 's,^[^0-9]*,,'` in
- '' | 0.[0-9] | 0.[0-9].* | 0.1[0-4] | 0.1[0-4].*) GMSGFMT_015=: ;;
- *) GMSGFMT_015=$GMSGFMT ;;
- esac
-changequote([,])dnl
- AC_SUBST([GMSGFMT_015])
-
- dnl Search for GNU xgettext 0.12 or newer in the PATH.
- dnl The first test excludes Solaris xgettext and early GNU xgettext versions.
- dnl The second test excludes FreeBSD xgettext.
- AM_PATH_PROG_WITH_TEST(XGETTEXT, xgettext,
- [$ac_dir/$ac_word --omit-header --copyright-holder= --msgid-bugs-address= /dev/null
>&]AS_MESSAGE_LOG_FD[ 2>&1 &&
- (if $ac_dir/$ac_word --omit-header --copyright-holder= --msgid-bugs-address=
/dev/null 2>&1 >/dev/null | grep usage >/dev/null; then exit 1; else exit 0;
fi)],
- :)
- dnl Remove leftover from FreeBSD xgettext call.
- rm -f messages.po
-
- dnl Test whether it is GNU xgettext >= 0.15.
-changequote(,)dnl
- case `$XGETTEXT --version | sed 1q | sed -e 's,^[^0-9]*,,'` in
- '' | 0.[0-9] | 0.[0-9].* | 0.1[0-4] | 0.1[0-4].*) XGETTEXT_015=: ;;
- *) XGETTEXT_015=$XGETTEXT ;;
- esac
-changequote([,])dnl
- AC_SUBST([XGETTEXT_015])
-
- dnl Search for GNU msgmerge 0.11 or newer in the PATH.
- AM_PATH_PROG_WITH_TEST(MSGMERGE, msgmerge,
- [$ac_dir/$ac_word --update -q /dev/null /dev/null >&]AS_MESSAGE_LOG_FD[
2>&1], :)
-
- dnl Installation directories.
- dnl Autoconf >= 2.60 defines localedir. For older versions of autoconf, we
- dnl have to define it here, so that it can be used in po/Makefile.
- test -n "$localedir" || localedir='${datadir}/locale'
- AC_SUBST([localedir])
-
- dnl Support for AM_XGETTEXT_OPTION.
- test -n "${XGETTEXT_EXTRA_OPTIONS+set}" || XGETTEXT_EXTRA_OPTIONS=
- AC_SUBST([XGETTEXT_EXTRA_OPTIONS])
-
- AC_CONFIG_COMMANDS([po-directories], [[
- for ac_file in $CONFIG_FILES; do
- # Support "outfile[:infile[:infile...]]"
- case "$ac_file" in
- *:*) ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;;
- esac
- # PO directories have a Makefile.in generated from Makefile.in.in.
- case "$ac_file" in */Makefile.in)
- # Adjust a relative srcdir.
- ac_dir=`echo "$ac_file"|sed 's%/[^/][^/]*$%%'`
- ac_dir_suffix="/`echo "$ac_dir"|sed 's%^\./%%'`"
- ac_dots=`echo "$ac_dir_suffix"|sed 's%/[^/]*%../%g'`
- # In autoconf-2.13 it is called $ac_given_srcdir.
- # In autoconf-2.50 it is called $srcdir.
- test -n "$ac_given_srcdir" || ac_given_srcdir="$srcdir"
- case "$ac_given_srcdir" in
- .) top_srcdir=`echo $ac_dots|sed 's%/$%%'` ;;
- /*) top_srcdir="$ac_given_srcdir" ;;
- *) top_srcdir="$ac_dots$ac_given_srcdir" ;;
- esac
- # Treat a directory as a PO directory if and only if it has a
- # POTFILES.in file. This allows packages to have multiple PO
- # directories under different names or in different locations.
- if test -f "$ac_given_srcdir/$ac_dir/POTFILES.in"; then
- rm -f "$ac_dir/POTFILES"
- test -n "$as_me" && echo "$as_me: creating
$ac_dir/POTFILES" || echo "creating $ac_dir/POTFILES"
- cat "$ac_given_srcdir/$ac_dir/POTFILES.in" | sed -e "/^#/d"
-e "/^[ ]*\$/d" -e "s,.*, $top_srcdir/& \\\\," | sed -e
"\$s/\(.*\) \\\\/\1/" > "$ac_dir/POTFILES"
- POMAKEFILEDEPS="POTFILES.in"
- # ALL_LINGUAS, POFILES, UPDATEPOFILES, DUMMYPOFILES, GMOFILES depend
- # on $ac_dir but don't depend on user-specified configuration
- # parameters.
- if test -f "$ac_given_srcdir/$ac_dir/LINGUAS"; then
- # The LINGUAS file contains the set of available languages.
- if test -n "$OBSOLETE_ALL_LINGUAS"; then
- test -n "$as_me" && echo "$as_me: setting
ALL_LINGUAS in configure.in is obsolete" || echo "setting ALL_LINGUAS in
configure.in is obsolete"
- fi
- ALL_LINGUAS_=`sed -e "/^#/d" -e "s/#.*//"
"$ac_given_srcdir/$ac_dir/LINGUAS"`
- # Hide the ALL_LINGUAS assigment from automake < 1.5.
- eval 'ALL_LINGUAS''=$ALL_LINGUAS_'
- POMAKEFILEDEPS="$POMAKEFILEDEPS LINGUAS"
- else
- # The set of available languages was given in configure.in.
- # Hide the ALL_LINGUAS assigment from automake < 1.5.
- eval 'ALL_LINGUAS''=$OBSOLETE_ALL_LINGUAS'
- fi
- # Compute POFILES
- # as $(foreach lang, $(ALL_LINGUAS), $(srcdir)/$(lang).po)
- # Compute UPDATEPOFILES
- # as $(foreach lang, $(ALL_LINGUAS), $(lang).po-update)
- # Compute DUMMYPOFILES
- # as $(foreach lang, $(ALL_LINGUAS), $(lang).nop)
- # Compute GMOFILES
- # as $(foreach lang, $(ALL_LINGUAS), $(srcdir)/$(lang).gmo)
- case "$ac_given_srcdir" in
- .) srcdirpre= ;;
- *) srcdirpre='$(srcdir)/' ;;
- esac
- POFILES=
- UPDATEPOFILES=
- DUMMYPOFILES=
- GMOFILES=
- for lang in $ALL_LINGUAS; do
- POFILES="$POFILES $srcdirpre$lang.po"
- UPDATEPOFILES="$UPDATEPOFILES $lang.po-update"
- DUMMYPOFILES="$DUMMYPOFILES $lang.nop"
- GMOFILES="$GMOFILES $srcdirpre$lang.gmo"
- done
- # CATALOGS depends on both $ac_dir and the user's LINGUAS
- # environment variable.
- INST_LINGUAS=
- if test -n "$ALL_LINGUAS"; then
- for presentlang in $ALL_LINGUAS; do
- useit=no
- if test "%UNSET%" != "$LINGUAS"; then
- desiredlanguages="$LINGUAS"
- else
- desiredlanguages="$ALL_LINGUAS"
- fi
- for desiredlang in $desiredlanguages; do
- # Use the presentlang catalog if desiredlang is
- # a. equal to presentlang, or
- # b. a variant of presentlang (because in this case,
- # presentlang can be used as a fallback for messages
- # which are not translated in the desiredlang catalog).
- case "$desiredlang" in
- "$presentlang"*) useit=yes;;
- esac
- done
- if test $useit = yes; then
- INST_LINGUAS="$INST_LINGUAS $presentlang"
- fi
- done
- fi
- CATALOGS=
- if test -n "$INST_LINGUAS"; then
- for lang in $INST_LINGUAS; do
- CATALOGS="$CATALOGS $lang.gmo"
- done
- fi
- test -n "$as_me" && echo "$as_me: creating
$ac_dir/Makefile" || echo "creating $ac_dir/Makefile"
- sed -e "/^POTFILES =/r $ac_dir/POTFILES" -e "/^# Makevars/r
$ac_given_srcdir/$ac_dir/Makevars" -e "s|@POFILES@|$POFILES|g" -e
"s|@UPDATEPOFILES@|$UPDATEPOFILES|g" -e
"s|@DUMMYPOFILES@|$DUMMYPOFILES|g" -e "s|@GMOFILES@|$GMOFILES|g" -e
"s|@CATALOGS@|$CATALOGS|g" -e "s|@POMAKEFILEDEPS@|$POMAKEFILEDEPS|g"
"$ac_dir/Makefile.in" > "$ac_dir/Makefile"
- for f in "$ac_given_srcdir/$ac_dir"/Rules-*; do
- if test -f "$f"; then
- case "$f" in
- *.orig | *.bak | *~) ;;
- *) cat "$f" >> "$ac_dir/Makefile" ;;
- esac
- fi
- done
- fi
- ;;
- esac
- done]],
- [# Capture the value of obsolete ALL_LINGUAS because we need it to compute
- # POFILES, UPDATEPOFILES, DUMMYPOFILES, GMOFILES, CATALOGS. But hide it
- # from automake < 1.5.
- eval 'OBSOLETE_ALL_LINGUAS''="$ALL_LINGUAS"'
- # Capture the value of LINGUAS because we need it to compute CATALOGS.
- LINGUAS="${LINGUAS-%UNSET%}"
- ])
-])
-
-dnl Postprocesses a Makefile in a directory containing PO files.
-AC_DEFUN([AM_POSTPROCESS_PO_MAKEFILE],
-[
- # When this code is run, in config.status, two variables have already been
- # set:
- # - OBSOLETE_ALL_LINGUAS is the value of LINGUAS set in configure.in,
- # - LINGUAS is the value of the environment variable LINGUAS at configure
- # time.
-
-changequote(,)dnl
- # Adjust a relative srcdir.
- ac_dir=`echo "$ac_file"|sed 's%/[^/][^/]*$%%'`
- ac_dir_suffix="/`echo "$ac_dir"|sed 's%^\./%%'`"
- ac_dots=`echo "$ac_dir_suffix"|sed 's%/[^/]*%../%g'`
- # In autoconf-2.13 it is called $ac_given_srcdir.
- # In autoconf-2.50 it is called $srcdir.
- test -n "$ac_given_srcdir" || ac_given_srcdir="$srcdir"
- case "$ac_given_srcdir" in
- .) top_srcdir=`echo $ac_dots|sed 's%/$%%'` ;;
- /*) top_srcdir="$ac_given_srcdir" ;;
- *) top_srcdir="$ac_dots$ac_given_srcdir" ;;
- esac
-
- # Find a way to echo strings without interpreting backslash.
- if test "X`(echo '\t') 2>/dev/null`" = 'X\t'; then
- gt_echo='echo'
- else
- if test "X`(printf '%s\n' '\t') 2>/dev/null`" =
'X\t'; then
- gt_echo='printf %s\n'
- else
- echo_func () {
- cat <<EOT
-$*
-EOT
- }
- gt_echo='echo_func'
- fi
- fi
-
- # A sed script that extracts the value of VARIABLE from a Makefile.
- sed_x_variable='
-# Test if the hold space is empty.
-x
-s/P/P/
-x
-ta
-# Yes it was empty. Look if we have the expected variable definition.
-/^[ ]*VARIABLE[ ]*=/{
- # Seen the first line of the variable definition.
- s/^[ ]*VARIABLE[ ]*=//
- ba
-}
-bd
-:a
-# Here we are processing a line from the variable definition.
-# Remove comment, more precisely replace it with a space.
-s/#.*$/ /
-# See if the line ends in a backslash.
-tb
-:b
-s/\\$//
-# Print the line, without the trailing backslash.
-p
-tc
-# There was no trailing backslash. The end of the variable definition is
-# reached. Clear the hold space.
-s/^.*$//
-x
-bd
-:c
-# A trailing backslash means that the variable definition continues in the
-# next line. Put a nonempty string into the hold space to indicate this.
-s/^.*$/P/
-x
-:d
-'
-changequote([,])dnl
-
- # Set POTFILES to the value of the Makefile variable POTFILES.
- sed_x_POTFILES=`$gt_echo "$sed_x_variable" | sed -e '/^ *#/d' -e
's/VARIABLE/POTFILES/g'`
- POTFILES=`sed -n -e "$sed_x_POTFILES" < "$ac_file"`
- # Compute POTFILES_DEPS as
- # $(foreach file, $(POTFILES), $(top_srcdir)/$(file))
- POTFILES_DEPS=
- for file in $POTFILES; do
- POTFILES_DEPS="$POTFILES_DEPS "'$(top_srcdir)/'"$file"
- done
- POMAKEFILEDEPS=""
-
- if test -n "$OBSOLETE_ALL_LINGUAS"; then
- test -n "$as_me" && echo "$as_me: setting ALL_LINGUAS in
configure.in is obsolete" || echo "setting ALL_LINGUAS in configure.in is
obsolete"
- fi
- if test -f "$ac_given_srcdir/$ac_dir/LINGUAS"; then
- # The LINGUAS file contains the set of available languages.
- ALL_LINGUAS_=`sed -e "/^#/d" -e "s/#.*//"
"$ac_given_srcdir/$ac_dir/LINGUAS"`
- POMAKEFILEDEPS="$POMAKEFILEDEPS LINGUAS"
- else
- # Set ALL_LINGUAS to the value of the Makefile variable LINGUAS.
- sed_x_LINGUAS=`$gt_echo "$sed_x_variable" | sed -e '/^ *#/d' -e
's/VARIABLE/LINGUAS/g'`
- ALL_LINGUAS_=`sed -n -e "$sed_x_LINGUAS" < "$ac_file"`
- fi
- # Hide the ALL_LINGUAS assigment from automake < 1.5.
- eval 'ALL_LINGUAS''=$ALL_LINGUAS_'
- # Compute POFILES
- # as $(foreach lang, $(ALL_LINGUAS), $(srcdir)/$(lang).po)
- # Compute UPDATEPOFILES
- # as $(foreach lang, $(ALL_LINGUAS), $(lang).po-update)
- # Compute DUMMYPOFILES
- # as $(foreach lang, $(ALL_LINGUAS), $(lang).nop)
- # Compute GMOFILES
- # as $(foreach lang, $(ALL_LINGUAS), $(srcdir)/$(lang).gmo)
- # Compute PROPERTIESFILES
- # as $(foreach lang, $(ALL_LINGUAS), $(top_srcdir)/$(DOMAIN)_$(lang).properties)
- # Compute CLASSFILES
- # as $(foreach lang, $(ALL_LINGUAS), $(top_srcdir)/$(DOMAIN)_$(lang).class)
- # Compute QMFILES
- # as $(foreach lang, $(ALL_LINGUAS), $(srcdir)/$(lang).qm)
- # Compute MSGFILES
- # as $(foreach lang, $(ALL_LINGUAS), $(srcdir)/$(frob $(lang)).msg)
- # Compute RESOURCESDLLFILES
- # as $(foreach lang, $(ALL_LINGUAS), $(srcdir)/$(frob
$(lang))/$(DOMAIN).resources.dll)
- case "$ac_given_srcdir" in
- .) srcdirpre= ;;
- *) srcdirpre='$(srcdir)/' ;;
- esac
- POFILES=
- UPDATEPOFILES=
- DUMMYPOFILES=
- GMOFILES=
- PROPERTIESFILES=
- CLASSFILES=
- QMFILES=
- MSGFILES=
- RESOURCESDLLFILES=
- for lang in $ALL_LINGUAS; do
- POFILES="$POFILES $srcdirpre$lang.po"
- UPDATEPOFILES="$UPDATEPOFILES $lang.po-update"
- DUMMYPOFILES="$DUMMYPOFILES $lang.nop"
- GMOFILES="$GMOFILES $srcdirpre$lang.gmo"
- PROPERTIESFILES="$PROPERTIESFILES
\$(top_srcdir)/\$(DOMAIN)_$lang.properties"
- CLASSFILES="$CLASSFILES \$(top_srcdir)/\$(DOMAIN)_$lang.class"
- QMFILES="$QMFILES $srcdirpre$lang.qm"
- frobbedlang=`echo $lang | sed -e 's/\..*$//' -e
'y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/'`
- MSGFILES="$MSGFILES $srcdirpre$frobbedlang.msg"
- frobbedlang=`echo $lang | sed -e 's/_/-/g' -e 's/^sr-CS/sr-SP/' -e
's/@latin$/-Latn/' -e 's/@cyrillic$/-Cyrl/' -e
's/^sr-SP$/sr-SP-Latn/' -e 's/^uz-UZ$/uz-UZ-Latn/'`
- RESOURCESDLLFILES="$RESOURCESDLLFILES
$srcdirpre$frobbedlang/\$(DOMAIN).resources.dll"
- done
- # CATALOGS depends on both $ac_dir and the user's LINGUAS
- # environment variable.
- INST_LINGUAS=
- if test -n "$ALL_LINGUAS"; then
- for presentlang in $ALL_LINGUAS; do
- useit=no
- if test "%UNSET%" != "$LINGUAS"; then
- desiredlanguages="$LINGUAS"
- else
- desiredlanguages="$ALL_LINGUAS"
- fi
- for desiredlang in $desiredlanguages; do
- # Use the presentlang catalog if desiredlang is
- # a. equal to presentlang, or
- # b. a variant of presentlang (because in this case,
- # presentlang can be used as a fallback for messages
- # which are not translated in the desiredlang catalog).
- case "$desiredlang" in
- "$presentlang"*) useit=yes;;
- esac
- done
- if test $useit = yes; then
- INST_LINGUAS="$INST_LINGUAS $presentlang"
- fi
- done
- fi
- CATALOGS=
- JAVACATALOGS=
- QTCATALOGS=
- TCLCATALOGS=
- CSHARPCATALOGS=
- if test -n "$INST_LINGUAS"; then
- for lang in $INST_LINGUAS; do
- CATALOGS="$CATALOGS $lang.gmo"
- JAVACATALOGS="$JAVACATALOGS \$(DOMAIN)_$lang.properties"
- QTCATALOGS="$QTCATALOGS $lang.qm"
- frobbedlang=`echo $lang | sed -e 's/\..*$//' -e
'y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/'`
- TCLCATALOGS="$TCLCATALOGS $frobbedlang.msg"
- frobbedlang=`echo $lang | sed -e 's/_/-/g' -e 's/^sr-CS/sr-SP/' -e
's/@latin$/-Latn/' -e 's/@cyrillic$/-Cyrl/' -e
's/^sr-SP$/sr-SP-Latn/' -e 's/^uz-UZ$/uz-UZ-Latn/'`
- CSHARPCATALOGS="$CSHARPCATALOGS $frobbedlang/\$(DOMAIN).resources.dll"
- done
- fi
-
- sed -e "s|@POTFILES_DEPS@|$POTFILES_DEPS|g" -e
"s|@POFILES@|$POFILES|g" -e "s|@UPDATEPOFILES@|$UPDATEPOFILES|g" -e
"s|@DUMMYPOFILES@|$DUMMYPOFILES|g" -e "s|@GMOFILES@|$GMOFILES|g" -e
"s|@PROPERTIESFILES@|$PROPERTIESFILES|g" -e
"s|@CLASSFILES@|$CLASSFILES|g" -e "s|@QMFILES@|$QMFILES|g" -e
"s|@MSGFILES@|$MSGFILES|g" -e
"s|@RESOURCESDLLFILES@|$RESOURCESDLLFILES|g" -e
"s|@CATALOGS@|$CATALOGS|g" -e "s|@JAVACATALOGS@|$JAVACATALOGS|g" -e
"s|@QTCATALOGS@|$QTCATALOGS|g" -e "s|@TCLCATALOGS@|$TCLCATALOGS|g" -e
"s|@CSHARPCATALOGS@|$CSHARPCATALOGS|g" -e 's,^#distdir:,distdir:,' <
"$ac_file" > "$ac_file.tmp"
- if grep -l '@TCLCATALOGS@' "$ac_file" > /dev/null; then
- # Add dependencies that cannot be formulated as a simple suffix rule.
- for lang in $ALL_LINGUAS; do
- frobbedlang=`echo $lang | sed -e 's/\..*$//' -e
'y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/'`
- cat >> "$ac_file.tmp" <<EOF
-$frobbedlang.msg: $lang.po
- @echo "\$(MSGFMT) -c --tcl -d \$(srcdir) -l $lang $srcdirpre$lang.po"; \
- \$(MSGFMT) -c --tcl -d "\$(srcdir)" -l $lang $srcdirpre$lang.po || { rm -f
"\$(srcdir)/$frobbedlang.msg"; exit 1; }
-EOF
- done
- fi
- if grep -l '@CSHARPCATALOGS@' "$ac_file" > /dev/null; then
- # Add dependencies that cannot be formulated as a simple suffix rule.
- for lang in $ALL_LINGUAS; do
- frobbedlang=`echo $lang | sed -e 's/_/-/g' -e 's/^sr-CS/sr-SP/' -e
's/@latin$/-Latn/' -e 's/@cyrillic$/-Cyrl/' -e
's/^sr-SP$/sr-SP-Latn/' -e 's/^uz-UZ$/uz-UZ-Latn/'`
- cat >> "$ac_file.tmp" <<EOF
-$frobbedlang/\$(DOMAIN).resources.dll: $lang.po
- @echo "\$(MSGFMT) -c --csharp -d \$(srcdir) -l $lang $srcdirpre$lang.po -r
\$(DOMAIN)"; \
- \$(MSGFMT) -c --csharp -d "\$(srcdir)" -l $lang $srcdirpre$lang.po -r
"\$(DOMAIN)" || { rm -f "\$(srcdir)/$frobbedlang.msg"; exit 1; }
-EOF
- done
- fi
- if test -n "$POMAKEFILEDEPS"; then
- cat >> "$ac_file.tmp" <<EOF
-Makefile: $POMAKEFILEDEPS
-EOF
- fi
- mv "$ac_file.tmp" "$ac_file"
-])
-
-dnl Initializes the accumulator used by AM_XGETTEXT_OPTION.
-AC_DEFUN([AM_XGETTEXT_OPTION_INIT],
-[
- XGETTEXT_EXTRA_OPTIONS=
-])
-
-dnl Registers an option to be passed to xgettext in the po subdirectory.
-AC_DEFUN([AM_XGETTEXT_OPTION],
-[
- AC_REQUIRE([AM_XGETTEXT_OPTION_INIT])
- XGETTEXT_EXTRA_OPTIONS="$XGETTEXT_EXTRA_OPTIONS $1"
-])
diff --git a/plugins/kimchi/m4/progtest.m4 b/plugins/kimchi/m4/progtest.m4
deleted file mode 100644
index 2d804ac..0000000
--- a/plugins/kimchi/m4/progtest.m4
+++ /dev/null
@@ -1,92 +0,0 @@
-# progtest.m4 serial 6 (gettext-0.18)
-dnl Copyright (C) 1996-2003, 2005, 2008-2010 Free Software Foundation, Inc.
-dnl This file is free software; the Free Software Foundation
-dnl gives unlimited permission to copy and/or distribute it,
-dnl with or without modifications, as long as this notice is preserved.
-dnl
-dnl This file can can be used in projects which are not available under
-dnl the GNU General Public License or the GNU Library General Public
-dnl License but which still want to provide support for the GNU gettext
-dnl functionality.
-dnl Please note that the actual code of the GNU gettext library is covered
-dnl by the GNU Library General Public License, and the rest of the GNU
-dnl gettext package package is covered by the GNU General Public License.
-dnl They are *not* in the public domain.
-
-dnl Authors:
-dnl Ulrich Drepper <drepper(a)cygnus.com>, 1996.
-
-AC_PREREQ([2.50])
-
-# Search path for a program which passes the given test.
-
-dnl AM_PATH_PROG_WITH_TEST(VARIABLE, PROG-TO-CHECK-FOR,
-dnl TEST-PERFORMED-ON-FOUND_PROGRAM [, VALUE-IF-NOT-FOUND [, PATH]])
-AC_DEFUN([AM_PATH_PROG_WITH_TEST],
-[
-# Prepare PATH_SEPARATOR.
-# The user is always right.
-if test "${PATH_SEPARATOR+set}" != set; then
- echo "#! /bin/sh" >conf$$.sh
- echo "exit 0" >>conf$$.sh
- chmod +x conf$$.sh
- if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then
- PATH_SEPARATOR=';'
- else
- PATH_SEPARATOR=:
- fi
- rm -f conf$$.sh
-fi
-
-# Find out how to test for executable files. Don't use a zero-byte file,
-# as systems may use methods other than mode bits to determine executability.
-cat >conf$$.file <<_ASEOF
-#! /bin/sh
-exit 0
-_ASEOF
-chmod +x conf$$.file
-if test -x conf$$.file >/dev/null 2>&1; then
- ac_executable_p="test -x"
-else
- ac_executable_p="test -f"
-fi
-rm -f conf$$.file
-
-# Extract the first word of "$2", so it can be a program name with args.
-set dummy $2; ac_word=[$]2
-AC_MSG_CHECKING([for $ac_word])
-AC_CACHE_VAL([ac_cv_path_$1],
-[case "[$]$1" in
- [[\\/]]* | ?:[[\\/]]*)
- ac_cv_path_$1="[$]$1" # Let the user override the test with a path.
- ;;
- *)
- ac_save_IFS="$IFS"; IFS=$PATH_SEPARATOR
- for ac_dir in ifelse([$5], , $PATH, [$5]); do
- IFS="$ac_save_IFS"
- test -z "$ac_dir" && ac_dir=.
- for ac_exec_ext in '' $ac_executable_extensions; do
- if $ac_executable_p "$ac_dir/$ac_word$ac_exec_ext"; then
- echo "$as_me: trying $ac_dir/$ac_word..." >&AS_MESSAGE_LOG_FD
- if [$3]; then
- ac_cv_path_$1="$ac_dir/$ac_word$ac_exec_ext"
- break 2
- fi
- fi
- done
- done
- IFS="$ac_save_IFS"
-dnl If no 4th arg is given, leave the cache variable unset,
-dnl so AC_PATH_PROGS will keep looking.
-ifelse([$4], , , [ test -z "[$]ac_cv_path_$1" &&
ac_cv_path_$1="$4"
-])dnl
- ;;
-esac])dnl
-$1="$ac_cv_path_$1"
-if test ifelse([$4], , [-n "[$]$1"], ["[$]$1" != "$4"]);
then
- AC_MSG_RESULT([$][$1])
-else
- AC_MSG_RESULT([no])
-fi
-AC_SUBST([$1])dnl
-])
diff --git a/plugins/kimchi/mockmodel.py b/plugins/kimchi/mockmodel.py
deleted file mode 100644
index b269c26..0000000
--- a/plugins/kimchi/mockmodel.py
+++ /dev/null
@@ -1,627 +0,0 @@
-#
-# Project Kimchi
-#
-# Copyright IBM, Corp. 2013-2015
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-
-import libvirt
-import lxml.etree as ET
-import os
-import random
-import time
-from lxml import objectify
-from lxml.builder import E
-
-from wok.exception import NotFoundError, OperationFailed
-from wok.objectstore import ObjectStore
-from wok.utils import add_task, get_next_clone_name, wok_log
-from wok.xmlutils.utils import xml_item_update
-
-import config
-import imageinfo
-import osinfo
-from model import cpuinfo
-from model.debugreports import DebugReportsModel
-from model.host import DeviceModel
-from model.libvirtstoragepool import IscsiPoolDef, NetfsPoolDef
-from model.libvirtstoragepool import StoragePoolDef
-from model.model import Model
-from model.storagepools import StoragePoolModel
-from model.storagevolumes import StorageVolumeModel, StorageVolumesModel
-from model.templates import LibvirtVMTemplate
-from model.users import PAMUsersModel
-from model.groups import PAMGroupsModel
-from vmtemplate import VMTemplate
-
-
-fake_user = {'root': 'letmein!'}
-mockmodel_defaults = {
- 'storagepool': '/plugins/kimchi/storagepools/default-pool',
- 'domain': 'test', 'arch': 'i686'
-}
-
-
-class MockModel(Model):
- _mock_vms = {}
- _mock_snapshots = {}
- _XMLDesc = libvirt.virDomain.XMLDesc
- _defineXML = libvirt.virConnect.defineXML
- _undefineDomain = libvirt.virDomain.undefine
- _libvirt_get_vol_path = LibvirtVMTemplate._get_volume_path
-
- def __init__(self, objstore_loc=None):
- # Override osinfo.defaults to ajust the values according to
- # test:///default driver
- defaults = dict(osinfo.defaults)
- defaults.update(mockmodel_defaults)
- osinfo.defaults = dict(defaults)
-
- self._mock_devices = MockDevices()
- self._mock_partitions = MockPartitions()
- self._mock_storagevolumes = MockStorageVolumes()
- self._mock_swupdate = MockSoftwareUpdate()
- self._mock_repositories = MockRepositories()
-
- cpuinfo.get_topo_capabilities = \
- MockModel.get_topo_capabilities
- libvirt.virConnect.defineXML = MockModel.domainDefineXML
- libvirt.virDomain.XMLDesc = MockModel.domainXMLDesc
- libvirt.virDomain.undefine = MockModel.undefineDomain
- libvirt.virDomain.attachDeviceFlags = MockModel.attachDeviceFlags
- libvirt.virDomain.detachDeviceFlags = MockModel.detachDeviceFlags
- libvirt.virDomain.updateDeviceFlags = MockModel.updateDeviceFlags
- libvirt.virStorageVol.resize = MockModel.volResize
- libvirt.virStorageVol.wipePattern = MockModel.volWipePattern
-
- IscsiPoolDef.prepare = NetfsPoolDef.prepare = StoragePoolDef.prepare
-
- PAMUsersModel.auth_type = 'fake'
- PAMGroupsModel.auth_type = 'fake'
-
- super(MockModel, self).__init__('test:///default', objstore_loc)
- self.objstore_loc = objstore_loc
- self.objstore = ObjectStore(objstore_loc)
-
- # The MockModel methods are instantiated on runtime according to Model
- # and BaseModel
- # Because that a normal method override will not work here
- # Instead of that we also need to do the override on runtime
- for method in dir(self):
- if method.startswith('_mock_'):
- mock_method = getattr(self, method)
- if not callable(mock_method):
- continue
-
- m = method[6:]
- model_method = getattr(self, m)
- setattr(self, '_model_' + m, model_method)
- setattr(self, m, mock_method)
-
- DeviceModel.lookup = self._mock_device_lookup
- StoragePoolModel._update_lvm_disks = self._update_lvm_disks
- StorageVolumesModel.get_list = self._mock_storagevolumes_get_list
- StorageVolumeModel.doUpload = self._mock_storagevolume_doUpload
- DebugReportsModel._gen_debugreport_file = self._gen_debugreport_file
- LibvirtVMTemplate._get_volume_path = self._get_volume_path
- VMTemplate.get_iso_info = self._probe_image
- imageinfo.probe_image = self._probe_image
-
- def reset(self):
- MockModel._mock_vms = {}
- MockModel._mock_snapshots = {}
- self._mock_swupdate = MockSoftwareUpdate()
- self._mock_repositories = MockRepositories()
-
- if hasattr(self, 'objstore'):
- self.objstore = ObjectStore(self.objstore_loc)
-
- params = {'vms': [u'test'], 'templates': [],
- 'networks': [u'default'], 'storagepools':
[u'default-pool']}
-
- for res, items in params.iteritems():
- resources = getattr(self, '%s_get_list' % res)()
- for i in resources:
- if i in items:
- continue
-
- try:
- getattr(self, '%s_deactivate' % res[:-1])(i)
- except:
- pass
-
- getattr(self, '%s_delete' % res[:-1])(i)
-
- volumes = self.storagevolumes_get_list('default-pool')
- for v in volumes:
- self.storagevolume_delete('default-pool', v)
-
- @staticmethod
- def get_topo_capabilities(conn):
- # The libvirt test driver doesn't return topology.
- xml = "<topology sockets='1' cores='2'
threads='2'/>"
- return ET.fromstring(xml)
-
- @staticmethod
- def domainDefineXML(conn, xml):
- name = objectify.fromstring(xml).name.text
- try:
- dom = conn.lookupByName(name)
- if not dom.isActive():
- MockModel._mock_vms[name] = xml
- except:
- pass
-
- return MockModel._defineXML(conn, xml)
-
- @staticmethod
- def domainXMLDesc(dom, flags=0):
- return MockModel._mock_vms.get(dom.name(),
- MockModel._XMLDesc(dom, flags))
-
- @staticmethod
- def undefineDomain(dom):
- name = dom.name()
- if name in MockModel._mock_vms.keys():
- del MockModel._mock_vms[dom.name()]
- return MockModel._undefineDomain(dom)
-
- @staticmethod
- def attachDeviceFlags(dom, xml, flags=0):
- old_xml = dom.XMLDesc(libvirt.VIR_DOMAIN_XML_SECURE)
- root = objectify.fromstring(old_xml)
- dev = objectify.fromstring(xml)
- root.devices.append(dev)
-
- MockModel._mock_vms[dom.name()] = ET.tostring(root, encoding="utf-8")
-
- @staticmethod
- def _get_device_node(dom, xml):
- xpath_map = {'disk': 'target',
- 'interface': 'mac',
- 'graphics': 'listen'}
-
- dev = objectify.fromstring(xml)
- dev_id = dev.find(xpath_map[dev.tag]).items()
-
- dev_filter = ''
- for key, value in dev_id:
- dev_filter += "[@%s='%s']" % (key, value)
-
- old_xml = dom.XMLDesc(libvirt.VIR_DOMAIN_XML_SECURE)
- root = objectify.fromstring(old_xml)
- devices = root.devices
-
- dev = devices.find("./%s/%s%s/.." % (dev.tag, xpath_map[dev.tag],
- dev_filter))
-
- return (root, dev)
-
- @staticmethod
- def detachDeviceFlags(dom, xml, flags=0):
- root, dev = MockModel._get_device_node(dom, xml)
- root.devices.remove(dev)
-
- MockModel._mock_vms[dom.name()] = ET.tostring(root, encoding="utf-8")
-
- @staticmethod
- def updateDeviceFlags(dom, xml, flags=0):
- root, old_dev = MockModel._get_device_node(dom, xml)
- root.devices.replace(old_dev, objectify.fromstring(xml))
- MockModel._mock_vms[dom.name()] = ET.tostring(root, encoding="utf-8")
-
- @staticmethod
- def volResize(vol, size, flags=0):
- new_xml = xml_item_update(vol.XMLDesc(0), './capacity', str(size))
- vol.delete(0)
- pool = vol.storagePoolLookupByVolume()
- pool.createXML(new_xml)
-
- @staticmethod
- def volWipePattern(vol, algorithm, flags=0):
- new_xml = xml_item_update(vol.XMLDesc(0), './allocation', '0')
- vol.delete(0)
- pool = vol.storagePoolLookupByVolume()
- pool.createXML(new_xml)
-
- def _probe_image(self, path):
- return ('unknown', 'unknown')
-
- def _get_volume_path(self, pool, vol):
- pool_info = self.storagepool_lookup(pool)
- if pool_info['type'] == 'scsi':
- return self._mock_storagevolumes.scsi_volumes[vol]['path']
-
- return MockModel._libvirt_get_vol_path(pool, vol)
-
- def _gen_debugreport_file(self, name):
- return add_task('/plugins/kimchi/debugreports/%s' % name,
- self._create_log, self.objstore, name)
-
- def _create_log(self, cb, name):
- path = config.get_debugreports_path()
- tmpf = os.path.join(path, name + '.tmp')
- realf = os.path.join(path, name + '.txt')
- length = random.randint(1000, 10000)
- with open(tmpf, 'w') as fd:
- while length:
- fd.write('I am logged')
- length = length - 1
- os.rename(tmpf, realf)
- cb("OK", True)
-
- def _update_lvm_disks(self, pool_name, disks):
- conn = self.conn.get()
- pool = conn.storagePoolLookupByName(pool_name.encode('utf-8'))
- xml = pool.XMLDesc(0)
-
- root = ET.fromstring(xml)
- source = root.xpath('./source')[0]
-
- for d in disks:
- dev = E.device(path=d)
- source.append(dev)
-
- conn.storagePoolDefineXML(ET.tostring(root), 0)
-
- def _mock_host_shutdown(self, *name):
- wok_log.info("The host system will be shutted down")
-
- def _mock_host_reboot(self, *name):
- wok_log.info("The host system will be rebooted")
-
- def _mock_storagevolumes_create(self, pool, params):
- vol_source = ['url', 'capacity']
- index_list = list(i for i in range(len(vol_source))
- if vol_source[i] in params)
- create_param = vol_source[index_list[0]]
- name = params.get('name')
- if name is None and create_param == 'url':
- params['name'] = os.path.basename(params['url'])
- del params['url']
- params['capacity'] = 1024
-
- return self._model_storagevolumes_create(pool, params)
-
- def _mock_storagevolumes_get_list(self, pool):
- pool_info = self.storagepool_lookup(pool)
- if pool_info['type'] == 'scsi':
- return self._mock_storagevolumes.scsi_volumes.keys()
-
- return self._model_storagevolumes_get_list(pool)
-
- def _mock_storagevolume_lookup(self, pool, vol):
- pool_info = self.storagepool_lookup(pool)
- if pool_info['type'] == 'scsi':
- return self._mock_storagevolumes.scsi_volumes[vol]
-
- return self._model_storagevolume_lookup(pool, vol)
-
- def _mock_storagevolume_doUpload(self, cb, vol, offset, data, data_size):
- vol_path = vol.path()
-
- # MockModel does not create the storage volume as a file
- # So create it to do the file upload
- if offset == 0:
- dirname = os.path.dirname(vol_path)
- if not os.path.exists(dirname):
- os.makedirs(dirname)
- open(vol_path, 'w').close()
-
- try:
- with open(vol_path, 'a') as fd:
- fd.seek(offset)
- fd.write(data)
- except Exception, e:
- os.remove(vol_path)
- cb('', False)
- raise OperationFailed("KCHVOL0029E", {"err": e.message})
-
- def _mock_partitions_get_list(self):
- return self._mock_partitions.partitions.keys()
-
- def _mock_partition_lookup(self, name):
- return self._mock_partitions.partitions[name]
-
- def _mock_devices_get_list(self, _cap=None, _passthrough=None,
- _passthrough_affected_by=None):
- if _cap is None:
- return self._mock_devices.devices.keys()
-
- if _cap == 'fc_host':
- _cap = 'scsi_host'
-
- return [dev['name'] for dev in self._mock_devices.devices.values()
- if dev['device_type'] == _cap]
-
- def _mock_device_lookup(self, dev_name):
- return self._mock_devices.devices[dev_name]
-
- def _mock_packagesupdate_get_list(self):
- return self._mock_swupdate.pkgs.keys()
-
- def _mock_packageupdate_lookup(self, pkg_name):
- return self._mock_swupdate.pkgs[pkg_name]
-
- def _mock_host_swupdate(self, args=None):
- task_id = add_task('/plugins/kimchi/host/swupdate',
- self._mock_swupdate.doUpdate, self.objstore)
- return self.task_lookup(task_id)
-
- def _mock_repositories_get_list(self):
- return self._mock_repositories.repos.keys()
-
- def _mock_repositories_create(self, params):
- # Create a repo_id if not given by user. The repo_id will follow
- # the format kimchi_repo_<integer>, where integer is the number of
- # seconds since the Epoch (January 1st, 1970), in UTC.
- repo_id = params.get('repo_id', None)
- if repo_id is None:
- repo_id = "kimchi_repo_%s" % str(int(time.time() * 1000))
- params.update({'repo_id': repo_id})
-
- config = params.get('config', {})
- info = {'repo_id': repo_id,
- 'baseurl': params['baseurl'],
- 'enabled': True,
- 'config': {'repo_name': config.get('repo_name',
repo_id),
- 'gpgkey': config.get('gpgkey', []),
- 'gpgcheck': True,
- 'mirrorlist': params.get('mirrorlist',
'')}}
- self._mock_repositories.repos[repo_id] = info
- return repo_id
-
- def _mock_repository_lookup(self, repo_id):
- return self._mock_repositories.repos[repo_id]
-
- def _mock_repository_delete(self, repo_id):
- del self._mock_repositories.repos[repo_id]
-
- def _mock_repository_enable(self, repo_id):
- self._mock_repositories.repos[repo_id]['enabled'] = True
-
- def _mock_repository_disable(self, repo_id):
- self._mock_repositories.repos[repo_id]['enabled'] = False
-
- def _mock_repository_update(self, repo_id, params):
- self._mock_repositories.repos[repo_id].update(params)
- return repo_id
-
- def _mock_vm_clone(self, name):
- new_name = get_next_clone_name(self.vms_get_list(), name)
- snapshots = MockModel._mock_snapshots.get(name, [])
- MockModel._mock_snapshots[new_name] = snapshots
- return self._model_vm_clone(name)
-
- def _mock_vmsnapshots_create(self, vm_name, params):
- name = params.get('name', unicode(int(time.time())))
- params = {'vm_name': vm_name, 'name': name}
- taskid = add_task(u'/plugins/kimchi/vms/%s/snapshots/%s' %
- (vm_name, name), self._vmsnapshots_create_task,
- self.objstore, params)
- return self.task_lookup(taskid)
-
- def _vmsnapshots_create_task(self, cb, params):
- vm_name = params['vm_name']
- name = params['name']
- parent = u''
-
- snapshots = MockModel._mock_snapshots.get(vm_name, [])
- for sn in snapshots:
- if sn.current:
- sn.current = False
- parent = sn.name
-
- snapshots.append(MockVMSnapshot(name, {'parent': parent}))
- MockModel._mock_snapshots[vm_name] = snapshots
-
- cb('OK', True)
-
- def _mock_vmsnapshots_get_list(self, vm_name):
- snapshots = MockModel._mock_snapshots.get(vm_name, [])
- return sorted([snap.name for snap in snapshots])
-
- def _mock_currentvmsnapshot_lookup(self, vm_name):
- for sn in MockModel._mock_snapshots.get(vm_name, []):
- if sn.current:
- return sn.info
-
- def _mock_vmsnapshot_lookup(self, vm_name, name):
- for sn in MockModel._mock_snapshots.get(vm_name, []):
- if sn.name == name:
- return sn.info
-
- raise NotFoundError('KCHSNAP0003E', {'name': name, 'vm':
vm_name})
-
- def _mock_vmsnapshot_delete(self, vm_name, name):
- snapshots = MockModel._mock_snapshots.get(vm_name, [])
- for sn in snapshots:
- if sn.name == name:
- del snapshots[snapshots.index(sn)]
-
- MockModel._mock_snapshots[vm_name] = snapshots
-
- def _mock_vmsnapshot_revert(self, vm_name, name):
- snapshots = MockModel._mock_snapshots.get(vm_name, [])
- for sn in snapshots:
- if sn.current:
- sn.current = False
-
- for sn in snapshots:
- if sn.name == name:
- sn.current = True
-
-
-class MockStorageVolumes(object):
- def __init__(self):
- base_path = "/dev/disk/by-path/pci-0000:0e:00.0-fc-0x20-lun"
- self.scsi_volumes = {'unit:0:0:1': {'capacity': 1024,
- 'format': 'unknown',
- 'allocation': 512,
- 'type': 'block',
- 'path': base_path + '1',
- 'used_by': []},
- 'unit:0:0:2': {'capacity': 2048,
- 'format': 'unknown',
- 'allocation': 512,
- 'type': 'block',
- 'path': base_path + '2',
- 'used_by': []}}
-
-
-class MockPartitions(object):
- def __init__(self):
- self.partitions = {"vdx": {"available": True,
"name": "vdx",
- "fstype": "", "path":
"/dev/vdx",
- "mountpoint": "",
"type": "disk",
- "size": "2147483648"},
- "vdz": {"available": True,
"name": "vdz",
- "fstype": "", "path":
"/dev/vdz",
- "mountpoint": "",
"type": "disk",
- "size": "2147483648"}}
-
-
-class MockDevices(object):
- def __init__(self):
- self.devices = {
- 'computer': {'device_type': 'system',
- 'firmware': {'release_date':
'01/01/2012',
- 'vendor': 'LENOVO',
- 'version': 'XXXXX (X.XX )'},
- 'hardware': {'serial': 'PXXXXX',
- 'uuid':
- '9d660370-820f-4241-8731-5a60c97e8aa6',
- 'vendor': 'LENOVO',
- 'version': 'ThinkPad T420'},
- 'name': 'computer',
- 'parent': None,
- 'product': '4180XXX'},
- 'pci_0000_03_00_0': {'bus': 3,
- 'device_type': 'pci',
- 'domain': 0,
- 'driver': {'name': 'iwlwifi'},
- 'function': 0,
- 'iommuGroup': 7,
- 'name': 'pci_0000_03_00_0',
- 'parent': 'computer',
- 'path':
- '/sys/devices/pci0000:00/0000:03:00.0',
- 'product': {
- 'description':
- 'Centrino Advanced-N 6205 [Taylor Peak]',
- 'id': '0x0085'},
- 'slot': 0,
- 'vendor': {'description': 'Intel
Corporation',
- 'id': '0x8086'}},
- 'pci_0000_0d_00_0': {'bus': 13,
- 'device_type': 'pci',
- 'domain': 0,
- 'driver': {'name':
'sdhci-pci'},
- 'function': 0,
- 'iommuGroup': 7,
- 'name': 'pci_0000_0d_00_0',
- 'parent': 'computer',
- 'path':
- '/sys/devices/pci0000:00/0000:0d:00.0',
- 'product': {'description':
- 'PCIe SDXC/MMC Host Controller',
- 'id': '0xe823'},
- 'slot': 0,
- 'vendor': {'description': 'Ricoh Co
Ltd',
- 'id': '0x1180'}},
- 'scsi_host0': {'adapter': {'fabric_wwn':
'37df6c1efa1b4388',
- 'type': 'fc_host',
- 'wwnn': 'efb6563f06434a98',
- 'wwpn': '742f32073aab45d7'},
- 'device_type': 'scsi_host',
- 'host': 0,
- 'name': 'scsi_host0',
- 'parent': 'computer',
- 'path':
'/sys/devices/pci0000:00/0000:40:00.0/0'},
- 'scsi_host1': {'adapter': {'fabric_wwn':
'542efa5dced34123',
- 'type': 'fc_host',
- 'wwnn': 'b7433a40c9b84092',
- 'wwpn': '25c1f485ae42497f'},
- 'device_type': 'scsi_host',
- 'host': 0,
- 'name': 'scsi_host1',
- 'parent': 'computer',
- 'path':
'/sys/devices/pci0000:00/0000:40:00.0/1'},
- 'scsi_host2': {'adapter': {'fabric_wwn':
'5c373c334c20478d',
- 'type': 'fc_host',
- 'wwnn': 'f2030bec4a254e6b',
- 'wwpn': '07dbca4164d44096'},
- 'device_type': 'scsi_host',
- 'host': 0,
- 'name': 'scsi_host2',
- 'parent': 'computer',
- 'path':
'/sys/devices/pci0000:00/0000:40:00.0/2'}}
-
-
-class MockSoftwareUpdate(object):
- def __init__(self):
- self.pkgs = {
- 'udevmountd': {'repository': 'openSUSE-13.1-Update',
- 'version': '0.81.5-14.1',
- 'arch': 'x86_64',
- 'package_name': 'udevmountd'},
- 'sysconfig-network': {'repository':
'openSUSE-13.1-Extras',
- 'version': '0.81.5-14.1',
- 'arch': 'x86_64',
- 'package_name': 'sysconfig-network'},
- 'libzypp': {'repository': 'openSUSE-13.1-Update',
- 'version': '13.9.0-10.1',
- 'arch': 'noarch',
- 'package_name': 'libzypp'}}
- self._num2update = 3
-
- def doUpdate(self, cb, params):
- msgs = []
- for pkg in self.pkgs.keys():
- msgs.append("Updating package %s" % pkg)
- cb('\n'.join(msgs))
- time.sleep(1)
-
- time.sleep(2)
- msgs.append("All packages updated")
- cb('\n'.join(msgs), True)
-
- # After updating all packages any package should be listed to be
- # updated, so reset self._packages
- self.pkgs = {}
-
-
-class MockRepositories(object):
- def __init__(self):
- self.repos = {"kimchi_repo_1392167832":
- {"repo_id": "kimchi_repo_1392167832",
- "enabled": True,
- "baseurl": "http://www.fedora.org",
- "config": {"repo_name":
"kimchi_repo_1392167832",
- "gpgkey": [],
- "gpgcheck": True,
- "mirrorlist": ""}}}
-
-
-class MockVMSnapshot(object):
- def __init__(self, name, params={}):
- self.name = name
- self.current = True
-
- self.info = {'created': params.get('created',
- unicode(int(time.time()))),
- 'name': name,
- 'parent': params.get('parent', u''),
- 'state': params.get('state', u'shutoff')}
diff --git a/plugins/kimchi/model/Makefile.am b/plugins/kimchi/model/Makefile.am
deleted file mode 100644
index f4f4750..0000000
--- a/plugins/kimchi/model/Makefile.am
+++ /dev/null
@@ -1,25 +0,0 @@
-#
-# Kimchi
-#
-# Copyright IBM Corp, 2013
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-
-model_PYTHON = *.py
-
-modeldir = $(pythondir)/wok/plugins/kimchi/model
-
-install-data-local:
- $(MKDIR_P) $(DESTDIR)$(modeldir)
diff --git a/plugins/kimchi/model/__init__.py b/plugins/kimchi/model/__init__.py
deleted file mode 100644
index ca7ede4..0000000
--- a/plugins/kimchi/model/__init__.py
+++ /dev/null
@@ -1,18 +0,0 @@
-#
-# Project Kimchi
-#
-# Copyright IBM, Corp. 2014
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
diff --git a/plugins/kimchi/model/config.py b/plugins/kimchi/model/config.py
deleted file mode 100644
index 464ffae..0000000
--- a/plugins/kimchi/model/config.py
+++ /dev/null
@@ -1,176 +0,0 @@
-#
-# Project Kimchi
-#
-# Copyright IBM, Corp. 2014-2015
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-
-import cherrypy
-from multiprocessing.pool import ThreadPool
-
-from wok.basemodel import Singleton
-from wok.config import config as kconfig
-from wok.config import get_version
-from wok.exception import NotFoundError
-from wok.utils import check_url_path, run_command, wok_log
-
-from ..config import find_qemu_binary
-from ..distroloader import DistroLoader
-from ..repositories import Repositories
-from ..screenshot import VMScreenshot
-from ..swupdate import SoftwareUpdate
-from debugreports import DebugReportsModel
-from featuretests import FeatureTests, FEATURETEST_POOL_NAME
-from featuretests import FEATURETEST_VM_NAME
-
-
-class ConfigModel(object):
- def __init__(self, **kargs):
- pass
-
- def lookup(self, name):
- proxy_port = kconfig.get('display', 'display_proxy_port')
- return {'display_proxy_port': proxy_port,
- 'version': get_version()}
-
-
-class CapabilitiesModel(object):
- __metaclass__ = Singleton
-
- def __init__(self, **kargs):
- self.conn = kargs['conn']
- self.qemu_stream = False
- self.libvirt_stream_protocols = []
- self.fc_host_support = False
- self.metadata_support = False
- self.kernel_vfio = False
- self.mem_hotplug_support = False
-
- # Subscribe function to set host capabilities to be run when cherrypy
- # server is up
- # It is needed because some features tests depends on the server
- cherrypy.engine.subscribe('start', self._set_capabilities)
-
- # Subscribe function to clean any Kimchi leftovers
- cherrypy.engine.subscribe('stop', self._clean_leftovers)
-
- def _clean_leftovers(self):
- conn = self.conn.get()
- FeatureTests.disable_libvirt_error_logging()
- try:
- dom = conn.lookupByName(FEATURETEST_VM_NAME)
- dom.undefine()
- except Exception:
- # Any exception can be ignored here
- pass
-
- try:
- pool = conn.storagePoolLookupByName(FEATURETEST_POOL_NAME)
- pool.undefine()
- except Exception:
- # Any exception can be ignored here
- pass
-
- FeatureTests.enable_libvirt_error_logging()
-
- def _set_capabilities(self):
- wok_log.info("*** Running feature tests ***")
- conn = self.conn.get()
- self.qemu_stream = FeatureTests.qemu_supports_iso_stream()
- self.nfs_target_probe = FeatureTests.libvirt_support_nfs_probe(conn)
- self.fc_host_support = FeatureTests.libvirt_support_fc_host(conn)
- self.metadata_support = FeatureTests.has_metadata_support(conn)
- self.kernel_vfio = FeatureTests.kernel_support_vfio()
- self.mem_hotplug_support = FeatureTests.has_mem_hotplug_support(conn)
-
- self.libvirt_stream_protocols = []
- for p in ['http', 'https', 'ftp', 'ftps',
'tftp']:
- if FeatureTests.libvirt_supports_iso_stream(conn, p):
- self.libvirt_stream_protocols.append(p)
-
- wok_log.info("*** Feature tests completed ***")
- _set_capabilities.priority = 90
-
- def _qemu_support_spice(self):
- qemu_path = find_qemu_binary(find_emulator=True)
- out, err, rc = run_command(['ldd', qemu_path])
- if rc != 0:
- wok_log.error('Failed to find qemu binary dependencies: %s',
- err)
- return False
- for line in out.split('\n'):
- if line.lstrip().startswith('libspice-server.so'):
- return True
- return False
-
- def lookup(self, *ident):
- report_tool = DebugReportsModel.get_system_report_tool()
- try:
- SoftwareUpdate()
- except Exception:
- update_tool = False
- else:
- update_tool = True
-
- try:
- repo = Repositories()
- except Exception:
- repo_mngt_tool = None
- else:
- repo_mngt_tool = repo._pkg_mnger.TYPE
-
- return {'libvirt_stream_protocols': self.libvirt_stream_protocols,
- 'qemu_spice': self._qemu_support_spice(),
- 'qemu_stream': self.qemu_stream,
- 'screenshot': VMScreenshot.get_stream_test_result(),
- 'system_report_tool': bool(report_tool),
- 'update_tool': update_tool,
- 'repo_mngt_tool': repo_mngt_tool,
- 'federation': kconfig.get("server",
"federation"),
- 'auth': kconfig.get("authentication",
"method"),
- 'kernel_vfio': self.kernel_vfio,
- 'nm_running': FeatureTests.is_nm_running(),
- 'mem_hotplug_support': self.mem_hotplug_support
- }
-
-
-class DistrosModel(object):
- def __init__(self, **kargs):
- distroloader = DistroLoader()
- self.distros = distroloader.get()
-
- def get_list(self):
- def validate_distro(distro):
- if check_url_path(distro['path']):
- return distro['name']
-
- n_processes = len(self.distros.keys())
- pool = ThreadPool(processes=n_processes)
- map_res = pool.map_async(validate_distro, self.distros.values())
- pool.close()
- pool.join()
- res = list(set(map_res.get()) - set([None]))
- return sorted(res)
-
-
-class DistroModel(object):
- def __init__(self, **kargs):
- self._distros = DistrosModel()
-
- def lookup(self, name):
- try:
- return self._distros.distros[name]
- except KeyError:
- raise NotFoundError("KCHDISTRO0001E", {'name': name})
diff --git a/plugins/kimchi/model/cpuinfo.py b/plugins/kimchi/model/cpuinfo.py
deleted file mode 100644
index 299e445..0000000
--- a/plugins/kimchi/model/cpuinfo.py
+++ /dev/null
@@ -1,126 +0,0 @@
-#
-# Project Kimchi
-#
-# Copyright IBM, Corp. 2014-2015
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-
-import platform
-from xml.etree import ElementTree as ET
-
-from wok.exception import InvalidParameter, InvalidOperation
-from wok.utils import run_command, wok_log
-
-
-ARCH = 'power' if platform.machine().startswith('ppc') else
'x86'
-
-
-def get_topo_capabilities(connect):
- """
- This helper function exists solely to be overridden for
- mockmodel tests. Since other modules use getCapabilies(),
- it can't be overridden directly.
- """
- xml = connect.getCapabilities()
- capabilities = ET.fromstring(xml)
- return
capabilities.find('host').find('cpu').find('topology')
-
-
-class CPUInfoModel(object):
- """
- Get information about a CPU for hyperthreading (on x86)
- or SMT (on POWER) for logic when creating templates and VMs.
- """
-
- def __init__(self, **kargs):
- self.guest_threads_enabled = False
- self.sockets = 0
- self.cores_present = 0
- self.cores_available = 0
- self.cores_per_socket = 0
- self.threads_per_core = 0
- self.max_threads = 0
-
- self.conn = kargs['conn']
- libvirt_topology = None
- try:
- connect = self.conn.get()
- libvirt_topology = get_topo_capabilities(connect)
- except Exception as e:
- wok_log.info("Unable to get CPU topology capabilities: %s"
- % e.message)
- return
- if libvirt_topology is None:
- wok_log.info("cpu_info topology not supported.")
- return
-
- if ARCH == 'power':
- # IBM PowerPC
- self.guest_threads_enabled = True
- out, error, rc = run_command(['ppc64_cpu', '--smt'])
- if rc or 'on' in out:
- # SMT has to be disabled for guest to use threads as CPUs.
- # rc is always zero, whether SMT is off or on.
- self.guest_threads_enabled = False
- out, error, rc = run_command(['ppc64_cpu',
'--cores-present'])
- if not rc:
- self.cores_present = int(out.split()[-1])
- out, error, rc = run_command(['ppc64_cpu', '--cores-on'])
- if not rc:
- self.cores_available = int(out.split()[-1])
- out, error, rc = run_command(['ppc64_cpu',
'--threads-per-core'])
- if not rc:
- self.threads_per_core = int(out.split()[-1])
- self.sockets = self.cores_present/self.threads_per_core
- if self.sockets == 0:
- self.sockets = 1
- self.cores_per_socket = self.cores_present/self.sockets
- else:
- # Intel or AMD
- self.guest_threads_enabled = True
- self.sockets = int(libvirt_topology.get('sockets'))
- self.cores_per_socket = int(libvirt_topology.get('cores'))
- self.cores_present = self.cores_per_socket * self.sockets
- self.cores_available = self.cores_present
- self.threads_per_core = int(libvirt_topology.get('threads'))
-
- def lookup(self, ident):
- return {
- 'guest_threads_enabled': self.guest_threads_enabled,
- 'sockets': self.sockets,
- 'cores_per_socket': self.cores_per_socket,
- 'cores_present': self.cores_present,
- 'cores_available': self.cores_available,
- 'threads_per_core': self.threads_per_core,
- }
-
- def check_topology(self, vcpus, topology):
- """
- param vcpus: should be an integer
- param iso_path: the path of the guest ISO
- param topology: {'sockets': x, 'cores': x, 'threads':
x}
- """
- sockets = topology['sockets']
- cores = topology['cores']
- threads = topology['threads']
-
- if not self.guest_threads_enabled:
- raise InvalidOperation("KCHCPUINF0003E")
- if vcpus != sockets * cores * threads:
- raise InvalidParameter("KCHCPUINF0002E")
- if vcpus > self.cores_available * self.threads_per_core:
- raise InvalidParameter("KCHCPUINF0001E")
- if threads > self.threads_per_core:
- raise InvalidParameter("KCHCPUINF0002E")
diff --git a/plugins/kimchi/model/debugreports.py b/plugins/kimchi/model/debugreports.py
deleted file mode 100644
index 48e6b26..0000000
--- a/plugins/kimchi/model/debugreports.py
+++ /dev/null
@@ -1,213 +0,0 @@
-#
-# Project Kimchi
-#
-# Copyright IBM, Corp. 2014-2015
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-
-import fnmatch
-import glob
-import logging
-import os
-import shutil
-import subprocess
-import time
-
-from wok.exception import InvalidParameter, NotFoundError, OperationFailed
-from wok.exception import WokException
-from wok.utils import add_task, wok_log
-from wok.utils import run_command
-from wok.model.tasks import TaskModel
-
-from .. import config
-
-
-class DebugReportsModel(object):
- def __init__(self, **kargs):
- self.objstore = kargs['objstore']
- self.task = TaskModel(**kargs)
-
- def create(self, params):
- ident = params.get('name').strip()
- # Generate a name with time and millisec precision, if necessary
- if ident is None or ident == "":
- ident = 'report-' + str(int(time.time() * 1000))
- else:
- if ident in self.get_list():
- raise InvalidParameter("KCHDR0008E", {"name":
ident})
- taskid = self._gen_debugreport_file(ident)
- return self.task.lookup(taskid)
-
- def get_list(self):
- path = config.get_debugreports_path()
- file_pattern = os.path.join(path, '*.*')
- file_lists = glob.glob(file_pattern)
- file_lists = [os.path.split(file)[1] for file in file_lists]
- name_lists = [file.split('.', 1)[0] for file in file_lists]
-
- return name_lists
-
- def _gen_debugreport_file(self, name):
- gen_cmd = self.get_system_report_tool()
-
- if gen_cmd is not None:
- return add_task('/plugins/kimchi/debugreports/%s' % name, gen_cmd,
- self.objstore, name)
-
- raise OperationFailed("KCHDR0002E")
-
- @staticmethod
- def sosreport_generate(cb, name):
- def log_error(e):
- log = logging.getLogger('Model')
- log.warning('Exception in generating debug file: %s', e)
-
- try:
- command = ['sosreport', '--batch', '--name=%s' %
name]
- output, error, retcode = run_command(command)
-
- if retcode != 0:
- raise OperationFailed("KCHDR0003E", {'name': name,
- 'err': retcode})
-
- # SOSREPORT might create file in /tmp or /var/tmp
- # FIXME: The right way should be passing the tar.xz file directory
- # though the parameter '--tmp-dir', but it is failing in Fedora 20
- patterns = ['/tmp/sosreport-%s-*',
'/var/tmp/sosreport-%s-*']
- reports = []
- reportFile = None
- for p in patterns:
- reports = reports + [f for f in glob.glob(p % name)]
- for f in reports:
- if not fnmatch.fnmatch(f, '*.md5'):
- reportFile = f
- break
- # Some error in sosreport happened
- if reportFile is None:
- wok_log.error('Debug report file not found. See sosreport '
- 'output for detail:\n%s', output)
- fname = (patterns[0] % name).split('/')[-1]
- raise OperationFailed('KCHDR0004E', {'name': fname})
-
- md5_report_file = reportFile + '.md5'
- report_file_extension = '.' + reportFile.split('.', 1)[1]
- path = config.get_debugreports_path()
- target = os.path.join(path, name + report_file_extension)
- # Moving report
- msg = 'Moving debug report file "%s" to "%s"' %
(reportFile,
- target)
- wok_log.info(msg)
- shutil.move(reportFile, target)
- # Deleting md5
- msg = 'Deleting report md5 file: "%s"' % (md5_report_file)
- wok_log.info(msg)
- with open(md5_report_file) as f:
- md5 = f.read().strip()
- wok_log.info('Md5 file content: "%s"', md5)
- os.remove(md5_report_file)
- cb('OK', True)
- return
-
- except WokException as e:
- log_error(e)
- raise
-
- except OSError as e:
- log_error(e)
- raise
-
- except Exception, e:
- # No need to call cb to update the task status here.
- # The task object will catch the exception raised here
- # and update the task status there
- log_error(e)
- raise OperationFailed("KCHDR0005E", {'name': name,
'err': e})
-
- @staticmethod
- def get_system_report_tool():
- # Please add new possible debug report command here
- # and implement the report generating function
- # based on the new report command
- report_tools = ({'cmd': 'sosreport --help',
- 'fn': DebugReportsModel.sosreport_generate},)
-
- # check if the command can be found by shell one by one
- for helper_tool in report_tools:
- try:
- retcode = subprocess.call(helper_tool['cmd'], shell=True,
- stdout=subprocess.PIPE,
- stderr=subprocess.PIPE)
- if retcode == 0:
- return helper_tool['fn']
- except Exception, e:
- wok_log.info('Exception running command: %s', e)
-
- return None
-
-
-class DebugReportModel(object):
- def __init__(self, **kargs):
- pass
-
- def lookup(self, name):
- path = config.get_debugreports_path()
- file_pattern = os.path.join(path, name)
- file_pattern = file_pattern + '.*'
- try:
- file_target = glob.glob(file_pattern)[0]
- except IndexError:
- raise NotFoundError("KCHDR0001E", {'name': name})
-
- ctime = os.stat(file_target).st_mtime
- ctime = time.strftime("%Y-%m-%d-%H:%M:%S", time.localtime(ctime))
- file_target = os.path.split(file_target)[-1]
- file_target = os.path.join("plugins/kimchi/data/debugreports",
- file_target)
- return {'uri': file_target,
- 'ctime': ctime}
-
- def update(self, name, params):
- path = config.get_debugreports_path()
- file_pattern = os.path.join(path, name + '.*')
- try:
- file_source = glob.glob(file_pattern)[0]
- except IndexError:
- raise NotFoundError("KCHDR0001E", {'name': name})
-
- file_target = file_source.replace(name, params['name'])
- if os.path.isfile(file_target):
- raise InvalidParameter('KCHDR0008E', {'name':
params['name']})
-
- shutil.move(file_source, file_target)
- wok_log.info('%s renamed to %s' % (file_source, file_target))
- return params['name']
-
- def delete(self, name):
- path = config.get_debugreports_path()
- file_pattern = os.path.join(path, name + '.*')
- try:
- file_target = glob.glob(file_pattern)[0]
- except IndexError:
- raise NotFoundError("KCHDR0001E", {'name': name})
-
- os.remove(file_target)
-
-
-class DebugReportContentModel(object):
- def __init__(self, **kargs):
- self._debugreport = DebugReportModel()
-
- def lookup(self, name):
- return self._debugreport.lookup(name)
diff --git a/plugins/kimchi/model/diskutils.py b/plugins/kimchi/model/diskutils.py
deleted file mode 100644
index 350e6eb..0000000
--- a/plugins/kimchi/model/diskutils.py
+++ /dev/null
@@ -1,75 +0,0 @@
-#
-# Project Kimchi
-#
-# Copyright IBM, Corp. 2014-2015
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-
-from wok.exception import OperationFailed, NotFoundError
-from wok.utils import wok_log
-
-from ..xmlutils.disk import get_vm_disk_info, get_vm_disks
-from vms import VMModel, VMsModel
-
-"""
- Functions that multiple storage-related models (e.g. VMStoragesModel,
- VolumesModel) will need.
-"""
-
-
-def get_disk_used_by(objstore, conn, path):
- try:
- with objstore as session:
- try:
- used_by = session.get('storagevolume', path)['used_by']
- except (KeyError, NotFoundError):
- wok_log.info('Volume %s not found in obj store.' % path)
- used_by = []
- # try to find this volume in existing vm
- vms_list = VMsModel.get_vms(conn)
- for vm in vms_list:
- dom = VMModel.get_vm(vm, conn)
- storages = get_vm_disks(dom)
- for disk in storages.keys():
- d_info = get_vm_disk_info(dom, disk)
- if path == d_info['path']:
- used_by.append(vm)
- try:
- session.store('storagevolume', path,
- {'used_by': used_by})
- except Exception as e:
- # Let the exception be raised. If we allow disks'
- # used_by to be out of sync, data corruption could
- # occour if a disk is added to two guests
- # unknowingly.
- wok_log.error('Unable to store storage volume id in'
- ' objectstore due error: %s',
- e.message)
- raise OperationFailed('KCHVOL0017E',
- {'err': e.message})
- except Exception as e:
- # This exception is going to catch errors returned by 'with',
- # specially ones generated by 'session.store'. It is outside
- # to avoid conflict with the __exit__ function of 'with'
- raise OperationFailed('KCHVOL0017E', {'err': e.message})
- return used_by
-
-
-def set_disk_used_by(objstore, path, new_used_by):
- try:
- with objstore as session:
- session.store('storagevolume', path, {'used_by':
new_used_by})
- except Exception as e:
- raise OperationFailed('KCHVOL0017E', {'err': e.message})
diff --git a/plugins/kimchi/model/featuretests.py b/plugins/kimchi/model/featuretests.py
deleted file mode 100644
index c53d1aa..0000000
--- a/plugins/kimchi/model/featuretests.py
+++ /dev/null
@@ -1,259 +0,0 @@
-#
-# Project Kimchi
-#
-# Copyright IBM, Corp. 2013-2015
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-
-import cherrypy
-import libvirt
-import lxml.etree as ET
-import platform
-import subprocess
-from lxml.builder import E
-
-from wok.rollbackcontext import RollbackContext
-from wok.utils import run_command, servermethod, wok_log
-
-
-FEATURETEST_VM_NAME = "FEATURETEST_VM"
-FEATURETEST_POOL_NAME = "FEATURETEST_POOL"
-
-ISO_STREAM_XML = """
-<domain type='%(domain)s'>
- <name>%(name)s</name>
- <memory unit='KiB'>1048576</memory>
- <os>
- <type arch='%(arch)s'>hvm</type>
- <boot dev='cdrom'/>
- </os>
- <devices>
- <disk type='network' device='cdrom'>
- <driver name='qemu' type='raw'/>
- <source protocol='%(protocol)s'
name='/url/path/to/iso/file'>
- <host name='host.name' port='1234'/>
- </source>
- <target dev='hdc' bus='ide'/>
- <readonly/>
- <alias name='ide0-1-0'/>
- <address type='drive' controller='0' bus='1'
target='0' unit='0'/>
- </disk>
- </devices>
-</domain>"""
-
-SIMPLE_VM_XML = """
-<domain type='%(domain)s'>
- <name>%(name)s</name>
- <memory unit='KiB'>10240</memory>
- <os>
- <type arch='%(arch)s'>hvm</type>
- <boot dev='hd'/>
- </os>
-</domain>"""
-
-MAXMEM_VM_XML = """
-<domain type='%(domain)s'>
- <name>%(name)s</name>
- <maxMemory slots='1' unit='KiB'>20480</maxMemory>
- <memory unit='KiB'>10240</memory>
- <os>
- <type arch='%(arch)s'>hvm</type>
- <boot dev='hd'/>
- </os>
-</domain>"""
-
-DEV_MEM_XML = """
-<memory model='dimm'>
- <target>
- <size unit='KiB'>10240</size>
- <node>0</node>
- </target>
-</memory>"""
-
-SCSI_FC_XML = """
-<pool type='scsi'>
- <name>%(name)s</name>
- <source>
- <adapter type='fc_host' wwnn='1234567890abcdef'
wwpn='abcdef1234567890'/>
- </source>
- <target>
- <path>/dev/disk/by-path</path>
- </target>
-</pool>
-"""
-
-
-class FeatureTests(object):
-
- @staticmethod
- def disable_libvirt_error_logging():
- def libvirt_errorhandler(userdata, error):
- # A libvirt error handler to ignore annoying messages in stderr
- pass
-
- # Filter functions are enable only in production env
- if cherrypy.config.get('environment') != 'production':
- return
- # Register the error handler to hide libvirt error in stderr
- libvirt.registerErrorHandler(f=libvirt_errorhandler, ctx=None)
-
- @staticmethod
- def enable_libvirt_error_logging():
- # Filter functions are enable only in production env
- if cherrypy.config.get('environment') != 'production':
- return
- # Unregister the error handler
- libvirt.registerErrorHandler(f=None, ctx=None)
-
- @staticmethod
- def libvirt_supports_iso_stream(conn, protocol):
- conn_type = conn.getType().lower()
- domain_type = 'test' if conn_type == 'test' else 'kvm'
- arch = 'i686' if conn_type == 'test' else platform.machine()
- arch = 'ppc64' if arch == 'ppc64le' else arch
- xml = ISO_STREAM_XML % {'name': FEATURETEST_VM_NAME,
- 'domain': domain_type, 'protocol':
protocol,
- 'arch': arch}
- try:
- FeatureTests.disable_libvirt_error_logging()
- dom = conn.defineXML(xml)
- dom.undefine()
- return True
- except libvirt.libvirtError, e:
- wok_log.error(e.message)
- return False
- finally:
- FeatureTests.enable_libvirt_error_logging()
-
- @staticmethod
- def libvirt_support_nfs_probe(conn):
- def _get_xml():
- obj = E.source(E.host(name='localhost'),
E.format(type='nfs'))
- xml = ET.tostring(obj)
- return xml
- try:
- FeatureTests.disable_libvirt_error_logging()
- conn.findStoragePoolSources('netfs', _get_xml(), 0)
- except libvirt.libvirtError as e:
- wok_log.error(e.message)
- if e.get_error_code() == 38:
- # if libvirt cannot find showmount,
- # it returns 38--general system call failure
- return False
- finally:
- FeatureTests.enable_libvirt_error_logging()
-
- return True
-
- @staticmethod
- @servermethod
- def qemu_supports_iso_stream():
- host = cherrypy.server.socket_host
- port = cherrypy.server.socket_port
- cmd = "qemu-io -r http://%s:%d/images/icon-fedora.png \
- -c 'read -v 0 512'" % (host, port)
- proc = subprocess.Popen(cmd, stdout=subprocess.PIPE,
- stderr=subprocess.PIPE, shell=True)
- stdout, stderr = proc.communicate()
- return len(stderr) == 0
-
- @staticmethod
- def libvirt_support_fc_host(conn):
- try:
- FeatureTests.disable_libvirt_error_logging()
- pool = None
- pool_xml = SCSI_FC_XML % {'name': FEATURETEST_POOL_NAME}
- pool = conn.storagePoolDefineXML(pool_xml, 0)
- except libvirt.libvirtError as e:
- if e.get_error_code() == 27:
- # Libvirt requires adapter name, not needed when supports to FC
- return False
- finally:
- FeatureTests.enable_libvirt_error_logging()
- pool is None or pool.undefine()
- return True
-
- @staticmethod
- def has_metadata_support(conn):
- KIMCHI_META_URL = "https://github.com/kimchi-project/kimchi/"
- KIMCHI_NAMESPACE = "kimchi"
- with RollbackContext() as rollback:
- FeatureTests.disable_libvirt_error_logging()
- rollback.prependDefer(FeatureTests.enable_libvirt_error_logging)
- conn_type = conn.getType().lower()
- domain_type = 'test' if conn_type == 'test' else
'kvm'
- arch = 'i686' if conn_type == 'test' else platform.machine()
- arch = 'ppc64' if arch == 'ppc64le' else arch
- dom = conn.defineXML(SIMPLE_VM_XML % {'name': FEATURETEST_VM_NAME,
- 'domain': domain_type,
- 'arch': arch})
- rollback.prependDefer(dom.undefine)
- try:
- dom.setMetadata(libvirt.VIR_DOMAIN_METADATA_ELEMENT,
- "<metatest/>", KIMCHI_NAMESPACE,
- KIMCHI_META_URL,
- flags=libvirt.VIR_DOMAIN_AFFECT_CURRENT)
- return True
- except libvirt.libvirtError:
- return False
-
- @staticmethod
- def kernel_support_vfio():
- out, err, rc = run_command(['modprobe', 'vfio-pci'])
- if rc != 0:
- wok_log.warning("Unable to load Kernal module vfio-pci.")
- return False
- return True
-
- @staticmethod
- def is_nm_running():
- '''Tries to determine whether NetworkManager is
running.'''
-
- out, err, rc = run_command(['nmcli', 'dev', 'status'])
- if rc != 0:
- return False
-
- return True
-
- @staticmethod
- def has_mem_hotplug_support(conn):
- '''
- A memory device can be hot-plugged or hot-unplugged since libvirt
- version 1.2.14.
- '''
- # Libvirt < 1.2.14 does not support memory devices, so firstly, check
- # its version, then try to attach a device. These steps avoid errors
- # with Libvirt 'test' driver for KVM
- version = 1000000*1 + 1000*2 + 14
- if libvirt.getVersion() < version:
- return False
-
- with RollbackContext() as rollback:
- FeatureTests.disable_libvirt_error_logging()
- rollback.prependDefer(FeatureTests.enable_libvirt_error_logging)
- conn_type = conn.getType().lower()
- domain_type = 'test' if conn_type == 'test' else
'kvm'
- arch = 'i686' if conn_type == 'test' else platform.machine()
- arch = 'ppc64' if arch == 'ppc64le' else arch
- dom = conn.defineXML(MAXMEM_VM_XML % {'name': FEATURETEST_VM_NAME,
- 'domain': domain_type,
- 'arch': arch})
- rollback.prependDefer(dom.undefine)
- try:
- dom.attachDeviceFlags(DEV_MEM_XML,
- libvirt.VIR_DOMAIN_MEM_CONFIG)
- return True
- except libvirt.libvirtError:
- return False
diff --git a/plugins/kimchi/model/groups.py b/plugins/kimchi/model/groups.py
deleted file mode 100644
index fc63d68..0000000
--- a/plugins/kimchi/model/groups.py
+++ /dev/null
@@ -1,67 +0,0 @@
-#
-# Project Kimchi
-#
-# Copyright IBM, Corp. 2014
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-
-import grp
-
-from wok.config import config
-
-
-class GroupsModel(object):
- def __init__(self, **args):
- auth_type = config.get("authentication", "method")
- for klass in GroupsModel.__subclasses__():
- if auth_type == klass.auth_type:
- self.grp = klass(**args)
-
- def get_list(self, **args):
- if hasattr(self.grp, '_get_list'):
- return self.grp._get_list(**args)
- else:
- return list()
-
- def validate(self, gid):
- return self.grp._validate(gid)
-
-
-class PAMGroupsModel(GroupsModel):
- auth_type = 'pam'
-
- def __init__(self, **kargs):
- pass
-
- def _get_list(self):
- return sorted([group.gr_name
- for group in grp.getgrall()])
-
- def _validate(self, gid):
- try:
- grp.getgrnam(gid)
- except KeyError:
- return False
- return True
-
-
-class LDAPGroupsModel(GroupsModel):
- auth_type = 'ldap'
-
- def __init__(self, **kargs):
- pass
-
- def _validate(self, gid):
- return False
diff --git a/plugins/kimchi/model/host.py b/plugins/kimchi/model/host.py
deleted file mode 100644
index 75d4de0..0000000
--- a/plugins/kimchi/model/host.py
+++ /dev/null
@@ -1,476 +0,0 @@
-#
-# Project Kimchi
-#
-# Copyright IBM, Corp. 2014-2015
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-
-import libvirt
-import os
-import platform
-import psutil
-import time
-from cherrypy.process.plugins import BackgroundTask
-from collections import defaultdict
-
-from wok.basemodel import Singleton
-from wok.exception import InvalidOperation, InvalidParameter
-from wok.exception import NotFoundError, OperationFailed
-from wok.utils import add_task, wok_log
-from wok.xmlutils.utils import xpath_get_text
-from wok.model.tasks import TaskModel
-
-import hostdev
-from .. import disks
-from .. import netinfo
-from ..repositories import Repositories
-from ..swupdate import SoftwareUpdate
-from config import CapabilitiesModel
-from vms import DOM_STATE_MAP
-
-
-HOST_STATS_INTERVAL = 1
-
-
-class HostModel(object):
- def __init__(self, **kargs):
- self.conn = kargs['conn']
- self.objstore = kargs['objstore']
- self.task = TaskModel(**kargs)
- self.host_info = self._get_host_info()
-
- def _get_ppc_cpu_info(self):
- res = {}
- with open('/proc/cpuinfo') as f:
- for line in f.xreadlines():
- # Parse CPU, CPU's revision and CPU's clock information
- for key in ['cpu', 'revision', 'clock']:
- if key in line:
- info = line.split(':')[1].strip()
- if key == 'clock':
- value = float(info.split('MHz')[0].strip()) / 1000
- else:
- value = info.split('(')[0].strip()
- res[key] = value
-
- # Power machines show, for each cpu/core, a block with
- # all cpu information. Here we control the scan of the
- # necessary information (1st block provides
- # everything), skipping the function when find all
- # information.
- if len(res.keys()) == 3:
- return "%(cpu)s (%(revision)s) @ %(clock)s GHz\
- " % res
-
- return ""
-
- def _get_host_info(self):
- res = {}
- if platform.machine().startswith('ppc'):
- res['cpu_model'] = self._get_ppc_cpu_info()
- else:
- with open('/proc/cpuinfo') as f:
- for line in f.xreadlines():
- if "model name" in line:
- res['cpu_model'] = line.split(':')[1].strip()
- break
-
- res['cpus'] = 0
- res['memory'] = 0L
-
- # Include IBM PowerKVM name to supported distro names
- _sup_distros = platform._supported_dists + ('ibm_powerkvm',)
- # 'fedora' '17' 'Beefy Miracle'
- distro, version, codename = platform.linux_distribution(
- supported_dists=_sup_distros)
- res['os_distro'] = distro
- res['os_version'] = version
- res['os_codename'] = unicode(codename, "utf-8")
-
- return res
-
- def lookup(self, *name):
- cpus = psutil.NUM_CPUS
-
- # psutil is unstable on how to get the number of
- # cpus, different versions call it differently
- if hasattr(psutil, 'cpu_count'):
- cpus = psutil.cpu_count()
-
- elif hasattr(psutil, '_psplatform'):
- for method_name in ['_get_num_cpus', 'get_num_cpus']:
-
- method = getattr(psutil._psplatform, method_name, None)
- if method is not None:
- cpus = method()
- break
-
- self.host_info['cpus'] = cpus
- self.host_info['memory'] = psutil.phymem_usage().total
- return self.host_info
-
- def swupdate(self, *name):
- try:
- swupdate = SoftwareUpdate()
- except:
- raise OperationFailed('KCHPKGUPD0004E')
-
- pkgs = swupdate.getNumOfUpdates()
- if pkgs == 0:
- raise OperationFailed('KCHPKGUPD0001E')
-
- wok_log.debug('Host is going to be updated.')
- taskid = add_task('/plugins/kimchi/host/swupdate', swupdate.doUpdate,
- self.objstore, None)
- return self.task.lookup(taskid)
-
- def shutdown(self, args=None):
- # Check for running vms before shutdown
- running_vms = self._get_vms_list_by_state('running')
- if len(running_vms) > 0:
- raise OperationFailed("KCHHOST0001E")
-
- wok_log.info('Host is going to shutdown.')
- os.system('shutdown -h now')
-
- def reboot(self, args=None):
- # Find running VMs
- running_vms = self._get_vms_list_by_state('running')
- if len(running_vms) > 0:
- raise OperationFailed("KCHHOST0002E")
-
- wok_log.info('Host is going to reboot.')
- os.system('reboot')
-
- def _get_vms_list_by_state(self, state):
- conn = self.conn.get()
- return [dom.name().decode('utf-8')
- for dom in conn.listAllDomains(0)
- if (DOM_STATE_MAP[dom.info()[0]]) == state]
-
-
-class HostStatsModel(object):
- __metaclass__ = Singleton
-
- def __init__(self, **kargs):
- self.host_stats = defaultdict(list)
- self.host_stats_thread = BackgroundTask(HOST_STATS_INTERVAL,
- self._update_host_stats)
- self.host_stats_thread.start()
-
- def lookup(self, *name):
- return {'cpu_utilization':
self.host_stats['cpu_utilization'][-1],
- 'memory': self.host_stats['memory'][-1],
- 'disk_read_rate': self.host_stats['disk_read_rate'][-1],
- 'disk_write_rate':
self.host_stats['disk_write_rate'][-1],
- 'net_recv_rate': self.host_stats['net_recv_rate'][-1],
- 'net_sent_rate': self.host_stats['net_sent_rate'][-1]}
-
- def _update_host_stats(self):
- preTimeStamp = self.host_stats['timestamp']
- timestamp = time.time()
- # FIXME when we upgrade psutil, we can get uptime by psutil.uptime
- # we get uptime by float(open("/proc/uptime").readline().split()[0])
- # and calculate the first io_rate after the OS started.
- with open("/proc/uptime") as time_f:
- seconds = (timestamp - preTimeStamp if preTimeStamp else
- float(time_f.readline().split()[0]))
-
- self.host_stats['timestamp'] = timestamp
- self._get_host_disk_io_rate(seconds)
- self._get_host_network_io_rate(seconds)
-
- self._get_percentage_host_cpu_usage()
- self._get_host_memory_stats()
-
- # store only 60 stats (1 min)
- for key, value in self.host_stats.iteritems():
- if isinstance(value, list):
- if len(value) == 60:
- self.host_stats[key] = value[10:]
-
- def _get_percentage_host_cpu_usage(self):
- # This is cpu usage producer. This producer will calculate the usage
- # at an interval of HOST_STATS_INTERVAL.
- # The psutil.cpu_percent works as non blocking.
- # psutil.cpu_percent maintains a cpu time sample.
- # It will update the cpu time sample when it is called.
- # So only this producer can call psutil.cpu_percent in kimchi.
- self.host_stats['cpu_utilization'].append(psutil.cpu_percent(None))
-
- def _get_host_memory_stats(self):
- virt_mem = psutil.virtual_memory()
- # available:
- # the actual amount of available memory that can be given
- # instantly to processes that request more memory in bytes; this
- # is calculated by summing different memory values depending on
- # the platform (e.g. free + buffers + cached on Linux)
- memory_stats = {'total': virt_mem.total,
- 'free': virt_mem.free,
- 'cached': virt_mem.cached,
- 'buffers': virt_mem.buffers,
- 'avail': virt_mem.available}
- self.host_stats['memory'].append(memory_stats)
-
- def _get_host_disk_io_rate(self, seconds):
- disk_read_bytes = self.host_stats['disk_read_bytes']
- disk_write_bytes = self.host_stats['disk_write_bytes']
- prev_read_bytes = disk_read_bytes[-1] if disk_read_bytes else 0
- prev_write_bytes = disk_write_bytes[-1] if disk_write_bytes else 0
-
- disk_io = psutil.disk_io_counters(False)
- read_bytes = disk_io.read_bytes
- write_bytes = disk_io.write_bytes
-
- rd_rate = int(float(read_bytes - prev_read_bytes) / seconds + 0.5)
- wr_rate = int(float(write_bytes - prev_write_bytes) / seconds + 0.5)
-
- self.host_stats['disk_read_rate'].append(rd_rate)
- self.host_stats['disk_write_rate'].append(wr_rate)
- self.host_stats['disk_read_bytes'].append(read_bytes)
- self.host_stats['disk_write_bytes'].append(write_bytes)
-
- def _get_host_network_io_rate(self, seconds):
- net_recv_bytes = self.host_stats['net_recv_bytes']
- net_sent_bytes = self.host_stats['net_sent_bytes']
- prev_recv_bytes = net_recv_bytes[-1] if net_recv_bytes else 0
- prev_sent_bytes = net_sent_bytes[-1] if net_sent_bytes else 0
-
- net_ios = psutil.network_io_counters(True)
- recv_bytes = 0
- sent_bytes = 0
- for key in set(netinfo.nics() +
- netinfo.wlans()) & set(net_ios.iterkeys()):
- recv_bytes = recv_bytes + net_ios[key].bytes_recv
- sent_bytes = sent_bytes + net_ios[key].bytes_sent
-
- rx_rate = int(float(recv_bytes - prev_recv_bytes) / seconds + 0.5)
- tx_rate = int(float(sent_bytes - prev_sent_bytes) / seconds + 0.5)
-
- self.host_stats['net_recv_rate'].append(rx_rate)
- self.host_stats['net_sent_rate'].append(tx_rate)
- self.host_stats['net_recv_bytes'].append(recv_bytes)
- self.host_stats['net_sent_bytes'].append(sent_bytes)
-
-
-class HostStatsHistoryModel(object):
- def __init__(self, **kargs):
- self.history = HostStatsModel(**kargs)
-
- def lookup(self, *name):
- return {'cpu_utilization':
self.history.host_stats['cpu_utilization'],
- 'memory': self.history.host_stats['memory'],
- 'disk_read_rate':
self.history.host_stats['disk_read_rate'],
- 'disk_write_rate':
self.history.host_stats['disk_write_rate'],
- 'net_recv_rate':
self.history.host_stats['net_recv_rate'],
- 'net_sent_rate':
self.history.host_stats['net_sent_rate']}
-
-
-class PartitionsModel(object):
- def __init__(self, **kargs):
- pass
-
- def get_list(self):
- result = disks.get_partitions_names()
- return result
-
-
-class PartitionModel(object):
- def __init__(self, **kargs):
- pass
-
- def lookup(self, name):
- return disks.get_partition_details(name)
-
-
-class DevicesModel(object):
- def __init__(self, **kargs):
- self.conn = kargs['conn']
- self.caps = CapabilitiesModel(**kargs)
- self.cap_map = \
- {'net': libvirt.VIR_CONNECT_LIST_NODE_DEVICES_CAP_NET,
- 'pci': libvirt.VIR_CONNECT_LIST_NODE_DEVICES_CAP_PCI_DEV,
- 'scsi': libvirt.VIR_CONNECT_LIST_NODE_DEVICES_CAP_SCSI,
- 'scsi_host': libvirt.VIR_CONNECT_LIST_NODE_DEVICES_CAP_SCSI_HOST,
- 'storage': libvirt.VIR_CONNECT_LIST_NODE_DEVICES_CAP_STORAGE,
- 'usb_device': libvirt.VIR_CONNECT_LIST_NODE_DEVICES_CAP_USB_DEV,
- 'usb':
- libvirt.VIR_CONNECT_LIST_NODE_DEVICES_CAP_USB_INTERFACE}
- # TODO: when no longer supporting Libvirt < 1.0.5 distros
- # (like RHEL6) remove this verification and insert the
- # key 'fc_host' with the libvirt variable in the hash
- # declaration above.
- try:
- self.cap_map['fc_host'] = \
- libvirt.VIR_CONNECT_LIST_NODE_DEVICES_CAP_FC_HOST
- except AttributeError:
- self.cap_map['fc_host'] = None
-
- def get_list(self, _cap=None, _passthrough=None,
- _passthrough_affected_by=None):
- if _passthrough_affected_by is not None:
- # _passthrough_affected_by conflicts with _cap and _passthrough
- if (_cap, _passthrough) != (None, None):
- raise InvalidParameter("KCHHOST0004E")
- return sorted(
- self._get_passthrough_affected_devs(_passthrough_affected_by))
-
- if _cap == 'fc_host':
- dev_names = self._get_devices_fc_host()
- else:
- dev_names = self._get_devices_with_capability(_cap)
-
- if _passthrough is not None and _passthrough.lower() == 'true':
- conn = self.conn.get()
- passthrough_names = [
- dev['name'] for dev in hostdev.get_passthrough_dev_infos(conn)]
- dev_names = list(set(dev_names) & set(passthrough_names))
-
- dev_names.sort()
- return dev_names
-
- def _get_devices_with_capability(self, cap):
- conn = self.conn.get()
- if cap is None:
- cap_flag = 0
- else:
- cap_flag = self.cap_map.get(cap)
- if cap_flag is None:
- return []
- return [name.name() for name in conn.listAllDevices(cap_flag)]
-
- def _get_passthrough_affected_devs(self, dev_name):
- conn = self.conn.get()
- info = DeviceModel(conn=self.conn).lookup(dev_name)
- affected = hostdev.get_affected_passthrough_devices(conn, info)
- return [dev_info['name'] for dev_info in affected]
-
- def _get_devices_fc_host(self):
- conn = self.conn.get()
- # Libvirt < 1.0.5 does not support fc_host capability
- if not self.caps.fc_host_support:
- ret = []
- scsi_hosts = self._get_devices_with_capability('scsi_host')
- for host in scsi_hosts:
- xml = conn.nodeDeviceLookupByName(host).XMLDesc(0)
- path = '/device/capability/capability/@type'
- if 'fc_host' in xpath_get_text(xml, path):
- ret.append(host)
- return ret
- # Double verification to catch the case where the libvirt
- # supports fc_host but does not, for some reason, recognize
- # the libvirt.VIR_CONNECT_LIST_NODE_DEVICES_CAP_FC_HOST
- # attribute.
- if not self.cap_map['fc_host']:
- return conn.listDevices('fc_host', 0)
- return self._get_devices_with_capability('fc_host')
-
-
-class DeviceModel(object):
- def __init__(self, **kargs):
- self.conn = kargs['conn']
-
- def lookup(self, nodedev_name):
- conn = self.conn.get()
- try:
- dev = conn.nodeDeviceLookupByName(nodedev_name)
- except:
- raise NotFoundError('KCHHOST0003E', {'name': nodedev_name})
- return hostdev.get_dev_info(dev)
-
-
-class PackagesUpdateModel(object):
- def __init__(self, **kargs):
- try:
- self.host_swupdate = SoftwareUpdate()
- except:
- self.host_swupdate = None
-
- def get_list(self):
- if self.host_swupdate is None:
- raise OperationFailed('KCHPKGUPD0004E')
-
- return self.host_swupdate.getUpdates()
-
-
-class PackageUpdateModel(object):
- def __init__(self, **kargs):
- pass
-
- def lookup(self, name):
- try:
- swupdate = SoftwareUpdate()
- except Exception:
- raise OperationFailed('KCHPKGUPD0004E')
-
- return swupdate.getUpdate(name)
-
-
-class RepositoriesModel(object):
- def __init__(self, **kargs):
- try:
- self.host_repositories = Repositories()
- except:
- self.host_repositories = None
-
- def get_list(self):
- if self.host_repositories is None:
- raise InvalidOperation('KCHREPOS0014E')
-
- return sorted(self.host_repositories.getRepositories())
-
- def create(self, params):
- if self.host_repositories is None:
- raise InvalidOperation('KCHREPOS0014E')
-
- return self.host_repositories.addRepository(params)
-
-
-class RepositoryModel(object):
- def __init__(self, **kargs):
- try:
- self._repositories = Repositories()
- except:
- self._repositories = None
-
- def lookup(self, repo_id):
- if self._repositories is None:
- raise InvalidOperation('KCHREPOS0014E')
-
- return self._repositories.getRepository(repo_id)
-
- def enable(self, repo_id):
- if self._repositories is None:
- raise InvalidOperation('KCHREPOS0014E')
-
- return self._repositories.enableRepository(repo_id)
-
- def disable(self, repo_id):
- if self._repositories is None:
- raise InvalidOperation('KCHREPOS0014E')
-
- return self._repositories.disableRepository(repo_id)
-
- def update(self, repo_id, params):
- if self._repositories is None:
- raise InvalidOperation('KCHREPOS0014E')
-
- return self._repositories.updateRepository(repo_id, params)
-
- def delete(self, repo_id):
- if self._repositories is None:
- raise InvalidOperation('KCHREPOS0014E')
-
- return self._repositories.removeRepository(repo_id)
diff --git a/plugins/kimchi/model/hostdev.py b/plugins/kimchi/model/hostdev.py
deleted file mode 100644
index 31211c7..0000000
--- a/plugins/kimchi/model/hostdev.py
+++ /dev/null
@@ -1,324 +0,0 @@
-#
-# Kimchi
-#
-# Copyright IBM, Corp. 2014
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-
-import os
-from pprint import pformat
-from pprint import pprint
-
-from wok.utils import wok_log
-from wok.xmlutils.utils import dictize
-
-from libvirtconnection import LibvirtConnection
-
-
-def _get_all_host_dev_infos(libvirt_conn):
- node_devs = libvirt_conn.listAllDevices(0)
- return [get_dev_info(node_dev) for node_dev in node_devs]
-
-
-def _get_dev_info_tree(dev_infos):
- devs = dict([(dev_info['name'], dev_info) for dev_info in dev_infos])
- root = None
- for dev_info in dev_infos:
- if dev_info['parent'] is None:
- root = dev_info
- continue
-
- try:
- parent = devs[dev_info['parent']]
- except KeyError:
- wok_log.error('Parent %s of device %s does not exist.',
- dev_info['parent'], dev_info['name'])
- continue
-
- try:
- children = parent['children']
- except KeyError:
- parent['children'] = [dev_info]
- else:
- children.append(dev_info)
- return root
-
-
-def _is_pci_qualified(pci_dev):
- # PCI bridge is not suitable to passthrough
- # KVM does not support passthrough graphic card now
- blacklist_classes = (0x030000, 0x060000)
-
- with open(os.path.join(pci_dev['path'], 'class')) as f:
- pci_class = int(f.readline().strip(), 16)
-
- if pci_class & 0xff0000 in blacklist_classes:
- return False
-
- return True
-
-
-def get_passthrough_dev_infos(libvirt_conn):
- ''' Get devices eligible to be passed through to VM. '''
-
- def is_eligible(dev):
- return dev['device_type'] in ('usb_device', 'scsi') or \
- (dev['device_type'] == 'pci' and _is_pci_qualified(dev))
-
- dev_infos = _get_all_host_dev_infos(libvirt_conn)
-
- return [dev_info for dev_info in dev_infos if is_eligible(dev_info)]
-
-
-def _get_same_iommugroup_devices(dev_infos, device_info):
- dev_dict = dict([(dev_info['name'], dev_info) for dev_info in dev_infos])
-
- def get_iommu_group(dev_info):
- # Find out the iommu group of a given device.
- # Child device belongs to the same iommu group as the parent device.
- try:
- return dev_info['iommuGroup']
- except KeyError:
- pass
-
- parent = dev_info['parent']
- while parent is not None:
- try:
- parent_info = dev_dict[parent]
- except KeyError:
- wok_log.error("Parent %s of device %s does not exist",
- parent, dev_info['name'])
- break
-
- try:
- iommuGroup = parent_info['iommuGroup']
- except KeyError:
- pass
- else:
- return iommuGroup
-
- parent = parent_info['parent']
-
- return None
-
- iommu_group = get_iommu_group(device_info)
-
- if iommu_group is None:
- return []
-
- return [dev_info for dev_info in dev_infos
- if dev_info['name'] != device_info['name'] and
- get_iommu_group(dev_info) == iommu_group]
-
-
-def _get_children_devices(dev_infos, device_info):
- def get_children_recursive(parent):
- try:
- children = parent['children']
- except KeyError:
- return []
-
- result = []
- for child in children:
- result.append(child)
- result.extend(get_children_recursive(child))
-
- return result
-
- # Annotate every the dev_info element with children information
- _get_dev_info_tree(dev_infos)
-
- for dev_info in dev_infos:
- if dev_info['name'] == device_info['name']:
- return get_children_recursive(dev_info)
-
- return []
-
-
-def get_affected_passthrough_devices(libvirt_conn, passthrough_dev):
- dev_infos = _get_all_host_dev_infos(libvirt_conn)
-
- group_devices = _get_same_iommugroup_devices(dev_infos, passthrough_dev)
- if not group_devices:
- # On host without iommu group support, the affected devices should
- # at least include all children devices
- group_devices.extend(_get_children_devices(dev_infos, passthrough_dev))
-
- return group_devices
-
-
-def get_dev_info(node_dev):
- ''' Parse the node device XML string into dict according to
-
http://libvirt.org/formatnode.html.
-
- scsi_generic is not documented in libvirt official website. Try to
- parse scsi_generic according to the following libvirt path series.
-
https://www.redhat.com/archives/libvir-list/2013-June/msg00014.html
-
- scsi_target is not documented in libvirt official website. Try to
- parse scsi_target according to the libvirt commit db19834a0a.
- '''
-
- xmlstr = node_dev.XMLDesc(0)
- info = dictize(xmlstr)['device']
- dev_type = info['capability'].pop('type')
- info['device_type'] = dev_type
- cap_dict = info.pop('capability')
- info.update(cap_dict)
- info['parent'] = node_dev.parent()
-
- if dev_type in ('scsi', 'scsi_generic', 'scsi_target',
'system', 'usb'):
- return info
-
- if dev_type in ('net', 'pci', 'scsi_host', 'storage',
'usb_device'):
- return globals()['_get_%s_dev_info' % dev_type](info)
-
- wok_log.error("Unknown device type: %s", dev_type)
- return info
-
-
-def _get_net_dev_info(info):
- cap = info.pop('capability')
- links = {"80203": "IEEE 802.3", "80211": "IEEE
802.11"}
- link_raw = cap['type']
- info['link_type'] = links.get(link_raw, link_raw)
-
- return info
-
-
-def _get_pci_dev_info(info):
- for k in ('vendor', 'product'):
- try:
- description = info[k].pop('pyval')
- except KeyError:
- description = None
- info[k]['description'] = description
- if 'path' not in info:
- # Old libvirt does not provide syspath info
- info['path'] = \
- "/sys/bus/pci/devices/" \
- "%(domain)04x:%(bus)02x:%(slot)02x.%(function)01x" % {
- 'domain': info['domain'], 'bus':
info['bus'],
- 'slot': info['slot'], 'function':
info['function']}
- try:
- info['iommuGroup'] = int(info['iommuGroup']['number'])
- except KeyError:
- # Old libvirt does not provide syspath info, figure it out ourselves
- iommu_link = os.path.join(info['path'], 'iommu_group')
- if os.path.exists(iommu_link):
- iommu_path = os.path.realpath(iommu_link)
- try:
- info['iommuGroup'] = int(iommu_path.rsplit('/', 1)[1])
- except (ValueError, IndexError):
- # No IOMMU group support at all.
- pass
- else:
- # No IOMMU group support at all.
- pass
- return info
-
-
-def _get_scsi_host_dev_info(info):
- try:
- cap_info = info.pop('capability')
- except KeyError:
- # kimchi.model.libvirtstoragepool.ScsiPoolDef assumes
- # info['adapter']['type'] always exists.
- info['adapter'] = {'type': ''}
- return info
- if isinstance(cap_info, list):
- info['adapter'] = {}
- for cap in cap_info:
- if cap['type'] == 'vport_ops':
- del cap['type']
- info['adapter']['vport_ops'] = cap
- else:
- info['adapter'].update(cap)
- else:
- info['adapter'] = cap_info
- return info
-
-
-def _get_storage_dev_info(info):
- try:
- cap_info = info.pop('capability')
- except KeyError:
- return info
-
- if cap_info['type'] == 'removable':
- cap_info['available'] = bool(cap_info.pop('media_available'))
- if cap_info['available']:
- for k in ('size', 'label'):
- try:
- cap_info[k] = cap_info.pop('media_' + k)
- except KeyError:
- cap_info[k] = None
- info['media'] = cap_info
- return info
-
-
-def _get_usb_device_dev_info(info):
- for k in ('vendor', 'product'):
- try:
- info[k]['description'] = info[k].pop('pyval')
- except KeyError:
- # Some USB devices don't provide vendor/product description.
- pass
- return info
-
-
-# For test and debug
-def _print_host_dev_tree(libvirt_conn):
- dev_infos = _get_all_host_dev_infos(libvirt_conn)
- root = _get_dev_info_tree(dev_infos)
- if root is None:
- print "No device found"
- return
- print '-----------------'
- print '\n'.join(_format_dev_node(root))
-
-
-def _format_dev_node(node):
- try:
- children = node['children']
- del node['children']
- except KeyError:
- children = []
-
- lines = []
- lines.extend([' ~' + line for line in pformat(node).split('\n')])
-
- count = len(children)
- for i, child in enumerate(children):
- if count == 1:
- lines.append(' \-----------------')
- else:
- lines.append(' +-----------------')
- clines = _format_dev_node(child)
- if i == count - 1:
- p = ' '
- else:
- p = ' |'
- lines.extend([p + cline for cline in clines])
- lines.append('')
-
- return lines
-
-
-if __name__ == '__main__':
- libvirt_conn = LibvirtConnection('qemu:///system').get()
- _print_host_dev_tree(libvirt_conn)
- print 'Eligible passthrough devices:'
- pprint(get_passthrough_dev_infos(libvirt_conn))
diff --git a/plugins/kimchi/model/interfaces.py b/plugins/kimchi/model/interfaces.py
deleted file mode 100644
index 149afe3..0000000
--- a/plugins/kimchi/model/interfaces.py
+++ /dev/null
@@ -1,44 +0,0 @@
-#
-# Project Kimchi
-#
-# Copyright IBM, Corp. 2014
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-
-from wok.exception import NotFoundError
-
-from .. import netinfo
-from networks import NetworksModel
-
-
-class InterfacesModel(object):
- def __init__(self, **kargs):
- self.conn = kargs['conn']
- self.networks = NetworksModel(**kargs)
-
- def get_list(self):
- return list(set(netinfo.all_favored_interfaces()) -
- set(self.networks.get_all_networks_interfaces()))
-
-
-class InterfaceModel(object):
- def __init__(self, **kargs):
- pass
-
- def lookup(self, name):
- try:
- return netinfo.get_interface_info(name)
- except ValueError:
- raise NotFoundError("KCHIFACE0001E", {'name': name})
diff --git a/plugins/kimchi/model/libvirtconnection.py
b/plugins/kimchi/model/libvirtconnection.py
deleted file mode 100644
index 73f3dcf..0000000
--- a/plugins/kimchi/model/libvirtconnection.py
+++ /dev/null
@@ -1,136 +0,0 @@
-#
-# Project Kimchi
-#
-# Copyright IBM, Corp. 2014
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-
-import cherrypy
-import libvirt
-import threading
-import time
-
-from wok.utils import wok_log
-
-
-class LibvirtConnection(object):
- _connections = {}
- _connectionLock = threading.Lock()
-
- def __init__(self, uri):
- self.uri = uri
- if self.uri not in LibvirtConnection._connections:
- LibvirtConnection._connections[self.uri] = {}
- self._connections = LibvirtConnection._connections[self.uri]
- self.wrappables = self.get_wrappable_objects()
-
- def get_wrappable_objects(self):
- """
- When a wrapped function returns an instance of another libvirt object,
- we also want to wrap that object so we can catch errors that happen
- when calling its methods.
- """
- objs = []
- for name in ('virDomain', 'virDomainSnapshot',
'virInterface',
- 'virNWFilter', 'virNetwork',
'virNodeDevice', 'virSecret',
- 'virStoragePool', 'virStorageVol',
'virStream'):
- try:
- attr = getattr(libvirt, name)
- except AttributeError:
- pass
- objs.append(attr)
- return tuple(objs)
-
- def get(self, conn_id=0):
- """
- Return current connection to libvirt or open a new one. Wrap all
- callable libvirt methods so we can catch connection errors and handle
- them by restarting the server.
- """
- def wrapMethod(f):
- def wrapper(*args, **kwargs):
- try:
- ret = f(*args, **kwargs)
- return ret
- except libvirt.libvirtError as e:
- edom = e.get_error_domain()
- ecode = e.get_error_code()
- EDOMAINS = (libvirt.VIR_FROM_REMOTE,
- libvirt.VIR_FROM_RPC)
- ECODES = (libvirt.VIR_ERR_SYSTEM_ERROR,
- libvirt.VIR_ERR_INTERNAL_ERROR,
- libvirt.VIR_ERR_NO_CONNECT,
- libvirt.VIR_ERR_INVALID_CONN)
- if edom in EDOMAINS and ecode in ECODES:
- wok_log.error('Connection to libvirt broken. '
- 'Recycling. ecode: %d edom: %d' %
- (ecode, edom))
- with LibvirtConnection._connectionLock:
- self._connections[conn_id] = None
- raise
- wrapper.__name__ = f.__name__
- wrapper.__doc__ = f.__doc__
- return wrapper
-
- with LibvirtConnection._connectionLock:
- conn = self._connections.get(conn_id)
- if not conn:
- retries = 5
- while True:
- retries = retries - 1
- try:
- conn = libvirt.open(self.uri)
- break
- except libvirt.libvirtError:
- wok_log.error('Unable to connect to libvirt.')
- if not retries:
- wok_log.error("Unable to establish connection "
- "with libvirt. Please check "
- "your libvirt URI which is often "
- "defined in "
- "/etc/libvirt/libvirt.conf")
- cherrypy.engine.stop()
- exit(1)
- time.sleep(2)
-
- for name in dir(libvirt.virConnect):
- method = getattr(conn, name)
- if callable(method) and not name.startswith('_'):
- setattr(conn, name, wrapMethod(method))
-
- for cls in self.wrappables:
- for name in dir(cls):
- method = getattr(cls, name)
- if callable(method) and not name.startswith('_'):
- setattr(cls, name, wrapMethod(method))
-
- self._connections[conn_id] = conn
- # In case we're running into troubles with keeping the
- # connections alive we should place here:
- # conn.setKeepAlive(interval=5, count=3)
- # However the values need to be considered wisely to not affect
- # hosts which are hosting a lot of virtual machines
- return conn
-
- def isQemuURI(self):
- """
- This method will return True or Value when the system libvirt
- URI is a qemu based URI. For example:
- qemu:///system or qemu+tcp://someipaddress/system
- """
- if self.get().getURI().startswith('qemu'):
- return True
- else:
- return False
diff --git a/plugins/kimchi/model/libvirtstoragepool.py
b/plugins/kimchi/model/libvirtstoragepool.py
deleted file mode 100644
index b22856b..0000000
--- a/plugins/kimchi/model/libvirtstoragepool.py
+++ /dev/null
@@ -1,264 +0,0 @@
-#
-# Project Kimchi
-#
-# Copyright IBM, Corp. 2014
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-
-import libvirt
-import lxml.etree as ET
-import os
-import tempfile
-from lxml.builder import E
-
-from wok.exception import InvalidParameter, OperationFailed, TimeoutExpired
-from wok.rollbackcontext import RollbackContext
-from wok.utils import parse_cmd_output, run_command, wok_log
-
-from ..iscsi import TargetClient
-
-
-class StoragePoolDef(object):
- @classmethod
- def create(cls, poolArgs):
- for klass in cls.__subclasses__():
- if poolArgs['type'] == klass.poolType:
- return klass(poolArgs)
- raise OperationFailed("KCHPOOL0014E", {'type':
poolArgs['type']})
-
- def __init__(self, poolArgs):
- self.poolArgs = poolArgs
-
- def prepare(self, conn):
- ''' Validate pool arguments and perform preparations. Operation
which
- would cause side effect should be put here. Subclasses can optionally
- override this method, or it always succeeds by default. '''
- pass
-
- @property
- def xml(self):
- ''' Subclasses have to override this method to actually generate the
- storage pool XML definition. Should cause no side effect and be
- idempotent'''
- # TODO: When add new pool type, should also add the related test in
- # tests/test_storagepool.py
- raise OperationFailed("KCHPOOL0015E", {'pool': self})
-
-
-class DirPoolDef(StoragePoolDef):
- poolType = 'dir'
-
- @property
- def xml(self):
- # Required parameters
- # name:
- # type:
- # path:
- pool = E.pool(type='dir')
- pool.append(E.name(self.poolArgs['name']))
- pool.append(E.target(E.path(self.poolArgs['path'])))
- return ET.tostring(pool, encoding='unicode', pretty_print=True)
-
-
-class NetfsPoolDef(StoragePoolDef):
- poolType = 'netfs'
-
- def __init__(self, poolArgs):
- super(NetfsPoolDef, self).__init__(poolArgs)
- self.path = '/var/lib/kimchi/nfs_mount/' + self.poolArgs['name']
-
- def prepare(self, conn):
- mnt_point = tempfile.mkdtemp(dir='/tmp')
- export_path = "%s:%s" % (
- self.poolArgs['source']['host'],
self.poolArgs['source']['path'])
- mount_cmd = ["mount", "-o",
'soft,timeo=100,retrans=3,retry=0',
- export_path, mnt_point]
- umount_cmd = ["umount", "-f", export_path]
- mounted = False
- # Due to an NFS bug (See Red Hat BZ 1023059), NFSv4 exports may take
- # 10-15 seconds to mount the first time.
- cmd_timeout = 15
-
- with RollbackContext() as rollback:
- rollback.prependDefer(os.rmdir, mnt_point)
- try:
- run_command(mount_cmd, cmd_timeout)
- rollback.prependDefer(run_command, umount_cmd, cmd_timeout)
- except TimeoutExpired:
- raise InvalidParameter("KCHPOOL0012E", {'path':
export_path})
- with open("/proc/mounts", "rb") as f:
- rawMounts = f.read()
- output_items = ['dev_path', 'mnt_point', 'type']
- mounts = parse_cmd_output(rawMounts, output_items)
- for item in mounts:
- if 'dev_path' in item and item['dev_path'] ==
export_path:
- mounted = True
-
- if not mounted:
- raise InvalidParameter("KCHPOOL0013E", {'path':
export_path})
-
- @property
- def xml(self):
- # Required parameters
- # name:
- # type:
- # source[host]:
- # source[path]:
- pool = E.pool(type='netfs')
- pool.append(E.name(self.poolArgs['name']))
-
- source = E.source()
- source.append(E.host(name=self.poolArgs['source']['host']))
- source.append(E.dir(path=self.poolArgs['source']['path']))
-
- pool.append(source)
- pool.append(E.target(E.path(self.path)))
- return ET.tostring(pool, encoding='unicode', pretty_print=True)
-
-
-class LogicalPoolDef(StoragePoolDef):
- poolType = 'logical'
-
- def __init__(self, poolArgs):
- super(LogicalPoolDef, self).__init__(poolArgs)
- self.path = '/dev/' + self.poolArgs['name']
-
- @property
- def xml(self):
- # Required parameters
- # name:
- # type:
- # source[devices]:
- pool = E.pool(type='logical')
- pool.append(E.name(self.poolArgs['name']))
-
- source = E.source()
- for device_path in self.poolArgs['source']['devices']:
- source.append(E.device(path=device_path))
-
- pool.append(source)
- pool.append(E.target(E.path(self.path)))
- return ET.tostring(pool, encoding='unicode', pretty_print=True)
-
-
-class ScsiPoolDef(StoragePoolDef):
- poolType = 'scsi'
-
- def prepare(self, conn=None):
- tmp_name = self.poolArgs['source']['name']
- self.poolArgs['source']['name'] =
tmp_name.replace('scsi_', '')
- # fc_host adapters type are only available in libvirt >= 1.0.5
- if not self.poolArgs['fc_host_support']:
- self.poolArgs['source']['adapter']['type'] =
'scsi_host'
- msg = "Libvirt version <= 1.0.5. Setting SCSI host name as
'%s'; "\
- "setting SCSI adapter type as 'scsi_host'; "\
- "ignoring wwnn and wwpn." % tmp_name
- wok_log.info(msg)
- # Path for Fibre Channel scsi hosts
- self.poolArgs['path'] = '/dev/disk/by-path'
- if not self.poolArgs['source']['adapter']['type']:
- self.poolArgs['source']['adapter']['type'] =
'scsi_host'
-
- @property
- def xml(self):
- # Required parameters
- # name:
- # source[adapter][type]:
- # source[name]:
- # source[adapter][wwnn]:
- # source[adapter][wwpn]:
- # path:
- pool = E.pool(type='scsi')
- pool.append(E.name(self.poolArgs['name']))
-
- adapter =
E.adapter(type=self.poolArgs['source']['adapter']['type'])
- adapter.set('name', self.poolArgs['source']['name'])
- adapter.set('wwnn',
self.poolArgs['source']['adapter']['wwnn'])
- adapter.set('wwpn',
self.poolArgs['source']['adapter']['wwpn'])
-
- pool.append(E.source(adapter))
- pool.append(E.target(E.path(self.poolArgs['path'])))
- return ET.tostring(pool, encoding='unicode', pretty_print=True)
-
-
-class IscsiPoolDef(StoragePoolDef):
- poolType = 'iscsi'
-
- def prepare(self, conn):
- source = self.poolArgs['source']
- if not TargetClient(**source).validate():
- msg_args = {'host': source['host'], 'target':
source['target']}
- raise OperationFailed("KCHISCSI0002E", msg_args)
- self._prepare_auth(conn)
-
- def _prepare_auth(self, conn):
- try:
- auth = self.poolArgs['source']['auth']
- except KeyError:
- return
-
- try:
- virSecret = conn.secretLookupByUsage(
- libvirt.VIR_SECRET_USAGE_TYPE_ISCSI, self.poolArgs['name'])
- except libvirt.libvirtError:
- secret = E.secret(ephemeral='no', private='yes')
-
- description = E.description('Secret for iSCSI storage pool %s' %
- self.poolArgs['name'])
- secret.append(description)
- secret.append(E.auth(type='chap',
username=auth['username']))
-
- usage = E.usage(type='iscsi')
- usage.append(E.target(self.poolArgs['name']))
- secret.append(usage)
- virSecret = conn.secretDefineXML(ET.tostring(secret))
-
- virSecret.setValue(auth['password'])
-
- @property
- def xml(self):
- # Required parameters
- # name:
- # type:
- # source[host]:
- # source[target]:
- #
- # Optional parameters
- # source[port]:
- pool = E.pool(type='iscsi')
- pool.append(E.name(self.poolArgs['name']))
-
- host = E.host(name=self.poolArgs['source']['host'])
- port = self.poolArgs['source'].get('port')
- if port is not None:
- host.set('port', str(port))
-
- source = E.source(host)
- source.append(E.device(path=self.poolArgs['source']['target']))
-
- source_auth = self.poolArgs['source'].get('auth')
- if source_auth is not None:
- auth = E.auth(type='chap')
- auth.set('username', source_auth['username'])
-
- secret = E.secret(type='iscsi')
- secret.set('usage', self.poolArgs['name'])
- auth.append(secret)
-
- source.append(auth)
-
- pool.append(source)
- pool.append(E.target(E.path('/dev/disk/by-id')))
- return ET.tostring(pool, encoding='unicode', pretty_print=True)
diff --git a/plugins/kimchi/model/model.py b/plugins/kimchi/model/model.py
deleted file mode 100644
index 0c94f63..0000000
--- a/plugins/kimchi/model/model.py
+++ /dev/null
@@ -1,52 +0,0 @@
-#
-# Project Kimchi
-#
-# Copyright IBM, Corp. 2014-2015
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-
-import inspect
-import os
-
-from wok.basemodel import BaseModel
-from wok.objectstore import ObjectStore
-from wok.utils import import_module, listPathModules
-
-from libvirtconnection import LibvirtConnection
-
-
-class Model(BaseModel):
- def __init__(self, libvirt_uri=None, objstore_loc=None):
-
- self.objstore = ObjectStore(objstore_loc)
- self.conn = LibvirtConnection(libvirt_uri)
- kargs = {'objstore': self.objstore, 'conn': self.conn}
-
- this = os.path.basename(__file__)
- this_mod = os.path.splitext(this)[0]
-
- models = []
- for mod_name in listPathModules(os.path.dirname(__file__)):
- if mod_name.startswith("_") or mod_name == this_mod:
- continue
-
- module = import_module('plugins.kimchi.model.' + mod_name)
- members = inspect.getmembers(module, inspect.isclass)
- for cls_name, instance in members:
- if inspect.getmodule(instance) == module:
- if cls_name.endswith('Model'):
- models.append(instance(**kargs))
-
- return super(Model, self).__init__(models)
diff --git a/plugins/kimchi/model/networks.py b/plugins/kimchi/model/networks.py
deleted file mode 100644
index b579865..0000000
--- a/plugins/kimchi/model/networks.py
+++ /dev/null
@@ -1,382 +0,0 @@
-#
-# Project Kimchi
-#
-# Copyright IBM, Corp. 2014-2015
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-
-import ipaddr
-import libvirt
-import sys
-import time
-from xml.sax.saxutils import escape
-
-from wok.config import PluginPaths
-from wok.exception import InvalidOperation, InvalidParameter
-from wok.exception import MissingParameter, NotFoundError, OperationFailed
-from wok.rollbackcontext import RollbackContext
-from wok.utils import run_command, wok_log
-from wok.xmlutils.utils import xpath_get_text
-
-from .. import netinfo
-from .. import network as knetwork
-from ..osinfo import defaults as tmpl_defaults
-from ..xmlutils.network import create_vlan_tagged_bridge_xml
-from ..xmlutils.network import to_network_xml
-
-
-KIMCHI_BRIDGE_PREFIX = 'kb'
-
-
-class NetworksModel(object):
- def __init__(self, **kargs):
- self.conn = kargs['conn']
- if self.conn.isQemuURI():
- self._check_default_networks()
-
- def _check_default_networks(self):
- networks = list(set(tmpl_defaults['networks']))
- conn = self.conn.get()
-
- error_msg = ("Please, check the configuration in %s/template.conf to "
- "ensure it lists only valid networks." %
- PluginPaths('kimchi').conf_dir)
-
- for net_name in networks:
- try:
- net = conn.networkLookupByName(net_name)
- except libvirt.libvirtError, e:
- msg = "Fatal: Unable to find network %s."
- wok_log.error(msg, net_name)
- wok_log.error(error_msg)
- wok_log.error("Details: %s", e.message)
- sys.exit(1)
-
- if net.isActive() == 0:
- try:
- net.create()
- except libvirt.libvirtError as e:
- msg = "Fatal: Unable to activate network %s."
- wok_log.error(msg, net_name)
- wok_log.error(error_msg)
- wok_log.error("Details: %s", e.message)
- sys.exit(1)
-
- def create(self, params):
- conn = self.conn.get()
- name = params['name']
- if name in self.get_list():
- raise InvalidOperation("KCHNET0001E", {'name': name})
-
- connection = params["connection"]
- # set forward mode, isolated do not need forward
- if connection != 'isolated':
- params['forward'] = {'mode': connection}
-
- # set subnet, bridge network do not need subnet
- if connection in ["nat", 'isolated']:
- self._set_network_subnet(params)
-
- # only bridge network need bridge(linux bridge) or interface(macvtap)
- if connection == 'bridge':
- self._set_network_bridge(params)
-
- params['name'] = escape(params['name'])
- xml = to_network_xml(**params)
-
- try:
- network = conn.networkDefineXML(xml.encode("utf-8"))
- network.setAutostart(True)
- except libvirt.libvirtError as e:
- raise OperationFailed("KCHNET0008E",
- {'name': name, 'err':
e.get_error_message()})
-
- return name
-
- def get_list(self):
- conn = self.conn.get()
- names = conn.listNetworks() + conn.listDefinedNetworks()
- return sorted(map(lambda x: x.decode('utf-8'), names))
-
- def _get_available_address(self, addr_pools=[]):
- invalid_addrs = []
- for net_name in self.get_list():
- network = NetworkModel.get_network(self.conn.get(), net_name)
- xml = network.XMLDesc(0)
- subnet = NetworkModel.get_network_from_xml(xml)['subnet']
- subnet and invalid_addrs.append(ipaddr.IPNetwork(subnet))
- addr_pools = addr_pools if addr_pools else knetwork.PrivateNets
- return knetwork.get_one_free_network(invalid_addrs, addr_pools)
-
- def _set_network_subnet(self, params):
- netaddr = params.get('subnet', '')
- # lookup a free network address for nat and isolated automatically
- if not netaddr:
- netaddr = self._get_available_address()
- if not netaddr:
- raise OperationFailed("KCHNET0009E", {'name':
params['name']})
-
- try:
- ip = ipaddr.IPNetwork(netaddr)
- except ValueError:
- raise InvalidParameter("KCHNET0003E", {'subent': netaddr,
- 'network':
params['name']})
-
- if ip.ip == ip.network:
- ip.ip = ip.ip + 1
-
- dhcp_start = str(ip.ip + ip.numhosts / 2)
- dhcp_end = str(ip.ip + ip.numhosts - 2)
- params.update({'net': str(ip),
- 'dhcp': {'range': {'start': dhcp_start,
- 'end': dhcp_end}}})
-
- def _ensure_iface_up(self, iface):
- if netinfo.operstate(iface) != 'up':
- _, err, rc = run_command(['ip', 'link', 'set',
'dev', iface, 'up'])
- if rc != 0:
- raise OperationFailed("KCHNET0020E",
- {'iface': iface, 'err': err})
- # Add a delay to wait for the link change takes into effect.
- for i in range(10):
- time.sleep(1)
- if netinfo.operstate(iface) == 'up':
- break
- else:
- raise OperationFailed("KCHNET0021E", {'iface': iface})
-
- def _set_network_bridge(self, params):
- try:
- iface = params['interface']
- if iface in self.get_all_networks_interfaces():
- msg_args = {'iface': iface, 'network':
params['name']}
- raise InvalidParameter("KCHNET0006E", msg_args)
- except KeyError:
- raise MissingParameter("KCHNET0004E", {'name':
params['name']})
-
- self._ensure_iface_up(iface)
- if netinfo.is_bridge(iface):
- if 'vlan_id' in params:
- raise InvalidParameter('KCHNET0019E', {'name': iface})
- params['bridge'] = iface
- elif netinfo.is_bare_nic(iface) or netinfo.is_bonding(iface):
- if params.get('vlan_id') is None:
- params['forward']['dev'] = iface
- else:
- params['bridge'] = \
- self._create_vlan_tagged_bridge(str(iface),
- str(params['vlan_id']))
- else:
- raise InvalidParameter("KCHNET0007E")
-
- def get_all_networks_interfaces(self):
- net_names = self.get_list()
- interfaces = []
- for name in net_names:
- conn = self.conn.get()
- network = conn.networkLookupByName(name.encode("utf-8"))
- xml = network.XMLDesc(0)
- net_dict = NetworkModel.get_network_from_xml(xml)
- forward = net_dict['forward']
- (forward['mode'] == 'bridge' and forward['interface']
and
- interfaces.append(forward['interface'][0]) is None or
- interfaces.extend(forward['interface'] + forward['pf']))
- net_dict['bridge'] and interfaces.append(net_dict['bridge'])
- return interfaces
-
- def _create_vlan_tagged_bridge(self, interface, vlan_id):
- # Truncate the interface name if it exceeds 8 characters to make sure
- # the length of bridge name is less than 15 (its maximum value).
- br_name = KIMCHI_BRIDGE_PREFIX + interface[-8:] + '-' + vlan_id
- br_xml = create_vlan_tagged_bridge_xml(br_name, interface, vlan_id)
- conn = self.conn.get()
-
- bridges = []
- for net in conn.listAllNetworks():
- # Bridged networks do not have a bridge name
- # So in those cases, libvirt raises an error when trying to get
- # the bridge name
- try:
- bridges.append(net.bridgeName())
- except libvirt.libvirtError, e:
- wok_log.error(e.message)
-
- if br_name in bridges:
- raise InvalidOperation("KCHNET0010E", {'iface': br_name})
-
- with RollbackContext() as rollback:
- try:
- vlan_tagged_br = conn.interfaceDefineXML(br_xml, 0)
- rollback.prependDefer(vlan_tagged_br.destroy)
- vlan_tagged_br.create(0)
- except libvirt.libvirtError as e:
- raise OperationFailed(e.message)
- else:
- return br_name
-
-
-class NetworkModel(object):
- def __init__(self, **kargs):
- self.conn = kargs['conn']
- self.objstore = kargs['objstore']
-
- def lookup(self, name):
- network = self.get_network(self.conn.get(), name)
- xml = network.XMLDesc(0)
- net_dict = self.get_network_from_xml(xml)
- subnet = net_dict['subnet']
- dhcp = net_dict['dhcp']
- forward = net_dict['forward']
- interface = net_dict['bridge']
-
- connection = forward['mode'] or "isolated"
- # FIXME, if we want to support other forward mode well.
- if connection == 'bridge':
- # macvtap bridge
- interface = interface or forward['interface'][0]
- # exposing the network on linux bridge or macvtap interface
- interface_subnet = knetwork.get_dev_netaddr(interface)
- subnet = subnet if subnet else interface_subnet
-
- # libvirt use format 192.168.0.1/24, standard should be 192.168.0.0/24
- #
http://www.ovirt.org/File:Issue3.png
- if subnet:
- subnet = ipaddr.IPNetwork(subnet)
- subnet = "%s/%s" % (subnet.network, subnet.prefixlen)
-
- return {'connection': connection,
- 'interface': interface,
- 'subnet': subnet,
- 'dhcp': dhcp,
- 'vms': self._get_vms_attach_to_a_network(name),
- 'in_use': self._is_network_in_use(name),
- 'autostart': network.autostart() == 1,
- 'state': network.isActive() and "active" or
"inactive",
- 'persistent': True if network.isPersistent() else False}
-
- def _is_network_in_use(self, name):
- # All the networks listed as default in template.conf file should not
- # be deactivate or deleted. Otherwise, we will allow user create
- # inconsistent templates from scratch
- if name in tmpl_defaults['networks']:
- return True
-
- vms = self._get_vms_attach_to_a_network(name)
- return bool(vms) or self._is_network_used_by_template(name)
-
- def _is_network_used_by_template(self, network):
- with self.objstore as session:
- templates = session.get_list('template')
- for tmpl in templates:
- tmpl_net = session.get('template', tmpl)['networks']
- if network in tmpl_net:
- return True
- return False
-
- def _get_vms_attach_to_a_network(self, network, filter="all"):
- DOM_STATE_MAP = {'nostate': 0, 'running': 1, 'blocked':
2,
- 'paused': 3, 'shutdown': 4, 'shutoff':
5,
- 'crashed': 6}
- state = DOM_STATE_MAP.get(filter)
- vms = []
- conn = self.conn.get()
- for dom in conn.listAllDomains(0):
- networks = self._vm_get_networks(dom)
- if network.encode('utf-8') in networks and \
- (state is None or state == dom.state(0)[0]):
- vms.append(dom.name())
- return vms
-
- def _vm_get_networks(self, dom):
- xml = dom.XMLDesc(0)
- xpath =
"/domain/devices/interface[@type='network']/source/@network"
- return xpath_get_text(xml, xpath)
-
- def activate(self, name):
- network = self.get_network(self.conn.get(), name)
- try:
- network.create()
- except libvirt.libvirtError, e:
- raise OperationFailed('KCHNET0022E', {'name': name,
- 'err': e.message})
-
- def deactivate(self, name):
- if self._is_network_in_use(name):
- vms = self._get_vms_attach_to_a_network(name)
- vms.sort()
- raise InvalidOperation("KCHNET0018E", {'name': name,
- 'vms': ',
'.join(vms)})
-
- network = self.get_network(self.conn.get(), name)
- network.destroy()
-
- def delete(self, name):
- if self._is_network_in_use(name):
- vms = self._get_vms_attach_to_a_network(name)
- vms.sort()
- raise InvalidOperation("KCHNET0017E", {'name': name,
- 'vms': ',
'.join(vms)})
-
- network = self.get_network(self.conn.get(), name)
- if network.isActive():
- raise InvalidOperation("KCHNET0005E", {'name': name})
-
- self._remove_vlan_tagged_bridge(network)
- network.undefine()
-
- @staticmethod
- def get_network(conn, name):
- name = name.encode("utf-8")
- try:
- return conn.networkLookupByName(name)
- except libvirt.libvirtError:
- raise NotFoundError("KCHNET0002E", {'name': name})
-
- @staticmethod
- def get_network_from_xml(xml):
- address = xpath_get_text(xml, "/network/ip/@address")
- address = address and address[0] or ''
- netmask = xpath_get_text(xml, "/network/ip/@netmask")
- netmask = netmask and netmask[0] or ''
- net = address and netmask and "/".join([address, netmask]) or
''
-
- dhcp_start = xpath_get_text(xml, "/network/ip/dhcp/range/@start")
- dhcp_start = dhcp_start and dhcp_start[0] or ''
- dhcp_end = xpath_get_text(xml, "/network/ip/dhcp/range/@end")
- dhcp_end = dhcp_end and dhcp_end[0] or ''
- dhcp = {'start': dhcp_start, 'end': dhcp_end}
-
- forward_mode = xpath_get_text(xml, "/network/forward/@mode")
- forward_mode = forward_mode and forward_mode[0] or ''
- forward_if = xpath_get_text(xml, "/network/forward/interface/@dev")
- forward_pf = xpath_get_text(xml, "/network/forward/pf/@dev")
- bridge = xpath_get_text(xml, "/network/bridge/@name")
- bridge = bridge and bridge[0] or ''
- return {'subnet': net, 'dhcp': dhcp, 'bridge': bridge,
- 'forward': {'mode': forward_mode,
- 'interface': forward_if,
- 'pf': forward_pf}}
-
- def _remove_vlan_tagged_bridge(self, network):
- try:
- bridge = network.bridgeName()
- except libvirt.libvirtError:
- pass
- else:
- if bridge.startswith(KIMCHI_BRIDGE_PREFIX):
- conn = self.conn.get()
- iface = conn.interfaceLookupByName(bridge)
- iface.isActive() and iface.destroy(0)
- iface.undefine()
diff --git a/plugins/kimchi/model/peers.py b/plugins/kimchi/model/peers.py
deleted file mode 100644
index 7577364..0000000
--- a/plugins/kimchi/model/peers.py
+++ /dev/null
@@ -1,72 +0,0 @@
-#
-# Project Kimchi
-#
-# Copyright IBM, Corp. 2014-2015
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-
-import cherrypy
-import re
-import socket
-
-from wok.config import config
-from wok.utils import run_command, wok_log
-
-
-class PeersModel(object):
- def __init__(self, **kargs):
- # check federation feature is enabled on Kimchi server
- if config.get("server", "federation") == "off":
- return
-
- # register server on openslp
- hostname = socket.getfqdn(config.get("server", "host"))
- port = config.get("server", "ssl_port")
- self.url = hostname + ":" + port
-
- cmd = ["slptool", "register",
- "service:wokd://%s" % self.url]
- out, error, ret = run_command(cmd)
- if out and len(out) != 0:
- wok_log.error("Unable to register server on openSLP."
- " Details: %s" % out)
- cherrypy.engine.subscribe('exit', self._peer_deregister)
-
- def _peer_deregister(self):
- cmd = ["slptool", "deregister",
- "service:wokd://%s" % self.url]
- out, error, ret = run_command(cmd)
- if out and len(out) != 0:
- wok_log.error("Unable to deregister server on openSLP."
- " Details: %s" % out)
-
- def get_list(self):
- # check federation feature is enabled on Kimchi server
- if config.get("server", "federation") == "off":
- return []
-
- cmd = ["slptool", "findsrvs", "service:wokd"]
- out, error, ret = run_command(cmd)
- if ret != 0:
- return []
-
- peers = []
- for server in out.strip().split("\n"):
- match = re.match("service:wokd://(.*?),.*", server)
- peer = match.group(1)
- if peer != self.url:
- peers.append("https://" + peer)
-
- return peers
diff --git a/plugins/kimchi/model/storagepools.py b/plugins/kimchi/model/storagepools.py
deleted file mode 100644
index 0db2ef4..0000000
--- a/plugins/kimchi/model/storagepools.py
+++ /dev/null
@@ -1,490 +0,0 @@
-#
-# Project Kimchi
-#
-# Copyright IBM, Corp. 2014-2015
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-
-import libvirt
-import lxml.etree as ET
-import sys
-from lxml.builder import E
-
-from wok.config import config, PluginPaths
-from wok.exception import InvalidOperation, MissingParameter
-from wok.exception import NotFoundError, OperationFailed
-from wok.utils import add_task, run_command, wok_log
-from wok.xmlutils.utils import xpath_get_text
-
-from ..osinfo import defaults as tmpl_defaults
-from ..scan import Scanner
-from ..utils import pool_name_from_uri
-from config import CapabilitiesModel
-from host import DeviceModel
-from libvirtstoragepool import StoragePoolDef
-
-
-ISO_POOL_NAME = u'kimchi_isos'
-
-POOL_STATE_MAP = {0: 'inactive',
- 1: 'initializing',
- 2: 'active',
- 3: 'degraded',
- 4: 'inaccessible'}
-
-# Types of pools supported
-STORAGE_SOURCES = {'netfs': {'addr': '/pool/source/host/@name',
- 'path': '/pool/source/dir/@path'},
- 'iscsi': {'addr': '/pool/source/host/@name',
- 'port': '/pool/source/host/@port',
- 'path': '/pool/source/device/@path'},
- 'scsi': {'adapter_type':
'/pool/source/adapter/@type',
- 'adapter_name':
'/pool/source/adapter/@name',
- 'wwnn': '/pool/source/adapter/@wwnn',
- 'wwpn': '/pool/source/adapter/@wwpn'}}
-
-
-class StoragePoolsModel(object):
- def __init__(self, **kargs):
- self.conn = kargs['conn']
- self.objstore = kargs['objstore']
- self.scanner = Scanner(self._clean_scan)
- self.scanner.delete()
- self.caps = CapabilitiesModel(**kargs)
- self.device = DeviceModel(**kargs)
-
- if self.conn.isQemuURI():
- self._check_default_pools()
-
- def _check_default_pools(self):
- pools = {}
-
- default_pool = tmpl_defaults['storagepool']
- default_pool = default_pool.split('/')[-1]
-
- pools[default_pool] = {}
- if default_pool == 'default':
- pools[default_pool] = {'path': '/var/lib/libvirt/images'}
-
- if config.get("server", "create_iso_pool") ==
"true":
- pools['ISO'] = {'path': '/var/lib/kimchi/isos'}
-
- error_msg = ("Please, check the configuration in %s/template.conf to "
- "ensure it has a valid storage pool." %
- PluginPaths('kimchi').conf_dir)
-
- conn = self.conn.get()
- for pool_name in pools:
- try:
- pool = conn.storagePoolLookupByName(pool_name)
- except libvirt.libvirtError, e:
- pool_path = pools[pool_name].get('path')
- if pool_path is None:
- msg = "Fatal: Unable to find storage pool %s. " +
error_msg
- wok_log.error(msg % pool_name)
- wok_log.error("Details: %s", e.message)
- sys.exit(1)
-
- # Try to create the pool
- pool = E.pool(E.name(pool_name), type='dir')
- pool.append(E.target(E.path(pool_path)))
- xml = ET.tostring(pool)
- try:
- pool = conn.storagePoolDefineXML(xml, 0)
- except libvirt.libvirtError, e:
- msg = "Fatal: Unable to create storage pool %s. "
- msg += error_msg
- wok_log.error(msg % pool_name)
- wok_log.error("Details: %s", e.message)
- sys.exit(1)
-
- # Build and set autostart value to pool
- # Ignore error as the pool was already successfully created
- try:
- # Add build step to make sure target directory created
- # The build process may fail when the pool directory
- # already exists on system
- pool.build(libvirt.VIR_STORAGE_POOL_BUILD_NEW)
- pool.setAutostart(1)
- except:
- pass
-
- if pool.isActive() == 0:
- try:
- pool.create(0)
- except libvirt.libvirtError, e:
- msg = "Fatal: Unable to craete storage pool %s. "
- msg += error_msg
- wok_log.error(msg % pool_name)
- wok_log.error("Details: %s", e.message)
- sys.exit(1)
-
- def get_list(self):
- try:
- conn = self.conn.get()
- names = conn.listStoragePools()
- names += conn.listDefinedStoragePools()
- return sorted(map(lambda x: x.decode('utf-8'), names))
- except libvirt.libvirtError as e:
- raise OperationFailed("KCHPOOL0006E",
- {'err': e.get_error_message()})
-
- def create(self, params):
- task_id = None
- conn = self.conn.get()
- try:
- name = params['name']
- if name == ISO_POOL_NAME:
- raise InvalidOperation("KCHPOOL0031E")
-
- # The user may want to create a logical pool with the same name
- # used before but a volume group will already exist with this name
- # So check the volume group does not exist to create the pool
- if params['type'] == 'logical':
- vgdisplay_cmd = ['vgdisplay', name.encode('utf-8')]
- output, error, returncode = run_command(vgdisplay_cmd)
- # From vgdisplay error codes:
- # 1 error reading VGDA
- # 2 volume group doesn't exist
- # 3 not all physical volumes of volume group online
- # 4 volume group not found
- # 5 no volume groups found at all
- # 6 error reading VGDA from lvmtab
- if returncode not in [2, 4, 5]:
- raise InvalidOperation("KCHPOOL0036E", {'name':
name})
-
- if params['type'] == 'kimchi-iso':
- task_id = self._do_deep_scan(params)
-
- if params['type'] == 'scsi':
- adapter_name = params['source']['adapter_name']
- extra_params = self.device.lookup(adapter_name)
- # Adds name, adapter_type, wwpn and wwnn to source information
- params['source'].update(extra_params)
- params['fc_host_support'] = self.caps.fc_host_support
-
- poolDef = StoragePoolDef.create(params)
- poolDef.prepare(conn)
- xml = poolDef.xml.encode("utf-8")
- except KeyError, item:
- raise MissingParameter("KCHPOOL0004E",
- {'item': str(item), 'name': name})
-
- if name in self.get_list():
- raise InvalidOperation("KCHPOOL0001E", {'name': name})
-
- try:
- if task_id:
- # Create transient pool for deep scan
- conn.storagePoolCreateXML(xml, 0)
- return name
-
- pool = conn.storagePoolDefineXML(xml, 0)
- except libvirt.libvirtError as e:
- wok_log.error("Problem creating Storage Pool: %s", e)
- raise OperationFailed("KCHPOOL0007E",
- {'name': name, 'err':
e.get_error_message()})
-
- # Build and set autostart value to pool
- # Ignore error as the pool was already successfully created
- # The build process fails when the pool directory already exists
- try:
- if params['type'] in ['logical', 'dir',
'netfs', 'scsi']:
- pool.build(libvirt.VIR_STORAGE_POOL_BUILD_NEW)
- pool.setAutostart(1)
- else:
- pool.setAutostart(0)
- except:
- pass
-
- if params['type'] == 'netfs':
- output, error, returncode = run_command(['setsebool', '-P',
- 'virt_use_nfs=1'])
- if error or returncode:
- wok_log.error("Unable to set virt_use_nfs=1. If you use "
- "SELinux, this may prevent NFS pools from "
- "being used.")
- return name
-
- def _clean_scan(self, pool_name):
- try:
- conn = self.conn.get()
- pool = conn.storagePoolLookupByName(pool_name.encode("utf-8"))
- pool.destroy()
- with self.objstore as session:
- session.delete('scanning', pool_name)
- except Exception, e:
- err = "Exception %s occured when cleaning scan result"
- wok_log.debug(err % e.message)
-
- def _do_deep_scan(self, params):
- scan_params = dict(ignore_list=[])
- scan_params['scan_path'] = params['path']
- params['type'] = 'dir'
-
- for pool in self.get_list():
- try:
- res = StoragePoolModel(conn=self.conn,
- objstore=self.objstore).lookup(pool)
- if res['state'] == 'active':
- scan_params['ignore_list'].append(res['path'])
- except Exception, e:
- err = "Exception %s occured when get ignore path"
- wok_log.debug(err % e.message)
-
- params['path'] = self.scanner.scan_dir_prepare(params['name'])
- scan_params['pool_path'] = params['path']
- task_id = add_task('/plugins/kimchi/storagepools/%s' % ISO_POOL_NAME,
- self.scanner.start_scan, self.objstore, scan_params)
- # Record scanning-task/storagepool mapping for future querying
- try:
- with self.objstore as session:
- session.store('scanning', params['name'], task_id)
- return task_id
- except Exception as e:
- raise OperationFailed('KCHPOOL0037E', {'err': e.message})
-
-
-class StoragePoolModel(object):
- def __init__(self, **kargs):
- self.conn = kargs['conn']
- self.objstore = kargs['objstore']
-
- @staticmethod
- def get_storagepool(name, conn):
- conn = conn.get()
- try:
- return conn.storagePoolLookupByName(name.encode("utf-8"))
- except libvirt.libvirtError as e:
- if e.get_error_code() == libvirt.VIR_ERR_NO_STORAGE_POOL:
- raise NotFoundError("KCHPOOL0002E", {'name': name})
- else:
- raise
-
- def _get_storagepool_vols_num(self, pool):
- try:
- if pool.isActive():
- pool.refresh(0)
- return pool.numOfVolumes()
- else:
- return 0
- except libvirt.libvirtError as e:
- # If something (say a busy pool) prevents the refresh,
- # throwing an Exception here would prevent all pools from
- # displaying information -- so return None for busy
- wok_log.error("ERROR: Storage Pool get vol count: %s "
- % e.get_error_message())
- wok_log.error("ERROR: Storage Pool get vol count error no: %s "
- % e.get_error_code())
- return 0
- except Exception as e:
- raise OperationFailed("KCHPOOL0008E",
- {'name': pool.name(),
- 'err': e.get_error_message()})
-
- def _get_storage_source(self, pool_type, pool_xml):
- source = {}
- if pool_type not in STORAGE_SOURCES:
- return source
-
- for key, val in STORAGE_SOURCES[pool_type].items():
- res = xpath_get_text(pool_xml, val)
- if len(res) == 1:
- source[key] = res[0]
- elif len(res) == 0:
- source[key] = ""
- else:
- source[key] = res
- return source
-
- def _nfs_status_online(self, pool, poolArgs=None):
- if not poolArgs:
- xml = pool.XMLDesc(0)
- pool_type = xpath_get_text(xml, "/pool/@type")[0]
- source = self._get_storage_source(pool_type, xml)
- poolArgs = {}
- poolArgs['name'] = pool.name()
- poolArgs['type'] = pool_type
- poolArgs['source'] = {'path': source['path'],
- 'host': source['addr']}
- conn = self.conn.get()
- poolDef = StoragePoolDef.create(poolArgs)
- try:
- poolDef.prepare(conn)
- return True
- except Exception:
- return False
-
- def lookup(self, name):
- pool = self.get_storagepool(name, self.conn)
- info = pool.info()
- autostart = True if pool.autostart() else False
- persistent = True if pool.isPersistent() else False
- xml = pool.XMLDesc(0)
- path = xpath_get_text(xml, "/pool/target/path")[0]
- pool_type = xpath_get_text(xml, "/pool/@type")[0]
- source = self._get_storage_source(pool_type, xml)
- # FIXME: nfs workaround - prevent any libvirt operation
- # for a nfs if the corresponding NFS server is down.
- if pool_type == 'netfs' and not self._nfs_status_online(pool):
- wok_log.debug("NFS pool %s is offline, reason: NFS "
- "server %s is unreachable.", name,
source['addr'])
- # Mark state as '4' => inaccessible.
- info[0] = 4
- # skip calculating volumes
- nr_volumes = 0
- else:
- nr_volumes = self._get_storagepool_vols_num(pool)
-
- res = {'state': POOL_STATE_MAP[info[0]],
- 'path': path,
- 'source': source,
- 'type': pool_type,
- 'autostart': autostart,
- 'capacity': info[1],
- 'allocated': info[2],
- 'available': info[3],
- 'nr_volumes': nr_volumes,
- 'persistent': persistent}
-
- if not pool.isPersistent():
- # Deal with deep scan generated pool
- try:
- with self.objstore as session:
- task_id = session.get('scanning', name)
- res['task_id'] = str(task_id)
- res['type'] = 'kimchi-iso'
- except NotFoundError:
- # User created normal pool
- pass
- return res
-
- def _update_lvm_disks(self, pool_name, disks):
- # check if all the disks/partitions exists in the host
- for disk in disks:
- lsblk_cmd = ['lsblk', disk]
- output, error, returncode = run_command(lsblk_cmd)
- if returncode != 0:
- wok_log.error('%s is not a valid disk/partition. Could not '
- 'add it to the pool %s.', disk, pool_name)
- raise OperationFailed('KCHPOOL0027E', {'disk': disk,
- 'pool': pool_name})
- # add disks to the lvm pool using vgextend + virsh refresh
- vgextend_cmd = ["vgextend", pool_name]
- vgextend_cmd += disks
- output, error, returncode = run_command(vgextend_cmd)
- if returncode != 0:
- msg = "Could not add disks to pool %s, error: %s"
- wok_log.error(msg, pool_name, error)
- raise OperationFailed('KCHPOOL0028E', {'pool': pool_name,
- 'err': error})
- # refreshing pool state
- pool = self.get_storagepool(pool_name, self.conn)
- if pool.isActive():
- pool.refresh(0)
-
- def update(self, name, params):
- pool = self.get_storagepool(name, self.conn)
- if 'autostart' in params:
- if params['autostart']:
- pool.setAutostart(1)
- else:
- pool.setAutostart(0)
-
- if 'disks' in params:
- # check if pool is type 'logical'
- xml = pool.XMLDesc(0)
- pool_type = xpath_get_text(xml, "/pool/@type")[0]
- if pool_type != 'logical':
- raise InvalidOperation('KCHPOOL0029E')
- self._update_lvm_disks(name, params['disks'])
- ident = pool.name()
- return ident.decode('utf-8')
-
- def activate(self, name):
- pool = self.get_storagepool(name, self.conn)
- # FIXME: nfs workaround - do not activate a NFS pool
- # if the NFS server is not reachable.
- xml = pool.XMLDesc(0)
- pool_type = xpath_get_text(xml, "/pool/@type")[0]
- if pool_type == 'netfs' and not self._nfs_status_online(pool):
- # block the user from activating the pool.
- source = self._get_storage_source(pool_type, xml)
- raise OperationFailed("KCHPOOL0032E",
- {'name': name, 'server':
source['addr']})
- return
- try:
- pool.create(0)
- except libvirt.libvirtError as e:
- raise OperationFailed("KCHPOOL0009E",
- {'name': name, 'err':
e.get_error_message()})
-
- def _pool_used_by_template(self, pool_name):
- with self.objstore as session:
- templates = session.get_list('template')
- for tmpl in templates:
- t_info = session.get('template', tmpl)
- t_pool = pool_name_from_uri(t_info['storagepool'])
- if t_pool == pool_name:
- return True
- return False
-
- def deactivate(self, name):
- if self._pool_used_by_template(name):
- raise InvalidOperation('KCHPOOL0034E', {'name': name})
-
- pool = self.get_storagepool(name, self.conn)
- # FIXME: nfs workaround - do not try to deactivate a NFS pool
- # if the NFS server is not reachable.
- xml = pool.XMLDesc(0)
- pool_type = xpath_get_text(xml, "/pool/@type")[0]
- if pool_type == 'netfs' and not self._nfs_status_online(pool):
- # block the user from dactivating the pool.
- source = self._get_storage_source(pool_type, xml)
- raise OperationFailed("KCHPOOL0033E",
- {'name': name, 'server':
source['addr']})
- return
- try:
- persistent = pool.isPersistent()
- pool.destroy()
- except libvirt.libvirtError as e:
- raise OperationFailed("KCHPOOL0010E",
- {'name': name, 'err':
e.get_error_message()})
- # If pool was not persistent, then it was erased by destroy() and
- # must return nothing here, to trigger _redirect() and avoid errors
- if not persistent:
- return ""
-
- def delete(self, name):
- if self._pool_used_by_template(name):
- raise InvalidOperation('KCHPOOL0035E', {'name': name})
-
- pool = self.get_storagepool(name, self.conn)
- if pool.isActive():
- raise InvalidOperation("KCHPOOL0005E", {'name': name})
- try:
- pool.undefine()
- except libvirt.libvirtError as e:
- raise OperationFailed("KCHPOOL0011E",
- {'name': name, 'err':
e.get_error_message()})
-
-
-class IsoPoolModel(object):
- def __init__(self, **kargs):
- pass
-
- def lookup(self, name):
- return {'state': 'active',
- 'type': 'kimchi-iso'}
diff --git a/plugins/kimchi/model/storageservers.py
b/plugins/kimchi/model/storageservers.py
deleted file mode 100644
index accc5f5..0000000
--- a/plugins/kimchi/model/storageservers.py
+++ /dev/null
@@ -1,81 +0,0 @@
-#
-# Project Kimchi
-#
-# Copyright IBM, Corp. 2014
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-
-from wok.exception import NotFoundError
-
-from storagepools import StoragePoolModel, StoragePoolsModel
-
-# Types of remote storage servers supported
-STORAGE_SERVERS = ['netfs', 'iscsi']
-
-
-class StorageServersModel(object):
- def __init__(self, **kargs):
- self.conn = kargs['conn']
- self.pool = StoragePoolModel(**kargs)
- self.pools = StoragePoolsModel(**kargs)
-
- def get_list(self, _target_type=None):
- if not _target_type:
- target_type = STORAGE_SERVERS
- else:
- target_type = [_target_type]
-
- pools = self.pools.get_list()
-
- server_list = []
- for pool in pools:
- try:
- pool_info = self.pool.lookup(pool)
- if (pool_info['type'] in target_type and
- pool_info['source']['addr'] not in server_list):
- # Avoid to add same server for multiple times
- # if it hosts more than one storage type
- server_list.append(pool_info['source']['addr'])
- except NotFoundError:
- pass
-
- return server_list
-
-
-class StorageServerModel(object):
- def __init__(self, **kargs):
- self.conn = kargs['conn']
- self.pool = StoragePoolModel(**kargs)
-
- def lookup(self, server):
- conn = self.conn.get()
- pools = conn.listStoragePools()
- pools += conn.listDefinedStoragePools()
- for pool in pools:
- try:
- pool_info = self.pool.lookup(pool)
- if (pool_info['type'] in STORAGE_SERVERS and
- pool_info['source']['addr'] == server):
- info = dict(host=server)
- if (pool_info['type'] == "iscsi" and
- 'port' in pool_info['source']):
- info["port"] =
pool_info['source']['port']
- return info
- except NotFoundError:
- # Avoid inconsistent pool result because of lease between list
- # lookup
- pass
-
- raise NotFoundError("KCHSR0001E", {'server': server})
diff --git a/plugins/kimchi/model/storagetargets.py
b/plugins/kimchi/model/storagetargets.py
deleted file mode 100644
index 4090b45..0000000
--- a/plugins/kimchi/model/storagetargets.py
+++ /dev/null
@@ -1,122 +0,0 @@
-#
-# Project Kimchi
-#
-# Copyright IBM, Corp. 2014
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-
-import libvirt
-import lxml.etree as ET
-from lxml import objectify
-from lxml.builder import E
-
-from wok.utils import patch_find_nfs_target, wok_log
-
-from config import CapabilitiesModel
-from storageservers import STORAGE_SERVERS
-
-
-class StorageTargetsModel(object):
- def __init__(self, **kargs):
- self.conn = kargs['conn']
- self.caps = CapabilitiesModel(**kargs)
-
- def get_list(self, storage_server, _target_type=None, _server_port=None):
- target_list = list()
- if not _target_type:
- target_types = STORAGE_SERVERS
- else:
- target_types = [_target_type]
-
- for target_type in target_types:
- if not self.caps.nfs_target_probe and target_type == 'netfs':
- targets = patch_find_nfs_target(storage_server)
- else:
- xml = self._get_storage_server_spec(server=storage_server,
- target_type=target_type,
- server_port=_server_port)
- conn = self.conn.get()
- try:
- ret = conn.findStoragePoolSources(target_type, xml, 0)
- except libvirt.libvirtError as e:
- err = "Query storage pool source fails because of %s"
- wok_log.warning(err, e.get_error_message())
- continue
-
- targets = self._parse_target_source_result(target_type, ret)
-
- target_list.extend(targets)
-
- # Get all netfs and iscsi paths in use
- used_paths = []
- try:
- conn = self.conn.get()
- # Get all existing ISCSI and NFS pools
- pools = conn.listAllStoragePools(
- libvirt.VIR_CONNECT_LIST_STORAGE_POOLS_ISCSI |
- libvirt.VIR_CONNECT_LIST_STORAGE_POOLS_NETFS)
- for pool in pools:
- pool_xml = pool.XMLDesc(0)
- root = objectify.fromstring(pool_xml)
- if root.get('type') == 'netfs' and \
- root.source.dir is not None:
- used_paths.append(root.source.dir.get('path'))
- elif root.get('type') == 'iscsi' and \
- root.source.device is not None:
- used_paths.append(root.source.device.get('path'))
-
- except libvirt.libvirtError as e:
- err = "Query storage pool source fails because of %s"
- wok_log.warning(err, e.get_error_message())
-
- # Filter target_list to not not show the used paths
- target_list = [elem for elem in target_list
- if elem.get('target') not in used_paths]
- return [dict(t) for t in set(tuple(t.items()) for t in target_list)]
-
- def _get_storage_server_spec(self, **kwargs):
- # Required parameters:
- # server:
- # target_type:
- extra_args = []
- server_type = kwargs['target_type']
- if server_type == 'netfs':
- extra_args.append(E.format(type='nfs'))
- else:
- extra_args.append(E.format(type=server_type))
-
- host_attr = {"name": kwargs['server']}
- server_port = kwargs.get("server_port")
- if server_port is not None:
- host_attr['port'] = server_port
-
- obj = E.source(E.host(host_attr), *extra_args)
- xml = ET.tostring(obj)
- return xml
-
- def _parse_target_source_result(self, target_type, xml_str):
- root = objectify.fromstring(xml_str)
- ret = []
- for source in root.getchildren():
- if target_type == 'netfs':
- target_path = source.dir.get('path')
- type = source.format.get('type')
- if target_type == 'iscsi':
- target_path = source.device.get('path')
- type = target_type
- host_name = source.host.get('name')
- ret.append(dict(host=host_name, target_type=type,
- target=target_path))
- return ret
diff --git a/plugins/kimchi/model/storagevolumes.py
b/plugins/kimchi/model/storagevolumes.py
deleted file mode 100644
index 99b17d3..0000000
--- a/plugins/kimchi/model/storagevolumes.py
+++ /dev/null
@@ -1,542 +0,0 @@
-#
-# Project Kimchi
-#
-# Copyright IBM, Corp. 2014-2015
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-
-import contextlib
-import libvirt
-import lxml.etree as ET
-import os
-import tempfile
-import threading
-import time
-import urllib2
-from lxml.builder import E
-
-from wok.exception import InvalidOperation, InvalidParameter, IsoFormatError
-from wok.exception import MissingParameter, NotFoundError, OperationFailed
-from wok.utils import add_task, get_next_clone_name, get_unique_file_name
-from wok.utils import wok_log
-from wok.xmlutils.utils import xpath_get_text
-from wok.model.tasks import TaskModel
-
-from ..config import READONLY_POOL_TYPE
-from ..isoinfo import IsoImage
-from diskutils import get_disk_used_by, set_disk_used_by
-from storagepools import StoragePoolModel
-
-
-VOLUME_TYPE_MAP = {0: 'file',
- 1: 'block',
- 2: 'directory',
- 3: 'network'}
-
-READ_CHUNK_SIZE = 1048576 # 1 MiB
-REQUIRE_NAME_PARAMS = ['capacity']
-
-upload_volumes = dict()
-
-
-class StorageVolumesModel(object):
- def __init__(self, **kargs):
- self.conn = kargs['conn']
- self.objstore = kargs['objstore']
- self.task = TaskModel(**kargs)
-
- def create(self, pool_name, params):
- vol_source = ['url', 'capacity']
-
- name = params.get('name')
-
- index_list = list(i for i in range(len(vol_source))
- if vol_source[i] in params)
- if len(index_list) != 1:
- raise InvalidParameter("KCHVOL0018E",
- {'param': ",".join(vol_source)})
-
- create_param = vol_source[index_list[0]]
-
- # Verify if the URL is valid
- if create_param == 'url':
- url = params['url']
- try:
- urllib2.urlopen(url).close()
- except:
- raise InvalidParameter('KCHVOL0022E', {'url': url})
-
- all_vol_names = self.get_list(pool_name)
-
- if name is None:
- # the methods listed in 'REQUIRE_NAME_PARAMS' cannot have
- # 'name' == None
- if create_param in REQUIRE_NAME_PARAMS:
- raise InvalidParameter('KCHVOL0016E')
-
- # if 'name' is omitted - except for the methods listed in
- # 'REQUIRE_NAME_PARAMS' - the default volume name will be the
- # file/URL basename.
- if create_param == 'url':
- name = os.path.basename(params['url'])
- else:
- name = 'upload-%s' % int(time.time())
-
- name = get_unique_file_name(all_vol_names, name)
- params['name'] = name
-
- try:
- create_func = getattr(self, '_create_volume_with_%s' %
- create_param)
- except AttributeError:
- raise InvalidParameter("KCHVOL0019E", {'param':
create_param})
-
- pool_info = StoragePoolModel(conn=self.conn,
- objstore=self.objstore).lookup(pool_name)
- if pool_info['type'] in READONLY_POOL_TYPE:
- raise InvalidParameter("KCHVOL0012E", {'type':
pool_info['type']})
- if pool_info['state'] == 'inactive':
- raise InvalidParameter('KCHVOL0003E', {'pool': pool_name,
- 'volume': name})
- if name in all_vol_names:
- raise InvalidParameter('KCHVOL0001E', {'name': name})
-
- params['pool'] = pool_name
- targeturi = '/plugins/kimchi/storagepools/%s/storagevolumes/%s' \
- % (pool_name, name)
- taskid = add_task(targeturi, create_func, self.objstore, params)
- return self.task.lookup(taskid)
-
- def _create_volume_with_capacity(self, cb, params):
- pool_name = params.pop('pool')
- vol_xml = """
- <volume>
- <name>%(name)s</name>
- <allocation unit='bytes'>%(allocation)s</allocation>
- <capacity unit='bytes'>%(capacity)s</capacity>
- <source>
- </source>
- <target>
- <format type='%(format)s'/>
- </target>
- </volume>
- """
- params.setdefault('allocation', 0)
- params.setdefault('format', 'qcow2')
-
- name = params['name']
- try:
- pool = StoragePoolModel.get_storagepool(pool_name, self.conn)
- xml = vol_xml % params
- except KeyError, item:
- raise MissingParameter("KCHVOL0004E", {'item': str(item),
- 'volume': name})
-
- try:
- pool.createXML(xml, 0)
- except libvirt.libvirtError as e:
- raise OperationFailed("KCHVOL0007E",
- {'name': name, 'pool': pool,
- 'err': e.get_error_message()})
-
- vol_info = StorageVolumeModel(conn=self.conn,
- objstore=self.objstore).lookup(pool_name,
- name)
-
- vol_path = vol_info['path']
- set_disk_used_by(self.objstore, vol_info['path'], [])
-
- if params.get('upload', False):
- upload_volumes[vol_path] = {'lock': threading.Lock(),
- 'offset': 0, 'cb': cb}
- cb('ready for upload')
- else:
- cb('OK', True)
-
- def _create_volume_with_url(self, cb, params):
- pool_name = params['pool']
- name = params['name']
- url = params['url']
-
- pool_model = StoragePoolModel(conn=self.conn,
- objstore=self.objstore)
- pool = pool_model.lookup(pool_name)
-
- if pool['type'] in ['dir', 'netfs']:
- file_path = os.path.join(pool['path'], name)
- else:
- file_path = tempfile.mkstemp(prefix=name)[1]
-
- with contextlib.closing(urllib2.urlopen(url)) as response:
- with open(file_path, 'w') as volume_file:
- remote_size = response.info().getheader('Content-Length',
'-')
- downloaded_size = 0
-
- try:
- while True:
- chunk_data = response.read(READ_CHUNK_SIZE)
- if not chunk_data:
- break
-
- volume_file.write(chunk_data)
- downloaded_size += len(chunk_data)
- cb('%s/%s' % (downloaded_size, remote_size))
- except (IOError, libvirt.libvirtError) as e:
- if os.path.isfile(file_path):
- os.remove(file_path)
-
- raise OperationFailed('KCHVOL0007E', {'name': name,
- 'pool': pool_name,
- 'err': e.message})
-
- if pool['type'] in ['dir', 'netfs']:
- virt_pool = StoragePoolModel.get_storagepool(pool_name, self.conn)
- virt_pool.refresh(0)
- else:
- def _stream_handler(stream, nbytes, fd):
- return fd.read(nbytes)
-
- virt_stream = virt_vol = None
-
- try:
- task = self.create(pool_name, {'name': name,
- 'format': 'raw',
- 'capacity': downloaded_size,
- 'allocation': downloaded_size})
- self.task.wait(task['id'])
- virt_vol = StorageVolumeModel.get_storagevolume(pool_name,
- name,
- self.conn)
-
- virt_stream = self.conn.get().newStream(0)
- virt_vol.upload(virt_stream, 0, downloaded_size, 0)
-
- with open(file_path) as fd:
- virt_stream.sendAll(_stream_handler, fd)
-
- virt_stream.finish()
- except (IOError, libvirt.libvirtError) as e:
- try:
- if virt_stream:
- virt_stream.abort()
- if virt_vol:
- virt_vol.delete(0)
- except libvirt.libvirtError, virt_e:
- wok_log.error(virt_e.message)
- finally:
- raise OperationFailed('KCHVOL0007E', {'name': name,
- 'pool': pool_name,
- 'err': e.message})
- finally:
- os.remove(file_path)
-
- vol_info = StorageVolumeModel(conn=self.conn,
- objstore=self.objstore).lookup(pool_name,
- name)
- set_disk_used_by(self.objstore, vol_info['path'], [])
-
- cb('OK', True)
-
- def get_list(self, pool_name):
- pool = StoragePoolModel.get_storagepool(pool_name, self.conn)
- if not pool.isActive():
- raise InvalidOperation("KCHVOL0006E", {'pool': pool_name})
- try:
- pool.refresh(0)
- return sorted(map(lambda x: x.decode('utf-8'), pool.listVolumes()))
- except libvirt.libvirtError as e:
- raise OperationFailed("KCHVOL0008E",
- {'pool': pool_name,
- 'err': e.get_error_message()})
-
-
-class StorageVolumeModel(object):
- def __init__(self, **kargs):
- self.conn = kargs['conn']
- self.objstore = kargs['objstore']
- self.task = TaskModel(**kargs)
- self.storagevolumes = StorageVolumesModel(**kargs)
- self.storagepool = StoragePoolModel(**kargs)
-
- @staticmethod
- def get_storagevolume(poolname, name, conn):
- pool = StoragePoolModel.get_storagepool(poolname, conn)
- if not pool.isActive():
- raise InvalidOperation("KCHVOL0006E", {'name': pool})
- try:
- return pool.storageVolLookupByName(name.encode("utf-8"))
- except libvirt.libvirtError as e:
- if e.get_error_code() == libvirt.VIR_ERR_NO_STORAGE_VOL:
- raise NotFoundError("KCHVOL0002E", {'name': name,
- 'pool': poolname})
- else:
- raise
-
- def lookup(self, pool, name):
- vol = StorageVolumeModel.get_storagevolume(pool, name, self.conn)
- path = vol.path()
- info = vol.info()
- xml = vol.XMLDesc(0)
- try:
- fmt = xpath_get_text(xml, "/volume/target/format/@type")[0]
- except IndexError:
- # Not all types of libvirt storage can provide volume format
- # infomation. When there is no format information, we assume
- # it's 'raw'.
- fmt = 'raw'
-
- iso_img = None
-
- # 'raw' volumes from 'logical' pools may actually be
'iso';
- # libvirt always reports them as 'raw'
- pool_info = self.storagepool.lookup(pool)
- if pool_info['type'] == 'logical' and fmt == 'raw':
- try:
- iso_img = IsoImage(path)
- except IsoFormatError:
- # not 'iso' afterall
- pass
- else:
- fmt = 'iso'
-
- used_by = get_disk_used_by(self.objstore, self.conn, path)
- res = dict(type=VOLUME_TYPE_MAP[info[0]],
- capacity=info[1],
- allocation=info[2],
- path=path,
- used_by=used_by,
- format=fmt)
- if fmt == 'iso':
- if os.path.islink(path):
- path = os.path.join(os.path.dirname(path), os.readlink(path))
- os_distro = os_version = 'unknown'
- try:
- if iso_img is None:
- iso_img = IsoImage(path)
- os_distro, os_version = iso_img.probe()
- bootable = True
- except IsoFormatError:
- bootable = False
- res.update(
- dict(os_distro=os_distro, os_version=os_version, path=path,
- bootable=bootable))
- return res
-
- def wipe(self, pool, name):
- volume = StorageVolumeModel.get_storagevolume(pool, name, self.conn)
- try:
- volume.wipePattern(libvirt.VIR_STORAGE_VOL_WIPE_ALG_ZERO, 0)
- except libvirt.libvirtError as e:
- raise OperationFailed("KCHVOL0009E",
- {'name': name, 'err':
e.get_error_message()})
-
- def delete(self, pool, name):
- pool_info = StoragePoolModel(conn=self.conn,
- objstore=self.objstore).lookup(pool)
- if pool_info['type'] in READONLY_POOL_TYPE:
- raise InvalidParameter("KCHVOL0012E", {'type':
pool_info['type']})
-
- volume = StorageVolumeModel.get_storagevolume(pool, name, self.conn)
- try:
- volume.delete(0)
- except libvirt.libvirtError as e:
- raise OperationFailed("KCHVOL0010E",
- {'name': name, 'err':
e.get_error_message()})
-
- def resize(self, pool, name, size):
- volume = StorageVolumeModel.get_storagevolume(pool, name, self.conn)
-
- # When decreasing the storage volume capacity, the flag
- # VIR_STORAGE_VOL_RESIZE_SHRINK must be used
- flags = 0
- if volume.info()[1] > size:
- # FIXME: Even using VIR_STORAGE_VOL_RESIZE_SHRINK flag it is not
- # possible to decrease the volume capacity due a libvirt bug
- # For reference:
- # -
https://bugzilla.redhat.com/show_bug.cgi?id=1021802
- flags = libvirt.VIR_STORAGE_VOL_RESIZE_SHRINK
-
- try:
- volume.resize(size, flags)
- except libvirt.libvirtError as e:
- raise OperationFailed("KCHVOL0011E",
- {'name': name, 'err':
e.get_error_message()})
-
- def clone(self, pool, name, new_pool=None, new_name=None):
- """Clone a storage volume.
-
- Arguments:
- pool -- The name of the original pool.
- name -- The name of the original volume.
- new_pool -- The name of the destination pool (optional). If omitted,
- the new volume will be created on the same pool as the
- original one.
- new_name -- The name of the new volume (optional). If omitted, a new
- value based on the original volume's name will be used.
-
- Return:
- A Task running the clone operation.
- """
- # the same pool will be used if no pool is specified
- if new_pool is None:
- new_pool = pool
-
- # a default name based on the original name will be used if no name
- # is specified
- if new_name is None:
- base, ext = os.path.splitext(name)
- new_name = get_next_clone_name(self.storagevolumes.get_list(pool),
- base, ext)
-
- params = {'pool': pool,
- 'name': name,
- 'new_pool': new_pool,
- 'new_name': new_name}
- taskid = add_task(u'/plugins/kimchi/storagepools/%s/storagevolumes/%s'
- % (pool, new_name), self._clone_task, self.objstore,
- params)
- return self.task.lookup(taskid)
-
- def _clone_task(self, cb, params):
- """Asynchronous function which performs the clone operation.
-
- This function copies all the data inside the original volume into the
- new one.
-
- Arguments:
- cb -- A callback function to signal the Task's progress.
- params -- A dict with the following values:
- "pool": The name of the original pool.
- "name": The name of the original volume.
- "new_pool": The name of the destination pool.
- "new_name": The name of the new volume.
- """
- orig_pool_name = params['pool']
- orig_vol_name = params['name']
- new_pool_name = params['new_pool']
- new_vol_name = params['new_name']
-
- try:
- cb('setting up volume cloning')
- orig_vir_vol = StorageVolumeModel.get_storagevolume(orig_pool_name,
- orig_vol_name,
- self.conn)
- orig_vol = self.lookup(orig_pool_name, orig_vol_name)
- new_vir_pool = StoragePoolModel.get_storagepool(new_pool_name,
- self.conn)
-
- cb('building volume XML')
- root_elem = E.volume()
- root_elem.append(E.name(new_vol_name))
- root_elem.append(E.capacity(unicode(orig_vol['capacity']),
- unit='bytes'))
- target_elem = E.target()
- target_elem.append(E.format(type=orig_vol['format']))
- root_elem.append(target_elem)
- new_vol_xml = ET.tostring(root_elem, encoding='utf-8',
- pretty_print=True)
-
- cb('cloning volume')
- new_vir_pool.createXMLFrom(new_vol_xml, orig_vir_vol, 0)
- except (InvalidOperation, NotFoundError, libvirt.libvirtError), e:
- raise OperationFailed('KCHVOL0023E',
- {'name': orig_vol_name,
- 'pool': orig_pool_name,
- 'err': e.get_error_message()})
-
- new_vol = self.lookup(new_pool_name, new_vol_name)
- cb('adding volume to the object store')
- set_disk_used_by(self.objstore, new_vol['path'], [])
-
- cb('OK', True)
-
- def doUpload(self, cb, vol, offset, data, data_size):
- try:
- st = self.conn.get().newStream(0)
- vol.upload(st, offset, data_size)
- st.send(data)
- st.finish()
- except Exception as e:
- st and st.abort()
- cb('', False)
-
- try:
- vol.delete(0)
- except Exception as e:
- pass
-
- raise OperationFailed("KCHVOL0029E", {"err": e.message})
-
- def update(self, pool, name, params):
- chunk_data = params['chunk'].fullvalue()
- chunk_size = int(params['chunk_size'])
-
- if len(chunk_data) != chunk_size:
- raise OperationFailed("KCHVOL0026E")
-
- vol = StorageVolumeModel.get_storagevolume(pool, name, self.conn)
- vol_path = vol.path()
- vol_capacity = vol.info()[1]
-
- vol_data = upload_volumes.get(vol_path)
- if vol_data is None:
- raise OperationFailed("KCHVOL0027E", {"vol": vol_path})
-
- cb = vol_data['cb']
- lock = vol_data['lock']
- with lock:
- offset = vol_data['offset']
- if (offset + chunk_size) > vol_capacity:
- raise OperationFailed("KCHVOL0028E")
-
- cb('%s/%s' % (offset, vol_capacity))
- self.doUpload(cb, vol, offset, chunk_data, chunk_size)
- cb('%s/%s' % (offset + chunk_size, vol_capacity))
-
- vol_data['offset'] += chunk_size
- if vol_data['offset'] == vol_capacity:
- del upload_volumes[vol_path]
- cb('OK', True)
-
-
-class IsoVolumesModel(object):
- def __init__(self, **kargs):
- self.conn = kargs['conn']
- self.storagevolume = StorageVolumeModel(**kargs)
-
- def get_list(self):
- iso_volumes = []
- conn = self.conn.get()
- pools = conn.listStoragePools()
- pools += conn.listDefinedStoragePools()
-
- for pool_name in pools:
- try:
- pool = StoragePoolModel.get_storagepool(pool_name, self.conn)
- pool.refresh(0)
- volumes = pool.listVolumes()
- except Exception, e:
- # Skip inactive pools
- wok_log.debug("Shallow scan: skipping pool %s because of "
- "error: %s", (pool_name, e.message))
- continue
-
- for volume in volumes:
- res = self.storagevolume.lookup(pool_name,
- volume.decode("utf-8"))
- if res['format'] == 'iso' and res['bootable']:
- res['name'] = '%s' % volume
- iso_volumes.append(res)
- return iso_volumes
diff --git a/plugins/kimchi/model/templates.py b/plugins/kimchi/model/templates.py
deleted file mode 100644
index 4f0b204..0000000
--- a/plugins/kimchi/model/templates.py
+++ /dev/null
@@ -1,303 +0,0 @@
-#
-# Project Kimchi
-#
-# Copyright IBM, Corp. 2014-2015
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-
-import copy
-import libvirt
-import os
-import stat
-
-from wok.exception import InvalidOperation, InvalidParameter
-from wok.exception import NotFoundError, OperationFailed
-from wok.utils import probe_file_permission_as_user, run_setfacl_set_attr
-from wok.xmlutils.utils import xpath_get_text
-
-from ..kvmusertests import UserTests
-from ..utils import pool_name_from_uri
-from ..vmtemplate import VMTemplate
-from cpuinfo import CPUInfoModel
-
-
-class TemplatesModel(object):
- def __init__(self, **kargs):
- self.objstore = kargs['objstore']
- self.conn = kargs['conn']
-
- def create(self, params):
- name = params.get('name', '').strip()
- iso = params.get('cdrom')
- # check search permission
- if iso and iso.startswith('/') and os.path.exists(iso):
- st_mode = os.stat(iso).st_mode
- if stat.S_ISREG(st_mode) or stat.S_ISBLK(st_mode):
- user = UserTests().probe_user()
- run_setfacl_set_attr(iso, user=user)
- ret, excp = probe_file_permission_as_user(iso, user)
- if ret is False:
- raise InvalidParameter('KCHISO0008E',
- {'filename': iso, 'user':
user,
- 'err': excp})
-
- cpu_info = params.get('cpu_info')
- if cpu_info:
- topology = cpu_info.get('topology')
- # Check, even though currently only topology
- # is supported.
- if topology:
- sockets = topology['sockets']
- cores = topology['cores']
- threads = topology['threads']
- if params.get('cpus') is None:
- params['cpus'] = sockets * cores * threads
- # check_topoology will raise the appropriate
- # exception if a topology is invalid.
- CPUInfoModel(conn=self.conn).\
- check_topology(params['cpus'], topology)
-
- conn = self.conn.get()
- pool_uri = params.get(u'storagepool', '')
- if pool_uri:
- try:
- pool_name = pool_name_from_uri(pool_uri)
- pool = conn.storagePoolLookupByName(pool_name.encode("utf-8"))
- except Exception:
- raise InvalidParameter("KCHTMPL0004E", {'pool':
pool_uri,
- 'template': name})
-
- tmp_volumes = [disk['volume'] for disk in params.get('disks',
[])
- if 'volume' in disk]
- self.template_volume_validate(tmp_volumes, pool)
-
- for net_name in params.get(u'networks', []):
- try:
- conn.networkLookupByName(net_name.encode('utf-8'))
- except Exception:
- raise InvalidParameter("KCHTMPL0003E", {'network':
net_name,
- 'template': name})
- # Creates the template class with necessary information
- # Checkings will be done while creating this class, so any exception
- # will be raised here
- t = LibvirtVMTemplate(params, scan=True, conn=self.conn)
- name = params['name']
- try:
- with self.objstore as session:
- if name in session.get_list('template'):
- raise InvalidOperation("KCHTMPL0001E", {'name':
name})
- session.store('template', name, t.info)
- except InvalidOperation:
- raise
- except Exception, e:
- raise OperationFailed('KCHTMPL0020E', {'err': e.message})
-
- return name
-
- def get_list(self):
- with self.objstore as session:
- return session.get_list('template')
-
- def template_volume_validate(self, tmp_volumes, pool):
- kwargs = {'conn': self.conn, 'objstore': self.objstore}
- pool_type = xpath_get_text(pool.XMLDesc(0), "/pool/@type")[0]
- pool_name = unicode(pool.name(), 'utf-8')
-
- # as we discussion, we do not mix disks from 2 different types of
- # storage pools, for instance: we do not create a template with 2
- # disks, where one comes from a SCSI pool and other is a .img in
- # a DIR pool.
- if pool_type in ['iscsi', 'scsi']:
- if not tmp_volumes:
- raise InvalidParameter("KCHTMPL0018E")
-
- storagevolumes = __import__("kimchi.model.storagevolumes",
- fromlist=[''])
- pool_volumes = storagevolumes.StorageVolumesModel(
- **kwargs).get_list(pool_name)
- vols = set(tmp_volumes) - set(pool_volumes)
- if vols:
- raise InvalidParameter("KCHTMPL0019E", {'pool':
pool_name,
- 'volume': vols})
-
-
-class TemplateModel(object):
- def __init__(self, **kargs):
- self.objstore = kargs['objstore']
- self.conn = kargs['conn']
- self.templates = TemplatesModel(**kargs)
-
- @staticmethod
- def get_template(name, objstore, conn, overrides=None):
- with objstore as session:
- params = session.get('template', name)
- if overrides:
- params.update(overrides)
- return LibvirtVMTemplate(params, False, conn)
-
- def lookup(self, name):
- t = self.get_template(name, self.objstore, self.conn)
- return t.validate_integrity()
-
- def clone(self, name):
- # set default name
- subfixs = [v[len(name):] for v in self.templates.get_list()
- if v.startswith(name)]
- indexs = [int(v.lstrip("-clone")) for v in subfixs
- if v.startswith("-clone") and
- v.lstrip("-clone").isdigit()]
- indexs.sort()
- index = "1" if not indexs else str(indexs[-1] + 1)
- clone_name = name + "-clone" + index
-
- temp = self.lookup(name)
- temp['name'] = clone_name
- ident = self.templates.create(temp)
- return ident
-
- def delete(self, name):
- try:
- with self.objstore as session:
- session.delete('template', name)
- except NotFoundError:
- raise
- except Exception as e:
- raise OperationFailed('KCHTMPL0021E', {'err': e.message})
-
- def update(self, name, params):
- old_t = self.lookup(name)
- new_t = copy.copy(old_t)
- new_t.update(params)
-
- if not self._validate_updated_cpu_params(new_t):
- raise InvalidParameter('KCHTMPL0025E')
-
- ident = name
-
- conn = self.conn.get()
- pool_uri = new_t.get(u'storagepool', '')
-
- if pool_uri:
- try:
- pool_name = pool_name_from_uri(pool_uri)
- pool = conn.storagePoolLookupByName(pool_name.encode("utf-8"))
- except Exception:
- raise InvalidParameter("KCHTMPL0004E", {'pool':
pool_uri,
- 'template': name})
- tmp_volumes = [disk['volume'] for disk in new_t.get('disks',
[])
- if 'volume' in disk]
- self.templates.template_volume_validate(tmp_volumes, pool)
-
- for net_name in params.get(u'networks', []):
- try:
- conn.networkLookupByName(net_name.encode('utf-8'))
- except Exception:
- raise InvalidParameter("KCHTMPL0003E", {'network':
net_name,
- 'template': name})
-
- self.delete(name)
- try:
- ident = self.templates.create(new_t)
- except:
- ident = self.templates.create(old_t)
- raise
- return ident
-
- def _validate_updated_cpu_params(self, info):
- # Note: cpu_info is the parent of topology. cpus is vcpus
- vcpus = info['cpus']
- cpu_info = info.get('cpu_info')
- # cpu_info will always be at least an empty dict
- topology = cpu_info.get('topology')
- if topology is None:
- return True
- return vcpus == topology['sockets'] * topology['cores'] * \
- topology['threads']
-
-
-class LibvirtVMTemplate(VMTemplate):
- def __init__(self, args, scan=False, conn=None):
- self.conn = conn
- VMTemplate.__init__(self, args, scan)
-
- def _storage_validate(self):
- pool_uri = self.info['storagepool']
- pool_name = pool_name_from_uri(pool_uri)
- try:
- conn = self.conn.get()
- pool = conn.storagePoolLookupByName(pool_name.encode("utf-8"))
- except libvirt.libvirtError:
- raise InvalidParameter("KCHTMPL0004E", {'pool': pool_uri,
- 'template': self.name})
-
- if not pool.isActive():
- raise InvalidParameter("KCHTMPL0005E", {'pool': pool_name,
- 'template': self.name})
-
- return pool
-
- def _get_all_networks_name(self):
- conn = self.conn.get()
- return sorted(conn.listNetworks() + conn.listDefinedNetworks())
-
- def _get_all_storagepools_name(self):
- conn = self.conn.get()
- names = conn.listStoragePools() + conn.listDefinedStoragePools()
- return sorted(map(lambda x: x.decode('utf-8'), names))
-
- def _network_validate(self):
- names = self.info['networks']
- for name in names:
- try:
- conn = self.conn.get()
- network = conn.networkLookupByName(name.encode('utf-8'))
- except libvirt.libvirtError:
- raise InvalidParameter("KCHTMPL0003E", {'network':
name,
- 'template': self.name})
-
- if not network.isActive():
- raise InvalidParameter("KCHTMPL0007E", {'network':
name,
- 'template': self.name})
-
- def _get_storage_path(self):
- pool = self._storage_validate()
- xml = pool.XMLDesc(0)
- return xpath_get_text(xml, "/pool/target/path")[0]
-
- def _get_storage_type(self):
- pool = self._storage_validate()
- xml = pool.XMLDesc(0)
- return xpath_get_text(xml, "/pool/@type")[0]
-
- def _get_volume_path(self, pool, vol):
- pool = self._storage_validate()
- try:
- return pool.storageVolLookupByName(vol).path()
- except:
- raise NotFoundError("KCHVOL0002E", {'name': vol,
- 'pool': pool})
-
- def fork_vm_storage(self, vm_uuid):
- # Provision storage:
- # TODO: Rebase on the storage API once upstream
- pool = self._storage_validate()
- vol_list = self.to_volume_list(vm_uuid)
- try:
- for v in vol_list:
- # outgoing text to libvirt, encode('utf-8')
- pool.createXML(v['xml'].encode('utf-8'), 0)
- except libvirt.libvirtError as e:
- raise OperationFailed("KCHVMSTOR0008E", {'error':
e.message})
- return vol_list
diff --git a/plugins/kimchi/model/users.py b/plugins/kimchi/model/users.py
deleted file mode 100644
index 2fa65dd..0000000
--- a/plugins/kimchi/model/users.py
+++ /dev/null
@@ -1,90 +0,0 @@
-#
-# Project Kimchi
-#
-# Copyright IBM, Corp. 2014
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-
-import ldap
-import pwd
-
-from wok.config import config
-from wok.exception import NotFoundError
-
-
-class UsersModel(object):
- def __init__(self, **args):
- auth_type = config.get("authentication", "method")
- for klass in UsersModel.__subclasses__():
- if auth_type == klass.auth_type:
- self.user = klass(**args)
-
- def get_list(self, **args):
- return self.user._get_list(**args)
-
- def validate(self, user):
- return self.user._validate(user)
-
-
-class PAMUsersModel(UsersModel):
- auth_type = 'pam'
-
- def __init__(self, **kargs):
- pass
-
- def _get_list(self):
- return [user.pw_name for user in pwd.getpwall()
- if user.pw_shell.rsplit("/")[-1] not in ["nologin",
"false"]]
-
- def _validate(self, user):
- try:
- return user in self._get_list()
- except:
- return False
-
-
-class LDAPUsersModel(UsersModel):
- auth_type = 'ldap'
-
- def __init__(self, **kargs):
- pass
-
- def _get_list(self, _user_id=''):
- return self._get_user(_user_id)
-
- def _validate(self, user):
- try:
- self._get_user(user)
- return True
- except NotFoundError:
- return False
-
- def _get_user(self, _user_id):
- ldap_server = config.get("authentication",
"ldap_server").strip('"')
- ldap_search_base = config.get(
- "authentication",
"ldap_search_base").strip('"')
- ldap_search_filter = config.get(
- "authentication", "ldap_search_filter",
- vars={"username":
_user_id.encode("utf-8")}).strip('"')
-
- connect = ldap.open(ldap_server)
- try:
- result = connect.search_s(
- ldap_search_base, ldap.SCOPE_SUBTREE, ldap_search_filter)
- if len(result) == 0:
- raise NotFoundError("KCHAUTH0004E", {'user_id':
_user_id})
- return result[0][1]
- except ldap.NO_SUCH_OBJECT:
- raise NotFoundError("KCHAUTH0004E", {'user_id': _user_id})
diff --git a/plugins/kimchi/model/utils.py b/plugins/kimchi/model/utils.py
deleted file mode 100644
index 53d719d..0000000
--- a/plugins/kimchi/model/utils.py
+++ /dev/null
@@ -1,161 +0,0 @@
-#
-# Project Kimchi
-#
-# Copyright IBM, Corp. 2014-2015
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-
-import libvirt
-from lxml import etree, objectify
-from lxml.builder import E, ElementMaker
-
-from wok.exception import OperationFailed
-
-
-KIMCHI_META_URL = "https://github.com/kimchi-project/kimchi"
-KIMCHI_NAMESPACE = "kimchi"
-
-
-def get_vm_name(vm_name, t_name, name_list):
- if vm_name:
- return vm_name
- for i in xrange(1, 1000):
- # VM will have templace name, but without slashes
- vm_name = "%s-vm-%i" % (t_name.replace('/', '-'), i)
- if vm_name not in name_list:
- return vm_name
- raise OperationFailed("KCHUTILS0003E")
-
-
-def get_vm_config_flag(dom, mode="persistent"):
- # libvirt.VIR_DOMAIN_AFFECT_CURRENT is 0
- # VIR_DOMAIN_AFFECT_LIVE is 1, VIR_DOMAIN_AFFECT_CONFIG is 2
- flag = {"live": libvirt.VIR_DOMAIN_AFFECT_LIVE,
- "persistent": libvirt.VIR_DOMAIN_AFFECT_CONFIG,
- "current": libvirt.VIR_DOMAIN_AFFECT_CURRENT,
- "all": libvirt.VIR_DOMAIN_AFFECT_CONFIG +
- libvirt.VIR_DOMAIN_AFFECT_LIVE if dom.isActive() and
- dom.isPersistent() else libvirt.VIR_DOMAIN_AFFECT_CURRENT}
-
- return flag[mode]
-
-
-# avoid duplicate codes
-def update_node(root, node):
- old_node = root.find(node.tag)
- (root.replace(old_node, node) if old_node is not None
- else root.append(node))
- return root
-
-
-def _kimchi_set_metadata_node(dom, node):
- # some other tools will not let libvirt create a persistent
- # configuration, raise exception.
- if not dom.isPersistent():
- msg = 'The VM has not a persistent configuration'
- raise OperationFailed("KCHVM0030E",
- {'name': dom.name(), "err": msg})
- xml = dom.XMLDesc(libvirt.VIR_DOMAIN_XML_INACTIVE)
- root = etree.fromstring(xml)
- kimchi = root.find("metadata/{%s}kimchi" % KIMCHI_META_URL)
-
- EM = ElementMaker(namespace=KIMCHI_META_URL,
- nsmap={KIMCHI_NAMESPACE: KIMCHI_META_URL})
- kimchi = EM("kimchi") if kimchi is None else kimchi
-
- update_node(kimchi, node)
- metadata = root.find("metadata")
- metadata = E.metadata() if metadata is None else metadata
- update_node(metadata, kimchi)
- update_node(root, metadata)
- dom.connect().defineXML(etree.tostring(root))
-
-
-def libvirt_get_kimchi_metadata_node(dom, mode="current"):
- if not metadata_exists(dom):
- return None
- try:
- xml = dom.metadata(libvirt.VIR_DOMAIN_METADATA_ELEMENT,
- KIMCHI_META_URL,
- flags=get_vm_config_flag(dom, mode))
- return etree.fromstring(xml)
- except libvirt.libvirtError:
- return None
-
-
-def set_metadata_node(dom, node, metadata_support, mode="all"):
- if metadata_support:
- kimchi = libvirt_get_kimchi_metadata_node(dom, mode)
- kimchi = E.metadata(E.kimchi()) if kimchi is None else kimchi
-
- update_node(kimchi, node)
- kimchi_xml = etree.tostring(kimchi)
- # From libvirt doc, Passing None for @metadata says to remove that
- # element from the domain XML (passing the empty string leaves the
- # element present). Do not support remove the old metadata.
- dom.setMetadata(libvirt.VIR_DOMAIN_METADATA_ELEMENT, kimchi_xml,
- KIMCHI_NAMESPACE, KIMCHI_META_URL,
- flags=get_vm_config_flag(dom, mode))
- else:
- # FIXME remove this code when all distro libvirt supports metadata
- # element
- _kimchi_set_metadata_node(dom, node)
-
-
-def _kimchi_get_metadata_node(dom, tag):
- # some other tools will not let libvirt create a persistent
- # configuration, just return empty
- if not dom.isPersistent():
- return None
- xml = dom.XMLDesc(libvirt.VIR_DOMAIN_XML_INACTIVE)
- root = etree.fromstring(xml)
- kimchi = root.find("metadata/{%s}kimchi" % KIMCHI_META_URL)
- # remove the "kimchi" prefix of xml
- if kimchi is not None:
- for elem in kimchi.getiterator():
- if not hasattr(elem.tag, 'find'):
- continue
- i = elem.tag.find('}')
- if i >= 0:
- elem.tag = elem.tag[i+1:]
-
- objectify.deannotate(kimchi)
- etree.cleanup_namespaces(kimchi)
- return kimchi
- return None
-
-
-def get_metadata_node(dom, tag, metadata_support, mode="current"):
- if metadata_support:
- kimchi = libvirt_get_kimchi_metadata_node(dom, mode)
- else:
- # FIXME remove this code when all distro libvirt supports metadata
- # element
- kimchi = _kimchi_get_metadata_node(dom, tag)
-
- if kimchi is not None:
- node = kimchi.find(tag)
- if node is not None:
- return etree.tostring(node)
- return ""
-
-
-def metadata_exists(dom):
- xml = dom.XMLDesc(libvirt.VIR_DOMAIN_XML_INACTIVE)
- root = etree.fromstring(xml)
-
- if root.find("metadata") is None:
- return False
- return True
diff --git a/plugins/kimchi/model/vmhostdevs.py b/plugins/kimchi/model/vmhostdevs.py
deleted file mode 100644
index 0cc6bd3..0000000
--- a/plugins/kimchi/model/vmhostdevs.py
+++ /dev/null
@@ -1,336 +0,0 @@
-#
-# Project Kimchi
-#
-# Copyright IBM, Corp. 2014-2015
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-
-import glob
-import libvirt
-import os
-import platform
-from lxml import etree, objectify
-from lxml.builder import E
-
-from wok.exception import InvalidOperation, InvalidParameter, NotFoundError
-from wok.exception import OperationFailed
-from wok.rollbackcontext import RollbackContext
-from wok.utils import run_command, wok_log
-
-from config import CapabilitiesModel
-from host import DeviceModel, DevicesModel
-from utils import get_vm_config_flag
-from vms import DOM_STATE_MAP, VMModel
-
-
-class VMHostDevsModel(object):
- def __init__(self, **kargs):
- self.conn = kargs['conn']
- self.caps = CapabilitiesModel(**kargs)
-
- def get_list(self, vmid):
- dom = VMModel.get_vm(vmid, self.conn)
- xmlstr = dom.XMLDesc(0)
- root = objectify.fromstring(xmlstr)
- try:
- hostdev = root.devices.hostdev
- except AttributeError:
- return []
-
- return [self._deduce_dev_name(e) for e in hostdev]
-
- @staticmethod
- def _toint(num_str):
- if num_str.startswith('0x'):
- return int(num_str, 16)
- elif num_str.startswith('0'):
- return int(num_str, 8)
- else:
- return int(num_str)
-
- def _deduce_dev_name(self, e):
- return getattr(self, '_deduce_dev_name_%s' %
e.attrib['type'])(e)
-
- def _deduce_dev_name_pci(self, e):
- attrib = {}
- for field in ('domain', 'bus', 'slot',
'function'):
- attrib[field] = self._toint(e.source.address.attrib[field])
- return 'pci_%(domain)04x_%(bus)02x_%(slot)02x_%(function)x' % attrib
-
- def _deduce_dev_name_scsi(self, e):
- attrib = {}
- for field in ('bus', 'target', 'unit'):
- attrib[field] = self._toint(e.source.address.attrib[field])
- attrib['host'] = self._toint(
- e.source.adapter.attrib['name'][len('scsi_host'):])
- return 'scsi_%(host)d_%(bus)d_%(target)d_%(unit)d' % attrib
-
- def _deduce_dev_name_usb(self, e):
- dev_names = DevicesModel(conn=self.conn).get_list(_cap='usb_device')
- usb_infos = [DeviceModel(conn=self.conn).lookup(dev_name)
- for dev_name in dev_names]
-
- unknown_dev = None
-
- try:
- evendor = self._toint(e.source.vendor.attrib['id'])
- eproduct = self._toint(e.source.product.attrib['id'])
- except AttributeError:
- evendor = 0
- eproduct = 0
- else:
- unknown_dev = 'usb_vendor_%s_product_%s' % (evendor, eproduct)
-
- try:
- ebus = self._toint(e.source.address.attrib['bus'])
- edevice = self._toint(e.source.address.attrib['device'])
- except AttributeError:
- ebus = -1
- edevice = -1
- else:
- unknown_dev = 'usb_bus_%s_device_%s' % (ebus, edevice)
-
- for usb_info in usb_infos:
- ivendor = self._toint(usb_info['vendor']['id'])
- iproduct = self._toint(usb_info['product']['id'])
- if evendor == ivendor and eproduct == iproduct:
- return usb_info['name']
- ibus = usb_info['bus']
- idevice = usb_info['device']
- if ebus == ibus and edevice == idevice:
- return usb_info['name']
- return unknown_dev
-
- def _passthrough_device_validate(self, dev_name):
- eligible_dev_names = \
- DevicesModel(conn=self.conn).get_list(_passthrough='true')
- if dev_name not in eligible_dev_names:
- raise InvalidParameter('KCHVMHDEV0002E', {'dev_name':
dev_name})
-
- def create(self, vmid, params):
- dev_name = params['name']
- self._passthrough_device_validate(dev_name)
- dev_info = DeviceModel(conn=self.conn).lookup(dev_name)
-
- with RollbackContext() as rollback:
- try:
- dev = self.conn.get().nodeDeviceLookupByName(dev_name)
- dev.dettach()
- except Exception:
- raise OperationFailed('KCHVMHDEV0005E', {'name':
dev_name})
- else:
- rollback.prependDefer(dev.reAttach)
-
- attach_device = getattr(
- self, '_attach_%s_device' % dev_info['device_type'])
-
- info = attach_device(vmid, dev_info)
- rollback.commitAll()
-
- return info
-
- def _get_pci_device_xml(self, dev_info):
- if 'detach_driver' not in dev_info:
- dev_info['detach_driver'] = 'kvm'
-
- source = E.source(E.address(domain=str(dev_info['domain']),
- bus=str(dev_info['bus']),
- slot=str(dev_info['slot']),
- function=str(dev_info['function'])))
- driver = E.driver(name=dev_info['detach_driver'])
- host_dev = E.hostdev(source, driver,
- mode='subsystem', type='pci',
managed='yes')
-
- return etree.tostring(host_dev)
-
- @staticmethod
- def _validate_pci_passthrough_env():
- # Linux kernel < 3.5 doesn't provide /sys/kernel/iommu_groups
- if os.path.isdir('/sys/kernel/iommu_groups'):
- if not glob.glob('/sys/kernel/iommu_groups/*'):
- raise InvalidOperation("KCHVMHDEV0003E")
-
- # Enable virt_use_sysfs on RHEL6 and older distributions
- # In recent Fedora, there is no virt_use_sysfs.
- out, err, rc = run_command(['getsebool', 'virt_use_sysfs'])
- if rc == 0 and out.rstrip('\n') != "virt_use_sysfs --> on":
- out, err, rc = run_command(['setsebool', '-P',
- 'virt_use_sysfs=on'])
- if rc != 0:
- wok_log.warning("Unable to turn on sebool virt_use_sysfs")
-
- def _attach_pci_device(self, vmid, dev_info):
- self._validate_pci_passthrough_env()
-
- dom = VMModel.get_vm(vmid, self.conn)
- # Due to libvirt limitation, we don't support live assigne device to
- # vfio driver.
- driver = ('vfio' if DOM_STATE_MAP[dom.info()[0]] == "shutoff"
and
- self.caps.kernel_vfio else 'kvm')
-
- # on powerkvm systems it must be vfio driver.
- distro, _, _ = platform.linux_distribution()
- if distro == 'IBM_PowerKVM':
- driver = 'vfio'
-
- # Attach all PCI devices in the same IOMMU group
- dev_model = DeviceModel(conn=self.conn)
- devs_model = DevicesModel(conn=self.conn)
- affected_names = devs_model.get_list(
- _passthrough_affected_by=dev_info['name'])
- passthrough_names = devs_model.get_list(
- _cap='pci', _passthrough='true')
- group_names = list(set(affected_names) & set(passthrough_names))
- pci_infos = [dev_model.lookup(dev_name) for dev_name in group_names]
- pci_infos.append(dev_info)
-
- device_flags = get_vm_config_flag(dom, mode='all')
-
- with RollbackContext() as rollback:
- for pci_info in pci_infos:
- pci_info['detach_driver'] = driver
- xmlstr = self._get_pci_device_xml(pci_info)
- try:
- dom.attachDeviceFlags(xmlstr, device_flags)
- except libvirt.libvirtError:
- wok_log.error(
- 'Failed to attach host device %s to VM %s: \n%s',
- pci_info['name'], vmid, xmlstr)
- raise
- rollback.prependDefer(dom.detachDeviceFlags,
- xmlstr, device_flags)
- rollback.commitAll()
-
- return dev_info['name']
-
- def _get_scsi_device_xml(self, dev_info):
- adapter = E.adapter(name=('scsi_host%s' % dev_info['host']))
- address = E.address(type='scsi', bus=str(dev_info['bus']),
- target=str(dev_info['target']),
- unit=str(dev_info['lun']))
- host_dev = E.hostdev(E.source(adapter, address),
- mode='subsystem', type='scsi',
sgio='unfiltered')
- return etree.tostring(host_dev)
-
- def _attach_scsi_device(self, vmid, dev_info):
- xmlstr = self._get_scsi_device_xml(dev_info)
- dom = VMModel.get_vm(vmid, self.conn)
- dom.attachDeviceFlags(xmlstr, get_vm_config_flag(dom, mode='all'))
- return dev_info['name']
-
- def _get_usb_device_xml(self, dev_info):
- source = E.source(
- E.vendor(id=dev_info['vendor']['id']),
- E.product(id=dev_info['product']['id']),
- E.address(bus=str(dev_info['bus']),
- device=str(dev_info['device'])),
- startupPolicy='optional')
- host_dev = E.hostdev(source, mode='subsystem',
- ype='usb', managed='yes')
- return etree.tostring(host_dev)
-
- def _attach_usb_device(self, vmid, dev_info):
- xmlstr = self._get_usb_device_xml(dev_info)
- dom = VMModel.get_vm(vmid, self.conn)
- dom.attachDeviceFlags(xmlstr, get_vm_config_flag(dom, mode='all'))
- return dev_info['name']
-
-
-class VMHostDevModel(object):
- def __init__(self, **kargs):
- self.conn = kargs['conn']
-
- def lookup(self, vmid, dev_name):
- dom = VMModel.get_vm(vmid, self.conn)
- xmlstr = dom.XMLDesc(0)
- root = objectify.fromstring(xmlstr)
- try:
- hostdev = root.devices.hostdev
- except AttributeError:
- raise NotFoundError('KCHVMHDEV0001E',
- {'vmid': vmid, 'dev_name': dev_name})
-
- devsmodel = VMHostDevsModel(conn=self.conn)
-
- for e in hostdev:
- deduced_name = devsmodel._deduce_dev_name(e)
- if deduced_name == dev_name:
- return {'name': dev_name, 'type':
e.attrib['type']}
-
- raise NotFoundError('KCHVMHDEV0001E',
- {'vmid': vmid, 'dev_name': dev_name})
-
- def delete(self, vmid, dev_name):
- dom = VMModel.get_vm(vmid, self.conn)
- xmlstr = dom.XMLDesc(0)
- root = objectify.fromstring(xmlstr)
-
- try:
- hostdev = root.devices.hostdev
- except AttributeError:
- raise NotFoundError('KCHVMHDEV0001E',
- {'vmid': vmid, 'dev_name': dev_name})
-
- devsmodel = VMHostDevsModel(conn=self.conn)
- pci_devs = [(devsmodel._deduce_dev_name(e), e) for e in hostdev
- if e.attrib['type'] == 'pci']
-
- for e in hostdev:
- if devsmodel._deduce_dev_name(e) == dev_name:
- xmlstr = etree.tostring(e)
- dom.detachDeviceFlags(
- xmlstr, get_vm_config_flag(dom, mode='all'))
- if e.attrib['type'] == 'pci':
- self._delete_affected_pci_devices(dom, dev_name, pci_devs)
- break
- else:
- raise NotFoundError('KCHVMHDEV0001E',
- {'vmid': vmid, 'dev_name': dev_name})
-
- def _delete_affected_pci_devices(self, dom, dev_name, pci_devs):
- dev_model = DeviceModel(conn=self.conn)
- try:
- dev_model.lookup(dev_name)
- except NotFoundError:
- return
-
- affected_names = set(
- DevicesModel(
- conn=self.conn).get_list(_passthrough_affected_by=dev_name))
-
- for pci_name, e in pci_devs:
- if pci_name in affected_names:
- xmlstr = etree.tostring(e)
- dom.detachDeviceFlags(
- xmlstr, get_vm_config_flag(dom, mode='all'))
-
-
-class VMHoldersModel(object):
- def __init__(self, **kargs):
- self.conn = kargs['conn']
-
- def get_list(self, device_id):
- devsmodel = VMHostDevsModel(conn=self.conn)
-
- conn = self.conn.get()
- doms = conn.listAllDomains(0)
-
- res = []
- for dom in doms:
- dom_name = dom.name()
- if device_id in devsmodel.get_list(dom_name):
- state = DOM_STATE_MAP[dom.info()[0]]
- res.append({"name": dom_name, "state": state})
- return res
diff --git a/plugins/kimchi/model/vmifaces.py b/plugins/kimchi/model/vmifaces.py
deleted file mode 100644
index 87565c8..0000000
--- a/plugins/kimchi/model/vmifaces.py
+++ /dev/null
@@ -1,186 +0,0 @@
-#
-# Project Kimchi
-#
-# Copyright IBM, Corp. 2014-2015
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-
-import libvirt
-import random
-from lxml import etree, objectify
-
-from wok.exception import InvalidParameter, MissingParameter
-from wok.exception import NotFoundError, InvalidOperation
-
-from ..xmlutils.interface import get_iface_xml
-from config import CapabilitiesModel
-from vms import DOM_STATE_MAP, VMModel
-
-
-class VMIfacesModel(object):
- def __init__(self, **kargs):
- self.conn = kargs['conn']
- self.caps = CapabilitiesModel(**kargs)
-
- def get_list(self, vm):
- macs = []
- for iface in self.get_vmifaces(vm, self.conn):
- macs.append(iface.mac.get('address'))
- return macs
-
- def create(self, vm, params):
- conn = self.conn.get()
- networks = conn.listNetworks() + conn.listDefinedNetworks()
- networks = map(lambda x: x.decode('utf-8'), networks)
-
- if params['type'] == 'network':
- network = params.get("network")
-
- if network is None:
- raise MissingParameter('KCHVMIF0007E')
-
- if network not in networks:
- raise InvalidParameter('KCHVMIF0002E',
- {'name': vm, 'network': network})
-
- macs = (iface.mac.get('address')
- for iface in self.get_vmifaces(vm, self.conn))
-
- # user defined customized mac address
- if 'mac' in params and params['mac']:
- # make sure it is unique
- if params['mac'] in macs:
- raise InvalidParameter('KCHVMIF0009E',
- {'name': vm, 'mac':
params['mac']})
-
- # otherwise choose a random mac address
- else:
- while True:
- params['mac'] = VMIfacesModel.random_mac()
- if params['mac'] not in macs:
- break
-
- dom = VMModel.get_vm(vm, self.conn)
-
- os_data = VMModel.vm_get_os_metadata(dom, self.caps.metadata_support)
- os_version, os_distro = os_data
- xml = get_iface_xml(params, conn.getInfo()[0], os_distro, os_version)
-
- flags = 0
- if dom.isPersistent():
- flags |= libvirt.VIR_DOMAIN_AFFECT_CONFIG
- if DOM_STATE_MAP[dom.info()[0]] != "shutoff":
- flags |= libvirt.VIR_DOMAIN_AFFECT_LIVE
-
- dom.attachDeviceFlags(xml, flags)
-
- return params['mac']
-
- @staticmethod
- def get_vmifaces(vm, conn):
- dom = VMModel.get_vm(vm, conn)
- xml = dom.XMLDesc(0)
- root = objectify.fromstring(xml)
-
- return root.devices.findall("interface")
-
- @staticmethod
- def random_mac():
- mac = [0x52, 0x54, 0x00,
- random.randint(0x00, 0x7f),
- random.randint(0x00, 0xff),
- random.randint(0x00, 0xff)]
- return ':'.join(map(lambda x: u'%02x' % x, mac))
-
-
-class VMIfaceModel(object):
- def __init__(self, **kargs):
- self.conn = kargs['conn']
-
- def _get_vmiface(self, vm, mac):
- ifaces = VMIfacesModel.get_vmifaces(vm, self.conn)
-
- for iface in ifaces:
- if iface.mac.get('address') == mac:
- return iface
- return None
-
- def lookup(self, vm, mac):
- info = {}
-
- iface = self._get_vmiface(vm, mac)
- if iface is None:
- raise NotFoundError("KCHVMIF0001E", {'name': vm,
'iface': mac})
-
- info['type'] = iface.attrib['type']
- info['mac'] = iface.mac.get('address')
- if iface.find("model") is not None:
- info['model'] = iface.model.get('type')
- if info['type'] == 'network':
- info['network'] = iface.source.get('network')
- if info['type'] == 'bridge':
- info['bridge'] = iface.source.get('bridge')
-
- return info
-
- def delete(self, vm, mac):
- dom = VMModel.get_vm(vm, self.conn)
- iface = self._get_vmiface(vm, mac)
-
- if iface is None:
- raise NotFoundError("KCHVMIF0001E", {'name': vm,
'iface': mac})
-
- flags = 0
- if dom.isPersistent():
- flags |= libvirt.VIR_DOMAIN_AFFECT_CONFIG
- if DOM_STATE_MAP[dom.info()[0]] != "shutoff":
- flags |= libvirt.VIR_DOMAIN_AFFECT_LIVE
-
- dom.detachDeviceFlags(etree.tostring(iface), flags)
-
- def update(self, vm, mac, params):
- dom = VMModel.get_vm(vm, self.conn)
- iface = self._get_vmiface(vm, mac)
-
- if iface is None:
- raise NotFoundError("KCHVMIF0001E", {'name': vm,
'iface': mac})
-
- # cannot change mac address in a running system
- if DOM_STATE_MAP[dom.info()[0]] != "shutoff":
- raise InvalidOperation('KCHVMIF0011E')
-
- # mac address is a required parameter
- if 'mac' not in params:
- raise MissingParameter('KCHVMIF0008E')
-
- # new mac address must be unique
- if self._get_vmiface(vm, params['mac']) is not None:
- raise InvalidParameter('KCHVMIF0009E',
- {'name': vm, 'mac':
params['mac']})
-
- flags = 0
- if dom.isPersistent():
- flags |= libvirt.VIR_DOMAIN_AFFECT_CONFIG
-
- # remove the current nic
- xml = etree.tostring(iface)
- dom.detachDeviceFlags(xml, flags=flags)
-
- # add the nic with the desired mac address
- iface.mac.attrib['address'] = params['mac']
- xml = etree.tostring(iface)
- dom.attachDeviceFlags(xml, flags=flags)
-
- return [vm, params['mac']]
diff --git a/plugins/kimchi/model/vms.py b/plugins/kimchi/model/vms.py
deleted file mode 100644
index f37b5d6..0000000
--- a/plugins/kimchi/model/vms.py
+++ /dev/null
@@ -1,1307 +0,0 @@
-#
-# Project Kimchi
-#
-# Copyright IBM, Corp. 2014-2015
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-
-import libvirt
-import lxml.etree as ET
-import os
-import random
-import string
-import time
-import uuid
-from lxml import etree, objectify
-from lxml.builder import E
-from xml.etree import ElementTree
-
-from wok.config import config
-from wok.exception import InvalidOperation, InvalidParameter
-from wok.exception import NotFoundError, OperationFailed
-from wok.rollbackcontext import RollbackContext
-from wok.utils import add_task, convert_data_size, get_next_clone_name
-from wok.utils import import_class, run_setfacl_set_attr, wok_log
-from wok.xmlutils.utils import xpath_get_text, xml_item_update
-from wok.xmlutils.utils import dictize
-from wok.model.tasks import TaskModel
-
-from .. import model
-from .. import vnc
-from ..config import READONLY_POOL_TYPE
-from ..kvmusertests import UserTests
-from ..screenshot import VMScreenshot
-from ..utils import template_name_from_uri
-from ..xmlutils.cpu import get_cpu_xml, get_numa_xml
-from config import CapabilitiesModel
-from templates import TemplateModel
-from utils import get_vm_name
-from utils import get_metadata_node
-from utils import set_metadata_node
-
-
-DOM_STATE_MAP = {0: 'nostate',
- 1: 'running',
- 2: 'blocked',
- 3: 'paused',
- 4: 'shutdown',
- 5: 'shutoff',
- 6: 'crashed',
- 7: 'pmsuspended'}
-
-VM_STATIC_UPDATE_PARAMS = {'name': './name',
- 'cpus': './vcpu'}
-VM_LIVE_UPDATE_PARAMS = {}
-
-XPATH_DOMAIN_DISK =
"/domain/devices/disk[@device='disk']/source/@file"
-XPATH_DOMAIN_DISK_BY_FILE =
"./devices/disk[@device='disk']/source[@file='%s']"
-XPATH_DOMAIN_NAME = '/domain/name'
-XPATH_DOMAIN_MAC =
"/domain/devices/interface[@type='network']/mac/@address"
-XPATH_DOMAIN_MAC_BY_ADDRESS = "./devices/interface[@type='network']/"\
- "mac[@address='%s']"
-XPATH_DOMAIN_MEMORY = '/domain/memory'
-XPATH_DOMAIN_MEMORY_UNIT = '/domain/memory/@unit'
-XPATH_DOMAIN_UUID = '/domain/uuid'
-
-XPATH_NUMA_CELL = './cpu/numa/cell'
-
-
-class VMsModel(object):
- def __init__(self, **kargs):
- self.conn = kargs['conn']
- self.objstore = kargs['objstore']
- self.caps = CapabilitiesModel(**kargs)
- self.task = TaskModel(**kargs)
-
- def create(self, params):
- t_name = template_name_from_uri(params['template'])
- vm_list = self.get_list()
- name = get_vm_name(params.get('name'), t_name, vm_list)
- # incoming text, from js json, is unicode, do not need decode
- if name in vm_list:
- raise InvalidOperation("KCHVM0001E", {'name': name})
-
- vm_overrides = dict()
- pool_uri = params.get('storagepool')
- if pool_uri:
- vm_overrides['storagepool'] = pool_uri
- vm_overrides['fc_host_support'] = self.caps.fc_host_support
- t = TemplateModel.get_template(t_name, self.objstore, self.conn,
- vm_overrides)
-
- if not self.caps.qemu_stream and t.info.get('iso_stream', False):
- raise InvalidOperation("KCHVM0005E")
-
- t.validate()
- data = {'name': name, 'template': t,
- 'graphics': params.get('graphics', {})}
- taskid = add_task(u'/plugins/kimchi/vms/%s' % name, self._create_task,
- self.objstore, data)
-
- return self.task.lookup(taskid)
-
- def _create_task(self, cb, params):
- """
- params: A dict with the following values:
- - vm_uuid: The UUID of the VM being created
- - template: The template being used to create the VM
- - name: The name for the new VM
- """
- vm_uuid = str(uuid.uuid4())
- t = params['template']
- name = params['name']
- conn = self.conn.get()
-
- cb('Storing VM icon')
- # Store the icon for displaying later
- icon = t.info.get('icon')
- if icon:
- try:
- with self.objstore as session:
- session.store('vm', vm_uuid, {'icon': icon})
- except Exception as e:
- # It is possible to continue Kimchi executions without store
- # vm icon info
- wok_log.error('Error trying to update database with guest '
- 'icon information due error: %s', e.message)
-
- # If storagepool is SCSI, volumes will be LUNs and must be passed by
- # the user from UI or manually.
- cb('Provisioning storage for new VM')
- vol_list = []
- if t._get_storage_type() not in ["iscsi", "scsi"]:
- vol_list = t.fork_vm_storage(vm_uuid)
-
- graphics = params.get('graphics', {})
- stream_protocols = self.caps.libvirt_stream_protocols
- xml = t.to_vm_xml(name, vm_uuid,
- libvirt_stream_protocols=stream_protocols,
- graphics=graphics,
- volumes=vol_list)
-
- cb('Defining new VM')
- try:
- conn.defineXML(xml.encode('utf-8'))
- except libvirt.libvirtError as e:
- if t._get_storage_type() not in READONLY_POOL_TYPE:
- for v in vol_list:
- vol = conn.storageVolLookupByPath(v['path'])
- vol.delete(0)
- raise OperationFailed("KCHVM0007E", {'name': name,
- 'err': e.get_error_message()})
-
- cb('Updating VM metadata')
- VMModel.vm_update_os_metadata(VMModel.get_vm(name, self.conn), t.info,
- self.caps.metadata_support)
- cb('OK', True)
-
- def get_list(self):
- return VMsModel.get_vms(self.conn)
-
- @staticmethod
- def get_vms(conn):
- conn_ = conn.get()
- names = [dom.name().decode('utf-8') for dom in conn_.listAllDomains(0)]
- names = sorted(names, key=unicode.lower)
- return names
-
-
-class VMModel(object):
- def __init__(self, **kargs):
- self.conn = kargs['conn']
- self.objstore = kargs['objstore']
- self.caps = CapabilitiesModel(**kargs)
- self.vmscreenshot = VMScreenshotModel(**kargs)
- self.users = import_class(
- 'plugins.kimchi.model.users.UsersModel'
- )(**kargs)
- self.groups = import_class(
- 'plugins.kimchi.model.groups.GroupsModel'
- )(**kargs)
- self.vms = VMsModel(**kargs)
- self.task = TaskModel(**kargs)
- self.storagepool = model.storagepools.StoragePoolModel(**kargs)
- self.storagevolume = model.storagevolumes.StorageVolumeModel(**kargs)
- self.storagevolumes = model.storagevolumes.StorageVolumesModel(**kargs)
- cls = import_class('plugins.kimchi.model.vmsnapshots.VMSnapshotModel')
- self.vmsnapshot = cls(**kargs)
- cls = import_class('plugins.kimchi.model.vmsnapshots.VMSnapshotsModel')
- self.vmsnapshots = cls(**kargs)
- self.stats = {}
-
- def update(self, name, params):
- dom = self.get_vm(name, self.conn)
- dom = self._static_vm_update(dom, params)
- self._live_vm_update(dom, params)
- return dom.name().decode('utf-8')
-
- def clone(self, name):
- """Clone a virtual machine based on an existing one.
-
- The new virtual machine will have the exact same configuration as the
- original VM, except for the name, UUID, MAC addresses and disks. The
- name will have the form "<name>-clone-<number>", with
<number> starting
- at 1; the UUID will be generated randomly; the MAC addresses will be
- generated randomly with no conflicts within the original and the new
- VM; and the disks will be new volumes [mostly] on the same storage
- pool, with the same content as the original disks. The storage pool
- 'default' will always be used when cloning SCSI and iSCSI disks and
- when the original storage pool cannot hold the new volume.
-
- An exception will be raised if the virtual machine <name> is not
- shutoff, if there is no available space to copy a new volume to the
- storage pool 'default' (when there was also no space to copy it to the
- original storage pool) and if one of the virtual machine's disks belong
- to a storage pool not supported by Kimchi.
-
- Parameters:
- name -- The name of the existing virtual machine to be cloned.
-
- Return:
- A Task running the clone operation.
- """
- name = name.decode('utf-8')
-
- # VM must be shutoff in order to clone it
- info = self.lookup(name)
- if info['state'] != u'shutoff':
- raise InvalidParameter('KCHVM0033E', {'name': name})
-
- # the new VM's name will be used as the Task's 'target_uri' so it
needs
- # to be defined now.
-
- vms_being_created = []
-
- # lookup names of VMs being created right now
- with self.objstore as session:
- task_names = session.get_list('task')
- for tn in task_names:
- t = session.get('task', tn)
- if t['target_uri'].startswith('/plugins/kimchi/vms/'):
- uri_name =
t['target_uri'].lstrip('/plugins/kimchi/vms/')
- vms_being_created.append(uri_name)
-
- current_vm_names = self.vms.get_list() + vms_being_created
- new_name = get_next_clone_name(current_vm_names, name)
-
- # create a task with the actual clone function
- taskid = add_task(u'/plugins/kimchi/vms/%s/clone' % new_name,
- self._clone_task, self.objstore,
- {'name': name, 'new_name': new_name})
-
- return self.task.lookup(taskid)
-
- def _clone_task(self, cb, params):
- """Asynchronous function which performs the clone operation.
-
- Parameters:
- cb -- A callback function to signal the Task's progress.
- params -- A dict with the following values:
- "name": the name of the original VM.
- "new_name": the name of the new VM.
- """
- name = params['name']
- new_name = params['new_name']
- vir_conn = self.conn.get()
-
- # fetch base XML
- cb('reading source VM XML')
- try:
- vir_dom = vir_conn.lookupByName(name)
- flags = libvirt.VIR_DOMAIN_XML_SECURE
- xml = vir_dom.XMLDesc(flags).decode('utf-8')
- except libvirt.libvirtError, e:
- raise OperationFailed('KCHVM0035E', {'name': name,
- 'err': e.message})
-
- # update UUID
- cb('updating VM UUID')
- old_uuid = xpath_get_text(xml, XPATH_DOMAIN_UUID)[0]
- new_uuid = unicode(uuid.uuid4())
- xml = xml_item_update(xml, './uuid', new_uuid)
-
- # update MAC addresses
- cb('updating VM MAC addresses')
- xml = self._clone_update_mac_addresses(xml)
-
- with RollbackContext() as rollback:
- # copy disks
- cb('copying VM disks')
- xml = self._clone_update_disks(xml, rollback)
-
- # update objstore entry
- cb('updating object store')
- self._clone_update_objstore(old_uuid, new_uuid, rollback)
-
- # update name
- cb('updating VM name')
- xml = xml_item_update(xml, './name', new_name)
-
- # create new guest
- cb('defining new VM')
- try:
- vir_conn.defineXML(xml)
- except libvirt.libvirtError, e:
- raise OperationFailed('KCHVM0035E', {'name': name,
- 'err': e.message})
-
- rollback.commitAll()
-
- cb('OK', True)
-
- @staticmethod
- def _clone_update_mac_addresses(xml):
- """Update the MAC addresses with new values in the XML descriptor
of a
- cloning domain.
-
- The new MAC addresses will be generated randomly, and their values are
- guaranteed to be distinct from the ones in the original VM.
-
- Arguments:
- xml -- The XML descriptor of the original domain.
-
- Return:
- The XML descriptor <xml> with the new MAC addresses instead of the
- old ones.
- """
- old_macs = xpath_get_text(xml, XPATH_DOMAIN_MAC)
- new_macs = []
-
- for mac in old_macs:
- while True:
- new_mac = model.vmifaces.VMIfacesModel.random_mac()
- # make sure the new MAC doesn't conflict with the original VM
- # and with the new values on the new VM.
- if new_mac not in (old_macs + new_macs):
- new_macs.append(new_mac)
- break
-
- xml = xml_item_update(xml, XPATH_DOMAIN_MAC_BY_ADDRESS % mac,
- new_mac, 'address')
-
- return xml
-
- def _clone_update_disks(self, xml, rollback):
- """Clone disks from a virtual machine. The disks are copied as
new
- volumes and the new VM's XML is updated accordingly.
-
- Arguments:
- xml -- The XML descriptor of the original VM + new value for
- "/domain/uuid".
- rollback -- A rollback context so the new volumes can be removed if an
- error occurs during the cloning operation.
-
- Return:
- The XML descriptor <xml> with the new disk paths instead of the
- old ones.
- """
- # the UUID will be used to create the disk paths
- uuid = xpath_get_text(xml, XPATH_DOMAIN_UUID)[0]
- all_paths = xpath_get_text(xml, XPATH_DOMAIN_DISK)
-
- vir_conn = self.conn.get()
-
- def _delete_disk_from_objstore(path):
- with self.objstore as session:
- session.delete('storagevolume', path)
-
- domain_name = xpath_get_text(xml, XPATH_DOMAIN_NAME)[0]
-
- for i, path in enumerate(all_paths):
- try:
- vir_orig_vol = vir_conn.storageVolLookupByPath(path)
- vir_pool = vir_orig_vol.storagePoolLookupByVolume()
-
- orig_pool_name = vir_pool.name().decode('utf-8')
- orig_vol_name = vir_orig_vol.name().decode('utf-8')
- except libvirt.libvirtError, e:
- raise OperationFailed('KCHVM0035E', {'name':
domain_name,
- 'err': e.message})
-
- orig_pool = self.storagepool.lookup(orig_pool_name)
- orig_vol = self.storagevolume.lookup(orig_pool_name, orig_vol_name)
-
- new_pool_name = orig_pool_name
- new_pool = orig_pool
-
- if orig_pool['type'] in ['dir', 'netfs',
'logical']:
- # if a volume in a pool 'dir', 'netfs' or
'logical' cannot hold
- # a new volume with the same size, the pool 'default' should
- # be used
- if orig_vol['capacity'] > orig_pool['available']:
- wok_log.warning('storage pool \'%s\' doesn\'t have
'
- 'enough free space to store image '
- '\'%s\'; falling back to
\'default\'',
- orig_pool_name, path)
- new_pool_name = u'default'
- new_pool = self.storagepool.lookup(u'default')
-
- # ...and if even the pool 'default' cannot hold a new
- # volume, raise an exception
- if orig_vol['capacity'] > new_pool['available']:
- domain_name = xpath_get_text(xml, XPATH_DOMAIN_NAME)[0]
- raise InvalidOperation('KCHVM0034E',
- {'name': domain_name})
-
- elif orig_pool['type'] in ['scsi', 'iscsi']:
- # SCSI and iSCSI always fall back to the storage pool 'default'
- wok_log.warning('cannot create new volume for clone in '
- 'storage pool \'%s\'; falling back to '
- '\'default\'', orig_pool_name)
- new_pool_name = u'default'
- new_pool = self.storagepool.lookup(u'default')
-
- # if the pool 'default' cannot hold a new volume, raise
- # an exception
- if orig_vol['capacity'] > new_pool['available']:
- domain_name = xpath_get_text(xml, XPATH_DOMAIN_NAME)[0]
- raise InvalidOperation('KCHVM0034E', {'name':
domain_name})
-
- else:
- # unexpected storage pool type
- raise InvalidOperation('KCHPOOL0014E',
- {'type': orig_pool['type']})
-
- # new volume name: <UUID>-<loop-index>.<original
extension>
- # e.g. 1234-5678-9012-3456-0.img
- ext = os.path.splitext(path)[1]
- new_vol_name = u'%s-%d%s' % (uuid, i, ext)
- task = self.storagevolume.clone(orig_pool_name, orig_vol_name,
- new_name=new_vol_name)
- self.task.wait(task['id'], 3600) # 1 h
-
- # get the new volume path and update the XML descriptor
- new_vol = self.storagevolume.lookup(new_pool_name, new_vol_name)
- xml = xml_item_update(xml, XPATH_DOMAIN_DISK_BY_FILE % path,
- new_vol['path'], 'file')
-
- # set the new disk's used_by
- with self.objstore as session:
- session.store('storagevolume', new_vol['path'],
- {'used_by': [domain_name]})
- rollback.prependDefer(_delete_disk_from_objstore, new_vol['path'])
-
- # remove the new volume should an error occur later
- rollback.prependDefer(self.storagevolume.delete, new_pool_name,
- new_vol_name)
-
- return xml
-
- def _clone_update_objstore(self, old_uuid, new_uuid, rollback):
- """Update Kimchi's object store with the cloning VM.
-
- Arguments:
- old_uuid -- The UUID of the original VM.
- new_uuid -- The UUID of the new, clonning VM.
- rollback -- A rollback context so the object store entry can be removed
- if an error occurs during the cloning operation.
- """
- with self.objstore as session:
- try:
- vm = session.get('vm', old_uuid)
- icon = vm['icon']
- session.store('vm', new_uuid, {'icon': icon})
- except NotFoundError:
- # if we cannot find an object store entry for the original VM,
- # don't store one with an empty value.
- pass
- else:
- # we need to define a custom function to prepend to the
- # rollback context because the object store session needs to be
- # opened and closed correctly (i.e. "prependDefer" only
- # accepts one command at a time but we need more than one to
- # handle an object store).
- def _rollback_objstore():
- with self.objstore as session_rb:
- session_rb.delete('vm', new_uuid, ignore_missing=True)
-
- # remove the new object store entry should an error occur later
- rollback.prependDefer(_rollback_objstore)
-
- def _build_access_elem(self, dom, users, groups):
- auth = config.get("authentication", "method")
- access_xml = get_metadata_node(dom, "access",
- self.caps.metadata_support)
-
- auth_elem = None
-
- if not access_xml:
- # there is no metadata element 'access'
- access_elem = E.access()
- else:
- access_elem = ET.fromstring(access_xml)
-
- same_auth = access_elem.xpath('./auth[@type="%s"]' % auth)
- if len(same_auth) > 0:
- # there is already a sub-element 'auth' with the same type;
- # update it.
- auth_elem = same_auth[0]
-
- if users is not None:
- for u in auth_elem.findall('user'):
- auth_elem.remove(u)
-
- if groups is not None:
- for g in auth_elem.findall('group'):
- auth_elem.remove(g)
-
- if auth_elem is None:
- # there is no sub-element 'auth' with the same type
- # (or no 'auth' at all); create it.
- auth_elem = E.auth(type=auth)
- access_elem.append(auth_elem)
-
- if users is not None:
- for u in users:
- auth_elem.append(E.user(u))
-
- if groups is not None:
- for g in groups:
- auth_elem.append(E.group(g))
-
- return access_elem
-
- def _vm_update_access_metadata(self, dom, params):
- users = groups = None
- if "users" in params:
- users = params["users"]
- for user in users:
- if not self.users.validate(user):
- raise InvalidParameter("KCHVM0027E",
- {'users': user})
- if "groups" in params:
- groups = params["groups"]
- for group in groups:
- if not self.groups.validate(group):
- raise InvalidParameter("KCHVM0028E",
- {'groups': group})
-
- if users is None and groups is None:
- return
-
- node = self._build_access_elem(dom, users, groups)
- set_metadata_node(dom, node, self.caps.metadata_support)
-
- def _get_access_info(self, dom):
- users = groups = list()
- access_xml = (get_metadata_node(dom, "access",
- self.caps.metadata_support) or
- """<access></access>""")
- access_info = dictize(access_xml)
- auth = config.get("authentication", "method")
- if ('auth' in access_info['access'] and
- ('type' in access_info['access']['auth'] or
- len(access_info['access']['auth']) > 1)):
- users = xpath_get_text(access_xml,
- "/access/auth[@type='%s']/user" %
auth)
- groups = xpath_get_text(access_xml,
- "/access/auth[@type='%s']/group" %
auth)
- elif auth == 'pam':
- # Compatible to old permission tagging
- users = xpath_get_text(access_xml, "/access/user")
- groups = xpath_get_text(access_xml, "/access/group")
- return users, groups
-
- @staticmethod
- def vm_get_os_metadata(dom, metadata_support):
- os_xml = (get_metadata_node(dom, "os", metadata_support) or
- """<os></os>""")
- os_elem = ET.fromstring(os_xml)
- return (os_elem.attrib.get("version"),
os_elem.attrib.get("distro"))
-
- @staticmethod
- def vm_update_os_metadata(dom, params, metadata_support):
- distro = params.get("os_distro")
- version = params.get("os_version")
- if distro is None:
- return
- os_elem = E.os({"distro": distro, "version": version})
- set_metadata_node(dom, os_elem, metadata_support)
-
- def _update_graphics(self, dom, xml, params):
- root = objectify.fromstring(xml)
- graphics = root.devices.find("graphics")
- if graphics is None:
- return xml
-
- password = params['graphics'].get("passwd")
- if password is not None and len(password.strip()) == 0:
- password = "".join(random.sample(string.ascii_letters +
- string.digits, 8))
-
- if password is not None:
- graphics.attrib['passwd'] = password
-
- expire = params['graphics'].get("passwdValidTo")
- to = graphics.attrib.get('passwdValidTo')
- if to is not None:
- if (time.mktime(time.strptime(to, '%Y-%m-%dT%H:%M:%S')) -
- time.time() <= 0):
- expire = expire if expire is not None else 30
-
- if expire is not None:
- expire_time = time.gmtime(time.time() + float(expire))
- valid_to = time.strftime('%Y-%m-%dT%H:%M:%S', expire_time)
- graphics.attrib['passwdValidTo'] = valid_to
-
- if not dom.isActive():
- return ET.tostring(root, encoding="utf-8")
-
- xml = dom.XMLDesc(libvirt.VIR_DOMAIN_XML_SECURE)
- dom.updateDeviceFlags(etree.tostring(graphics),
- libvirt.VIR_DOMAIN_AFFECT_LIVE)
- return xml
-
- def _backup_snapshots(self, snap, all_info):
- """ Append "snap" and the children of "snap"
to the list "all_info".
-
- The list *must* always contain the parent snapshots before their
- children so the function "_redefine_snapshots" can work correctly.
-
- Arguments:
- snap -- a native domain snapshot.
- all_info -- a list of dict keys:
- "{'xml': <snap XML>, 'current': <is snap
current?>'}"
- """
- all_info.append({'xml': snap.getXMLDesc(0),
- 'current': snap.isCurrent(0)})
-
- for child in snap.listAllChildren(0):
- self._backup_snapshots(child, all_info)
-
- def _redefine_snapshots(self, dom, all_info):
- """ Restore the snapshots stored in "all_info" to the
domain "dom".
-
- Arguments:
- dom -- the domain which will have its snapshots restored.
- all_info -- a list of dict keys, as described in "_backup_snapshots",
- containing the original snapshot information.
- """
- for info in all_info:
- flags = libvirt.VIR_DOMAIN_SNAPSHOT_CREATE_REDEFINE
-
- if info['current']:
- flags |= libvirt.VIR_DOMAIN_SNAPSHOT_CREATE_CURRENT
-
- dom.snapshotCreateXML(info['xml'], flags)
-
- def _static_vm_update(self, dom, params):
- old_xml = new_xml = dom.XMLDesc(0)
-
- for key, val in params.items():
- if key in VM_STATIC_UPDATE_PARAMS:
- if type(val) == int:
- val = str(val)
- xpath = VM_STATIC_UPDATE_PARAMS[key]
- new_xml = xml_item_update(new_xml, xpath, val)
-
- # Updating memory and NUMA if necessary, if vm is offline
- if not dom.isActive():
- if 'memory' in params:
- new_xml = self._update_memory_config(new_xml, params)
- elif 'cpus' in params and \
- (xpath_get_text(new_xml, XPATH_NUMA_CELL + '/@memory') != []):
- vcpus = params['cpus']
- new_xml = xml_item_update(
- new_xml,
- XPATH_NUMA_CELL,
- value='0-' + str(vcpus - 1) if vcpus > 1 else
'0',
- attr='cpus')
-
- if 'graphics' in params:
- new_xml = self._update_graphics(dom, new_xml, params)
-
- snapshots_info = []
- vm_name = dom.name()
- conn = self.conn.get()
- try:
- if 'name' in params:
- state = DOM_STATE_MAP[dom.info()[0]]
- if state != 'shutoff':
- msg_args = {'name': vm_name, 'new_name':
params['name']}
- raise InvalidParameter("KCHVM0003E", msg_args)
-
- lflags = libvirt.VIR_DOMAIN_SNAPSHOT_LIST_ROOTS
- dflags = (libvirt.VIR_DOMAIN_SNAPSHOT_DELETE_CHILDREN |
- libvirt.VIR_DOMAIN_SNAPSHOT_DELETE_METADATA_ONLY)
-
- for virt_snap in dom.listAllSnapshots(lflags):
- snapshots_info.append({'xml': virt_snap.getXMLDesc(0),
- 'current': virt_snap.isCurrent(0)})
- self._backup_snapshots(virt_snap, snapshots_info)
-
- virt_snap.delete(dflags)
-
- # Undefine old vm, only if name is going to change
- dom.undefine()
-
- dom = conn.defineXML(new_xml)
- if 'name' in params:
- self._redefine_snapshots(dom, snapshots_info)
- except libvirt.libvirtError as e:
- dom = conn.defineXML(old_xml)
- if 'name' in params:
- self._redefine_snapshots(dom, snapshots_info)
-
- raise OperationFailed("KCHVM0008E", {'name': vm_name,
- 'err': e.get_error_message()})
- return dom
-
- def _update_memory_config(self, xml, params):
- # Checks if NUMA memory is already configured, if not, checks if CPU
- # element is already configured (topology). Then add NUMA element as
- # apropriated
- root = ET.fromstring(xml)
- numa_mem = xpath_get_text(xml, XPATH_NUMA_CELL + '/@memory')
- vcpus = params.get('cpus')
- if numa_mem == []:
- if vcpus is None:
- vcpus = int(xpath_get_text(xml,
- VM_STATIC_UPDATE_PARAMS['cpus'])[0])
- cpu = root.find('./cpu')
- if cpu is None:
- cpu = get_cpu_xml(vcpus, params['memory'] << 10)
- root.insert(0, ET.fromstring(cpu))
- else:
- numa_element = get_numa_xml(vcpus, params['memory'] << 10)
- cpu.insert(0, ET.fromstring(numa_element))
- else:
- if vcpus is not None:
- xml = xml_item_update(
- xml,
- XPATH_NUMA_CELL,
- value='0-' + str(vcpus - 1) if vcpus > 1 else
'0',
- attr='cpus')
- root = ET.fromstring(xml_item_update(xml, XPATH_NUMA_CELL,
- str(params['memory'] <<
10),
- attr='memory'))
-
- # Remove currentMemory, automatically set later by libvirt
- currentMem = root.find('.currentMemory')
- if currentMem is not None:
- root.remove(currentMem)
-
- memory = root.find('.memory')
- # Update/Adds maxMemory accordingly
- if not self.caps.mem_hotplug_support:
- if memory is not None:
- memory.text = str(params['memory'] << 10)
- else:
- if memory is not None:
- root.remove(memory)
- maxMem = root.find('.maxMemory')
- host_mem = self.conn.get().getInfo()[1]
- slots = (host_mem - params['memory']) >> 10
- # Libvirt does not accepts slots <= 1
- if slots < 0:
- raise OperationFailed("KCHVM0041E")
- elif slots == 0:
- slots = 1
- if maxMem is None:
- max_mem_xml = E.maxMemory(
- str(host_mem * 1024),
- unit='Kib',
- slots=str(slots))
- root.insert(0, max_mem_xml)
- new_xml = ET.tostring(root, encoding="utf-8")
- else:
- # Update slots only
- new_xml = xml_item_update(ET.tostring(root, encoding="utf-8"),
- './maxMemory',
- str(slots),
- attr='slots')
- return new_xml
- return ET.tostring(root, encoding="utf-8")
-
- def _live_vm_update(self, dom, params):
- self._vm_update_access_metadata(dom, params)
- if 'memory' in params and dom.isActive():
- self._update_memory_live(dom, params)
-
- def _update_memory_live(self, dom, params):
- # Check if host supports memory device
- if not self.caps.mem_hotplug_support:
- raise InvalidOperation("KCHVM0046E")
-
- # Check if the vm xml supports memory hotplug, if not, static update
- # must be done firstly, then Kimchi is going to update the xml
- xml = dom.XMLDesc(0)
- numa_mem = xpath_get_text(xml, XPATH_NUMA_CELL + '/@memory')
- max_mem = xpath_get_text(xml, './maxMemory')
- if numa_mem == [] or max_mem == []:
- raise OperationFailed('KCHVM0042E', {'name': dom.name()})
-
- # Memory live update must be done in chunks of 1024 Mib or 1Gib
- new_mem = params['memory']
- old_mem = int(xpath_get_text(xml, XPATH_DOMAIN_MEMORY)[0]) >> 10
- if new_mem < old_mem:
- raise OperationFailed('KCHVM0043E')
- if (new_mem - old_mem) % 1024 != 0:
- raise OperationFailed('KCHVM0044E')
-
- # Check slot spaces:
- total_slots = int(xpath_get_text(xml, './maxMemory/@slots')[0])
- needed_slots = (new_mem - old_mem) / 1024
- used_slots = len(xpath_get_text(xml, './devices/memory'))
- if needed_slots > (total_slots - used_slots):
- raise OperationFailed('KCHVM0045E')
- elif needed_slots == 0:
- # New memory value is same that current memory set
- return
-
- # Finally, we are ok to hot add the memory devices
- try:
- self._hot_add_memory_devices(dom, needed_slots)
- except Exception as e:
- raise OperationFailed("KCHVM0047E", {'error': e.message})
-
- def _hot_add_memory_devices(self, dom, amount):
- # Hot add given number of memory devices in the guest
- flags = libvirt.VIR_DOMAIN_MEM_CONFIG | libvirt.VIR_DOMAIN_MEM_LIVE
- # Create memory device xml
- mem_dev_xml = etree.tostring(
- E.memory(
- E.target(
- E.size('1', unit='GiB'),
- E.node('0')),
- model='dimm'))
- # Add chunks of 1G of memory
- for i in range(amount):
- dom.attachDeviceFlags(mem_dev_xml, flags)
-
- def _has_video(self, dom):
- dom = ElementTree.fromstring(dom.XMLDesc(0))
- return dom.find('devices/video') is not None
-
- def _update_guest_stats(self, name):
- try:
- dom = VMModel.get_vm(name, self.conn)
-
- vm_uuid = dom.UUIDString()
- info = dom.info()
- state = DOM_STATE_MAP[info[0]]
-
- if state != 'running':
- self.stats[vm_uuid] = {}
- return
-
- if self.stats.get(vm_uuid, None) is None:
- self.stats[vm_uuid] = {}
-
- timestamp = time.time()
- prevStats = self.stats.get(vm_uuid, {})
- seconds = timestamp - prevStats.get('timestamp', 0)
- self.stats[vm_uuid].update({'timestamp': timestamp})
-
- self._get_percentage_cpu_usage(vm_uuid, info, seconds)
- self._get_network_io_rate(vm_uuid, dom, seconds)
- self._get_disk_io_rate(vm_uuid, dom, seconds)
- except Exception as e:
- # VM might be deleted just after we get the list.
- # This is OK, just skip.
- wok_log.debug('Error processing VM stats: %s', e.message)
-
- def _get_percentage_cpu_usage(self, vm_uuid, info, seconds):
- prevCpuTime = self.stats[vm_uuid].get('cputime', 0)
-
- cpus = info[3]
- cpuTime = info[4] - prevCpuTime
-
- base = (((cpuTime) * 100.0) / (seconds * 1000.0 * 1000.0 * 1000.0))
- percentage = max(0.0, min(100.0, base / cpus))
-
- self.stats[vm_uuid].update({'cputime': info[4], 'cpu':
percentage})
-
- def _get_network_io_rate(self, vm_uuid, dom, seconds):
- prevNetRxKB = self.stats[vm_uuid].get('netRxKB', 0)
- prevNetTxKB = self.stats[vm_uuid].get('netTxKB', 0)
- currentMaxNetRate = self.stats[vm_uuid].get('max_net_io', 100)
-
- rx_bytes = 0
- tx_bytes = 0
-
- tree = ElementTree.fromstring(dom.XMLDesc(0))
- for target in tree.findall('devices/interface/target'):
- dev = target.get('dev')
- io = dom.interfaceStats(dev)
- rx_bytes += io[0]
- tx_bytes += io[4]
-
- netRxKB = float(rx_bytes) / 1000
- netTxKB = float(tx_bytes) / 1000
-
- rx_stats = (netRxKB - prevNetRxKB) / seconds
- tx_stats = (netTxKB - prevNetTxKB) / seconds
-
- rate = rx_stats + tx_stats
- max_net_io = round(max(currentMaxNetRate, int(rate)), 1)
-
- self.stats[vm_uuid].update({'net_io': rate, 'max_net_io':
max_net_io,
- 'netRxKB': netRxKB, 'netTxKB':
netTxKB})
-
- def _get_disk_io_rate(self, vm_uuid, dom, seconds):
- prevDiskRdKB = self.stats[vm_uuid].get('diskRdKB', 0)
- prevDiskWrKB = self.stats[vm_uuid].get('diskWrKB', 0)
- currentMaxDiskRate = self.stats[vm_uuid].get('max_disk_io', 100)
-
- rd_bytes = 0
- wr_bytes = 0
-
- tree = ElementTree.fromstring(dom.XMLDesc(0))
- for target in tree.findall("devices/disk/target"):
- dev = target.get("dev")
- io = dom.blockStats(dev)
- rd_bytes += io[1]
- wr_bytes += io[3]
-
- diskRdKB = float(rd_bytes) / 1024
- diskWrKB = float(wr_bytes) / 1024
-
- rd_stats = (diskRdKB - prevDiskRdKB) / seconds
- wr_stats = (diskWrKB - prevDiskWrKB) / seconds
-
- rate = rd_stats + wr_stats
- max_disk_io = round(max(currentMaxDiskRate, int(rate)), 1)
-
- self.stats[vm_uuid].update({'disk_io': rate,
- 'max_disk_io': max_disk_io,
- 'diskRdKB': diskRdKB,
- 'diskWrKB': diskWrKB})
-
- def lookup(self, name):
- dom = self.get_vm(name, self.conn)
- info = dom.info()
- state = DOM_STATE_MAP[info[0]]
- screenshot = None
- # (type, listen, port, passwd, passwdValidTo)
- graphics = self._vm_get_graphics(name)
- graphics_port = graphics[2]
- graphics_port = graphics_port if state == 'running' else None
- try:
- if state == 'running' and self._has_video(dom):
- screenshot = self.vmscreenshot.lookup(name)
- elif state == 'shutoff':
- # reset vm stats when it is powered off to avoid sending
- # incorrect (old) data
- self.stats[dom.UUIDString()] = {}
- except NotFoundError:
- pass
-
- with self.objstore as session:
- try:
- extra_info = session.get('vm', dom.UUIDString())
- except NotFoundError:
- extra_info = {}
- icon = extra_info.get('icon')
-
- self._update_guest_stats(name)
- vm_stats = self.stats.get(dom.UUIDString(), {})
- res = {}
- res['cpu_utilization'] = vm_stats.get('cpu', 0)
- res['net_throughput'] = vm_stats.get('net_io', 0)
- res['net_throughput_peak'] = vm_stats.get('max_net_io', 100)
- res['io_throughput'] = vm_stats.get('disk_io', 0)
- res['io_throughput_peak'] = vm_stats.get('max_disk_io', 100)
- users, groups = self._get_access_info(dom)
-
- if state == 'shutoff':
- xml = dom.XMLDesc(0)
- val = xpath_get_text(xml, XPATH_DOMAIN_MEMORY)[0]
- unit_list = xpath_get_text(xml, XPATH_DOMAIN_MEMORY_UNIT)
- if len(unit_list) > 0:
- unit = unit_list[0]
- else:
- unit = 'KiB'
- memory = convert_data_size(val, unit, 'MiB')
- else:
- memory = info[2] >> 10
-
- return {'name': name,
- 'state': state,
- 'stats': res,
- 'uuid': dom.UUIDString(),
- 'memory': memory,
- 'cpus': info[3],
- 'screenshot': screenshot,
- 'icon': icon,
- # (type, listen, port, passwd, passwdValidTo)
- 'graphics': {"type": graphics[0],
- "listen": graphics[1],
- "port": graphics_port,
- "passwd": graphics[3],
- "passwdValidTo": graphics[4]},
- 'users': users,
- 'groups': groups,
- 'access': 'full',
- 'persistent': True if dom.isPersistent() else False
- }
-
- def _vm_get_disk_paths(self, dom):
- xml = dom.XMLDesc(0)
- xpath = "/domain/devices/disk[@device='disk']/source/@file"
- return xpath_get_text(xml, xpath)
-
- @staticmethod
- def get_vm(name, conn):
- conn = conn.get()
- try:
- # outgoing text to libvirt, encode('utf-8')
- return conn.lookupByName(name.encode("utf-8"))
- except libvirt.libvirtError as e:
- if e.get_error_code() == libvirt.VIR_ERR_NO_DOMAIN:
- raise NotFoundError("KCHVM0002E", {'name': name})
- else:
- raise OperationFailed("KCHVM0009E", {'name': name,
- 'err': e.message})
-
- def delete(self, name):
- conn = self.conn.get()
- dom = self.get_vm(name, self.conn)
- if not dom.isPersistent():
- raise InvalidOperation("KCHVM0036E", {'name': name})
-
- self._vmscreenshot_delete(dom.UUIDString())
- paths = self._vm_get_disk_paths(dom)
- info = self.lookup(name)
-
- if info['state'] != 'shutoff':
- self.poweroff(name)
-
- # delete existing snapshots before deleting VM
-
- # libvirt's Test driver does not support the function
- # "virDomainListAllSnapshots", so "VMSnapshots.get_list" will
raise
- # "OperationFailed" in that case.
- try:
- snapshot_names = self.vmsnapshots.get_list(name)
- except OperationFailed, e:
- wok_log.error('cannot list snapshots: %s; '
- 'skipping snapshot deleting...' % e.message)
- else:
- for s in snapshot_names:
- self.vmsnapshot.delete(name, s)
-
- try:
- dom.undefine()
- except libvirt.libvirtError as e:
- raise OperationFailed("KCHVM0021E",
- {'name': name, 'err':
e.get_error_message()})
-
- for path in paths:
- try:
- vol = conn.storageVolLookupByPath(path)
- pool = vol.storagePoolLookupByVolume()
- xml = pool.XMLDesc(0)
- pool_type = xpath_get_text(xml, "/pool/@type")[0]
- if pool_type not in READONLY_POOL_TYPE:
- vol.delete(0)
- # Update objstore to remove the volume
- with self.objstore as session:
- session.delete('storagevolume', path,
- ignore_missing=True)
- except libvirt.libvirtError as e:
- wok_log.error('Unable to get storage volume by path: %s' %
- e.message)
- except Exception as e:
- raise OperationFailed('KCHVOL0017E', {'err': e.message})
-
- try:
- with self.objstore as session:
- if path in session.get_list('storagevolume'):
- used_by = session.get('storagevolume',
path)['used_by']
- used_by.remove(name)
- session.store('storagevolume', path,
- {'used_by': used_by})
- except Exception as e:
- raise OperationFailed('KCHVOL0017E', {'err': e.message})
-
- try:
- with self.objstore as session:
- session.delete('vm', dom.UUIDString(), ignore_missing=True)
- except Exception as e:
- # It is possible to delete vm without delete its database info
- wok_log.error('Error deleting vm information from database: '
- '%s', e.message)
-
- vnc.remove_proxy_token(name)
-
- def start(self, name):
- # make sure the ISO file has read permission
- dom = self.get_vm(name, self.conn)
- xml = dom.XMLDesc(0)
- xpath = "/domain/devices/disk[@device='cdrom']/source/@file"
- isofiles = xpath_get_text(xml, xpath)
-
- user = UserTests.probe_user()
- for iso in isofiles:
- run_setfacl_set_attr(iso, user=user)
-
- dom = self.get_vm(name, self.conn)
- try:
- dom.create()
- except libvirt.libvirtError as e:
- raise OperationFailed("KCHVM0019E",
- {'name': name, 'err':
e.get_error_message()})
-
- def poweroff(self, name):
- dom = self.get_vm(name, self.conn)
- try:
- dom.destroy()
- except libvirt.libvirtError as e:
- raise OperationFailed("KCHVM0020E",
- {'name': name, 'err':
e.get_error_message()})
-
- def shutdown(self, name):
- dom = self.get_vm(name, self.conn)
- try:
- dom.shutdown()
- except libvirt.libvirtError as e:
- raise OperationFailed("KCHVM0029E",
- {'name': name, 'err':
e.get_error_message()})
-
- def reset(self, name):
- dom = self.get_vm(name, self.conn)
- try:
- dom.reset(flags=0)
- except libvirt.libvirtError as e:
- raise OperationFailed("KCHVM0022E",
- {'name': name, 'err':
e.get_error_message()})
-
- def _vm_get_graphics(self, name):
- dom = self.get_vm(name, self.conn)
- xml = dom.XMLDesc(libvirt.VIR_DOMAIN_XML_SECURE)
-
- expr = "/domain/devices/graphics/@type"
- res = xpath_get_text(xml, expr)
- graphics_type = res[0] if res else None
-
- expr = "/domain/devices/graphics/@listen"
- res = xpath_get_text(xml, expr)
- graphics_listen = res[0] if res else None
-
- graphics_port = graphics_passwd = graphics_passwdValidTo = None
- if graphics_type:
- expr = "/domain/devices/graphics[@type='%s']/@port"
- res = xpath_get_text(xml, expr % graphics_type)
- graphics_port = int(res[0]) if res else None
-
- expr = "/domain/devices/graphics[@type='%s']/@passwd"
- res = xpath_get_text(xml, expr % graphics_type)
- graphics_passwd = res[0] if res else None
-
- expr =
"/domain/devices/graphics[@type='%s']/@passwdValidTo"
- res = xpath_get_text(xml, expr % graphics_type)
- if res:
- to = time.mktime(time.strptime(res[0], '%Y-%m-%dT%H:%M:%S'))
- graphics_passwdValidTo = to - time.mktime(time.gmtime())
-
- return (graphics_type, graphics_listen, graphics_port,
- graphics_passwd, graphics_passwdValidTo)
-
- def connect(self, name):
- # (type, listen, port, passwd, passwdValidTo)
- graphics_port = self._vm_get_graphics(name)[2]
- if graphics_port is not None:
- vnc.add_proxy_token(name, graphics_port)
- else:
- raise OperationFailed("KCHVM0010E", {'name': name})
-
- def _vmscreenshot_delete(self, vm_uuid):
- screenshot = VMScreenshotModel.get_screenshot(vm_uuid, self.objstore,
- self.conn)
- screenshot.delete()
- try:
- with self.objstore as session:
- session.delete('screenshot', vm_uuid)
- except Exception as e:
- # It is possible to continue Kimchi executions without delete
- # screenshots
- wok_log.error('Error trying to delete vm screenshot from '
- 'database due error: %s', e.message)
-
- def suspend(self, name):
- """Suspend the virtual machine's execution and puts it in the
- state 'paused'. Use the function "resume" to restore its
state.
- If the VM is not running, an exception will be raised.
-
- Parameters:
- name -- the name of the VM to be suspended.
- """
- vm = self.lookup(name)
- if vm['state'] != 'running':
- raise InvalidOperation('KCHVM0037E', {'name': name})
-
- vir_dom = self.get_vm(name, self.conn)
-
- try:
- vir_dom.suspend()
- except libvirt.libvirtError, e:
- raise OperationFailed('KCHVM0038E', {'name': name,
- 'err': e.message})
-
- def resume(self, name):
- """Resume the virtual machine's execution and puts it in the
- state 'running'. The VM should have been suspended previously by the
- function "suspend" and be in the state 'paused', otherwise an
exception
- will be raised.
-
- Parameters:
- name -- the name of the VM to be resumed.
- """
- vm = self.lookup(name)
- if vm['state'] != 'paused':
- raise InvalidOperation('KCHVM0039E', {'name': name})
-
- vir_dom = self.get_vm(name, self.conn)
-
- try:
- vir_dom.resume()
- except libvirt.libvirtError, e:
- raise OperationFailed('KCHVM0040E', {'name': name,
- 'err': e.message})
-
-
-class VMScreenshotModel(object):
- def __init__(self, **kargs):
- self.objstore = kargs['objstore']
- self.conn = kargs['conn']
-
- def lookup(self, name):
- dom = VMModel.get_vm(name, self.conn)
- d_info = dom.info()
- vm_uuid = dom.UUIDString()
- if DOM_STATE_MAP[d_info[0]] != 'running':
- raise NotFoundError("KCHVM0004E", {'name': name})
-
- screenshot = self.get_screenshot(vm_uuid, self.objstore, self.conn)
- img_path = screenshot.lookup()
- # screenshot info changed after scratch generation
- try:
- with self.objstore as session:
- session.store('screenshot', vm_uuid, screenshot.info)
- except Exception as e:
- # It is possible to continue Kimchi executions without store
- # screenshots
- wok_log.error('Error trying to update database with guest '
- 'screenshot information due error: %s', e.message)
- return img_path
-
- @staticmethod
- def get_screenshot(vm_uuid, objstore, conn):
- try:
- with objstore as session:
- try:
- params = session.get('screenshot', vm_uuid)
- except NotFoundError:
- params = {'uuid': vm_uuid}
- session.store('screenshot', vm_uuid, params)
- except Exception as e:
- # The 'except' outside of 'with' is necessary to catch
possible
- # exception from '__exit__' when calling 'session.store'
- # It is possible to continue Kimchi vm executions without
- # screenshots
- wok_log.error('Error trying to update database with guest '
- 'screenshot information due error: %s', e.message)
- return LibvirtVMScreenshot(params, conn)
-
-
-class LibvirtVMScreenshot(VMScreenshot):
- def __init__(self, vm_uuid, conn):
- VMScreenshot.__init__(self, vm_uuid)
- self.conn = conn
-
- def _generate_scratch(self, thumbnail):
- def handler(stream, buf, opaque):
- fd = opaque
- os.write(fd, buf)
-
- fd = os.open(thumbnail, os.O_WRONLY | os.O_TRUNC | os.O_CREAT, 0644)
- try:
- conn = self.conn.get()
- dom = conn.lookupByUUIDString(self.vm_uuid)
- vm_name = dom.name()
- stream = conn.newStream(0)
- dom.screenshot(stream, 0, 0)
- stream.recvAll(handler, fd)
- except libvirt.libvirtError:
- try:
- stream.abort()
- except:
- pass
- raise NotFoundError("KCHVM0006E", {'name': vm_name})
- else:
- stream.finish()
- finally:
- os.close(fd)
diff --git a/plugins/kimchi/model/vmsnapshots.py b/plugins/kimchi/model/vmsnapshots.py
deleted file mode 100644
index fff1908..0000000
--- a/plugins/kimchi/model/vmsnapshots.py
+++ /dev/null
@@ -1,204 +0,0 @@
-#
-# Project Kimchi
-#
-# Copyright IBM, Corp. 2014-2015
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-
-import libvirt
-import lxml.etree as ET
-import time
-from lxml import objectify
-from lxml.builder import E
-
-from wok.exception import InvalidOperation, NotFoundError, OperationFailed
-from wok.utils import add_task
-from wok.xmlutils.utils import xpath_get_text
-from wok.model.tasks import TaskModel
-
-from vms import DOM_STATE_MAP, VMModel
-from vmstorages import VMStorageModel, VMStoragesModel
-
-
-class VMSnapshotsModel(object):
- def __init__(self, **kargs):
- self.conn = kargs['conn']
- self.objstore = kargs['objstore']
- self.task = TaskModel(**kargs)
- self.vmstorages = VMStoragesModel(**kargs)
- self.vmstorage = VMStorageModel(**kargs)
-
- def create(self, vm_name, params={}):
- """Create a snapshot with the current domain state.
-
- The VM must be stopped and contain only disks with format 'qcow2';
- otherwise an exception will be raised.
-
- Parameters:
- vm_name -- the name of the VM where the snapshot will be created.
- params -- a dict with the following values:
- "name": The snapshot name (optional). If omitted, a default value
- based on the current time will be used.
-
- Return:
- A Task running the operation.
- """
- vir_dom = VMModel.get_vm(vm_name, self.conn)
- if DOM_STATE_MAP[vir_dom.info()[0]] != u'shutoff':
- raise InvalidOperation('KCHSNAP0001E', {'vm': vm_name})
-
- # if the VM has a non-CDROM disk with type 'raw', abort.
- for storage_name in self.vmstorages.get_list(vm_name):
- storage = self.vmstorage.lookup(vm_name, storage_name)
- type = storage['type']
- format = storage['format']
-
- if type != u'cdrom' and format != u'qcow2':
- raise InvalidOperation('KCHSNAP0010E', {'vm': vm_name,
- 'format': format})
-
- name = params.get('name', unicode(int(time.time())))
-
- task_params = {'vm_name': vm_name, 'name': name}
- taskid = add_task(u'/plugins/kimchi/vms/%s/snapshots/%s' % (vm_name,
- name), self._create_task, self.objstore, task_params)
- return self.task.lookup(taskid)
-
- def _create_task(self, cb, params):
- """Asynchronous function which actually creates the snapshot.
-
- Parameters:
- cb -- a callback function to signal the Task's progress.
- params -- a dict with the following values:
- "vm_name": the name of the VM where the snapshot will be created.
- "name": the snapshot name.
- """
- vm_name = params['vm_name']
- name = params['name']
-
- cb('building snapshot XML')
- root_elem = E.domainsnapshot()
- root_elem.append(E.name(name))
- xml = ET.tostring(root_elem, encoding='utf-8')
-
- try:
- cb('fetching snapshot domain')
- vir_dom = VMModel.get_vm(vm_name, self.conn)
- cb('creating snapshot')
- vir_dom.snapshotCreateXML(xml, 0)
- except (NotFoundError, OperationFailed, libvirt.libvirtError), e:
- raise OperationFailed('KCHSNAP0002E',
- {'name': name, 'vm': vm_name,
- 'err': e.message})
-
- cb('OK', True)
-
- def get_list(self, vm_name):
- vir_dom = VMModel.get_vm(vm_name, self.conn)
-
- try:
- vir_snaps = vir_dom.listAllSnapshots(0)
- return sorted([s.getName().decode('utf-8') for s in vir_snaps],
- key=unicode.lower)
- except libvirt.libvirtError, e:
- raise OperationFailed('KCHSNAP0005E',
- {'vm': vm_name, 'err': e.message})
-
-
-class VMSnapshotModel(object):
- def __init__(self, **kargs):
- self.conn = kargs['conn']
-
- def lookup(self, vm_name, name):
- vir_snap = self.get_vmsnapshot(vm_name, name)
-
- try:
- snap_xml_str = vir_snap.getXMLDesc(0).decode('utf-8')
- except libvirt.libvirtError, e:
- raise OperationFailed('KCHSNAP0004E', {'name': name,
- 'vm': vm_name,
- 'err': e.message})
-
- snap_xml = objectify.fromstring(snap_xml_str)
-
- try:
- parent = unicode(snap_xml.parent.name)
- except AttributeError:
- parent = u''
-
- return {'created': unicode(snap_xml.creationTime),
- 'name': unicode(snap_xml.name),
- 'parent': parent,
- 'state': unicode(snap_xml.state)}
-
- def delete(self, vm_name, name):
- try:
- vir_snap = self.get_vmsnapshot(vm_name, name)
- vir_snap.delete(0)
- except libvirt.libvirtError, e:
- raise OperationFailed('KCHSNAP0006E', {'name': name,
- 'vm': vm_name,
- 'err': e.message})
-
- def revert(self, vm_name, name):
- try:
- vir_dom = VMModel.get_vm(vm_name, self.conn)
- vir_snap = self.get_vmsnapshot(vm_name, name)
- vir_dom.revertToSnapshot(vir_snap, 0)
-
- # get vm name recorded in the snapshot and return new uri params
- vm_new_name = xpath_get_text(vir_snap.getXMLDesc(0),
- 'domain/name')[0]
- return [vm_new_name, name]
- except libvirt.libvirtError, e:
- raise OperationFailed('KCHSNAP0009E', {'name': name,
- 'vm': vm_name,
- 'err': e.message})
-
- def get_vmsnapshot(self, vm_name, name):
- vir_dom = VMModel.get_vm(vm_name, self.conn)
-
- try:
- return vir_dom.snapshotLookupByName(name, 0)
- except libvirt.libvirtError, e:
- code = e.get_error_code()
- if code == libvirt.VIR_ERR_NO_DOMAIN_SNAPSHOT:
- raise NotFoundError('KCHSNAP0003E', {'name': name,
- 'vm': vm_name})
- else:
- raise OperationFailed('KCHSNAP0004E', {'name': name,
- 'vm': vm_name,
- 'err': e.message})
-
-
-class CurrentVMSnapshotModel(object):
- def __init__(self, **kargs):
- self.conn = kargs['conn']
- self.vmsnapshot = VMSnapshotModel(**kargs)
-
- def lookup(self, vm_name):
- vir_dom = VMModel.get_vm(vm_name, self.conn)
-
- try:
- vir_snap = vir_dom.snapshotCurrent(0)
- snap_name = vir_snap.getName().decode('utf-8')
- except libvirt.libvirtError, e:
- if e.get_error_code() == libvirt.VIR_ERR_NO_DOMAIN_SNAPSHOT:
- return {}
-
- raise OperationFailed('KCHSNAP0008E',
- {'vm': vm_name, 'err': e.message})
-
- return self.vmsnapshot.lookup(vm_name, snap_name)
diff --git a/plugins/kimchi/model/vmstorages.py b/plugins/kimchi/model/vmstorages.py
deleted file mode 100644
index bec16c6..0000000
--- a/plugins/kimchi/model/vmstorages.py
+++ /dev/null
@@ -1,252 +0,0 @@
-#
-# Project Kimchi
-#
-# Copyright IBM, Corp. 2014-2015
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-
-import string
-from lxml import etree
-
-from wok.exception import InvalidOperation, InvalidParameter, NotFoundError
-from wok.exception import OperationFailed
-from wok.utils import wok_log
-
-from ..osinfo import lookup
-from ..xmlutils.disk import get_device_node, get_disk_xml
-from ..xmlutils.disk import get_vm_disk_info, get_vm_disks
-from config import CapabilitiesModel
-from diskutils import get_disk_used_by, set_disk_used_by
-from storagevolumes import StorageVolumeModel
-from utils import get_vm_config_flag
-from vms import DOM_STATE_MAP, VMModel
-
-
-HOTPLUG_TYPE = ['scsi', 'virtio']
-
-
-def _get_device_bus(dev_type, dom, metadata_support):
- try:
- version, distro = VMModel.vm_get_os_metadata(dom, metadata_support)
- except:
- version, distro = ('unknown', 'unknown')
- return lookup(distro, version)[dev_type+'_bus']
-
-
-class VMStoragesModel(object):
- def __init__(self, **kargs):
- self.conn = kargs['conn']
- self.objstore = kargs['objstore']
- self.caps = CapabilitiesModel(**kargs)
-
- def _get_available_bus_address(self, bus_type, vm_name):
- if bus_type not in ['ide']:
- return dict()
- # libvirt limitation of just 1 ide controller
- # each controller have at most 2 buses and each bus 2 units.
- dom = VMModel.get_vm(vm_name, self.conn)
- disks = self.get_list(vm_name)
- valid_id = [('0', '0'), ('0', '1'), ('1',
'0'), ('1', '1')]
- controller_id = '0'
- for dev_name in disks:
- disk = get_device_node(dom, dev_name)
- if disk.target.attrib['bus'] == 'ide':
- controller_id = disk.address.attrib['controller']
- bus_id = disk.address.attrib['bus']
- unit_id = disk.address.attrib['unit']
- if (bus_id, unit_id) in valid_id:
- valid_id.remove((bus_id, unit_id))
- continue
- if not valid_id:
- raise OperationFailed('KCHVMSTOR0014E',
- {'type': 'ide', 'limit': 4})
- else:
- address = {'controller': controller_id,
- 'bus': valid_id[0][0], 'unit': valid_id[0][1]}
- return dict(address=address)
-
- def create(self, vm_name, params):
- vol_model = None
- # Path will never be blank due to API.json verification.
- # There is no need to cover this case here.
- if not ('vol' in params) ^ ('path' in params):
- raise InvalidParameter("KCHVMSTOR0017E")
-
- dom = VMModel.get_vm(vm_name, self.conn)
- params['bus'] = _get_device_bus(params['type'], dom,
- self.caps.metadata_support)
- params['format'] = 'raw'
-
- dev_list = [dev for dev, bus in get_vm_disks(dom).iteritems()
- if bus == params['bus']]
- dev_list.sort()
- if len(dev_list) == 0:
- params['index'] = 0
- else:
- char = dev_list.pop()[2]
- params['index'] = string.ascii_lowercase.index(char) + 1
-
- if (params['bus'] not in HOTPLUG_TYPE and
- DOM_STATE_MAP[dom.info()[0]] != 'shutoff'):
- raise InvalidOperation('KCHVMSTOR0011E')
-
- if params.get('vol'):
- try:
- pool = params['pool']
- vol_model = StorageVolumeModel(conn=self.conn,
- objstore=self.objstore)
- vol_info = vol_model.lookup(pool, params['vol'])
- except KeyError:
- raise InvalidParameter("KCHVMSTOR0012E")
- except Exception as e:
- raise InvalidParameter("KCHVMSTOR0015E", {'error': e})
- if len(vol_info['used_by']) != 0:
- raise InvalidParameter("KCHVMSTOR0016E")
-
- valid_format = {
- "disk": ["raw", "bochs", "qcow",
"qcow2", "qed", "vmdk"],
- "cdrom": "iso"}
-
- if vol_info['type'] == 'file':
- if (params['type'] == 'disk' and
- vol_info['format'] in
valid_format[params['type']]):
- params['format'] = vol_info['format']
- else:
- raise InvalidParameter("KCHVMSTOR0018E",
- {"format":
vol_info['format'],
- "type": params['type']})
-
- params['path'] = vol_info['path']
- params['disk'] = vol_info['type']
-
- params.update(self._get_available_bus_address(params['bus'], vm_name))
-
- # Add device to VM
- dev, xml = get_disk_xml(params)
- try:
- conn = self.conn.get()
- dom = conn.lookupByName(vm_name)
- dom.attachDeviceFlags(xml, get_vm_config_flag(dom, 'all'))
- except Exception as e:
- raise OperationFailed("KCHVMSTOR0008E", {'error':
e.message})
-
- # Don't put a try-block here. Let the exception be raised. If we
- # allow disks used_by to be out of sync, data corruption could
- # occour if a disk is added to two guests unknowingly.
- if params.get('vol'):
- used_by = vol_info['used_by']
- used_by.append(vm_name)
- set_disk_used_by(self.objstore, params['path'], used_by)
-
- return dev
-
- def get_list(self, vm_name):
- dom = VMModel.get_vm(vm_name, self.conn)
- return get_vm_disks(dom).keys()
-
-
-class VMStorageModel(object):
- def __init__(self, **kargs):
- self.conn = kargs['conn']
- self.objstore = kargs['objstore']
- self.caps = CapabilitiesModel(**kargs)
-
- def lookup(self, vm_name, dev_name):
- # Retrieve disk xml and format return dict
- dom = VMModel.get_vm(vm_name, self.conn)
- return get_vm_disk_info(dom, dev_name)
-
- def delete(self, vm_name, dev_name):
- conn = self.conn.get()
-
- try:
- bus_type = self.lookup(vm_name, dev_name)['bus']
- dom = conn.lookupByName(vm_name)
- except NotFoundError:
- raise
-
- if (bus_type not in HOTPLUG_TYPE and
- DOM_STATE_MAP[dom.info()[0]] != 'shutoff'):
- raise InvalidOperation('KCHVMSTOR0011E')
-
- try:
- disk = get_device_node(dom, dev_name)
- path = get_vm_disk_info(dom, dev_name)['path']
- if path is None or len(path) < 1:
- path = self.lookup(vm_name, dev_name)['path']
- # This has to be done before it's detached. If it wasn't
- # in the obj store, its ref count would have been updated
- # by get_disk_used_by()
- if path is not None:
- used_by = get_disk_used_by(self.objstore, self.conn, path)
- else:
- wok_log.error("Unable to decrement volume used_by on"
- " delete because no path could be found.")
- dom.detachDeviceFlags(etree.tostring(disk),
- get_vm_config_flag(dom, 'all'))
- except Exception as e:
- raise OperationFailed("KCHVMSTOR0010E", {'error':
e.message})
-
- if used_by is not None and vm_name in used_by:
- used_by.remove(vm_name)
- set_disk_used_by(self.objstore, path, used_by)
- else:
- wok_log.error("Unable to update %s:%s used_by on delete."
- % (vm_name, dev_name))
-
- def update(self, vm_name, dev_name, params):
- old_disk_used_by = None
- new_disk_used_by = None
-
- dom = VMModel.get_vm(vm_name, self.conn)
-
- dev_info = self.lookup(vm_name, dev_name)
- if dev_info['type'] != 'cdrom':
- raise InvalidOperation("KCHVMSTOR0006E")
-
- params['path'] = params.get('path', '')
- old_disk_path = dev_info['path']
- new_disk_path = params['path']
- if new_disk_path != old_disk_path:
- # An empty path means a CD-ROM was empty or ejected:
- if old_disk_path is not '':
- old_disk_used_by = get_disk_used_by(
- self.objstore, self.conn, old_disk_path)
- if new_disk_path is not '':
- new_disk_used_by = get_disk_used_by(
- self.objstore, self.conn, new_disk_path)
-
- dev_info.update(params)
- dev, xml = get_disk_xml(dev_info)
-
- try:
- dom.updateDeviceFlags(xml, get_vm_config_flag(dom, 'all'))
- except Exception as e:
- raise OperationFailed("KCHVMSTOR0009E", {'error':
e.message})
-
- try:
- if old_disk_used_by is not None and \
- vm_name in old_disk_used_by:
- old_disk_used_by.remove(vm_name)
- set_disk_used_by(self.objstore, old_disk_path,
- old_disk_used_by)
- if new_disk_used_by is not None:
- new_disk_used_by.append(vm_name)
- set_disk_used_by(self.objstore, new_disk_path,
- new_disk_used_by)
- except Exception as e:
- wok_log.error("Unable to update dev used_by on update due to"
- " %s:" % e.message)
- return dev
diff --git a/plugins/kimchi/netinfo.py b/plugins/kimchi/netinfo.py
deleted file mode 100644
index c5746d7..0000000
--- a/plugins/kimchi/netinfo.py
+++ /dev/null
@@ -1,216 +0,0 @@
-# Project Kimchi
-#
-# Copyright IBM, Corp. 2013-2015
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-#
-
-import ethtool
-import glob
-import os
-
-
-NET_PATH = '/sys/class/net'
-NIC_PATH = '/sys/class/net/*/device'
-BRIDGE_PATH = '/sys/class/net/*/bridge'
-BONDING_PATH = '/sys/class/net/*/bonding'
-WLAN_PATH = '/sys/class/net/*/wireless'
-NET_BRPORT = '/sys/class/net/%s/brport'
-NET_MASTER = '/sys/class/net/%s/master'
-NET_STATE = '/sys/class/net/%s/carrier'
-PROC_NET_VLAN = '/proc/net/vlan/'
-BONDING_SLAVES = '/sys/class/net/%s/bonding/slaves'
-BRIDGE_PORTS = '/sys/class/net/%s/brif'
-
-
-def wlans():
- return [b.split('/')[-2] for b in glob.glob(WLAN_PATH)]
-
-
-def is_wlan(iface):
- return iface in wlans()
-
-
-# FIXME if we do not want to list usb nic
-def nics():
- return list(set([b.split('/')[-2] for b in glob.glob(NIC_PATH)]) -
- set(wlans()))
-
-
-def is_nic(iface):
- return iface in nics()
-
-
-def bondings():
- return [b.split('/')[-2] for b in glob.glob(BONDING_PATH)]
-
-
-def is_bonding(iface):
- return iface in bondings()
-
-
-def vlans():
- return list(set([b.split('/')[-1]
- for b in glob.glob(NET_PATH + '/*')]) &
- set([b.split('/')[-1]
- for b in glob.glob(PROC_NET_VLAN + '*')]))
-
-
-def is_vlan(iface):
- return iface in vlans()
-
-
-def bridges():
- return [b.split('/')[-2] for b in glob.glob(BRIDGE_PATH)]
-
-
-def is_bridge(iface):
- return iface in bridges()
-
-
-def all_interfaces():
- return [d.rsplit("/", 1)[-1] for d in glob.glob(NET_PATH + '/*')]
-
-
-def slaves(bonding):
- with open(BONDING_SLAVES % bonding) as bonding_file:
- res = bonding_file.readline().split()
- return res
-
-
-def ports(bridge):
- return os.listdir(BRIDGE_PORTS % bridge)
-
-
-def is_brport(nic):
- return os.path.exists(NET_BRPORT % nic)
-
-
-def is_bondlave(nic):
- return os.path.exists(NET_MASTER % nic)
-
-
-def operstate(dev):
- link_status = link_detected(dev)
- return "down" if link_status == "n/a" else "up"
-
-
-def link_detected(dev):
- # try to read interface carrier (link) status
- try:
- with open(NET_STATE % dev) as dev_file:
- carrier = dev_file.readline().strip()
- # when IOError is raised, interface is down
- except IOError:
- return "n/a"
-
- # if value is 1, interface up with cable connected
- # 0 corresponds to interface up with cable disconnected
- return "yes" if carrier == '1' else "no"
-
-
-def get_vlan_device(vlan):
- """ Return the device of the given VLAN. """
- dev = None
-
- if os.path.exists(PROC_NET_VLAN + vlan):
- with open(PROC_NET_VLAN + vlan) as vlan_file:
- for line in vlan_file:
- if "Device:" in line:
- dummy, dev = line.split()
- break
- return dev
-
-
-def get_bridge_port_device(bridge):
- """Return the nics list that belongs to bridge."""
- # br --- v --- bond --- nic1
- if bridge not in bridges():
- raise ValueError('unknown bridge %s' % bridge)
- nics = []
- for port in ports(bridge):
- if port in vlans():
- device = get_vlan_device(port)
- if device in bondings():
- nics.extend(slaves(device))
- else:
- nics.append(device)
- if port in bondings():
- nics.extend(slaves(port))
- else:
- nics.append(port)
- return nics
-
-
-def aggregated_bridges():
- return [bridge for bridge in bridges() if
- (set(get_bridge_port_device(bridge)) & set(nics()))]
-
-
-def bare_nics():
- "The nic is not a port of a bridge or a slave of bond."
- return [nic for nic in nics() if not (is_brport(nic) or is_bondlave(nic))]
-
-
-def is_bare_nic(iface):
- return iface in bare_nics()
-
-
-# The nic will not be exposed when it is a port of a bridge or
-# a slave of bond.
-# The bridge will not be exposed when all it's port are tap.
-def all_favored_interfaces():
- return aggregated_bridges() + bare_nics() + bondings()
-
-
-def get_interface_type(iface):
- # FIXME if we want to get more device type
- # just support nic, bridge, bondings and vlan, for we just
- # want to expose this 4 kinds of interface
- try:
- if is_nic(iface):
- return "nic"
- if is_bonding(iface):
- return "bonding"
- if is_bridge(iface):
- return "bridge"
- if is_vlan(iface):
- return "vlan"
- return 'unknown'
- except IOError:
- return 'unknown'
-
-
-def get_interface_info(iface):
- if iface not in ethtool.get_devices():
- raise ValueError('unknown interface: %s' % iface)
-
- ipaddr = ''
- netmask = ''
- try:
- ipaddr = ethtool.get_ipaddr(iface)
- netmask = ethtool.get_netmask(iface)
- except IOError:
- pass
-
- iface_link_detected = link_detected(iface)
- iface_status = 'active' if iface_link_detected != "n/a" else
"inactive"
-
- return {'name': iface,
- 'type': get_interface_type(iface),
- 'status': iface_status,
- 'link_detected': iface_link_detected,
- 'ipaddr': ipaddr,
- 'netmask': netmask}
diff --git a/plugins/kimchi/network.py b/plugins/kimchi/network.py
deleted file mode 100644
index 1433b8a..0000000
--- a/plugins/kimchi/network.py
+++ /dev/null
@@ -1,62 +0,0 @@
-#
-# Project Kimchi
-#
-# Copyright IBM, Corp. 2013-2014
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-#
-
-import ethtool
-import ipaddr
-
-
-APrivateNets = ipaddr.IPNetwork("10.0.0.0/8")
-BPrivateNets = ipaddr.IPNetwork("172.16.0.0/12")
-CPrivateNets = ipaddr.IPNetwork('192.168.0.0/16')
-PrivateNets = [CPrivateNets, BPrivateNets, APrivateNets]
-DefaultNetsPool = [ipaddr.IPNetwork('192.168.122.0/23'),
- ipaddr.IPNetwork('192.168.124.0/22'),
- ipaddr.IPNetwork('192.168.128.0/17')]
-
-
-def get_dev_netaddr(dev):
- info = ethtool.get_interfaces_info(dev)[0]
- return (info.ipv4_address and
- "%s/%s" % (info.ipv4_address, info.ipv4_netmask) or '')
-
-
-def get_dev_netaddrs():
- nets = []
- for dev in ethtool.get_devices():
- devnet = get_dev_netaddr(dev)
- devnet and nets.append(ipaddr.IPNetwork(devnet))
- return nets
-
-
-# used_nets should include all the subnet allocated in libvirt network
-# will get host network by get_dev_netaddrs
-def get_one_free_network(used_nets, nets_pool=PrivateNets):
- def _get_free_network(nets, used_nets):
- for net in nets.subnet(new_prefix=24):
- if not any(net.overlaps(used) for used in used_nets):
- return str(net)
- return None
-
- used_nets = used_nets + get_dev_netaddrs()
- for nets in nets_pool:
- net = _get_free_network(nets, used_nets)
- if net:
- return net
- return None
diff --git a/plugins/kimchi/osinfo.py b/plugins/kimchi/osinfo.py
deleted file mode 100644
index 5b1277c..0000000
--- a/plugins/kimchi/osinfo.py
+++ /dev/null
@@ -1,213 +0,0 @@
-#
-# Project Kimchi
-#
-# Copyright IBM, Corp. 2013-2015
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-
-import copy
-import glob
-import os
-import psutil
-from collections import defaultdict
-from configobj import ConfigObj
-from distutils.version import LooseVersion
-
-from wok.config import PluginPaths
-
-
-SUPPORTED_ARCHS = {'x86': ('i386', 'i686', 'x86_64'),
- 'power': ('ppc', 'ppc64'),
- 'ppc64le': ('ppc64le')}
-
-
-template_specs = {'x86': {'old': dict(disk_bus='ide',
- nic_model='e1000',
sound_model='ich6'),
- 'modern': dict(disk_bus='virtio',
- nic_model='virtio',
- sound_model='ich6')},
- 'power': {'old': dict(disk_bus='scsi',
- nic_model='spapr-vlan',
- cdrom_bus='scsi',
- kbd_type="kbd",
- kbd_bus='usb', mouse_bus='usb',
- tablet_bus='usb', memory=1280),
- 'modern': dict(disk_bus='virtio',
- nic_model='virtio',
- cdrom_bus='scsi',
- kbd_bus='usb',
- kbd_type="kbd",
- mouse_bus='usb',
tablet_bus='usb',
- memory=1280)},
- 'ppc64le': {'old': dict(disk_bus='virtio',
- nic_model='virtio',
- cdrom_bus='scsi',
- kbd_bus='usb',
- kbd_type="keyboard",
- mouse_bus='usb',
tablet_bus='usb',
- memory=1280),
- 'modern': dict(disk_bus='virtio',
- nic_model='virtio',
- cdrom_bus='scsi',
- kbd_bus='usb',
- kbd_type="keyboard",
- mouse_bus='usb',
tablet_bus='usb',
- memory=1280)}}
-
-
-custom_specs = {'fedora': {'22': dict(video_model='qxl')}}
-
-
-modern_version_bases = {'x86': {'debian': '6.0',
'ubuntu': '7.10',
- 'opensuse': '10.3', 'centos':
'5.3',
- 'rhel': '6.0', 'fedora':
'16', 'gentoo': '0',
- 'sles': '11', 'arch':
'0'},
- 'power': {'rhel': '6.5',
'fedora': '19',
- 'ubuntu': '14.04',
- 'opensuse': '13.1',
- 'sles': '11sp3'},
- 'ppc64le': {'rhel': '6.5',
'fedora': '19',
- 'ubuntu': '14.04',
- 'opensuse': '13.1',
- 'sles': '11sp3'}}
-
-
-icon_available_distros = [icon[5:-4] for icon in glob.glob1('%s/images/'
- % PluginPaths('kimchi').ui_dir, 'icon-*.png')]
-
-
-def _get_tmpl_defaults():
- """
- ConfigObj returns a dict like below when no changes were made in the
- template configuration file (template.conf)
-
- {'main': {}, 'storage': {'disk.0': {}}, 'processor':
{}, 'graphics': {}}
-
- The default values should be like below:
-
- {'main': {'networks': ['default'], 'memory':
'1024'},
- 'storage': {'pool': 'default',
- 'disk.0': {'format': 'qcow2', 'size':
'10'}},
- 'processor': {'cpus': '1'},
- 'graphics': {'type': 'spice', 'listen':
'127.0.0.1'}}
- """
- # Create dict with default values
- tmpl_defaults = defaultdict(dict)
- tmpl_defaults['main']['networks'] = ['default']
- tmpl_defaults['main']['memory'] = 1024
- tmpl_defaults['storage']['pool'] = 'default'
- tmpl_defaults['storage']['disk.0'] = {'size': 10,
'format': 'qcow2'}
- tmpl_defaults['processor']['cpus'] = 1
- tmpl_defaults['graphics'] = {'type': 'vnc', 'listen':
'127.0.0.1'}
-
- default_config = ConfigObj(tmpl_defaults)
-
- # Load template configuration file
- config_file = os.path.join(PluginPaths('kimchi').conf_dir,
'template.conf')
- config = ConfigObj(config_file)
-
- # Merge default configuration with file configuration
- default_config.merge(config)
-
- # Create a dict with default values according to data structure
- # expected by VMTemplate
- defaults = {'domain': 'kvm', 'arch': os.uname()[4],
- 'cdrom_bus': 'ide', 'cdrom_index': 2,
'mouse_bus': 'ps2'}
-
- # Parse main section to get networks and memory values
- main_section = default_config.pop('main')
- defaults.update(main_section)
-
- # Parse storage section to get storage pool and disks values
- storage_section = default_config.pop('storage')
- defaults['storagepool'] = '/plugins/kimchi/storagepools/' + \
- storage_section.pop('pool')
- defaults['disks'] = []
- for disk in storage_section.keys():
- data = storage_section[disk]
- data['index'] = int(disk.split('.')[1])
- defaults['disks'].append(data)
-
- # Parse processor section to get cpus and cpu_topology values
- processor_section = default_config.pop('processor')
- defaults['cpus'] = processor_section.pop('cpus')
- defaults['cpu_info'] = {}
- if len(processor_section.keys()) > 0:
- defaults['cpu_info']['topology'] = processor_section
-
- # Update defaults values with graphics values
- defaults['graphics'] = default_config.pop('graphics')
-
- return defaults
-
-
-# Set defaults values according to template.conf file
-defaults = _get_tmpl_defaults()
-
-
-def _get_arch():
- for arch, sub_archs in SUPPORTED_ARCHS.iteritems():
- if os.uname()[4] in sub_archs:
- return arch
-
-
-def get_template_default(template_type, field):
- host_arch = _get_arch()
- # Assuming 'power' = 'ppc64le' because lookup() does the same,
- # claiming libvirt compatibility.
- host_arch = 'power' if host_arch == 'ppc64le' else host_arch
- tmpl_defaults = copy.deepcopy(defaults)
- tmpl_defaults.update(template_specs[host_arch][template_type])
- return tmpl_defaults[field]
-
-
-def lookup(distro, version):
- """
- Lookup all parameters needed to run a VM of a known or unknown operating
- system type and version. The data is constructed by starting with the
- 'defaults' and merging the parameters given for the identified OS. If
- known, a link to a remote install CD is added.
- """
- params = copy.deepcopy(defaults)
- params['os_distro'] = distro
- params['os_version'] = version
- arch = _get_arch()
-
- # Setting maxMemory of the VM, which will be equal total Host memory in Kib
- params['max_memory'] = psutil.TOTAL_PHYMEM >> 10
-
- # set up arch to ppc64 instead of ppc64le due to libvirt compatibility
- if params["arch"] == "ppc64le":
- params["arch"] = "ppc64"
-
- if distro in modern_version_bases[arch]:
- if LooseVersion(version) >= LooseVersion(
- modern_version_bases[arch][distro]):
- params.update(template_specs[arch]['modern'])
- else:
- params.update(template_specs[arch]['old'])
- else:
- params['os_distro'] = params['os_version'] = "unknown"
- params.update(template_specs[arch]['old'])
-
- # Get custom specifications
- params.update(custom_specs.get(distro, {}).get(version, {}))
-
- if distro in icon_available_distros:
- params['icon'] = 'plugins/kimchi/images/icon-%s.png' % distro
- else:
- params['icon'] = 'plugins/kimchi/images/icon-vm.png'
-
- return params
diff --git a/plugins/kimchi/po/LINGUAS b/plugins/kimchi/po/LINGUAS
deleted file mode 100644
index 3fcb18f..0000000
--- a/plugins/kimchi/po/LINGUAS
+++ /dev/null
@@ -1,11 +0,0 @@
-en_US
-pt_BR
-zh_CN
-de_DE
-es_ES
-fr_FR
-it_IT
-ja_JP
-ko_KR
-ru_RU
-zh_TW
diff --git a/plugins/kimchi/po/Makefile.in.in b/plugins/kimchi/po/Makefile.in.in
deleted file mode 100644
index d01fb31..0000000
--- a/plugins/kimchi/po/Makefile.in.in
+++ /dev/null
@@ -1,398 +0,0 @@
-# Makefile for PO directory in any package using GNU gettext.
-# Copyright (C) 1995-1997, 2000-2007, 2009-2010 by Ulrich Drepper
<drepper(a)gnu.ai.mit.edu>
-#
-# This file can be copied and used freely without restrictions. It can
-# be used in projects which are not available under the GNU General Public
-# License but which still want to provide support for the GNU gettext
-# functionality.
-# Please note that the actual code of GNU gettext is covered by the GNU
-# General Public License and is *not* in the public domain.
-#
-# Origin: gettext-0.18
-GETTEXT_MACRO_VERSION = 0.18
-
-PACKAGE = @PACKAGE@
-VERSION = @VERSION@
-PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
-
-SHELL = /bin/sh
-@SET_MAKE@
-
-srcdir = @srcdir@
-top_srcdir = @top_srcdir@
-VPATH = @srcdir@
-
-prefix = @prefix@
-exec_prefix = @exec_prefix@
-datarootdir = @datarootdir@
-datadir = @datadir@
-localedir = @prefix@/share/locale
-gettextsrcdir = $(datadir)/gettext/po
-
-INSTALL = @INSTALL@
-INSTALL_DATA = @INSTALL_DATA@
-
-# We use $(MKDIR_P).
-# This macro uses the 'mkdir -p' command if possible. Otherwise, it falls back
-# on invoking install-sh with the -d option, so your package should contain
-# install-sh as described under AC_PROG_INSTALL.
-mkinstalldirs = $(SHELL) @install_sh@ -d
-install_sh = $(SHELL) @install_sh@
-MKDIR_P = @MKDIR_P@
-MKDIR_P = @MKDIR_P@
-
-GMSGFMT_ = @GMSGFMT@
-GMSGFMT_no = @GMSGFMT@
-GMSGFMT_yes = @GMSGFMT_015@
-GMSGFMT = $(GMSGFMT_$(USE_MSGCTXT))
-MSGFMT_ = @MSGFMT@
-MSGFMT_no = @MSGFMT@
-MSGFMT_yes = @MSGFMT_015@
-MSGFMT = $(MSGFMT_$(USE_MSGCTXT))
-XGETTEXT_ = @XGETTEXT@
-XGETTEXT_no = @XGETTEXT@
-XGETTEXT_yes = @XGETTEXT_015@
-XGETTEXT = $(XGETTEXT_$(USE_MSGCTXT))
-MSGMERGE = msgmerge
-MSGMERGE_UPDATE = @MSGMERGE@ --update
-MSGINIT = msginit
-MSGCONV = msgconv
-MSGFILTER = msgfilter
-
-POFILES = @POFILES@
-GMOFILES = @GMOFILES@
-UPDATEPOFILES = @UPDATEPOFILES@
-DUMMYPOFILES = @DUMMYPOFILES@
-DISTFILES.common = Makefile.in.in \
-$(DISTFILES.common.extra1) $(DISTFILES.common.extra2) $(DISTFILES.common.extra3)
-DISTFILES = $(DISTFILES.common) Makevars POTFILES.in gen-pot.in \
-$(POFILES) $(GMOFILES) \
-$(DISTFILES.extra1) $(DISTFILES.extra2) $(DISTFILES.extra3)
-
-POTFILES = \
-
-CATALOGS = @CATALOGS@
-
-# Makevars gets inserted here. (Don't remove this line!)
-
-.SUFFIXES:
-.SUFFIXES: .po .gmo .mo .sed .sin .nop .po-create .po-update
-
-.po.mo:
- @echo "$(MSGFMT) -c -o $@ $<"; \
- $(MSGFMT) -c -o t-$@ $< && mv t-$@ $@
-
-.po.gmo:
- @lang=`echo $* | sed -e 's,.*/,,'`; \
- test "$(srcdir)" = . && cdcmd="" || cdcmd="cd $(srcdir)
&& "; \
- echo "$${cdcmd}rm -f $${lang}.gmo && $(GMSGFMT) -c --statistics --verbose
-o $${lang}.gmo $${lang}.po"; \
- cd $(srcdir) && rm -f $${lang}.gmo && $(GMSGFMT) -c --statistics
--verbose -o t-$${lang}.gmo $${lang}.po && mv t-$${lang}.gmo $${lang}.gmo
-
-.sin.sed:
- sed -e '/^#/d' $< > t-$@
- mv t-$@ $@
-
-
-all: check-macro-version update-gmo all-@USE_NLS@
-
-all-yes: stamp-po
-all-no:
-
-# Ensure that the gettext macros and this Makefile.in.in are in sync.
-check-macro-version:
- @test "$(GETTEXT_MACRO_VERSION)" = "@GETTEXT_MACRO_VERSION@" \
- || { echo "*** error: gettext infrastructure mismatch: using a Makefile.in.in
from gettext version $(GETTEXT_MACRO_VERSION) but the autoconf macros are from gettext
version @GETTEXT_MACRO_VERSION@" 1>&2; \
- exit 1; \
- }
-
-# $(srcdir)/$(DOMAIN).pot is only created when needed. When xgettext finds no
-# internationalized messages, no $(srcdir)/$(DOMAIN).pot is created (because
-# we don't want to bother translators with empty POT files). We assume that
-# LINGUAS is empty in this case, i.e. $(POFILES) and $(GMOFILES) are empty.
-# In this case, stamp-po is a nop (i.e. a phony target).
-
-# stamp-po is a timestamp denoting the last time at which the CATALOGS have
-# been loosely updated. Its purpose is that when a developer or translator
-# checks out the package via CVS, and the $(DOMAIN).pot file is not in CVS,
-# "make" will update the $(DOMAIN).pot and the $(CATALOGS), but subsequent
-# invocations of "make" will do nothing. This timestamp would not be necessary
-# if updating the $(CATALOGS) would always touch them; however, the rule for
-# $(POFILES) has been designed to not touch files that don't need to be
-# changed.
-stamp-po: $(srcdir)/$(DOMAIN).pot
- test ! -f $(srcdir)/$(DOMAIN).pot || \
- test -z "$(GMOFILES)" || $(MAKE) $(GMOFILES)
- @test ! -f $(srcdir)/$(DOMAIN).pot || { \
- echo "touch stamp-po" && \
- echo timestamp > stamp-poT && \
- mv stamp-poT stamp-po; \
- }
-
-# Note: Target 'all' must not depend on target '$(DOMAIN).pot-update',
-# otherwise packages like GCC can not be built if only parts of the source
-# have been downloaded.
-
-$(DOMAIN).pot-update: $(POTFILES) $(srcdir)/POTFILES.in
- $(srcdir)/gen-pot $(POTFILES)
-
-# This rule has no dependencies: we don't need to update $(DOMAIN).pot at
-# every "make" invocation, only create it when it is missing.
-# Only "make $(DOMAIN).pot-update" or "make dist" will force an
update.
-$(srcdir)/$(DOMAIN).pot:
- $(MAKE) $(DOMAIN).pot-update
-
-# This target rebuilds a PO file if $(DOMAIN).pot has changed.
-# Note that a PO file is not touched if it doesn't need to be changed.
-$(POFILES): $(srcdir)/$(DOMAIN).pot
- @lang=`echo $@ | sed -e 's,.*/,,' -e 's/\.po$$//'`; \
- if test -f "$(srcdir)/$${lang}.po"; then \
- test "$(srcdir)" = . && cdcmd="" || cdcmd="cd
$(srcdir) && "; \
- echo "$${cdcmd}$(MSGMERGE_UPDATE) $(MSGMERGE_OPTIONS) --lang=$${lang} $${lang}.po
$(DOMAIN).pot"; \
- cd $(srcdir) \
- && { case `$(MSGMERGE_UPDATE) --version | sed 1q | sed -e
's,^[^0-9]*,,'` in \
- '' | 0.[0-9] | 0.[0-9].* | 0.1[0-7] | 0.1[0-7].*) \
- $(MSGMERGE_UPDATE) $(MSGMERGE_OPTIONS) $${lang}.po $(DOMAIN).pot;; \
- *) \
- $(MSGMERGE_UPDATE) $(MSGMERGE_OPTIONS) --lang=$${lang} $${lang}.po
$(DOMAIN).pot;; \
- esac; \
- }; \
- else \
- $(MAKE) $${lang}.po-create; \
- fi
-
-
-install: install-exec install-data
-install-exec:
-install-data: install-data-@USE_NLS@
- if test "$(PACKAGE)" = "gettext-tools"; then \
- $(MKDIR_P) $(DESTDIR)$(gettextsrcdir); \
- for file in $(DISTFILES.common) Makevars.template; do \
- $(INSTALL_DATA) $(srcdir)/$$file \
- $(DESTDIR)$(gettextsrcdir)/$$file; \
- done; \
- for file in Makevars; do \
- rm -f $(DESTDIR)$(gettextsrcdir)/$$file; \
- done; \
- else \
- : ; \
- fi
-install-data-no: all
-install-data-yes: all
- @catalogs='$(CATALOGS)'; \
- for cat in $$catalogs; do \
- cat=`basename $$cat`; \
- lang=`echo $$cat | sed -e 's/\.gmo$$//'`; \
- dir=$(localedir)/$$lang/LC_MESSAGES; \
- $(MKDIR_P) $(DESTDIR)$$dir; \
- if test -r $$cat; then realcat=$$cat; else realcat=$(srcdir)/$$cat; fi; \
- $(INSTALL_DATA) $$realcat $(DESTDIR)$$dir/$(DOMAIN).mo; \
- echo "installing $$realcat as $(DESTDIR)$$dir/$(DOMAIN).mo"; \
- for lc in '' $(EXTRA_LOCALE_CATEGORIES); do \
- if test -n "$$lc"; then \
- if (cd $(DESTDIR)$(localedir)/$$lang && LC_ALL=C ls -l -d $$lc
2>/dev/null) | grep ' -> ' >/dev/null; then \
- link=`cd $(DESTDIR)$(localedir)/$$lang && LC_ALL=C ls -l -d $$lc | sed
-e 's/^.* -> //'`; \
- mv $(DESTDIR)$(localedir)/$$lang/$$lc $(DESTDIR)$(localedir)/$$lang/$$lc.old; \
- mkdir $(DESTDIR)$(localedir)/$$lang/$$lc; \
- (cd $(DESTDIR)$(localedir)/$$lang/$$lc.old && \
- for file in *; do \
- if test -f $$file; then \
- ln -s ../$$link/$$file $(DESTDIR)$(localedir)/$$lang/$$lc/$$file; \
- fi; \
- done); \
- rm -f $(DESTDIR)$(localedir)/$$lang/$$lc.old; \
- else \
- if test -d $(DESTDIR)$(localedir)/$$lang/$$lc; then \
- :; \
- else \
- rm -f $(DESTDIR)$(localedir)/$$lang/$$lc; \
- mkdir $(DESTDIR)$(localedir)/$$lang/$$lc; \
- fi; \
- fi; \
- rm -f $(DESTDIR)$(localedir)/$$lang/$$lc/$(DOMAIN).mo; \
- ln -s ../LC_MESSAGES/$(DOMAIN).mo $(DESTDIR)$(localedir)/$$lang/$$lc/$(DOMAIN).mo
2>/dev/null || \
- ln $(DESTDIR)$(localedir)/$$lang/LC_MESSAGES/$(DOMAIN).mo
$(DESTDIR)$(localedir)/$$lang/$$lc/$(DOMAIN).mo 2>/dev/null || \
- cp -p $(DESTDIR)$(localedir)/$$lang/LC_MESSAGES/$(DOMAIN).mo
$(DESTDIR)$(localedir)/$$lang/$$lc/$(DOMAIN).mo; \
- echo "installing $$realcat link as
$(DESTDIR)$(localedir)/$$lang/$$lc/$(DOMAIN).mo"; \
- fi; \
- done; \
- done
-
-install-strip: install
-
-installdirs: installdirs-exec installdirs-data
-installdirs-exec:
-installdirs-data: installdirs-data-@USE_NLS@
- if test "$(PACKAGE)" = "gettext-tools"; then \
- $(MKDIR_P) $(DESTDIR)$(gettextsrcdir); \
- else \
- : ; \
- fi
-installdirs-data-no:
-installdirs-data-yes:
- @catalogs='$(CATALOGS)'; \
- for cat in $$catalogs; do \
- cat=`basename $$cat`; \
- lang=`echo $$cat | sed -e 's/\.gmo$$//'`; \
- dir=$(localedir)/$$lang/LC_MESSAGES; \
- $(MKDIR_P) $(DESTDIR)$$dir; \
- for lc in '' $(EXTRA_LOCALE_CATEGORIES); do \
- if test -n "$$lc"; then \
- if (cd $(DESTDIR)$(localedir)/$$lang && LC_ALL=C ls -l -d $$lc
2>/dev/null) | grep ' -> ' >/dev/null; then \
- link=`cd $(DESTDIR)$(localedir)/$$lang && LC_ALL=C ls -l -d $$lc | sed
-e 's/^.* -> //'`; \
- mv $(DESTDIR)$(localedir)/$$lang/$$lc $(DESTDIR)$(localedir)/$$lang/$$lc.old; \
- mkdir $(DESTDIR)$(localedir)/$$lang/$$lc; \
- (cd $(DESTDIR)$(localedir)/$$lang/$$lc.old && \
- for file in *; do \
- if test -f $$file; then \
- ln -s ../$$link/$$file $(DESTDIR)$(localedir)/$$lang/$$lc/$$file; \
- fi; \
- done); \
- rm -f $(DESTDIR)$(localedir)/$$lang/$$lc.old; \
- else \
- if test -d $(DESTDIR)$(localedir)/$$lang/$$lc; then \
- :; \
- else \
- rm -f $(DESTDIR)$(localedir)/$$lang/$$lc; \
- mkdir $(DESTDIR)$(localedir)/$$lang/$$lc; \
- fi; \
- fi; \
- fi; \
- done; \
- done
-
-# Define this as empty until I found a useful application.
-installcheck:
-
-uninstall: uninstall-exec uninstall-data
-uninstall-exec:
-uninstall-data: uninstall-data-@USE_NLS@
- if test "$(PACKAGE)" = "gettext-tools"; then \
- for file in $(DISTFILES.common) Makevars.template; do \
- rm -f $(DESTDIR)$(gettextsrcdir)/$$file; \
- done; \
- else \
- : ; \
- fi
-uninstall-data-no:
-uninstall-data-yes:
- catalogs='$(CATALOGS)'; \
- for cat in $$catalogs; do \
- cat=`basename $$cat`; \
- lang=`echo $$cat | sed -e 's/\.gmo$$//'`; \
- for lc in LC_MESSAGES $(EXTRA_LOCALE_CATEGORIES); do \
- rm -f $(DESTDIR)$(localedir)/$$lang/$$lc/$(DOMAIN).mo; \
- done; \
- done
-
-check: all
-
-info dvi ps pdf html tags TAGS ctags CTAGS ID:
-
-mostlyclean:
- rm -f remove-potcdate.sed
- rm -f stamp-poT
- rm -f core core.* $(DOMAIN).po $(DOMAIN).1po $(DOMAIN).2po *.new.po
- rm -fr *.o
-
-clean: mostlyclean
-
-distclean: clean
- rm -f Makefile Makefile.in POTFILES *.mo
-
-maintainer-clean: distclean
- @echo "This command is intended for maintainers to use;"
- @echo "it deletes files that may require special tools to rebuild."
- rm -f stamp-po $(GMOFILES)
-
-distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir)
-dist distdir:
- $(MAKE) update-po
- @$(MAKE) dist2
-# This is a separate target because 'update-po' must be executed before.
-dist2: stamp-po $(DISTFILES)
- dists="$(DISTFILES)"; \
- if test "$(PACKAGE)" = "gettext-tools"; then \
- dists="$$dists Makevars.template"; \
- fi; \
- if test -f $(srcdir)/$(DOMAIN).pot; then \
- dists="$$dists $(DOMAIN).pot stamp-po"; \
- fi; \
- if test -f $(srcdir)/ChangeLog; then \
- dists="$$dists ChangeLog"; \
- fi; \
- for i in 0 1 2 3 4 5 6 7 8 9; do \
- if test -f $(srcdir)/ChangeLog.$$i; then \
- dists="$$dists ChangeLog.$$i"; \
- fi; \
- done; \
- if test -f $(srcdir)/LINGUAS; then dists="$$dists LINGUAS"; fi; \
- for file in $$dists; do \
- if test -f $$file; then \
- cp -p $$file $(distdir) || exit 1; \
- else \
- cp -p $(srcdir)/$$file $(distdir) || exit 1; \
- fi; \
- done
-
-update-po: Makefile
- $(MAKE) $(DOMAIN).pot-update
- test -z "$(UPDATEPOFILES)" || $(MAKE) $(UPDATEPOFILES)
- $(MAKE) update-gmo
-
-# General rule for creating PO files.
-
-.nop.po-create:
- @lang=`echo $@ | sed -e 's/\.po-create$$//'`; \
- echo "File $$lang.po does not exist. If you are a translator, you can create it
through 'msginit'." 1>&2; \
- exit 1
-
-# General rule for updating PO files.
-
-.nop.po-update:
- @lang=`echo $@ | sed -e 's/\.po-update$$//'`; \
- if test "$(PACKAGE)" = "gettext-tools"; then
PATH=`pwd`/../src:$$PATH; fi; \
- tmpdir=`pwd`; \
- echo "$$lang:"; \
- test "$(srcdir)" = . && cdcmd="" || cdcmd="cd $(srcdir)
&& "; \
- echo "$${cdcmd}$(MSGMERGE) $(MSGMERGE_OPTIONS) --lang=$$lang $$lang.po
$(DOMAIN).pot -o $$lang.new.po"; \
- cd $(srcdir); \
- if { case `$(MSGMERGE) --version | sed 1q | sed -e 's,^[^0-9]*,,'` in \
- '' | 0.[0-9] | 0.[0-9].* | 0.1[0-7] | 0.1[0-7].*) \
- $(MSGMERGE) $(MSGMERGE_OPTIONS) -o $$tmpdir/$$lang.new.po $$lang.po
$(DOMAIN).pot;; \
- *) \
- $(MSGMERGE) $(MSGMERGE_OPTIONS) --lang=$$lang -o $$tmpdir/$$lang.new.po
$$lang.po $(DOMAIN).pot;; \
- esac; \
- }; then \
- if cmp $$lang.po $$tmpdir/$$lang.new.po >/dev/null 2>&1; then \
- rm -f $$tmpdir/$$lang.new.po; \
- else \
- if mv -f $$tmpdir/$$lang.new.po $$lang.po; then \
- :; \
- else \
- echo "msgmerge for $$lang.po failed: cannot move $$tmpdir/$$lang.new.po to
$$lang.po" 1>&2; \
- exit 1; \
- fi; \
- fi; \
- else \
- echo "msgmerge for $$lang.po failed!" 1>&2; \
- rm -f $$tmpdir/$$lang.new.po; \
- fi
-
-$(DUMMYPOFILES):
-
-update-gmo: Makefile $(GMOFILES)
- @:
-
-# Recreate Makefile by invoking config.status. Explicitly invoke the shell,
-# because execution permission bits may not work on the current file system.
-# Use @SHELL@, which is the shell determined by autoconf for the use by its
-# scripts, not $(SHELL) which is hardwired to /bin/sh and may be deficient.
-Makefile: Makefile.in.in Makevars $(top_builddir)/config.status @POMAKEFILEDEPS@
- cd $(top_builddir) \
- && @SHELL@ ./config.status $(subdir)/$@.in po-directories
-
-force:
-
-# Tell versions [3.59,3.63) of GNU make not to export all variables.
-# Otherwise a system limit (for SysV at least) may be exceeded.
-.NOEXPORT:
diff --git a/plugins/kimchi/po/Makevars b/plugins/kimchi/po/Makevars
deleted file mode 100644
index c29a807..0000000
--- a/plugins/kimchi/po/Makevars
+++ /dev/null
@@ -1,41 +0,0 @@
-# Makefile variables for PO directory in any package using GNU gettext.
-
-# Usually the message domain is the same as the package name.
-DOMAIN = kimchi
-
-# These two variables depend on the location of this directory.
-subdir = po
-top_builddir = ..
-
-# These options get passed to xgettext.
-XGETTEXT_OPTIONS = --keyword=_ --keyword=N_
-
-# This is the copyright holder that gets inserted into the header of the
-# $(DOMAIN).pot file. Set this to the copyright holder of the surrounding
-# package. (Note that the msgstr strings, extracted from the package's
-# sources, belong to the copyright holder of the package.) Translators are
-# expected to transfer the copyright for their translations to this person
-# or entity, or to disclaim their copyright. The empty string stands for
-# the public domain; in this case the translators are expected to disclaim
-# their copyright.
-COPYRIGHT_HOLDER =
-
-# This is the email address or URL to which the translators shall report
-# bugs in the untranslated strings:
-# - Strings which are not entire sentences, see the maintainer guidelines
-# in the GNU gettext documentation, section 'Preparing Strings'.
-# - Strings which use unclear terms or require additional context to be
-# understood.
-# - Strings which make invalid assumptions about notation of date, time or
-# money.
-# - Pluralisation problems.
-# - Incorrect English spelling.
-# - Incorrect formatting.
-# It can be your email address, or a mailing list address where translators
-# can write to without being subscribed, or the URL of a web page through
-# which the translators can contact you.
-MSGID_BUGS_ADDRESS = project-kimchi(a)googlegroups.com
-
-# This is the list of locale categories, beyond LC_MESSAGES, for which the
-# message catalogs shall be used. It is usually empty.
-EXTRA_LOCALE_CATEGORIES =
diff --git a/plugins/kimchi/po/POTFILES.in b/plugins/kimchi/po/POTFILES.in
deleted file mode 100644
index 92eef1e..0000000
--- a/plugins/kimchi/po/POTFILES.in
+++ /dev/null
@@ -1,3 +0,0 @@
-# List of source files which contain translatable strings.
-i18n.py
-ui/pages/*.tmpl
diff --git a/plugins/kimchi/po/de_DE.po b/plugins/kimchi/po/de_DE.po
deleted file mode 100644
index d3f3cc3..0000000
--- a/plugins/kimchi/po/de_DE.po
+++ /dev/null
@@ -1,2288 +0,0 @@
-# English translations for kimchi package.
-# Copyright (C) 2013 ORGANIZATION
-#
-msgid ""
-msgstr ""
-"Project-Id-Version: kimchi 0.1\n"
-"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2015-07-01 16:11-0300\n"
-"PO-Revision-Date: 2013-07-11 17:32-0400\n"
-"Last-Translator: Cr��stian Viana <vianac(a)linux.vnet.ibm.com>\n"
-"Language-Team: English\n"
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
-"Content-Transfer-Encoding: 8bit\n"
-"Language: de_DE\n"
-"Generated-By: pygettext.py 1.5\n"
-"Plural-Forms: nplurals=2; plural=(n != 1);\n"
-
-#, python-format
-msgid "Unknown parameter %(value)s"
-msgstr ""
-
-#, python-format
-msgid "Timeout of %(seconds)s seconds expired while running task
'%(task)s."
-msgstr ""
-
-#, python-format
-msgid "User %(user_id)s not found with given LDAP settings."
-msgstr ""
-
-msgid "Unknown \"_cap\" specified"
-msgstr ""
-
-msgid "\"_passthrough\" should be \"true\" or
\"false\""
-msgstr ""
-
-msgid "\"_passthrough_affected_by\" should be a device name string"
-msgstr ""
-
-#, python-format
-msgid "Error while getting block devices. Details: %(err)s"
-msgstr "Fehler beim Abrufen von Blockeinheiten. Details: %(err)s"
-
-#, python-format
-msgid "Error while getting block device information for %(device)s."
-msgstr "Fehler beim Abrufen von Blockeinheitinformationen f��r %(device)s."
-
-#, python-format
-msgid "Unable to find distro file: %(filename)s"
-msgstr "Distro-Datei konnte nicht gefunden werden: %(filename)s"
-
-#, python-format
-msgid ""
-"Unable to parse distro file: %(filename)s. Make sure, it is a JSON file."
-msgstr ""
-"Distro-Datei konnte nicht analysiert werden: %(filename)s. Stellen Sie "
-"sicher, dass es sich um eine JSON-Datei handelt."
-
-#, python-format
-msgid "Unable to login to iSCSI host target %(portal)s. Details: %(err)s"
-msgstr "Fehler beim Anmelden bei iSCSI-Hostziel %(portal)s. Details: %(err)s"
-
-#, python-format
-msgid "Unable to login to iSCSI host %(host)s target %(target)s"
-msgstr "Anmeldung bei iSCSI-Host %(host)s Ziel %(target)s nicht m��glich"
-
-#, python-format
-msgid "Unable to find ISO file %(filename)s"
-msgstr ""
-
-#, python-format
-msgid "The ISO file %(filename)s is not bootable"
-msgstr "Die ISO-Datei %(filename)s ist nicht bootf��hig"
-
-#, python-format
-msgid "The ISO file %(filename)s does not have a valid El Torito boot record"
-msgstr "Die ISO-Datei %(filename)s hat keinen g��ltigen El Torito-Bootsatz"
-
-#, python-format
-msgid "Invalid El Torito validation entry in ISO %(filename)s"
-msgstr "Ung��ltiger El Torito-Pr��feintrag in ISO-Datei %(filename)s"
-
-#, python-format
-msgid "Invalid El Torito boot indicator in ISO %(filename)s"
-msgstr "Ung��ltiger El Torito-Boot-Indikator in ISO-Datei %(filename)s"
-
-#, python-format
-msgid "Unexpected volume type for primary volume in ISO %(filename)s"
-msgstr ""
-"Unerwarteter Datentr��gertyp f��r Prim��rdatentr��ger in ISO-Datei
%(filename)s"
-
-#, python-format
-msgid "Bad format while reading volume descriptor in ISO %(filename)s"
-msgstr ""
-"Ung��ltiges Format beim Lesen des Datentr��gerdeskriptors in ISO-Datei %"
-"(filename)s"
-
-#, python-format
-msgid ""
-"The hypervisor doesn't have permission to use this ISO %(filename)s. "
-"Consider moving it under /var/lib/libvirt, or set the search permission to "
-"file access control lists for '%(user)s' user if possible, or add the
'%"
-"(user)s' to the ISO path group, or (not recommended) 'chmod -R o+x "
-"'path_to_iso'.Details: %(err)s"
-msgstr ""
-"Der Hypervisor hat nicht die Berechtigung, die ISO-Datei %(filename)s zu "
-"verwenden. Verschieben Sie sie entweder nach /var/lib/libvirt oder setzen "
-"Sie, sofern m��glich, die Suchberechtigung auf Dateizugriffssteuerungslisten
"
-"f��r den Benutzer '%(user)s' oder f��gen Sie '%(user)s' der
ISO-Pfadgruppe "
-"hinzu oder (nicht empfohlen) 'chmod -R o+x 'path_to_iso'. Details:
%(err)s"
-
-msgid "An error occurred when probing image OS information."
-msgstr ""
-
-msgid "No OS information found in given image."
-msgstr ""
-
-#, python-format
-msgid "Unable to read image file %(filename)s"
-msgstr ""
-
-#, python-format
-msgid ""
-"Image file must be an existing file on system. %(filename)s is not a valid "
-"input."
-msgstr ""
-
-#, python-format
-msgid "Virtual machine %(name)s already exists"
-msgstr "Virtuelle Maschine %(name)s ist bereits vorhanden"
-
-#, python-format
-msgid "Virtual machine %(name)s does not exist"
-msgstr "Virtuelle Maschine %(name)s ist nicht vorhanden"
-
-#, python-format
-msgid ""
-"Unable to rename virtual machine %(name)s. The name %(new_name)s is already "
-"in use or the virtual machine is not powered off."
-msgstr ""
-
-#, python-format
-msgid "Unable to retrieve screenshot for stopped virtual machine %(name)s"
-msgstr ""
-"Screenshot f��r gestoppte virtuelle Maschine %(name)s konnte nicht abgerufen
"
-"werden"
-
-msgid "Remote ISO image is not supported by this server."
-msgstr "Fernes ISO-Image wird von diesem Server nicht unterst��tzt."
-
-#, python-format
-msgid "Screenshot is not supported on virtual machine %(name)s"
-msgstr ""
-
-#, python-format
-msgid "Unable to create virtual machine %(name)s. Details: %(err)s"
-msgstr ""
-"Virtuelle Maschine %(name)s konnte nicht erstellt werden. Details: %(err)s"
-
-#, python-format
-msgid "Unable to update virtual machine %(name)s. Details: %(err)s"
-msgstr ""
-"Virtuelle Maschine %(name)s konnte nicht erstellt werden. Details: %(err)s"
-
-#, python-format
-msgid "Unable to retrieve virtual machine %(name)s. Details: %(err)s"
-msgstr ""
-"Virtuelle Maschine %(name)s konnte nicht abgerufen werden. Details: %(err)s"
-
-#, python-format
-msgid "Unable to connect to powered off virtual machine %(name)s."
-msgstr ""
-"Verbindung zur abgeschalteten Maschine %(name)s konnte nicht hergestellt "
-"werden."
-
-msgid "Virtual machine name must be a string without slashes (/)"
-msgstr ""
-
-#, python-format
-msgid "Invalid template URI %(value)s specified for virtual machine"
-msgstr ""
-
-#, python-format
-msgid "Invalid storage pool URI %(value)s specified for virtual machine"
-msgstr ""
-
-msgid "Supported virtual machine graphics are Spice or VNC"
-msgstr ""
-
-msgid "Graphics address to listen on must be IPv4 or IPv6"
-msgstr "Zu ��berwachende Grafikadresse muss IPv4 oder IPv6 sein"
-
-msgid "Specify a template to create a virtual machine from"
-msgstr "Vorlage angeben, aus der eine virtuelle Maschine erstellt werden soll"
-
-#, python-format
-msgid "Unable to start virtual machine %(name)s. Details: %(err)s"
-msgstr ""
-"Virtuelle Maschine %(name)s konnte nicht gestartet werden. Details: %(err)s"
-
-#, python-format
-msgid "Unable to power off virtual machine %(name)s. Details: %(err)s"
-msgstr ""
-"Virtuelle Maschine %(name)s konnte nicht gestoppt werden. Details: %(err)s"
-
-#, python-format
-msgid "Unable to delete virtual machine %(name)s. Details: %(err)s"
-msgstr ""
-"Virtuelle Maschine %(name)s konnte nicht gel��scht werden. Details: %(err)s"
-
-#, python-format
-msgid "Unable to reset virtual machine %(name)s. Details: %(err)s"
-msgstr ""
-"Virtuelle Maschine %(name)s konnte nicht umbenannt werden. Details: %(err)s"
-
-msgid "User name list must be an array"
-msgstr ""
-
-msgid "User name must be a string"
-msgstr "Netzname muss eine Zeichenfolge sein"
-
-msgid "Group name list must be an array"
-msgstr ""
-
-msgid "Group name must be a string"
-msgstr "Netzname muss eine Zeichenfolge sein"
-
-#, python-format
-msgid "User(s) '%(users)s' do not exist"
-msgstr "Benutzer '%(users)s' ist nicht vorhanden."
-
-#, python-format
-msgid "Group(s) '%(groups)s' do not exist"
-msgstr "Benutzer '%(groups)s' ist nicht vorhanden."
-
-#, python-format
-msgid "Unable to shutdown virtual machine %(name)s. Details: %(err)s"
-msgstr ""
-"Virtuelle Maschine %(name)s konnte nicht gestoppt werden. Details: %(err)s"
-
-#, python-format
-msgid ""
-"Unable to get access metadata of virtual machine %(name)s. Details: %(err)s"
-msgstr ""
-"Virtuelle Maschine %(name)s konnte nicht gestartet werden. Details: %(err)s"
-
-msgid "The guest console password must be a string."
-msgstr ""
-
-msgid "The life time for the guest console password must be a number."
-msgstr ""
-
-#, python-format
-msgid "Virtual machine '%(name)s' must be stopped before cloning it."
-msgstr ""
-
-#, python-format
-msgid "Insufficient disk space to clone virtual machine '%(name)s'"
-msgstr ""
-
-#, python-format
-msgid "Unable to clone VM '%(name)s'. Details: %(err)s"
-msgstr ""
-
-#, python-format
-msgid "Invalid operation for non-persistent virtual machine %(name)s"
-msgstr ""
-
-#, python-format
-msgid "Cannot suspend VM '%(name)s' because it is not running."
-msgstr ""
-
-#, python-format
-msgid "Unable to suspend VM '%(name)s'. Details: %(err)s"
-msgstr ""
-
-#, python-format
-msgid "Cannot resume VM '%(name)s' because it is not paused."
-msgstr ""
-
-#, python-format
-msgid "Unable to resume VM '%(name)s'. Details: %(err)s"
-msgstr ""
-
-msgid "Memory assigned is higher then the maximum allowed in the host."
-msgstr ""
-
-#, python-format
-msgid ""
-"VM '%(name)s' does not support live memory update. Update the memory with
"
-"the machine offline to enable this feature."
-msgstr ""
-
-msgid "Only increase memory is allowed in active VMs"
-msgstr ""
-
-msgid ""
-"For live memory update, new memory value must be equal old memory value plus
"
-"multiples of 1024 Mib"
-msgstr ""
-
-msgid "There are not enough free slots of 1024 Mib in the guest."
-msgstr ""
-
-msgid ""
-"Host's libvirt version does not support memory devices. Libvirt must be >=
"
-"1.2.14"
-msgstr ""
-
-#, python-format
-msgid "Error attaching memory device. Details: %(error)s"
-msgstr ""
-
-#, python-format
-msgid ""
-"VM %(vmid)s does not contain directly assigned host device %(dev_name)s."
-msgstr ""
-
-#, python-format
-msgid "The host device %(dev_name)s is not allowed to directly assign to VM."
-msgstr ""
-
-msgid ""
-"No IOMMU groups found. Host PCI pass through needs IOMMU group to function "
-"correctly. Please enable Intel VT-d or AMD IOMMU in your BIOS, then verify "
-"the Kernel is compiled with IOMMU support. For Intel CPU, add intel_iommu=on
"
-"to your Kernel parameter in /boot/grub2/grub.conf. For AMD CPU, add iommu=pt
"
-"iommu=1."
-msgstr ""
-
-msgid "\"name\" should be a device name string"
-msgstr ""
-
-#, python-format
-msgid ""
-"The device %(name)s is probably in use by the host. Unable to attach it to "
-"the guest."
-msgstr ""
-
-#, python-format
-msgid "Interface %(iface)s does not exist in virtual machine %(name)s"
-msgstr ""
-"Schnittstelle %(iface)s ist in virtueller Maschine %(name)s nicht vorhanden"
-
-#, python-format
-msgid ""
-"Network %(network)s specified for virtual machine %(name)s does not exist"
-msgstr ""
-"Das f��r die virtuelle Maschine %(name)s angegebene Netz %(network)s ist "
-"nicht vorhanden"
-
-msgid "Supported virtual machine interfaces type is only network"
-msgstr "Unterst��tzter Schnittstellentyp einer virtuellen Maschine ist nur
Netz"
-
-msgid "Network name for virtual machine interface must be a string"
-msgstr ""
-"Netzname f��r Schnittstelle einer virtuellen Maschine muss eine Zeichenfolge
"
-"sein"
-
-msgid "Invalid network model card specified for virtual machine interface"
-msgstr ""
-"Ung��ltige Netzmodellkarte f��r Schnittstelle einer virtuellen Maschine "
-"angegeben"
-
-msgid "Specify type and network to add a new virtual machine interface"
-msgstr ""
-"Geben Sie Typ und Netz an, um eine neue Schnittstelle f��r eine virtuelle "
-"Maschine hinzuzuf��gen"
-
-msgid "MAC Address must respect this format FF:FF:FF:FF:FF:FF"
-msgstr ""
-
-#, python-format
-msgid "MAC Address %(mac)s already exists in virtual machine %(name)s"
-msgstr ""
-
-msgid "Invalid MAC Address"
-msgstr ""
-
-msgid "Cannot change MAC address of a running virtual machine"
-msgstr ""
-
-#, python-format
-msgid "Template %(name)s already exists"
-msgstr "Vorlage %(name)s ist bereits vorhanden"
-
-#, python-format
-msgid ""
-"Network '%(network)s' specified for template %(template)s does not
exist"
-msgstr ""
-"Das f��r Vorlage %(template)s angegebene Netz '%(network)s' ist nicht
"
-"vorhanden"
-
-#, python-format
-msgid ""
-"Storage pool %(pool)s specified for template %(template)s does not exist"
-msgstr ""
-"Der f��r Vorlage %(template)s angegebene Speicherpool '%(pool)s' ist nicht
"
-"vorhanden"
-
-#, python-format
-msgid "Storage pool %(pool)s specified for template %(template)s is not
active"
-msgstr ""
-"Der f��r Vorlage %(template)s angegebene Speicherpool '%(pool)s' ist nicht
"
-"aktiv"
-
-#, python-format
-msgid "Invalid parameter '%(param)s' specified for CDROM."
-msgstr "Ung��ltiger Parameter '%(param)s' f��r CD-ROM angegeben."
-
-#, python-format
-msgid "Network %(network)s specified for template %(template)s is not active"
-msgstr ""
-"Das f��r Vorlage %(template)s angegebene Netz %(network)s ist nicht aktiv"
-
-msgid "Template name must be a string"
-msgstr "Vorlagenname muss eine Zeichenfolge sein"
-
-msgid "Template icon must be a path to the image"
-msgstr "Vorlagensymbol muss ein Pfad zum Image sein"
-
-msgid "Template distribution must be a string"
-msgstr "Vorlagenverteilung muss eine Zeichenfolge sein"
-
-msgid "Template distribution version must be a string"
-msgstr "Vorlagenverteilungsversion muss eine Zeichenfolge sein"
-
-msgid "The number of CPUs must be an integer greater than 0"
-msgstr "Die Anzahl der CPUs muss eine Ganzzahl sein"
-
-msgid "Amount of memory (MB) must be an integer greater than 512"
-msgstr "Speicherkapazit��t (MB) muss eine Ganzzahl gr����er als 512 sein"
-
-msgid "Template CDROM must be a local or remote ISO file"
-msgstr "Vorlagen-CD-ROM muss eine lokale oder ferne ISO-Datei sein"
-
-#, python-format
-msgid "Invalid storage pool URI %(value)s specified for template"
-msgstr "Ung��ltiger Speicherpool-URI %(value)s f��r Vorlage angegeben"
-
-msgid "Specify an ISO image as CDROM or a base image to create a template"
-msgstr "Geben Sie ein ISO-Image als CD-ROM an, um eine Vorlage zu erstellen"
-
-msgid "All networks for the template must be specified in a list."
-msgstr "Alle Netze f��r die Vorlage m��ssen in einer Liste angegeben werden."
-
-msgid "Specify a volume to a template when storage pool is iSCSI or SCSI"
-msgstr ""
-
-#, python-format
-msgid "The volume %(volume)s is not in storage pool %(pool)s"
-msgstr ""
-
-#, python-format
-msgid "Unable to create template due error: %(err)s"
-msgstr ""
-"Vorlage kann aufgrund des folgenden Fehlers nicht erstellt werden: %(err)s"
-
-#, python-format
-msgid "Unable to delete template due error: %(err)s"
-msgstr ""
-"Vorlage kann aufgrund des folgenden Fehlers nicht gel��scht werden: %(err)s"
-
-msgid "Disk size must be an integer greater than 1GB."
-msgstr ""
-
-msgid "Template base image must be a valid local image file"
-msgstr "Vorlagen-CD-ROM muss eine lokale oder ferne ISO-Datei sein"
-
-#, python-format
-msgid "Cannot identify base image %(path)s format"
-msgstr ""
-
-msgid ""
-"When specifying CPU topology, VCPUs must be a product of sockets, cores, and
"
-"threads."
-msgstr ""
-
-msgid ""
-"When specifying CPU topology, each element must be an integer greater than "
-"zero."
-msgstr ""
-
-msgid ""
-"Invalid disk image format. Valid formats: bochs, cloop, cow, dmg, qcow, "
-"qcow2, qed, raw, vmdk, vpc."
-msgstr ""
-
-#, python-format
-msgid "Storage pool %(name)s already exists"
-msgstr "Speicherpool %(name)s ist bereits vorhanden"
-
-#, python-format
-msgid "Storage pool %(name)s does not exist"
-msgstr "Speicherpool %(name)s ist nicht vorhanden"
-
-#, python-format
-msgid "Specify %(item)s in order to create the storage pool %(name)s"
-msgstr "Geben Sie %(item)s an, um den Speicherpool %(name)s zu erstellen"
-
-#, python-format
-msgid "Unable to delete active storage pool %(name)s"
-msgstr "Aktiver Speicherpool %(name)s konnte nicht gel��scht werden"
-
-#, python-format
-msgid "Unable to list storage pools. Details: %(err)s"
-msgstr "Speicherpools konnten nicht aufgelistet werden. Details: %(err)s"
-
-#, python-format
-msgid "Unable to create storage pool %(name)s. Details: %(err)s"
-msgstr "Speicherpool %(name)s konnte nicht erstellt werden. Details: %(err)s"
-
-#, python-format
-msgid ""
-"Unable to get number of storage volumes in storage pool %(name)s. Details: %"
-"(err)s"
-msgstr ""
-"Anzahl der Speicherdatentr��ger im Speicherpool %(name)s konnte nicht "
-"abgerufen werden. Details: %(err)s"
-
-#, python-format
-msgid "Unable to activate storage pool %(name)s. Details: %(err)s"
-msgstr "Speicherpool %(name)s konnte nicht aktiviert werden. Details: %(err)s"
-
-#, python-format
-msgid "Unable to deactivate storage pool %(name)s. Details: %(err)s"
-msgstr ""
-"Speicherpool %(name)s konnte nicht inaktiviert werden. Details: %(err)s"
-
-#, python-format
-msgid "Unable to delete storage pool %(name)s. Details: %(err)s"
-msgstr "Speicherpool %(name)s konnte nicht gel��scht werden. Details: %(err)s"
-
-#, python-format
-msgid ""
-"Unable to create NFS Pool as export path %(path)s may block during mount"
-msgstr ""
-"NFS-Pool konnte nicht erstellt werden, weil Exportpfad %(path)s beim Mounten
"
-"blockieren kann"
-
-#, python-format
-msgid "Unable to create NFS Pool as export path %(path)s mount failed"
-msgstr ""
-"NFS-Pool konnte nicht erstellt werden, weil das Mounten des Exportpfads%"
-"(path)s fehlgeschlagen ist"
-
-#, python-format
-msgid "Unsupported storage pool type: %(type)s"
-msgstr "Nicht unterst��tzter Speicherpooltyp: %(type)s"
-
-#, python-format
-msgid "Error while retrieving storage pool XML to %(pool)s"
-msgstr ""
-
-msgid "Storage pool name must be a string without slashes (/)"
-msgstr ""
-
-msgid ""
-"Supported storage pool types are dir, netfs, logical, iscsi, isci and
kimchi-"
-"iso"
-msgstr ""
-
-msgid "Storage pool path must be a string"
-msgstr "Speicherpoolpfad muss eine Zeichenfolge sein"
-
-msgid "Storage pool host must be a IP or hostname"
-msgstr "Speicherpoolhost muss eine IP oder ein Hostname sein"
-
-msgid "Storage pool device must be the absolute path to the block device"
-msgstr ""
-
-msgid "Storage pool devices parameter must be a list"
-msgstr "Einheitenparameter des Speicherpools muss eine Liste sein"
-
-msgid "Target IQN of an iSCSI pool must be a string"
-msgstr "Ziel-IQN eines iSCSI-Pools muss eine Zeichenfolge sein"
-
-msgid "Port of a remote storage server must be an integer between 1 and 65535"
-msgstr ""
-"Port eines fernen Speicherservers muss eine Ganzzahl zwischen 1 und 65535 "
-"sein"
-
-msgid "iSCSI target username must be a string"
-msgstr ""
-
-msgid "iSCSI target password must be a string"
-msgstr ""
-
-msgid "Specify name and type to create a storage pool"
-msgstr "Geben Sie Name und Typ an, um einen Speicherpool zu erstellen"
-
-#, python-format
-msgid ""
-"%(disk)s is not a valid disk/partition. Could not add it to the pool %(pool)"
-"s."
-msgstr ""
-"%(disk)s ist keine g��ltige Platte/Partition. Sie konnte nicht hinzugef��gt "
-"werden zum Pool %(pool)s."
-
-#, python-format
-msgid "Unable to extend logical pool %(pool)s. Details: %(err)s"
-msgstr ""
-
-msgid "The parameter disks only can be updated for logical storage pool."
-msgstr ""
-"Die Parameterplatten k��nnen nur f��r den logischen Speicherpool aktualisiert
"
-"werden."
-
-msgid "The SCSI host adapter name must be a string."
-msgstr "Der Name des SCSI-Hostadapters muss eine Zeichenfolge sein."
-
-msgid "The storage pool kimchi_isos is reserved for internal use"
-msgstr "Der Speicherpool kimchi_isos ist f��r die interne Verwendung
reserviert"
-
-#, python-format
-msgid ""
-"Unable to activate NFS storage pool %(name)s. NFS server %(server)s is "
-"unreachable."
-msgstr ""
-"Der NFS-Speicherpool %(name)s konnte nicht aktiviert werden. NFS-Server %"
-"(server)s ist nicht erreichbar."
-
-#, python-format
-msgid ""
-"Unable to deactivate NFS storage pool %(name)s. NFS server %(server)s is "
-"unreachable."
-msgstr ""
-"Der NFS-Speicherpool %(name)s konnte nicht inaktiviert werden. NFS-Server %"
-"(server)s ist nicht erreichbar."
-
-#, python-format
-msgid ""
-"Unable to deactivate pool %(name)s as it is associated with some templates"
-msgstr ""
-"Pool %(name)s konnte nicht inaktiviert werden, weil er einigen Vorlagen "
-"zugeordnet ist"
-
-#, python-format
-msgid "Unable to delete pool %(name)s as it is associated with some templates"
-msgstr ""
-"Pool %(name)s konnte nicht gel��scht werden, weil er einigen Vorlagen "
-"zugeordnet ist"
-
-#, python-format
-msgid ""
-"A volume group named '%(name)s' already exists. Please, choose another name
"
-"to create the logical pool."
-msgstr ""
-"Eine Datentr��gergruppe mit dem Namen '%(name)s' ist bereits vorhanden.
"
-"W��hlen Sie einen anderen Namen aus, um den logischen Pool zu erstellen."
-
-#, python-format
-msgid "Unable to update database with deep scan information due error:
%(err)s"
-msgstr ""
-"Datenbank mit Tiefenscaninformationen kann aufgrund des folgenden Fehlers "
-"nicht aktualisiert werden: %(err)s"
-
-#, python-format
-msgid "Storage volume %(name)s already exists"
-msgstr "Speicherdatentr��ger %(name)s ist bereits vorhanden"
-
-#, python-format
-msgid "Storage volume %(name)s does not exist in storage pool %(pool)s"
-msgstr ""
-"Speicherdatentr��ger %(name)s ist nicht im Speicherpool %(pool)s vorhanden"
-
-#, python-format
-msgid ""
-"Unable to create storage volume %(volume)s because storage pool %(pool)s is "
-"not active"
-msgstr ""
-
-#, python-format
-msgid "Specify %(item)s in order to create storage volume %(volume)s"
-msgstr "Geben Sie %(item)s an, um Speicherdatentr��ger %(volume)s zu
erstellen"
-
-#, python-format
-msgid ""
-"Unable to list storage volumes because storage pool %(pool)s is not active"
-msgstr ""
-"Speicherdatentr��ger konnten nicht aufgelistet werden, weil Speicherpool %"
-"(pool)s nicht aktiv ist"
-
-#, python-format
-msgid ""
-"Unable to create storage volume %(name)s in storage pool %(pool)s. Details:
%"
-"(err)s"
-msgstr ""
-"Speicherdatentr��ger %(name)s konnte nicht in Speicherpool %(pool)s erstellt
"
-"werden. Details: %(err)s"
-
-#, python-format
-msgid ""
-"Unable to list storage volumes in storage pool %(pool)s. Details: %(err)s"
-msgstr ""
-"Speicherdatentr��ger konnten nicht in Speicherpool %(pool)s aufgelistet "
-"werden. Details: %(err)s"
-
-#, python-format
-msgid "Unable to wipe storage volumes %(name)s. Details: %(err)s"
-msgstr ""
-"Speicherdatentr��ger %(name)s konnten nicht bereinigt werden. Details:
%(err)s"
-
-#, python-format
-msgid "Unable to delete storage volume %(name)s. Details: %(err)s"
-msgstr ""
-"Speicherdatentr��ger %(name)s konnte nicht gel��scht werden. Details:
%(err)s"
-
-#, python-format
-msgid "Unable to resize storage volume %(name)s. Details: %(err)s"
-msgstr ""
-"Gr����e des Speicherdatentr��gers %(name)s konnte nicht ge��ndert werden. "
-"Details: %(err)s"
-
-#, python-format
-msgid "Storage type %(type)s does not support volume create and delete"
-msgstr ""
-"Speichertyp %(type)s unterst��tzt nicht das Erstellen und L��schen von "
-"Datentr��gern"
-
-msgid "Storage volume name must be a string"
-msgstr "Name des Speicherdatentr��gers muss eine Zeichenfolge sein"
-
-msgid "Storage volume allocation must be an integer number"
-msgstr "Zuordnung des Speicherdatentr��gers muss eine Ganzzahl sein"
-
-msgid ""
-"Storage volume format not supported. Valid formats: bochs, cloop, cow, dmg, "
-"qcow, qcow2, qed, raw, vmdk, vpc."
-msgstr ""
-
-msgid "Storage volume requires a volume name"
-msgstr "Speicherdatentr��ger erfordert einen Datentr��gernamen"
-
-#, python-format
-msgid ""
-"Unable to update database with storage volume information due error: %(err)s"
-msgstr ""
-"Datenbank mit Datentr��gerinformationen kann aufgrund des folgenden Fehlers "
-"nicht aktualisiert werden: %(err)s"
-
-#, python-format
-msgid "Only one of parameter %(param)s can be specified"
-msgstr ""
-
-#, python-format
-msgid "Create volume from %(param)s is not supported"
-msgstr ""
-
-msgid "Storage volume capacity must be an integer number."
-msgstr ""
-
-msgid "Storage volume URL must be http://, https://, ftp:// or ftps://."
-msgstr ""
-
-#, python-format
-msgid "Unable to access file %(url)s. Please, check it."
-msgstr ""
-
-#, python-format
-msgid ""
-"Unable to clone storage volume '%(name)s' in pool '%(pool)s'.
Details: %(err)"
-"s"
-msgstr ""
-
-msgid "Specify chunk data and its size to upload a file."
-msgstr ""
-
-msgid "In order to upload a storage volume, specify the 'upload'
parameter."
-msgstr ""
-
-msgid ""
-"Unable to upload chunk data as it does not match with requested chunk size."
-msgstr ""
-
-#, python-format
-msgid "The storage volume %(vol)s is not under an upload process."
-msgstr ""
-
-msgid "The upload chunk data will exceed the storage volume size."
-msgstr ""
-
-#, python-format
-msgid "Unable to upload chunk data to storage volume. Details: %(err)s."
-msgstr ""
-
-#, python-format
-msgid "Interface %(name)s does not exist"
-msgstr "Schnittstelle %(name)s ist nicht vorhanden"
-
-#, python-format
-msgid "Network %(name)s already exists"
-msgstr "Netz %(name)s ist bereits vorhanden"
-
-#, python-format
-msgid "Network %(name)s does not exist"
-msgstr "Netz %(name)s ist nicht vorhanden"
-
-#, python-format
-msgid "Subnet %(subnet)s specified for network %(network)s is not valid."
-msgstr ""
-"Das f��r das Netz %(network)s angegebene Teilnetz %(subnet)s ist nicht
g��ltig."
-
-#, python-format
-msgid "Specify a network interface to create bridged network %(name)s"
-msgstr ""
-"Geben Sie eine Netzschnittstelle an, um ��berbr��cktes Netz %(name)s zu "
-"erstellen"
-
-#, python-format
-msgid "Unable to delete active network %(name)s"
-msgstr "Aktives Netz %(name)s konnte nicht gel��scht werden"
-
-#, python-format
-msgid "Interface %(iface)s specified for network %(network)s is already in
use"
-msgstr ""
-"Die f��r das Netz %(network)s angegebene Schnittstelle %(iface)s wird bereits
"
-"verwendet"
-
-msgid "Interface should be bare NIC, bonding or bridge device."
-msgstr "Schnittstelle sollte blo��es NIC, Bonding oder Br��ckeneinheit sein."
-
-#, python-format
-msgid "Unable to create network %(name)s. Details: %(err)s"
-msgstr "Netz %(name)s konnte nicht erstellt werden. Details: %(err)s"
-
-#, python-format
-msgid "Unable to find a free IP address for network '%(name)s'"
-msgstr "Es konnte keine freie IP-Adresse f��r Netz '%(name)s' gefunden
werden"
-
-#, python-format
-msgid "The interface %(iface)s already exists."
-msgstr ""
-
-msgid "Network name must be a string without slashes (/) or quotes (\")"
-msgstr ""
-
-msgid "Supported network types are isolated, NAT and bridge"
-msgstr "Unterst��tzte Netztypen sind Isoliert, NAT und Br��cke"
-
-msgid "Network subnet must be a string with IP address and prefix or netmask"
-msgstr ""
-"Teilnetz des Netzes muss eine Zeichenfolge mit IP-Adresse und Pr��fix oder "
-"Netzmaske sein"
-
-msgid "Network interface must be a string"
-msgstr "Netzschnittstelle muss eine Zeichenfolge sein"
-
-msgid "Network VLAN ID must be an integer between 1 and 4094"
-msgstr "Netz-VLAN-ID muss eine Ganzzahl zwischen 1 und 4094 sein"
-
-msgid "Specify name and type to create a Network"
-msgstr "Geben Sie Name und Typ an, um ein Netz zu erstellen"
-
-#, python-format
-msgid ""
-"Unable to delete network %(name)s. There are some virtual machines %(vms)s "
-"and/or templates linked to this network."
-msgstr ""
-"Netz %(name)s konnte nicht inaktiviert werden. Es sind einige virtuellen "
-"Maschinen %(vms)s und/oder Vorlagen mit diesem Netz verkn��pft."
-
-#, python-format
-msgid ""
-"Unable to deactivate network %(name)s. There are some virtual machines
%(vms)"
-"s and/or templates linked to this network."
-msgstr ""
-"Netz %(name)s konnte nicht inaktiviert werden. Es sind einige virtuellen "
-"Maschinen %(vms)s und/oder Vorlagen mit diesem Netz verkn��pft."
-
-#, python-format
-msgid "Bridge device %(name)s can not be the trunk device of a VLAN."
-msgstr "Br��ckeneinheit %(name)s kann nicht die Trunkeinheit eines VLAN sein."
-
-#, python-format
-msgid "Failed to activate interface %(iface)s: %(err)s."
-msgstr "Schnittstelle %(iface)s konnte nicht aktiviert werden: %(err)s."
-
-#, python-format
-msgid ""
-"Failed to activate interface %(iface)s. Please check the physical link "
-"status."
-msgstr ""
-"Schnittstelle %(iface)s konnte nicht aktiviert werden. Bitte ��berpr��fen Sie
"
-"den Status der physischen Verbindung."
-
-#, python-format
-msgid "Failed to start network %(name)s. Details: %(err)s"
-msgstr ""
-
-#, python-format
-msgid "Debug report %(name)s does not exist"
-msgstr "Debugbericht %(name)s ist nicht vorhanden"
-
-msgid "Debug report tool not found in system"
-msgstr "Debugberichtstool nicht im System gefunden"
-
-#, python-format
-msgid "Unable to create debug report %(name)s. Details: %(err)s."
-msgstr "Debugbericht %(name)s konnte nicht erstellt werden. Details: %(err)s."
-
-#, python-format
-msgid "Can not find any debug report with the given name %(name)s"
-msgstr ""
-
-#, python-format
-msgid "Unable to generate debug report %(name)s. Details: %(err)s"
-msgstr "Debugbericht %(name)s konnte nicht generiert werden. Details: %(err)s"
-
-msgid "You should give a name for the debug report file."
-msgstr ""
-
-msgid ""
-"Debug report name must be a string. Only letters, digits, underscore ('_')
"
-"and hyphen ('-') are allowed."
-msgstr ""
-
-#, python-format
-msgid ""
-"The debug report with specified name \"%(name)s\" already exists. Please
use "
-"another one."
-msgstr ""
-"Eine Datentr��gergruppe mit dem Namen '%(name)s' ist bereits vorhanden.
"
-"W��hlen Sie einen anderen Namen aus, um den logischen Pool zu erstellen."
-
-#, python-format
-msgid "Storage server %(server)s was not used by Kimchi"
-msgstr "Speicherserver %(server)s wurde nicht von Kimchi verwendet"
-
-#, python-format
-msgid "Distro '%(name)s' does not exist"
-msgstr "Distro '%(name)s' ist nicht vorhanden"
-
-#, python-format
-msgid "Partition %(name)s does not exist in the host"
-msgstr "Partition %(name)s ist nicht im Host vorhanden"
-
-msgid "Unable to shutdown host machine as there are running virtual machines"
-msgstr ""
-"Hostmaschine konnte nicht heruntergefahren werden, weil virtuelle Maschinen "
-"ausgef��hrt werden"
-
-msgid "Unable to reboot host machine as there are running virtual machines"
-msgstr ""
-"Hostmaschine konnte nicht neu gestartet werden, weil virtuelle Maschinen "
-"ausgef��hrt werden"
-
-#, python-format
-msgid "Node device '%(name)s' not found"
-msgstr "Knoteneinheit '%(name)s' nicht gefunden"
-
-msgid "Conflicting flag filters specified."
-msgstr ""
-
-msgid "No packages marked for update"
-msgstr "Keine Pakete f��r Aktualisierung markiert"
-
-#, python-format
-msgid "Package %(name)s is not marked to be updated."
-msgstr "Paket %(name)s ist nicht f��r Aktualisierung markiert."
-
-#, python-format
-msgid "Error while getting packages marked to be updated. Details: %(err)s"
-msgstr ""
-"Fehler beim Abrufen von Paketen, die f��r die Aktualsierung markiert sind. "
-"Details: %(err)s"
-
-msgid "There is no compatible package manager for this system."
-msgstr "Es gibt keinen kompatiblen Paketmanager f��r dieses System."
-
-#, python-format
-msgid "Invalid URI %(uri)s"
-msgstr "Ung��ltiger URI %(uri)s"
-
-msgid "Unable to choose a virtual machine name"
-msgstr ""
-
-msgid "Invalid storage type. Types supported: 'cdrom', 'disk'"
-msgstr "Ung��ltiger Speichertyp. Unterst��tzte Typen: 'cdrom'"
-
-#, python-format
-msgid "The path '%(value)s' is not a valid local/remote path for the
device"
-msgstr ""
-
-msgid "Only CDROM path can be update."
-msgstr ""
-
-#, python-format
-msgid ""
-"The storage device %(dev_name)s does not exist in the virtual machine %"
-"(vm_name)s"
-msgstr ""
-
-#, python-format
-msgid "Error while creating new storage device: %(error)s"
-msgstr "Fehler beim Erstellen einer neuen Speichereinheit: %(error)s"
-
-#, python-format
-msgid "Error while updating storage device: %(error)s"
-msgstr "Fehler beim Aktualisieren einer Speichereinheit: %(error)s"
-
-#, python-format
-msgid "Error while removing storage device: %(error)s"
-msgstr "Fehler beim Entfernen einer Speichereinheit: %(error)s"
-
-msgid "Do not support IDE device hot plug"
-msgstr ""
-
-msgid ""
-"Specify type and path or type and pool/volume to add a new virtual machine "
-"disk"
-msgstr ""
-"Geben Sie Typ und Pfad an, um einen neuen Datentr��ger f��r eine virtuelle "
-"Maschine hinzuzf��gen"
-
-msgid "Specify path to update virtual machine disk"
-msgstr ""
-"Geben Sie einen Pfad an, um die Platte der virtuellen Maschine zu "
-"aktualisieren"
-
-#, python-format
-msgid "Controller type %(type)s limitation of %(limit)s devices reached"
-msgstr ""
-
-#, python-format
-msgid "Cannot retrieve disk path information for given pool/volume: %(error)s"
-msgstr ""
-
-msgid "Volume already in use by other virtual machine."
-msgstr ""
-
-msgid ""
-"Only one of path or pool/volume can be specified to add a new virtual "
-"machine disk"
-msgstr ""
-"Geben Sie Typ und Pfad an, um einen neuen Datentr��ger f��r eine virtuelle "
-"Maschine hinzuzf��gen"
-
-#, python-format
-msgid ""
-"Volume chosen with format %(format)s does not fit in the storage type
%(type)"
-"s"
-msgstr ""
-
-msgid "YUM Repository ID must be one word only string."
-msgstr ""
-"YUM-Repository-ID darf nur ein aus einer Zeichenfolge bestehendes Wort sein."
-
-msgid "Repository URL must be an http://, ftp:// or file:// URL."
-msgstr "Repository-URL muss ein http://-, ftp://- oder file://-URL sein."
-
-msgid ""
-"Repository configuration is a dictionary with specific values according to "
-"repository type."
-msgstr ""
-"Repository-Konfiguration ist ein W��rterbuch mit bestimmten Werten "
-"hinsichtlich Repository-Typ."
-
-msgid "Distribution to DEB repository must be a string"
-msgstr "Verteilung an DEB-Repository muss eine Zeichenfolge sein"
-
-msgid "Components to DEB repository must be listed in a array"
-msgstr "Komponenten f��r DEB-Repository m��ssen in einem Array aufgelistet
sein"
-
-msgid "Components to DEB repository must be a string"
-msgstr "Komponenten f��r DEB-Repository m��ssen eine Zeichenfolge sein"
-
-msgid "Mirror list to repository must be a string"
-msgstr ""
-
-msgid "YUM Repository name must be string."
-msgstr "Name des YUM-Repositorys muss eine Zeichenfolge sein."
-
-msgid "GPG check must be a boolean value."
-msgstr "GPG-Pr��fung muss ein boolescher Wert sein."
-
-msgid "GPG key must be a URL pointing to the ASCII-armored file."
-msgstr "GPG-Schl��ssel muss ein URL sein, der auf die ASCII-Armor-Datei
zeigt."
-
-#, python-format
-msgid "Could not update repository %(repo_id)s."
-msgstr "Repository %(repo_id)s konnte nicht aktualisiert werden."
-
-#, python-format
-msgid "Repository %(repo_id)s does not exist."
-msgstr "Repository %(repo_id)s ist nicht vorhanden."
-
-msgid ""
-"Specify repository base URL, mirror list or metalink in order to create or "
-"update a YUM repository."
-msgstr ""
-
-msgid "Repository management tool was not recognized for your system."
-msgstr "Repository-Verwaltungstool wurde f��r Ihr System nicht erkannt."
-
-#, python-format
-msgid "Repository %(repo_id)s is already enabled."
-msgstr "Repository %(repo_id)s ist bereits aktiviert."
-
-#, python-format
-msgid "Repository %(repo_id)s is already disabled."
-msgstr "Repository %(repo_id)s ist bereits inaktiviert."
-
-#, python-format
-msgid "Could not remove repository %(repo_id)s."
-msgstr "Repository %(repo_id)s konnte nicht entfernt werden."
-
-#, python-format
-msgid "Could not write repository configuration file %(repo_file)s"
-msgstr ""
-"Repository-Konfigurationsdatei %(repo_file)s konnte nicht geschrieben werden"
-
-msgid "Specify repository distribution in order to create a DEB repository."
-msgstr ""
-"Geben Sie die Repository-Verteilung an, um ein DEB-Repository zu erstellen."
-
-#, python-format
-msgid "Could not enable repository %(repo_id)s."
-msgstr "Repository %(repo_id)s konnte nicht aktiviert werden."
-
-#, python-format
-msgid "Could not disable repository %(repo_id)s."
-msgstr "Repository %(repo_id)s konnte nicht inaktiviert werden."
-
-msgid "YUM Repository ID already exists"
-msgstr "YUM-Repository-ID ist bereits vorhanden"
-
-msgid "YUM Repository name must be a string"
-msgstr "YUM-Repository-Name muss eine Zeichenfolge sein"
-
-#, python-format
-msgid "Unable to list repositories. Details: '%(err)s'"
-msgstr "Repositorys konnten nicht aufgelistet werden. Details:
'%(err)s'"
-
-#, python-format
-msgid "Unable to retrieve repository information. Details: '%(err)s'"
-msgstr ""
-"Repository-Informationen konnten nicht abgerufen werden. Details:
'%(err)s'"
-
-#, python-format
-msgid "Unable to add repository. Details: '%(err)s'"
-msgstr "Repository konnte nicht hinzugef��gt werden. Details:
'%(err)s'"
-
-#, python-format
-msgid "Unable to remove repository. Details: '%(err)s'"
-msgstr "Repository konnte nicht entfernt werden. Details: '%(err)s'"
-
-#, python-format
-msgid ""
-"Configuration items: '%(items)s' are not supported by repository
manager"
-msgstr ""
-
-msgid "Repository metalink must be an http://, ftp:// or file:// URL."
-msgstr ""
-
-msgid "Cannot specify mirrorlist and metalink at the same time."
-msgstr ""
-
-#, python-format
-msgid ""
-"Virtual machine '%(vm)s' must be stopped before creating a snapshot of
it."
-msgstr ""
-
-#, python-format
-msgid ""
-"Unable to create snapshot '%(name)s' on virtual machine '%(vm)s'.
Details: %"
-"(err)s"
-msgstr ""
-
-#, python-format
-msgid "Snapshot '%(name)s' does not exist on virtual machine
'%(vm)s'."
-msgstr ""
-
-#, python-format
-msgid ""
-"Unable to retrieve snapshot '%(name)s' on virtual machine '%(vm)s'.
Details: "
-"%(err)s"
-msgstr ""
-
-#, python-format
-msgid "Unable to list snapshots on virtual machine '%(vm)s'. Details:
%(err)s"
-msgstr ""
-
-#, python-format
-msgid ""
-"Unable to delete snapshot '%(name)s' on virtual machine '%(vm)s'.
Details: %"
-"(err)s"
-msgstr ""
-
-#, python-format
-msgid ""
-"Unable to retrieve current snapshot of virtual machine '%(vm)s'. Details:
%"
-"(err)s"
-msgstr ""
-
-#, python-format
-msgid ""
-"Unable to revert virtual machine '%(vm)s' to snapshot '%(name)s'.
Details: %"
-"(err)s"
-msgstr ""
-
-#, python-format
-msgid ""
-"Unable to create snapshot of virtual machine '%(vm)s' because it contains a
"
-"disk with format '%(format)s'; only 'qcow2' is supported."
-msgstr ""
-
-msgid "The number of vCPUs is too large for this system."
-msgstr ""
-
-msgid "Invalid vCPU/topology combination."
-msgstr ""
-
-msgid "This host (or current configuration) does not allow CPU topology."
-msgstr ""
-
-msgid "ERROR CODE"
-msgstr "FEHLERCODE"
-
-msgid "REASON"
-msgstr "GRUND"
-
-msgid "STACK"
-msgstr "STACK"
-
-msgid "Go to Homepage"
-msgstr "Gehe zu Homepage"
-
-msgid "Create a New Virtual Machine"
-msgstr "Neue virtuelle Maschine erstellen"
-
-msgid "Virtual Machine Name"
-msgstr "Name der virtuellen Maschine"
-
-msgid ""
-"The name used to identify the virtual machine. If omitted, a name will be "
-"chosen based on the template used."
-msgstr ""
-"Der f��r die Kennzeichnung der virtuellen Maschine verwendete Name. Falls er
"
-"ausgelassen wird, wird ein Name anhand der verwendeten Vorlage ausgew��hlt."
-
-msgid "Template"
-msgstr "Vorlage"
-
-msgid "Please create a template first."
-msgstr "Erstellen Sie zun��chst eine Vorlage."
-
-msgid "Create a Template"
-msgstr "Vorlage erstellen"
-
-msgid "Please choose a template."
-msgstr "W��hlen Sie eine Vorlage aus."
-
-msgid "OS"
-msgstr "BS"
-
-msgid "OS Version"
-msgstr "BS-Version"
-
-msgid "CPUS"
-msgstr "CPUS"
-
-msgid "Memory"
-msgstr "Speicher"
-
-msgid "Create"
-msgstr "Erstellen"
-
-msgid "Creating..."
-msgstr ""
-
-msgid "Cancel"
-msgstr "Abbrechen"
-
-msgid "Edit Guest"
-msgstr "Gast bearbeiten"
-
-msgid "General"
-msgstr "Allgemein"
-
-msgid "Storage"
-msgstr "Speicher"
-
-msgid "Interface"
-msgstr "Schnittstelle"
-
-msgid "Permission"
-msgstr "Version"
-
-msgid "Host PCI Device"
-msgstr ""
-
-msgid "Snapshot"
-msgstr ""
-
-msgid "Name"
-msgstr "Name"
-
-msgid "CPUs"
-msgstr "CPUs"
-
-msgid "Memory (MB)"
-msgstr "Speicher"
-
-msgid "Icon"
-msgstr "Symbol"
-
-msgid "Device"
-msgstr "Einheitenname"
-
-msgid "Path"
-msgstr "NFS-Pfad"
-
-msgid "Network"
-msgstr "Netz"
-
-msgid "Type"
-msgstr "Typ"
-
-msgid "MAC Address"
-msgstr ""
-
-msgid "Available system users and groups"
-msgstr ""
-
-msgid "Selected system users and groups"
-msgstr ""
-
-msgid "User"
-msgstr ""
-
-msgid "All"
-msgstr "Alle"
-
-msgid "To Add"
-msgstr ""
-
-msgid "Added"
-msgstr ""
-
-msgid "filter"
-msgstr ""
-
-msgid "Product"
-msgstr ""
-
-msgid "Vendor"
-msgstr "Anbieter"
-
-msgid "Created"
-msgstr ""
-
-msgid "Save"
-msgstr "Speichern"
-
-msgid "Replace"
-msgstr "Ersetzen"
-
-msgid "Detach"
-msgstr "Abh��ngen"
-
-msgid "revert"
-msgstr ""
-
-msgid "Start"
-msgstr "Starten"
-
-msgid "Reset"
-msgstr "Zur��cksetzen"
-
-msgid "Pause"
-msgstr ""
-
-msgid "Resume"
-msgstr ""
-
-msgid "Power Off"
-msgstr ""
-
-msgid "Actions"
-msgstr "Aktionen"
-
-msgid "Connect"
-msgstr "Verbinden"
-
-msgid "Clone"
-msgstr ""
-
-msgid "Edit"
-msgstr "Bearbeiten"
-
-msgid "Shut Down"
-msgstr "Herunterfahren"
-
-msgid "Delete"
-msgstr "L��schen"
-
-msgid "CPU"
-msgstr "CPU"
-
-msgid "Disk I/O"
-msgstr "Platten-E/A"
-
-msgid "Network I/O"
-msgstr "Netz-E/A"
-
-msgid "Livetile"
-msgstr "Live Tile"
-
-msgid "No guests found."
-msgstr "Keine G��ste gefunden."
-
-msgid "Add a Storage Device to VM"
-msgstr "Speichereinheit zur virtuellen Maschine hinzuf��gen"
-
-msgid "Device Type"
-msgstr "Einheitentyp"
-
-msgid "The device type. Currently, \"cdrom\" and \"disk\" are
supported."
-msgstr "Der Einheitentyp. Derzeit wird nur \"cdrom\" unterst��tzt."
-
-msgid "Storage Pool"
-msgstr "Speicherpool"
-
-msgid "Storage pool which volume located in"
-msgstr "Speicherpoolpfad muss eine Zeichenfolge sein"
-
-msgid "Storage Volume"
-msgstr "Speicherpoolname"
-
-msgid "Storage volume to be attached"
-msgstr "Name des Speicherdatentr��gers muss eine Zeichenfolge sein"
-
-msgid "File Path"
-msgstr "Dateipfad"
-
-msgid "The ISO file path in the server for CDROM."
-msgstr "Der ISO-Dateipfad auf dem Server f��r die CD-ROM."
-
-msgid "Attach"
-msgstr "Anh��ngen"
-
-msgid "Shut down"
-msgstr "Herunterfahren"
-
-msgid "Restart"
-msgstr "Erneut starten"
-
-msgid "Basic Information"
-msgstr "Basisinformationen"
-
-msgid "OS Distro"
-msgstr "BS-Distro"
-
-msgid "OS Code Name"
-msgstr "BS-Codename"
-
-msgid "Processor"
-msgstr "Prozessor"
-
-msgid "CPU(s)"
-msgstr ""
-
-msgid "System Statistics"
-msgstr "Systemstatistik"
-
-msgid "Software Updates"
-msgstr "Software-Updates"
-
-msgid "Update Progress"
-msgstr "Aktualisierungsfortschritt"
-
-msgid "Repositories"
-msgstr "Repositorys"
-
-msgid "Debug Reports"
-msgstr "Debugberichte"
-
-msgid "The username or password you entered is incorrect. Please try again."
-msgstr ""
-"Der Benutzername oder das Kennwort, den bzw. das Sie eingegeben haben, ist "
-"falsch. Versuchen Sie es bitte erneut."
-
-msgid "This field is required."
-msgstr "Dieses Feld ist erforderlich."
-
-msgid "Log in"
-msgstr "Anmelden"
-
-msgid "Logging in..."
-msgstr "Wird angemeldet..."
-
-msgid "Host"
-msgstr "Host"
-
-msgid "Guests"
-msgstr "G��ste"
-
-msgid "Templates"
-msgstr "Vorlagen"
-
-msgid "Failed to get application configuration"
-msgstr "Anwendungskonfiguration konnte nicht abgerufen werden"
-
-msgid "This is not a valid Linux path"
-msgstr "Dies ist kein g��ltiger Linux-Pfad"
-
-msgid "This is not a valid URL."
-msgstr "Dies ist kein g��ltiger URL."
-
-msgid "No such data available."
-msgstr "Keine solchen Daten verf��gbar."
-
-msgid ""
-"Can not contact the host system. Verify the host system is up and that you "
-"have network connectivity to it. HTTP request response %1. "
-msgstr ""
-"Hostsystem kann nicht kontaktiert werden. Pr��fen Sie, ob das Hostsystem "
-"aktiv ist und obNetzkonnektivit��t besteht. HTTP-Anforderungsantwort %1. "
-
-msgid "Unable to read file."
-msgstr ""
-
-msgid "Error while uploading file."
-msgstr ""
-
-msgid "Delete Confirmation"
-msgstr "L��schbest��tigung"
-
-msgid "OK"
-msgstr "OK"
-
-msgid "Confirm"
-msgstr "Best��tigen"
-
-msgid "Warning"
-msgstr "Warnung"
-
-msgid "Cloning..."
-msgstr ""
-
-msgid "Loading..."
-msgstr "Wird geladen..."
-
-msgid "An error occurred while retrieving system information."
-msgstr ""
-
-msgid "Retry"
-msgstr "Wiederholen"
-
-msgid "Detailed message:"
-msgstr "Detaillierte Meldung:"
-
-msgid "No ISO found"
-msgstr ""
-
-msgid "This is not a valid ISO file."
-msgstr "Dies ist keine g��ltige ISO-Datei."
-
-msgid "This may take a long time. Do you want to continue?"
-msgstr "Dies wird einige Zeit dauern. M��chten Sie fortfahren?"
-
-msgid "This will permanently delete the template. Would you like to continue?"
-msgstr "Hiermit wird die Vorlage dauerhaft gel��scht. M��chten Sie
fortfahren?"
-
-msgid "Unable to shut down system as there are some virtual machines running!"
-msgstr ""
-"System konnte nicht heruntergefahren werden, weil einige virtuellen "
-"Maschinen ausgef��hrt werden!"
-
-msgid "Max:"
-msgstr "Max:"
-
-msgid "Utilization"
-msgstr "Auslastung"
-
-msgid "Available"
-msgstr "Verf��gbar"
-
-msgid "Read Rate"
-msgstr "Leserate"
-
-msgid "Write Rate"
-msgstr "Schreibrate"
-
-msgid "Received"
-msgstr "Empfangen"
-
-msgid "Sent"
-msgstr "Gesendet"
-
-msgid ""
-"Shutting down or restarting host will cause unsaved work lost. Continue to "
-"shut down/restarting?"
-msgstr ""
-"Durch das Herunterfahren oder Neustarten des Hosts k��nnen ungesicherte "
-"Arbeiten verloren gehen. M��chten Sie mit dem Herunterfahren/Neustarten "
-"fortfahren?"
-
-msgid ""
-"Repository will be removed permanently and can't be recovered. Do you want
"
-"to continue?"
-msgstr ""
-"Repository wird dauerhaft entfernt und kann nicht wiederhergestellt werden. "
-"M��chten Sie fortfahren?"
-
-msgid "ID"
-msgstr "ID"
-
-msgid "Base URL"
-msgstr "Basis-URL"
-
-msgid "Is Mirror"
-msgstr "Ist Spiegel"
-
-msgid "URL Args"
-msgstr "URL-Args"
-
-msgid "Enabled"
-msgstr "Aktiviert"
-
-msgid "GPG Check"
-msgstr "GPG-Pr��fung"
-
-msgid "GPG Key"
-msgstr "GPG-Schl��ssel"
-
-msgid "Add"
-msgstr "Hinzuf��gen"
-
-msgid "Remove"
-msgstr "Entfernen"
-
-msgid "Enable"
-msgstr "Aktivieren"
-
-msgid "Disable"
-msgstr "Inaktivieren"
-
-msgid "Package Name"
-msgstr "Paketname"
-
-msgid "Version"
-msgstr "Version"
-
-msgid "Architecture"
-msgstr "Architektur"
-
-msgid "Repository"
-msgstr "Repository"
-
-msgid "Update All"
-msgstr "Alle aktualisieren"
-
-msgid "Updating..."
-msgstr "Wird aktualisiert..."
-
-msgid "Failed to retrieve packages update information."
-msgstr ""
-
-msgid "Failed to update package(s)."
-msgstr "Pakete konnten nicht aktualisiert werden."
-
-msgid ""
-"Debug report will be removed permanently and can't be recovered. Do you want
"
-"to continue?"
-msgstr ""
-"Debugbericht wird dauerhaft entfernt und kann nicht wiederhergestellt "
-"werden. M��chten Sie fortfahren?"
-
-msgid "Generated Time"
-msgstr "Generierte Zeit"
-
-msgid "Generate"
-msgstr "Generieren"
-
-msgid "Generating..."
-msgstr "Wird generiert..."
-
-msgid "Rename"
-msgstr "Umbenennen"
-
-msgid "Download"
-msgstr "Herunterladen"
-
-msgid ""
-"Report name should contain only letters, digits, underscore ('_') and/or
"
-"hyphen ('-')."
-msgstr ""
-"Berichtsname darf nur Buchstaben, Zahlen und/oder Bindestriche ('-')
"
-"enthalten."
-
-msgid "Pending..."
-msgstr "Wird geladen..."
-
-msgid "Report name is the same as the original one."
-msgstr ""
-
-msgid ""
-"This will delete the virtual machine and its virtual disks. This operation "
-"cannot be undone. Would you like to continue?"
-msgstr ""
-"Hiermit werden die virtuelle Maschine und deren virtuellen Platten gel��scht.
"
-"Diese Operation kann nicht r��ckg��ngig gemacht werden. M��chten Sie
fortfahren?"
-
-msgid "Power off Confirmation"
-msgstr "L��schbest��tigung"
-
-msgid ""
-"This action may produce undesirable results, for example unflushed disk "
-"cache in the guest. Would you like to continue?"
-msgstr ""
-
-msgid "Reset Confirmation"
-msgstr "L��schbest��tigung"
-
-msgid ""
-"There is a risk of data loss caused by reset without the guest OS shutdown. "
-"Would you like to continue?"
-msgstr ""
-
-msgid "Shut Down Confirmation"
-msgstr "L��schbest��tigung"
-
-msgid "Note the guest OS may ignore this request. Would you like to continue?"
-msgstr "Hiermit wird die Vorlage dauerhaft gel��scht. M��chten Sie
fortfahren?"
-
-msgid "Virtual Machine delete Confirmation"
-msgstr ""
-
-msgid ""
-"This virtual machine is not persistent. Power Off will delete it. Continue?"
-msgstr ""
-
-msgid ""
-"When the target guest has SCSI or iSCSI volumes, they will be cloned on "
-"default storage pool. The same will happen when the target pool does not "
-"have enough space to clone the volumes. Do you want to continue?"
-msgstr ""
-
-msgid ""
-"This CDROM will be detached permanently and you can re-attach it. Continue "
-"to detach it?"
-msgstr ""
-"Diese CD-ROM wird dauerhaft abgeh��ngt und Sie k��nnen sie neu anh��ngen. "
-"M��chten Sie mit dem Abh��ngen fortfahren?"
-
-msgid "Attaching..."
-msgstr "Wird angeh��ngt..."
-
-msgid "Replacing..."
-msgstr "Wird ersetzt..."
-
-msgid "Successfully attached!"
-msgstr "Erfolgreich angeh��ngt!"
-
-msgid "Successfully replaced!"
-msgstr "Erfolgreich ersetzt!"
-
-msgid "Successfully detached!"
-msgstr "Erfolgreich abgeh��ngt!"
-
-msgid ""
-"This disk will be detached permanently and you can re-attach it. Continue to
"
-"detach it?"
-msgstr ""
-
-msgid "interface:"
-msgstr ""
-
-msgid "address:"
-msgstr ""
-
-msgid "link_type:"
-msgstr ""
-
-msgid "block:"
-msgstr ""
-
-msgid "drive_type:"
-msgstr ""
-
-msgid "model:"
-msgstr ""
-
-msgid "Affected devices:"
-msgstr ""
-
-msgid "The VLAN id must be between 1 and 4094."
-msgstr "Die VLAN-ID muss zwischen 1 und 4094 liegen."
-
-msgid "unavailable"
-msgstr "nicht verf��gbar"
-
-msgid ""
-"This action will interrupt network connectivity for any virtual machine that
"
-"depend on this network."
-msgstr ""
-"Diese Aktion unterbricht die Netzkonnektivit��t f��r jede virtuelle Maschine,
"
-"die von diesem Netz abh��ngt."
-
-msgid "Create a network"
-msgstr "Netz erstellen"
-
-msgid ""
-"This network is not persistent. Instead of stop, this action will "
-"permanently delete it. Would you like to continue?"
-msgstr ""
-"Dieser Speicherpool ist nicht permanent. Durch diese Aktion wird er nicht "
-"inaktiviert, sondern permanent gel��scht. M��chten Sie fortfahren?"
-
-msgid ""
-"The bridged VLAN tag may not work well with NetworkManager enabled. You "
-"should consider disabling it."
-msgstr ""
-
-msgid ""
-"This will permanently delete the storage pool. Would you like to continue?"
-msgstr ""
-"Hiermit wird der Speicherpool dauerhaft gel��scht. M��chten Sie fortfahren?"
-
-msgid "This storage pool is empty."
-msgstr "Dieser Speicherpool ist leer."
-
-msgid ""
-"It will format your disk and you will loose any data in there, are you sure "
-"to continue? "
-msgstr ""
-"Hiermit wird Ihre Platte formatiert und Sie verlieren s��mtliche Daten "
-"darauf. Sind Sie sicher, dass Sie fortfahren m��chten? "
-
-msgid "SCSI Fibre Channel"
-msgstr "SCSI-Fibre Channel"
-
-msgid "No SCSI adapters found."
-msgstr "Keine SCSI-Adapter gefunden."
-
-msgid "Loading iSCSI targets..."
-msgstr ""
-
-msgid "No iSCSI found. Please input one."
-msgstr ""
-
-msgid "Failed to load iSCSI targets."
-msgstr ""
-
-msgid "The storage pool name can not be blank."
-msgstr "Der Speicherpoolname darf nicht leer sein."
-
-msgid "The storage pool path can not be blank."
-msgstr "Der Speicherpoolpfad darf nicht leer sein."
-
-msgid "NFS server mount path can not be blank."
-msgstr "Der Mountpfad des NFS-Servers darf nicht leer sein."
-
-msgid "Invalid NFS mount path."
-msgstr "Ung��ltiger NFS-Mountpfad."
-
-msgid "No logical device selected."
-msgstr "Keine logische Einheit ausgew��hlt."
-
-msgid "The iSCSI target can not be blank."
-msgstr "Das iSCSI-Ziel darf nicht leer sein."
-
-msgid "Server name can not be blank."
-msgstr "Servername darf nicht leer sein."
-
-msgid "This is not a valid Server Name or IP. Please, modify it."
-msgstr ""
-
-msgid "Looking for available partitions ..."
-msgstr "Es wird nach verf��gbaren Partitionen gesucht..."
-
-msgid "No available partitions found."
-msgstr "Keine g��ltigen Partitionen gefunden."
-
-msgid ""
-"This storage pool is not persistent. Instead of deactivate, this action will
"
-"permanently delete it. Would you like to continue?"
-msgstr ""
-"Dieser Speicherpool ist nicht permanent. Durch diese Aktion wird er nicht "
-"inaktiviert, sondern permanent gel��scht. M��chten Sie fortfahren?"
-
-msgid "Unable to retrieve partitions information."
-msgstr ""
-"Repository-Informationen konnten nicht abgerufen werden. Details:
'%(err)s'"
-
-msgid "In progress..."
-msgstr ""
-
-msgid "Failed!"
-msgstr ""
-
-msgid "CDROM path needs to be a valid local/remote path and cannot be blank."
-msgstr ""
-
-msgid "Disk pool or volume cannot be blank."
-msgstr "Der Speicherpoolname darf nicht leer sein."
-
-msgid "Filter"
-msgstr ""
-
-msgid "Network Name"
-msgstr "Netzname"
-
-msgid "State"
-msgstr "Status"
-
-msgid "Network Type"
-msgstr "Netztyp"
-
-msgid "Address Space"
-msgstr "Adressraum"
-
-msgid "Name should not contain '/' and '\"'."
-msgstr "Ung��ltiger Speicherpoolname. Er darf nicht '/' enthalten."
-
-msgid "Isolated: no external network connection"
-msgstr "Isolatiert: keine physisische Netzverbindung"
-
-msgid "NAT: outbound physical network connection only"
-msgstr "NAT: nur ausgehende physische Netzverbindung"
-
-msgid "Bridged: Virtual machines are connected to physical network directly"
-msgstr ""
-"��berbr��ckt: Virtuelle Maschinen sind direkt mit physischem Netz verbunden"
-
-msgid "(No interfaces found)"
-msgstr ""
-
-msgid "Destination"
-msgstr "Ziel:"
-
-msgid "Enable VLAN"
-msgstr "Virtuelles LAN (VLAN) aktivieren:"
-
-msgid "VLAN ID"
-msgstr "VLAN-ID:"
-
-msgid "Stop"
-msgstr "Stoppen"
-
-msgid "Generate a New Debug Report"
-msgstr "Neuen Debugbericht erstellen"
-
-msgid "Report Name"
-msgstr "Berichtsname"
-
-msgid ""
-"The name used to identify the report. If omitted, a name will be chosen "
-"based on current time. Name can contain: letters, digits, underscore
(\"_\") "
-"and hyphen (\"-\")."
-msgstr ""
-"Der Name, mit dem der Bericht gekennzeichnet wird. Falls er ausgelassen "
-"wird, wird ein Name basierend auf der aktuellen Zeit ausgew��hlt. Der Name "
-"darf Buchstaben, Zahlen und Bindestriche (\"-\") enthalten."
-
-msgid "Rename a Debug Report"
-msgstr "Neuen Debugbericht erstellen"
-
-msgid ""
-"The name used to identify the report. Name can contain: letters, digits and "
-"hyphen (\"-\")."
-msgstr ""
-"Der Name, mit dem der Bericht gekennzeichnet wird. Falls er ausgelassen "
-"wird, wird ein Name basierend auf der aktuellen Zeit ausgew��hlt. Der Name "
-"darf Buchstaben, Zahlen und Bindestriche (\"-\") enthalten."
-
-msgid "Submit"
-msgstr ""
-
-msgid "Add a Repository"
-msgstr "Repository hinzuf��gen"
-
-msgid "Identifier"
-msgstr "Kennung"
-
-msgid "Single word, unique identifier for the repository."
-msgstr "Einzelnes Wort, eindeutige Kennung f��r das Repository."
-
-msgid "Textual name for the repository."
-msgstr "Textname f��r das Repository."
-
-msgid "URL"
-msgstr "URL"
-
-msgid "Required Field"
-msgstr "Erforderliches Feld"
-
-msgid "URL to the repository. Supported protocols are http, ftp, and file."
-msgstr "URL zum Repository. Unterst��tzte Protokolle sind http, ftp und file."
-
-msgid "Repository is a mirror"
-msgstr "Repository ist ein Spiegel."
-
-msgid "Distribution"
-msgstr "Verteilung"
-
-msgid "Distribution of the DEB repository."
-msgstr "Verteilung des DEB-Repositorys."
-
-msgid "Components"
-msgstr "Komponenten"
-
-msgid "List of components in DEB repository."
-msgstr "Liste der Komponenten im DEB-Repository."
-
-msgid "Edit Repository"
-msgstr "Repository bearbeiten"
-
-msgid "Mirror List URL"
-msgstr "Spiegellisten-URL"
-
-msgid "Yes"
-msgstr "Ja"
-
-msgid "No"
-msgstr "Nein"
-
-msgid "Capacity"
-msgstr "Kapazit��t"
-
-msgid "Allocated"
-msgstr "Zugeordnet"
-
-msgid "Location"
-msgstr "Position"
-
-msgid "Device path"
-msgstr "Einheitenpfad"
-
-msgid "active"
-msgstr "aktiv"
-
-msgid "inactive"
-msgstr "inaktiv"
-
-msgid "Deactivate"
-msgstr "Inaktivieren"
-
-msgid "Activate"
-msgstr "Aktivieren"
-
-msgid "Add Volume"
-msgstr ""
-
-msgid "Extend"
-msgstr ""
-
-msgid "Undefine"
-msgstr "Definition aufheben"
-
-msgid "Format"
-msgstr "Format:"
-
-msgid "Allocation"
-msgstr "Zuordnung:"
-
-msgid "Define a New Storage Pool"
-msgstr "Neuen Speicherpool definieren"
-
-msgid "Storage Pool Name"
-msgstr "Speicherpoolname"
-
-msgid ""
-"The name used to identify the storage pools, and it should not be empty."
-msgstr ""
-"Der Name, mit dem die Speicherpools gekennzeichnet werden. Er darf nicht "
-"leer sein."
-
-msgid "Storage Pool Type"
-msgstr "Speicherpooltyp"
-
-msgid "Storage Path"
-msgstr "Speicherpfad"
-
-msgid ""
-"The path of the Storage Pool. Each Storage Pool must have a unique path."
-msgstr ""
-"Der Pfad des Speicherpools. Jeder Speicherpool muss einen eindeutigen Pfad "
-"haben."
-
-msgid ""
-"Kimchi will try to create the directory when it does not already exist in "
-"your system."
-msgstr ""
-"Kimchi versucht, das Verzeichnis zu erstellen, wenn es noch nicht in Ihrem "
-"System vorhanden ist."
-
-msgid "NFS Server IP"
-msgstr "NFS-Server-IP"
-
-msgid "NFS server IP or hostname. It can be input or chosen from history."
-msgstr ""
-"IP oder Hostname des NFS-Servers. Diese(r) kann eingegeben oder aus dem "
-"Verlauf ausgew��hlt werden."
-
-msgid "NFS Path"
-msgstr "NFS-Pfad"
-
-msgid "The NFS exported path on NFS server."
-msgstr "Der NFS-Exportpfad auf dem NFS-Server."
-
-msgid "iSCSI Server"
-msgstr "iSCSI-Server"
-
-msgid "Server"
-msgstr "Server"
-
-msgid "Port"
-msgstr "Port"
-
-msgid "iSCSI server IP or hostname. It should not be empty."
-msgstr "IP oder Hostname des iSCSI-Servers. Diese(r) darf nicht leer sein."
-
-msgid "Target"
-msgstr "Ziel"
-
-msgid "The iSCSI target on iSCSI server"
-msgstr "Das iSCSI-Ziel auf dem iSCSI-Server"
-
-msgid "Add iSCSI Authentication"
-msgstr "iSCSI-Authentifizierung hinzuf��gen"
-
-msgid "iSCSI Authentication"
-msgstr "iSCSI-Authentifizierung"
-
-msgid "User Name"
-msgstr "Benutzername"
-
-msgid "Password"
-msgstr "Kennwort"
-
-msgid "SCSI Adapter"
-msgstr "SCSI-Adapter"
-
-msgid "Please, wait..."
-msgstr "Bitte warten..."
-
-msgid "Add a Volume to Storage Pool"
-msgstr ""
-
-msgid "Fetch from remote URL"
-msgstr ""
-
-msgid "Enter the remote URL here."
-msgstr ""
-
-msgid "Upload a file"
-msgstr ""
-
-msgid "Choose the file you want to upload."
-msgstr ""
-
-msgid "Add Template"
-msgstr "Vorlage hinzuf��gen"
-
-msgid "Where is the source media for this template? "
-msgstr "Wo ist der Quellendatentr��ger f��r diese Vorlage?"
-
-msgid "Local ISO Image"
-msgstr "Lokales ISO-Image"
-
-msgid "Local Image File"
-msgstr ""
-
-msgid "Remote ISO Image"
-msgstr "Fernes ISO-Image"
-
-msgid "Search ISOs"
-msgstr "ISOs suchen"
-
-msgid "The following ISOs are available:"
-msgstr "Die folgenden ISOs sind verf��gbar:"
-
-msgid "OS: "
-msgstr "BS: "
-
-msgid "Version: "
-msgstr "Version: "
-
-msgid "Size: "
-msgstr "Gr����e: "
-
-msgid "Search more ISOs"
-msgstr "Weitere ISOs suchen"
-
-msgid "Create Templates from Selected ISO"
-msgstr "Vorlagen aus ausgew��hltem ISO erstellen"
-
-msgid "I want to use a specific ISO file"
-msgstr "Ich m��chte eine bestimmte ISO-Datei verwenden"
-
-msgid "Loading default remote ISOs ..."
-msgstr "Standardm����ige ferne ISOs werden geladen ..."
-
-msgid "Arch: "
-msgstr "Arch: "
-
-msgid "I want to use a custom URL"
-msgstr "Ich m��chte einen benutzerdefinierten URL verwenden"
-
-msgid "Edit Template"
-msgstr "Vorlage bearbeiten"
-
-msgid "CDROM"
-msgstr "CD-ROM"
-
-msgid "Image File"
-msgstr ""
-
-msgid "Graphics"
-msgstr "Grafik"
-
-msgid "Disk(GB)"
-msgstr ""
-
-msgid "Disk Format"
-msgstr ""
-
-msgid "CPU Number"
-msgstr "CPU-Anzahl"
-
-msgid "Manually set CPU topology"
-msgstr ""
-
-msgid "Cores"
-msgstr ""
-
-msgid "Threads"
-msgstr ""
-
-msgid "No templates found."
-msgstr "Keine Vorlagen gefunden."
-
-#~ msgid "Delete is not allowed for %(resource)s"
-#~ msgstr "L��schen ist nicht zul��ssig f��r %(resource)s"
-
-#~ msgid "%(resource)s does not implement update method"
-#~ msgstr "%(resource)s implementiert keine Aktualisierungsmethode"
-
-#~ msgid "Create is not allowed for %(resource)s"
-#~ msgstr "Erstellen ist nicht zul��ssig f��r %(resource)s"
-
-#~ msgid "Unable to parse JSON request"
-#~ msgstr "JSON-Anfrage konnte nicht analysiert werden"
-
-#~ msgid "This API only supports JSON"
-#~ msgstr "Diese API unterst��tzt nur JSON"
-
-#~ msgid "Datastore is not initiated in the model object."
-#~ msgstr "Datenspeicher wird nicht im Modellobjekt initialisiert."
-
-#~ msgid "Unable to start task due error: %(err)s"
-#~ msgstr ""
-#~ "Task kann aufgrund des folgenden Fehlers nicht gestartet werden: %(err)s"
-
-#~ msgid ""
-#~ "Authentication failed for user '%(username)s'. [Error code:
%(code)s]"
-#~ msgstr ""
-#~ "Authentifizierung f��r Benutzer '%(username)s' fehlgeschlagen. "
-#~ "[Fehlercode: %(code)s]"
-
-#~ msgid "You are not authorized to access Kimchi"
-#~ msgstr "Sie sind nicht berechtigt, auf Kimchi zuzugreifen"
-
-#~ msgid "Specify %(item)s to login into Kimchi"
-#~ msgstr "Geben Sie %(item)s an, um sich bei Kimchi anzumelden"
-
-#~ msgid "Unable to find %(item)s in datastore"
-#~ msgstr "%(item)s konnten nicht im Datenspeicher gefunden werden"
-
-#~ msgid "Timeout while running command '%(cmd)s' after %(seconds)s
seconds"
-#~ msgstr ""
-#~ "Zeitlimit��berschreitung beim Ausf��hren des Befehls '%(cmd)s' nach
%"
-#~ "(seconds)s Sekunden"
-
-#~ msgid "Help"
-#~ msgstr "Hilfe"
-
-#~ msgid "About"
-#~ msgstr "Informationen"
-
-#~ msgid "Log out"
-#~ msgstr "Abmelden"
-
-#~ msgid "Version:"
-#~ msgstr "Version:"
diff --git a/plugins/kimchi/po/en_US.po b/plugins/kimchi/po/en_US.po
deleted file mode 100644
index a5d0d44..0000000
--- a/plugins/kimchi/po/en_US.po
+++ /dev/null
@@ -1,2075 +0,0 @@
-# English translations for kimchi package.
-# Copyright (C) 2013 ORGANIZATION
-# Adam Litke <agl(a)us.ibm.com>, 2013.
-#
-msgid ""
-msgstr ""
-"Project-Id-Version: kimchi 0.1\n"
-"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2015-07-01 16:11-0300\n"
-"PO-Revision-Date: 2013-07-11 17:32-0400\n"
-"Last-Translator: Cr��stian Viana <vianac(a)linux.vnet.ibm.com>\n"
-"Language-Team: English\n"
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
-"Content-Transfer-Encoding: 8bit\n"
-"Language: en_US\n"
-"Generated-By: pygettext.py 1.5\n"
-"Plural-Forms: nplurals=2; plural=(n != 1);\n"
-
-#, python-format
-msgid "Unknown parameter %(value)s"
-msgstr ""
-
-#, python-format
-msgid "Timeout of %(seconds)s seconds expired while running task
'%(task)s."
-msgstr ""
-
-#, python-format
-msgid "User %(user_id)s not found with given LDAP settings."
-msgstr ""
-
-msgid "Unknown \"_cap\" specified"
-msgstr ""
-
-msgid "\"_passthrough\" should be \"true\" or
\"false\""
-msgstr ""
-
-msgid "\"_passthrough_affected_by\" should be a device name string"
-msgstr ""
-
-#, python-format
-msgid "Error while getting block devices. Details: %(err)s"
-msgstr ""
-
-#, python-format
-msgid "Error while getting block device information for %(device)s."
-msgstr ""
-
-#, python-format
-msgid "Unable to find distro file: %(filename)s"
-msgstr ""
-
-#, python-format
-msgid ""
-"Unable to parse distro file: %(filename)s. Make sure, it is a JSON file."
-msgstr ""
-
-#, python-format
-msgid "Unable to login to iSCSI host target %(portal)s. Details: %(err)s"
-msgstr ""
-
-#, python-format
-msgid "Unable to login to iSCSI host %(host)s target %(target)s"
-msgstr ""
-
-#, python-format
-msgid "Unable to find ISO file %(filename)s"
-msgstr ""
-
-#, python-format
-msgid "The ISO file %(filename)s is not bootable"
-msgstr ""
-
-#, python-format
-msgid "The ISO file %(filename)s does not have a valid El Torito boot record"
-msgstr ""
-
-#, python-format
-msgid "Invalid El Torito validation entry in ISO %(filename)s"
-msgstr ""
-
-#, python-format
-msgid "Invalid El Torito boot indicator in ISO %(filename)s"
-msgstr ""
-
-#, python-format
-msgid "Unexpected volume type for primary volume in ISO %(filename)s"
-msgstr ""
-
-#, python-format
-msgid "Bad format while reading volume descriptor in ISO %(filename)s"
-msgstr ""
-
-#, python-format
-msgid ""
-"The hypervisor doesn't have permission to use this ISO %(filename)s. "
-"Consider moving it under /var/lib/libvirt, or set the search permission to "
-"file access control lists for '%(user)s' user if possible, or add the
'%"
-"(user)s' to the ISO path group, or (not recommended) 'chmod -R o+x "
-"'path_to_iso'.Details: %(err)s"
-msgstr ""
-
-msgid "An error occurred when probing image OS information."
-msgstr ""
-
-msgid "No OS information found in given image."
-msgstr ""
-
-#, python-format
-msgid "Unable to read image file %(filename)s"
-msgstr ""
-
-#, python-format
-msgid ""
-"Image file must be an existing file on system. %(filename)s is not a valid "
-"input."
-msgstr ""
-
-#, python-format
-msgid "Virtual machine %(name)s already exists"
-msgstr ""
-
-#, python-format
-msgid "Virtual machine %(name)s does not exist"
-msgstr ""
-
-#, python-format
-msgid ""
-"Unable to rename virtual machine %(name)s. The name %(new_name)s is already "
-"in use or the virtual machine is not powered off."
-msgstr ""
-
-#, python-format
-msgid "Unable to retrieve screenshot for stopped virtual machine %(name)s"
-msgstr ""
-
-msgid "Remote ISO image is not supported by this server."
-msgstr ""
-
-#, python-format
-msgid "Screenshot is not supported on virtual machine %(name)s"
-msgstr ""
-
-#, python-format
-msgid "Unable to create virtual machine %(name)s. Details: %(err)s"
-msgstr ""
-
-#, python-format
-msgid "Unable to update virtual machine %(name)s. Details: %(err)s"
-msgstr ""
-
-#, python-format
-msgid "Unable to retrieve virtual machine %(name)s. Details: %(err)s"
-msgstr ""
-
-#, python-format
-msgid "Unable to connect to powered off virtual machine %(name)s."
-msgstr ""
-
-msgid "Virtual machine name must be a string without slashes (/)"
-msgstr ""
-
-#, python-format
-msgid "Invalid template URI %(value)s specified for virtual machine"
-msgstr ""
-
-#, python-format
-msgid "Invalid storage pool URI %(value)s specified for virtual machine"
-msgstr ""
-
-msgid "Supported virtual machine graphics are Spice or VNC"
-msgstr ""
-
-msgid "Graphics address to listen on must be IPv4 or IPv6"
-msgstr ""
-
-msgid "Specify a template to create a virtual machine from"
-msgstr ""
-
-#, python-format
-msgid "Unable to start virtual machine %(name)s. Details: %(err)s"
-msgstr ""
-
-#, python-format
-msgid "Unable to power off virtual machine %(name)s. Details: %(err)s"
-msgstr ""
-
-#, python-format
-msgid "Unable to delete virtual machine %(name)s. Details: %(err)s"
-msgstr ""
-
-#, python-format
-msgid "Unable to reset virtual machine %(name)s. Details: %(err)s"
-msgstr ""
-
-msgid "User name list must be an array"
-msgstr ""
-
-msgid "User name must be a string"
-msgstr ""
-
-msgid "Group name list must be an array"
-msgstr ""
-
-msgid "Group name must be a string"
-msgstr ""
-
-#, python-format
-msgid "User(s) '%(users)s' do not exist"
-msgstr ""
-
-#, python-format
-msgid "Group(s) '%(groups)s' do not exist"
-msgstr ""
-
-#, python-format
-msgid "Unable to shutdown virtual machine %(name)s. Details: %(err)s"
-msgstr ""
-
-#, python-format
-msgid ""
-"Unable to get access metadata of virtual machine %(name)s. Details: %(err)s"
-msgstr ""
-
-msgid "The guest console password must be a string."
-msgstr ""
-
-msgid "The life time for the guest console password must be a number."
-msgstr ""
-
-#, python-format
-msgid "Virtual machine '%(name)s' must be stopped before cloning it."
-msgstr ""
-
-#, python-format
-msgid "Insufficient disk space to clone virtual machine '%(name)s'"
-msgstr ""
-
-#, python-format
-msgid "Unable to clone VM '%(name)s'. Details: %(err)s"
-msgstr ""
-
-#, python-format
-msgid "Invalid operation for non-persistent virtual machine %(name)s"
-msgstr ""
-
-#, python-format
-msgid "Cannot suspend VM '%(name)s' because it is not running."
-msgstr ""
-
-#, python-format
-msgid "Unable to suspend VM '%(name)s'. Details: %(err)s"
-msgstr ""
-
-#, python-format
-msgid "Cannot resume VM '%(name)s' because it is not paused."
-msgstr ""
-
-#, python-format
-msgid "Unable to resume VM '%(name)s'. Details: %(err)s"
-msgstr ""
-
-msgid "Memory assigned is higher then the maximum allowed in the host."
-msgstr ""
-
-#, python-format
-msgid ""
-"VM '%(name)s' does not support live memory update. Update the memory with
"
-"the machine offline to enable this feature."
-msgstr ""
-
-msgid "Only increase memory is allowed in active VMs"
-msgstr ""
-
-msgid ""
-"For live memory update, new memory value must be equal old memory value plus
"
-"multiples of 1024 Mib"
-msgstr ""
-
-msgid "There are not enough free slots of 1024 Mib in the guest."
-msgstr ""
-
-msgid ""
-"Host's libvirt version does not support memory devices. Libvirt must be >=
"
-"1.2.14"
-msgstr ""
-
-#, python-format
-msgid "Error attaching memory device. Details: %(error)s"
-msgstr ""
-
-#, python-format
-msgid ""
-"VM %(vmid)s does not contain directly assigned host device %(dev_name)s."
-msgstr ""
-
-#, python-format
-msgid "The host device %(dev_name)s is not allowed to directly assign to VM."
-msgstr ""
-
-msgid ""
-"No IOMMU groups found. Host PCI pass through needs IOMMU group to function "
-"correctly. Please enable Intel VT-d or AMD IOMMU in your BIOS, then verify "
-"the Kernel is compiled with IOMMU support. For Intel CPU, add intel_iommu=on
"
-"to your Kernel parameter in /boot/grub2/grub.conf. For AMD CPU, add iommu=pt
"
-"iommu=1."
-msgstr ""
-
-msgid "\"name\" should be a device name string"
-msgstr ""
-
-#, python-format
-msgid ""
-"The device %(name)s is probably in use by the host. Unable to attach it to "
-"the guest."
-msgstr ""
-
-#, python-format
-msgid "Interface %(iface)s does not exist in virtual machine %(name)s"
-msgstr ""
-
-#, python-format
-msgid ""
-"Network %(network)s specified for virtual machine %(name)s does not exist"
-msgstr ""
-
-msgid "Supported virtual machine interfaces type is only network"
-msgstr ""
-
-msgid "Network name for virtual machine interface must be a string"
-msgstr ""
-
-msgid "Invalid network model card specified for virtual machine interface"
-msgstr ""
-
-msgid "Specify type and network to add a new virtual machine interface"
-msgstr ""
-
-msgid "MAC Address must respect this format FF:FF:FF:FF:FF:FF"
-msgstr ""
-
-#, python-format
-msgid "MAC Address %(mac)s already exists in virtual machine %(name)s"
-msgstr ""
-
-msgid "Invalid MAC Address"
-msgstr ""
-
-msgid "Cannot change MAC address of a running virtual machine"
-msgstr ""
-
-#, python-format
-msgid "Template %(name)s already exists"
-msgstr ""
-
-#, python-format
-msgid ""
-"Network '%(network)s' specified for template %(template)s does not
exist"
-msgstr ""
-
-#, python-format
-msgid ""
-"Storage pool %(pool)s specified for template %(template)s does not exist"
-msgstr ""
-
-#, python-format
-msgid "Storage pool %(pool)s specified for template %(template)s is not
active"
-msgstr ""
-
-#, python-format
-msgid "Invalid parameter '%(param)s' specified for CDROM."
-msgstr ""
-
-#, python-format
-msgid "Network %(network)s specified for template %(template)s is not active"
-msgstr ""
-
-msgid "Template name must be a string"
-msgstr ""
-
-msgid "Template icon must be a path to the image"
-msgstr ""
-
-msgid "Template distribution must be a string"
-msgstr ""
-
-msgid "Template distribution version must be a string"
-msgstr ""
-
-msgid "The number of CPUs must be an integer greater than 0"
-msgstr ""
-
-msgid "Amount of memory (MB) must be an integer greater than 512"
-msgstr ""
-
-msgid "Template CDROM must be a local or remote ISO file"
-msgstr ""
-
-#, python-format
-msgid "Invalid storage pool URI %(value)s specified for template"
-msgstr ""
-
-msgid "Specify an ISO image as CDROM or a base image to create a template"
-msgstr ""
-
-msgid "All networks for the template must be specified in a list."
-msgstr ""
-
-msgid "Specify a volume to a template when storage pool is iSCSI or SCSI"
-msgstr ""
-
-#, python-format
-msgid "The volume %(volume)s is not in storage pool %(pool)s"
-msgstr ""
-
-#, python-format
-msgid "Unable to create template due error: %(err)s"
-msgstr ""
-
-#, python-format
-msgid "Unable to delete template due error: %(err)s"
-msgstr ""
-
-msgid "Disk size must be an integer greater than 1GB."
-msgstr ""
-
-msgid "Template base image must be a valid local image file"
-msgstr ""
-
-#, python-format
-msgid "Cannot identify base image %(path)s format"
-msgstr ""
-
-msgid ""
-"When specifying CPU topology, VCPUs must be a product of sockets, cores, and
"
-"threads."
-msgstr ""
-
-msgid ""
-"When specifying CPU topology, each element must be an integer greater than "
-"zero."
-msgstr ""
-
-msgid ""
-"Invalid disk image format. Valid formats: bochs, cloop, cow, dmg, qcow, "
-"qcow2, qed, raw, vmdk, vpc."
-msgstr ""
-
-#, python-format
-msgid "Storage pool %(name)s already exists"
-msgstr ""
-
-#, python-format
-msgid "Storage pool %(name)s does not exist"
-msgstr ""
-
-#, python-format
-msgid "Specify %(item)s in order to create the storage pool %(name)s"
-msgstr ""
-
-#, python-format
-msgid "Unable to delete active storage pool %(name)s"
-msgstr ""
-
-#, python-format
-msgid "Unable to list storage pools. Details: %(err)s"
-msgstr ""
-
-#, python-format
-msgid "Unable to create storage pool %(name)s. Details: %(err)s"
-msgstr ""
-
-#, python-format
-msgid ""
-"Unable to get number of storage volumes in storage pool %(name)s. Details: %"
-"(err)s"
-msgstr ""
-
-#, python-format
-msgid "Unable to activate storage pool %(name)s. Details: %(err)s"
-msgstr ""
-
-#, python-format
-msgid "Unable to deactivate storage pool %(name)s. Details: %(err)s"
-msgstr ""
-
-#, python-format
-msgid "Unable to delete storage pool %(name)s. Details: %(err)s"
-msgstr ""
-
-#, python-format
-msgid ""
-"Unable to create NFS Pool as export path %(path)s may block during mount"
-msgstr ""
-
-#, python-format
-msgid "Unable to create NFS Pool as export path %(path)s mount failed"
-msgstr ""
-
-#, python-format
-msgid "Unsupported storage pool type: %(type)s"
-msgstr ""
-
-#, python-format
-msgid "Error while retrieving storage pool XML to %(pool)s"
-msgstr ""
-
-msgid "Storage pool name must be a string without slashes (/)"
-msgstr ""
-
-msgid ""
-"Supported storage pool types are dir, netfs, logical, iscsi, isci and
kimchi-"
-"iso"
-msgstr ""
-
-msgid "Storage pool path must be a string"
-msgstr ""
-
-msgid "Storage pool host must be a IP or hostname"
-msgstr ""
-
-msgid "Storage pool device must be the absolute path to the block device"
-msgstr ""
-
-msgid "Storage pool devices parameter must be a list"
-msgstr ""
-
-msgid "Target IQN of an iSCSI pool must be a string"
-msgstr ""
-
-msgid "Port of a remote storage server must be an integer between 1 and 65535"
-msgstr ""
-
-msgid "iSCSI target username must be a string"
-msgstr ""
-
-msgid "iSCSI target password must be a string"
-msgstr ""
-
-msgid "Specify name and type to create a storage pool"
-msgstr ""
-
-#, python-format
-msgid ""
-"%(disk)s is not a valid disk/partition. Could not add it to the pool %(pool)"
-"s."
-msgstr ""
-
-#, python-format
-msgid "Unable to extend logical pool %(pool)s. Details: %(err)s"
-msgstr ""
-
-msgid "The parameter disks only can be updated for logical storage pool."
-msgstr ""
-
-msgid "The SCSI host adapter name must be a string."
-msgstr ""
-
-msgid "The storage pool kimchi_isos is reserved for internal use"
-msgstr ""
-
-#, python-format
-msgid ""
-"Unable to activate NFS storage pool %(name)s. NFS server %(server)s is "
-"unreachable."
-msgstr ""
-
-#, python-format
-msgid ""
-"Unable to deactivate NFS storage pool %(name)s. NFS server %(server)s is "
-"unreachable."
-msgstr ""
-
-#, python-format
-msgid ""
-"Unable to deactivate pool %(name)s as it is associated with some templates"
-msgstr ""
-
-#, python-format
-msgid "Unable to delete pool %(name)s as it is associated with some templates"
-msgstr ""
-
-#, python-format
-msgid ""
-"A volume group named '%(name)s' already exists. Please, choose another name
"
-"to create the logical pool."
-msgstr ""
-
-#, python-format
-msgid "Unable to update database with deep scan information due error:
%(err)s"
-msgstr ""
-
-#, python-format
-msgid "Storage volume %(name)s already exists"
-msgstr ""
-
-#, python-format
-msgid "Storage volume %(name)s does not exist in storage pool %(pool)s"
-msgstr ""
-
-#, python-format
-msgid ""
-"Unable to create storage volume %(volume)s because storage pool %(pool)s is "
-"not active"
-msgstr ""
-
-#, python-format
-msgid "Specify %(item)s in order to create storage volume %(volume)s"
-msgstr ""
-
-#, python-format
-msgid ""
-"Unable to list storage volumes because storage pool %(pool)s is not active"
-msgstr ""
-
-#, python-format
-msgid ""
-"Unable to create storage volume %(name)s in storage pool %(pool)s. Details:
%"
-"(err)s"
-msgstr ""
-
-#, python-format
-msgid ""
-"Unable to list storage volumes in storage pool %(pool)s. Details: %(err)s"
-msgstr ""
-
-#, python-format
-msgid "Unable to wipe storage volumes %(name)s. Details: %(err)s"
-msgstr ""
-
-#, python-format
-msgid "Unable to delete storage volume %(name)s. Details: %(err)s"
-msgstr ""
-
-#, python-format
-msgid "Unable to resize storage volume %(name)s. Details: %(err)s"
-msgstr ""
-
-#, python-format
-msgid "Storage type %(type)s does not support volume create and delete"
-msgstr ""
-
-msgid "Storage volume name must be a string"
-msgstr ""
-
-msgid "Storage volume allocation must be an integer number"
-msgstr ""
-
-msgid ""
-"Storage volume format not supported. Valid formats: bochs, cloop, cow, dmg, "
-"qcow, qcow2, qed, raw, vmdk, vpc."
-msgstr ""
-
-msgid "Storage volume requires a volume name"
-msgstr ""
-
-#, python-format
-msgid ""
-"Unable to update database with storage volume information due error: %(err)s"
-msgstr ""
-
-#, python-format
-msgid "Only one of parameter %(param)s can be specified"
-msgstr ""
-
-#, python-format
-msgid "Create volume from %(param)s is not supported"
-msgstr ""
-
-msgid "Storage volume capacity must be an integer number."
-msgstr ""
-
-msgid "Storage volume URL must be http://, https://, ftp:// or ftps://."
-msgstr ""
-
-#, python-format
-msgid "Unable to access file %(url)s. Please, check it."
-msgstr ""
-
-#, python-format
-msgid ""
-"Unable to clone storage volume '%(name)s' in pool '%(pool)s'.
Details: %(err)"
-"s"
-msgstr ""
-
-msgid "Specify chunk data and its size to upload a file."
-msgstr ""
-
-msgid "In order to upload a storage volume, specify the 'upload'
parameter."
-msgstr ""
-
-msgid ""
-"Unable to upload chunk data as it does not match with requested chunk size."
-msgstr ""
-
-#, python-format
-msgid "The storage volume %(vol)s is not under an upload process."
-msgstr ""
-
-msgid "The upload chunk data will exceed the storage volume size."
-msgstr ""
-
-#, python-format
-msgid "Unable to upload chunk data to storage volume. Details: %(err)s."
-msgstr ""
-
-#, python-format
-msgid "Interface %(name)s does not exist"
-msgstr ""
-
-#, python-format
-msgid "Network %(name)s already exists"
-msgstr ""
-
-#, python-format
-msgid "Network %(name)s does not exist"
-msgstr ""
-
-#, python-format
-msgid "Subnet %(subnet)s specified for network %(network)s is not valid."
-msgstr ""
-
-#, python-format
-msgid "Specify a network interface to create bridged network %(name)s"
-msgstr ""
-
-#, python-format
-msgid "Unable to delete active network %(name)s"
-msgstr ""
-
-#, python-format
-msgid "Interface %(iface)s specified for network %(network)s is already in
use"
-msgstr ""
-
-msgid "Interface should be bare NIC, bonding or bridge device."
-msgstr ""
-
-#, python-format
-msgid "Unable to create network %(name)s. Details: %(err)s"
-msgstr ""
-
-#, python-format
-msgid "Unable to find a free IP address for network '%(name)s'"
-msgstr ""
-
-#, python-format
-msgid "The interface %(iface)s already exists."
-msgstr ""
-
-msgid "Network name must be a string without slashes (/) or quotes (\")"
-msgstr ""
-
-msgid "Supported network types are isolated, NAT and bridge"
-msgstr ""
-
-msgid "Network subnet must be a string with IP address and prefix or netmask"
-msgstr ""
-
-msgid "Network interface must be a string"
-msgstr ""
-
-msgid "Network VLAN ID must be an integer between 1 and 4094"
-msgstr ""
-
-msgid "Specify name and type to create a Network"
-msgstr ""
-
-#, python-format
-msgid ""
-"Unable to delete network %(name)s. There are some virtual machines %(vms)s "
-"and/or templates linked to this network."
-msgstr ""
-
-#, python-format
-msgid ""
-"Unable to deactivate network %(name)s. There are some virtual machines
%(vms)"
-"s and/or templates linked to this network."
-msgstr ""
-
-#, python-format
-msgid "Bridge device %(name)s can not be the trunk device of a VLAN."
-msgstr ""
-
-#, python-format
-msgid "Failed to activate interface %(iface)s: %(err)s."
-msgstr ""
-
-#, python-format
-msgid ""
-"Failed to activate interface %(iface)s. Please check the physical link "
-"status."
-msgstr ""
-
-#, python-format
-msgid "Failed to start network %(name)s. Details: %(err)s"
-msgstr ""
-
-#, python-format
-msgid "Debug report %(name)s does not exist"
-msgstr ""
-
-msgid "Debug report tool not found in system"
-msgstr ""
-
-#, python-format
-msgid "Unable to create debug report %(name)s. Details: %(err)s."
-msgstr ""
-
-#, python-format
-msgid "Can not find any debug report with the given name %(name)s"
-msgstr ""
-
-#, python-format
-msgid "Unable to generate debug report %(name)s. Details: %(err)s"
-msgstr ""
-
-msgid "You should give a name for the debug report file."
-msgstr ""
-
-msgid ""
-"Debug report name must be a string. Only letters, digits, underscore ('_')
"
-"and hyphen ('-') are allowed."
-msgstr ""
-
-#, python-format
-msgid ""
-"The debug report with specified name \"%(name)s\" already exists. Please
use "
-"another one."
-msgstr ""
-
-#, python-format
-msgid "Storage server %(server)s was not used by Kimchi"
-msgstr ""
-
-#, python-format
-msgid "Distro '%(name)s' does not exist"
-msgstr ""
-
-#, python-format
-msgid "Partition %(name)s does not exist in the host"
-msgstr ""
-
-msgid "Unable to shutdown host machine as there are running virtual machines"
-msgstr ""
-
-msgid "Unable to reboot host machine as there are running virtual machines"
-msgstr ""
-
-#, python-format
-msgid "Node device '%(name)s' not found"
-msgstr ""
-
-msgid "Conflicting flag filters specified."
-msgstr ""
-
-msgid "No packages marked for update"
-msgstr ""
-
-#, python-format
-msgid "Package %(name)s is not marked to be updated."
-msgstr ""
-
-#, python-format
-msgid "Error while getting packages marked to be updated. Details: %(err)s"
-msgstr ""
-
-msgid "There is no compatible package manager for this system."
-msgstr ""
-
-#, python-format
-msgid "Invalid URI %(uri)s"
-msgstr ""
-
-msgid "Unable to choose a virtual machine name"
-msgstr ""
-
-msgid "Invalid storage type. Types supported: 'cdrom', 'disk'"
-msgstr ""
-
-#, python-format
-msgid "The path '%(value)s' is not a valid local/remote path for the
device"
-msgstr ""
-
-msgid "Only CDROM path can be update."
-msgstr ""
-
-#, python-format
-msgid ""
-"The storage device %(dev_name)s does not exist in the virtual machine %"
-"(vm_name)s"
-msgstr ""
-
-#, python-format
-msgid "Error while creating new storage device: %(error)s"
-msgstr ""
-
-#, python-format
-msgid "Error while updating storage device: %(error)s"
-msgstr ""
-
-#, python-format
-msgid "Error while removing storage device: %(error)s"
-msgstr ""
-
-msgid "Do not support IDE device hot plug"
-msgstr ""
-
-msgid ""
-"Specify type and path or type and pool/volume to add a new virtual machine "
-"disk"
-msgstr ""
-
-msgid "Specify path to update virtual machine disk"
-msgstr ""
-
-#, python-format
-msgid "Controller type %(type)s limitation of %(limit)s devices reached"
-msgstr ""
-
-#, python-format
-msgid "Cannot retrieve disk path information for given pool/volume: %(error)s"
-msgstr ""
-
-msgid "Volume already in use by other virtual machine."
-msgstr ""
-
-msgid ""
-"Only one of path or pool/volume can be specified to add a new virtual "
-"machine disk"
-msgstr ""
-
-#, python-format
-msgid ""
-"Volume chosen with format %(format)s does not fit in the storage type
%(type)"
-"s"
-msgstr ""
-
-msgid "YUM Repository ID must be one word only string."
-msgstr ""
-
-msgid "Repository URL must be an http://, ftp:// or file:// URL."
-msgstr ""
-
-msgid ""
-"Repository configuration is a dictionary with specific values according to "
-"repository type."
-msgstr ""
-
-msgid "Distribution to DEB repository must be a string"
-msgstr ""
-
-msgid "Components to DEB repository must be listed in a array"
-msgstr ""
-
-msgid "Components to DEB repository must be a string"
-msgstr ""
-
-msgid "Mirror list to repository must be a string"
-msgstr ""
-
-msgid "YUM Repository name must be string."
-msgstr ""
-
-msgid "GPG check must be a boolean value."
-msgstr ""
-
-msgid "GPG key must be a URL pointing to the ASCII-armored file."
-msgstr ""
-
-#, python-format
-msgid "Could not update repository %(repo_id)s."
-msgstr ""
-
-#, python-format
-msgid "Repository %(repo_id)s does not exist."
-msgstr ""
-
-msgid ""
-"Specify repository base URL, mirror list or metalink in order to create or "
-"update a YUM repository."
-msgstr ""
-
-msgid "Repository management tool was not recognized for your system."
-msgstr ""
-
-#, python-format
-msgid "Repository %(repo_id)s is already enabled."
-msgstr ""
-
-#, python-format
-msgid "Repository %(repo_id)s is already disabled."
-msgstr ""
-
-#, python-format
-msgid "Could not remove repository %(repo_id)s."
-msgstr ""
-
-#, python-format
-msgid "Could not write repository configuration file %(repo_file)s"
-msgstr ""
-
-msgid "Specify repository distribution in order to create a DEB repository."
-msgstr ""
-
-#, python-format
-msgid "Could not enable repository %(repo_id)s."
-msgstr ""
-
-#, python-format
-msgid "Could not disable repository %(repo_id)s."
-msgstr ""
-
-msgid "YUM Repository ID already exists"
-msgstr ""
-
-msgid "YUM Repository name must be a string"
-msgstr ""
-
-#, python-format
-msgid "Unable to list repositories. Details: '%(err)s'"
-msgstr ""
-
-#, python-format
-msgid "Unable to retrieve repository information. Details: '%(err)s'"
-msgstr ""
-
-#, python-format
-msgid "Unable to add repository. Details: '%(err)s'"
-msgstr ""
-
-#, python-format
-msgid "Unable to remove repository. Details: '%(err)s'"
-msgstr ""
-
-#, python-format
-msgid ""
-"Configuration items: '%(items)s' are not supported by repository
manager"
-msgstr ""
-
-msgid "Repository metalink must be an http://, ftp:// or file:// URL."
-msgstr ""
-
-msgid "Cannot specify mirrorlist and metalink at the same time."
-msgstr ""
-
-#, python-format
-msgid ""
-"Virtual machine '%(vm)s' must be stopped before creating a snapshot of
it."
-msgstr ""
-
-#, python-format
-msgid ""
-"Unable to create snapshot '%(name)s' on virtual machine '%(vm)s'.
Details: %"
-"(err)s"
-msgstr ""
-
-#, python-format
-msgid "Snapshot '%(name)s' does not exist on virtual machine
'%(vm)s'."
-msgstr ""
-
-#, python-format
-msgid ""
-"Unable to retrieve snapshot '%(name)s' on virtual machine '%(vm)s'.
Details: "
-"%(err)s"
-msgstr ""
-
-#, python-format
-msgid "Unable to list snapshots on virtual machine '%(vm)s'. Details:
%(err)s"
-msgstr ""
-
-#, python-format
-msgid ""
-"Unable to delete snapshot '%(name)s' on virtual machine '%(vm)s'.
Details: %"
-"(err)s"
-msgstr ""
-
-#, python-format
-msgid ""
-"Unable to retrieve current snapshot of virtual machine '%(vm)s'. Details:
%"
-"(err)s"
-msgstr ""
-
-#, python-format
-msgid ""
-"Unable to revert virtual machine '%(vm)s' to snapshot '%(name)s'.
Details: %"
-"(err)s"
-msgstr ""
-
-#, python-format
-msgid ""
-"Unable to create snapshot of virtual machine '%(vm)s' because it contains a
"
-"disk with format '%(format)s'; only 'qcow2' is supported."
-msgstr ""
-
-msgid "The number of vCPUs is too large for this system."
-msgstr ""
-
-msgid "Invalid vCPU/topology combination."
-msgstr ""
-
-msgid "This host (or current configuration) does not allow CPU topology."
-msgstr ""
-
-msgid "ERROR CODE"
-msgstr ""
-
-msgid "REASON"
-msgstr ""
-
-msgid "STACK"
-msgstr ""
-
-msgid "Go to Homepage"
-msgstr ""
-
-msgid "Create a New Virtual Machine"
-msgstr ""
-
-msgid "Virtual Machine Name"
-msgstr ""
-
-msgid ""
-"The name used to identify the virtual machine. If omitted, a name will be "
-"chosen based on the template used."
-msgstr ""
-
-msgid "Template"
-msgstr ""
-
-msgid "Please create a template first."
-msgstr ""
-
-msgid "Create a Template"
-msgstr ""
-
-msgid "Please choose a template."
-msgstr ""
-
-msgid "OS"
-msgstr ""
-
-msgid "OS Version"
-msgstr ""
-
-msgid "CPUS"
-msgstr ""
-
-msgid "Memory"
-msgstr ""
-
-msgid "Create"
-msgstr ""
-
-msgid "Creating..."
-msgstr ""
-
-msgid "Cancel"
-msgstr ""
-
-msgid "Edit Guest"
-msgstr ""
-
-msgid "General"
-msgstr ""
-
-msgid "Storage"
-msgstr ""
-
-msgid "Interface"
-msgstr ""
-
-msgid "Permission"
-msgstr ""
-
-msgid "Host PCI Device"
-msgstr ""
-
-msgid "Snapshot"
-msgstr ""
-
-msgid "Name"
-msgstr ""
-
-msgid "CPUs"
-msgstr ""
-
-msgid "Memory (MB)"
-msgstr ""
-
-msgid "Icon"
-msgstr ""
-
-msgid "Device"
-msgstr ""
-
-msgid "Path"
-msgstr ""
-
-msgid "Network"
-msgstr ""
-
-msgid "Type"
-msgstr ""
-
-msgid "MAC Address"
-msgstr ""
-
-msgid "Available system users and groups"
-msgstr ""
-
-msgid "Selected system users and groups"
-msgstr ""
-
-msgid "User"
-msgstr ""
-
-msgid "All"
-msgstr ""
-
-msgid "To Add"
-msgstr ""
-
-msgid "Added"
-msgstr ""
-
-msgid "filter"
-msgstr ""
-
-msgid "Product"
-msgstr ""
-
-msgid "Vendor"
-msgstr ""
-
-msgid "Created"
-msgstr ""
-
-msgid "Save"
-msgstr ""
-
-msgid "Replace"
-msgstr ""
-
-msgid "Detach"
-msgstr ""
-
-msgid "revert"
-msgstr ""
-
-msgid "Start"
-msgstr ""
-
-msgid "Reset"
-msgstr ""
-
-msgid "Pause"
-msgstr ""
-
-msgid "Resume"
-msgstr ""
-
-msgid "Power Off"
-msgstr ""
-
-msgid "Actions"
-msgstr ""
-
-msgid "Connect"
-msgstr ""
-
-msgid "Clone"
-msgstr ""
-
-msgid "Edit"
-msgstr ""
-
-msgid "Shut Down"
-msgstr ""
-
-msgid "Delete"
-msgstr ""
-
-msgid "CPU"
-msgstr ""
-
-msgid "Disk I/O"
-msgstr ""
-
-msgid "Network I/O"
-msgstr ""
-
-msgid "Livetile"
-msgstr ""
-
-msgid "No guests found."
-msgstr ""
-
-msgid "Add a Storage Device to VM"
-msgstr ""
-
-msgid "Device Type"
-msgstr ""
-
-msgid "The device type. Currently, \"cdrom\" and \"disk\" are
supported."
-msgstr ""
-
-msgid "Storage Pool"
-msgstr ""
-
-msgid "Storage pool which volume located in"
-msgstr ""
-
-msgid "Storage Volume"
-msgstr ""
-
-msgid "Storage volume to be attached"
-msgstr ""
-
-msgid "File Path"
-msgstr ""
-
-msgid "The ISO file path in the server for CDROM."
-msgstr ""
-
-msgid "Attach"
-msgstr ""
-
-msgid "Shut down"
-msgstr ""
-
-msgid "Restart"
-msgstr ""
-
-msgid "Basic Information"
-msgstr ""
-
-msgid "OS Distro"
-msgstr ""
-
-msgid "OS Code Name"
-msgstr ""
-
-msgid "Processor"
-msgstr ""
-
-msgid "CPU(s)"
-msgstr ""
-
-msgid "System Statistics"
-msgstr ""
-
-msgid "Software Updates"
-msgstr ""
-
-msgid "Update Progress"
-msgstr ""
-
-msgid "Repositories"
-msgstr ""
-
-msgid "Debug Reports"
-msgstr ""
-
-msgid "The username or password you entered is incorrect. Please try again."
-msgstr ""
-
-msgid "This field is required."
-msgstr ""
-
-msgid "Log in"
-msgstr ""
-
-msgid "Logging in..."
-msgstr ""
-
-msgid "Host"
-msgstr ""
-
-msgid "Guests"
-msgstr ""
-
-msgid "Templates"
-msgstr ""
-
-msgid "Failed to get application configuration"
-msgstr ""
-
-msgid "This is not a valid Linux path"
-msgstr ""
-
-msgid "This is not a valid URL."
-msgstr ""
-
-msgid "No such data available."
-msgstr ""
-
-msgid ""
-"Can not contact the host system. Verify the host system is up and that you "
-"have network connectivity to it. HTTP request response %1. "
-msgstr ""
-
-msgid "Unable to read file."
-msgstr ""
-
-msgid "Error while uploading file."
-msgstr ""
-
-msgid "Delete Confirmation"
-msgstr ""
-
-msgid "OK"
-msgstr ""
-
-msgid "Confirm"
-msgstr ""
-
-msgid "Warning"
-msgstr ""
-
-msgid "Cloning..."
-msgstr ""
-
-msgid "Loading..."
-msgstr ""
-
-msgid "An error occurred while retrieving system information."
-msgstr ""
-
-msgid "Retry"
-msgstr ""
-
-msgid "Detailed message:"
-msgstr ""
-
-msgid "No ISO found"
-msgstr ""
-
-msgid "This is not a valid ISO file."
-msgstr ""
-
-msgid "This may take a long time. Do you want to continue?"
-msgstr ""
-
-msgid "This will permanently delete the template. Would you like to continue?"
-msgstr ""
-
-msgid "Unable to shut down system as there are some virtual machines running!"
-msgstr ""
-
-msgid "Max:"
-msgstr ""
-
-msgid "Utilization"
-msgstr ""
-
-msgid "Available"
-msgstr ""
-
-msgid "Read Rate"
-msgstr ""
-
-msgid "Write Rate"
-msgstr ""
-
-msgid "Received"
-msgstr ""
-
-msgid "Sent"
-msgstr ""
-
-msgid ""
-"Shutting down or restarting host will cause unsaved work lost. Continue to "
-"shut down/restarting?"
-msgstr ""
-
-msgid ""
-"Repository will be removed permanently and can't be recovered. Do you want
"
-"to continue?"
-msgstr ""
-
-msgid "ID"
-msgstr ""
-
-msgid "Base URL"
-msgstr ""
-
-msgid "Is Mirror"
-msgstr ""
-
-msgid "URL Args"
-msgstr ""
-
-msgid "Enabled"
-msgstr ""
-
-msgid "GPG Check"
-msgstr ""
-
-msgid "GPG Key"
-msgstr ""
-
-msgid "Add"
-msgstr ""
-
-msgid "Remove"
-msgstr ""
-
-msgid "Enable"
-msgstr ""
-
-msgid "Disable"
-msgstr ""
-
-msgid "Package Name"
-msgstr ""
-
-msgid "Version"
-msgstr ""
-
-msgid "Architecture"
-msgstr ""
-
-msgid "Repository"
-msgstr ""
-
-msgid "Update All"
-msgstr ""
-
-msgid "Updating..."
-msgstr ""
-
-msgid "Failed to retrieve packages update information."
-msgstr ""
-
-msgid "Failed to update package(s)."
-msgstr ""
-
-msgid ""
-"Debug report will be removed permanently and can't be recovered. Do you want
"
-"to continue?"
-msgstr ""
-
-msgid "Generated Time"
-msgstr ""
-
-msgid "Generate"
-msgstr ""
-
-msgid "Generating..."
-msgstr ""
-
-msgid "Rename"
-msgstr ""
-
-msgid "Download"
-msgstr ""
-
-msgid ""
-"Report name should contain only letters, digits, underscore ('_') and/or
"
-"hyphen ('-')."
-msgstr ""
-
-msgid "Pending..."
-msgstr ""
-
-msgid "Report name is the same as the original one."
-msgstr ""
-
-msgid ""
-"This will delete the virtual machine and its virtual disks. This operation "
-"cannot be undone. Would you like to continue?"
-msgstr ""
-
-msgid "Power off Confirmation"
-msgstr ""
-
-msgid ""
-"This action may produce undesirable results, for example unflushed disk "
-"cache in the guest. Would you like to continue?"
-msgstr ""
-
-msgid "Reset Confirmation"
-msgstr ""
-
-msgid ""
-"There is a risk of data loss caused by reset without the guest OS shutdown. "
-"Would you like to continue?"
-msgstr ""
-
-msgid "Shut Down Confirmation"
-msgstr ""
-
-msgid "Note the guest OS may ignore this request. Would you like to continue?"
-msgstr ""
-
-msgid "Virtual Machine delete Confirmation"
-msgstr ""
-
-msgid ""
-"This virtual machine is not persistent. Power Off will delete it. Continue?"
-msgstr ""
-
-msgid ""
-"When the target guest has SCSI or iSCSI volumes, they will be cloned on "
-"default storage pool. The same will happen when the target pool does not "
-"have enough space to clone the volumes. Do you want to continue?"
-msgstr ""
-
-msgid ""
-"This CDROM will be detached permanently and you can re-attach it. Continue "
-"to detach it?"
-msgstr ""
-
-msgid "Attaching..."
-msgstr ""
-
-msgid "Replacing..."
-msgstr ""
-
-msgid "Successfully attached!"
-msgstr ""
-
-msgid "Successfully replaced!"
-msgstr ""
-
-msgid "Successfully detached!"
-msgstr ""
-
-msgid ""
-"This disk will be detached permanently and you can re-attach it. Continue to
"
-"detach it?"
-msgstr ""
-
-msgid "interface:"
-msgstr ""
-
-msgid "address:"
-msgstr ""
-
-msgid "link_type:"
-msgstr ""
-
-msgid "block:"
-msgstr ""
-
-msgid "drive_type:"
-msgstr ""
-
-msgid "model:"
-msgstr ""
-
-msgid "Affected devices:"
-msgstr ""
-
-msgid "The VLAN id must be between 1 and 4094."
-msgstr ""
-
-msgid "unavailable"
-msgstr ""
-
-msgid ""
-"This action will interrupt network connectivity for any virtual machine that
"
-"depend on this network."
-msgstr ""
-
-msgid "Create a network"
-msgstr ""
-
-msgid ""
-"This network is not persistent. Instead of stop, this action will "
-"permanently delete it. Would you like to continue?"
-msgstr ""
-
-msgid ""
-"The bridged VLAN tag may not work well with NetworkManager enabled. You "
-"should consider disabling it."
-msgstr ""
-
-msgid ""
-"This will permanently delete the storage pool. Would you like to continue?"
-msgstr ""
-
-msgid "This storage pool is empty."
-msgstr ""
-
-msgid ""
-"It will format your disk and you will loose any data in there, are you sure "
-"to continue? "
-msgstr ""
-
-msgid "SCSI Fibre Channel"
-msgstr ""
-
-msgid "No SCSI adapters found."
-msgstr ""
-
-msgid "Loading iSCSI targets..."
-msgstr ""
-
-msgid "No iSCSI found. Please input one."
-msgstr ""
-
-msgid "Failed to load iSCSI targets."
-msgstr ""
-
-msgid "The storage pool name can not be blank."
-msgstr ""
-
-msgid "The storage pool path can not be blank."
-msgstr ""
-
-msgid "NFS server mount path can not be blank."
-msgstr ""
-
-msgid "Invalid NFS mount path."
-msgstr ""
-
-msgid "No logical device selected."
-msgstr ""
-
-msgid "The iSCSI target can not be blank."
-msgstr ""
-
-msgid "Server name can not be blank."
-msgstr ""
-
-msgid "This is not a valid Server Name or IP. Please, modify it."
-msgstr ""
-
-msgid "Looking for available partitions ..."
-msgstr ""
-
-msgid "No available partitions found."
-msgstr ""
-
-msgid ""
-"This storage pool is not persistent. Instead of deactivate, this action will
"
-"permanently delete it. Would you like to continue?"
-msgstr ""
-
-msgid "Unable to retrieve partitions information."
-msgstr ""
-
-msgid "In progress..."
-msgstr ""
-
-msgid "Failed!"
-msgstr ""
-
-msgid "CDROM path needs to be a valid local/remote path and cannot be blank."
-msgstr ""
-
-msgid "Disk pool or volume cannot be blank."
-msgstr ""
-
-msgid "Filter"
-msgstr ""
-
-msgid "Network Name"
-msgstr ""
-
-msgid "State"
-msgstr ""
-
-msgid "Network Type"
-msgstr ""
-
-msgid "Address Space"
-msgstr ""
-
-msgid "Name should not contain '/' and '\"'."
-msgstr ""
-
-msgid "Isolated: no external network connection"
-msgstr ""
-
-msgid "NAT: outbound physical network connection only"
-msgstr ""
-
-msgid "Bridged: Virtual machines are connected to physical network directly"
-msgstr ""
-
-msgid "(No interfaces found)"
-msgstr ""
-
-msgid "Destination"
-msgstr ""
-
-msgid "Enable VLAN"
-msgstr ""
-
-msgid "VLAN ID"
-msgstr ""
-
-msgid "Stop"
-msgstr ""
-
-msgid "Generate a New Debug Report"
-msgstr ""
-
-msgid "Report Name"
-msgstr ""
-
-msgid ""
-"The name used to identify the report. If omitted, a name will be chosen "
-"based on current time. Name can contain: letters, digits, underscore
(\"_\") "
-"and hyphen (\"-\")."
-msgstr ""
-
-msgid "Rename a Debug Report"
-msgstr ""
-
-msgid ""
-"The name used to identify the report. Name can contain: letters, digits and "
-"hyphen (\"-\")."
-msgstr ""
-
-msgid "Submit"
-msgstr ""
-
-msgid "Add a Repository"
-msgstr ""
-
-msgid "Identifier"
-msgstr ""
-
-msgid "Single word, unique identifier for the repository."
-msgstr ""
-
-msgid "Textual name for the repository."
-msgstr ""
-
-msgid "URL"
-msgstr ""
-
-msgid "Required Field"
-msgstr ""
-
-msgid "URL to the repository. Supported protocols are http, ftp, and file."
-msgstr ""
-
-msgid "Repository is a mirror"
-msgstr ""
-
-msgid "Distribution"
-msgstr ""
-
-msgid "Distribution of the DEB repository."
-msgstr ""
-
-msgid "Components"
-msgstr ""
-
-msgid "List of components in DEB repository."
-msgstr ""
-
-msgid "Edit Repository"
-msgstr ""
-
-msgid "Mirror List URL"
-msgstr ""
-
-msgid "Yes"
-msgstr ""
-
-msgid "No"
-msgstr ""
-
-msgid "Capacity"
-msgstr ""
-
-msgid "Allocated"
-msgstr ""
-
-msgid "Location"
-msgstr ""
-
-msgid "Device path"
-msgstr ""
-
-msgid "active"
-msgstr ""
-
-msgid "inactive"
-msgstr ""
-
-msgid "Deactivate"
-msgstr ""
-
-msgid "Activate"
-msgstr ""
-
-msgid "Add Volume"
-msgstr ""
-
-msgid "Extend"
-msgstr ""
-
-msgid "Undefine"
-msgstr ""
-
-msgid "Format"
-msgstr ""
-
-msgid "Allocation"
-msgstr ""
-
-msgid "Define a New Storage Pool"
-msgstr ""
-
-msgid "Storage Pool Name"
-msgstr ""
-
-msgid ""
-"The name used to identify the storage pools, and it should not be empty."
-msgstr ""
-
-msgid "Storage Pool Type"
-msgstr ""
-
-msgid "Storage Path"
-msgstr ""
-
-msgid ""
-"The path of the Storage Pool. Each Storage Pool must have a unique path."
-msgstr ""
-
-msgid ""
-"Kimchi will try to create the directory when it does not already exist in "
-"your system."
-msgstr ""
-
-msgid "NFS Server IP"
-msgstr ""
-
-msgid "NFS server IP or hostname. It can be input or chosen from history."
-msgstr ""
-
-msgid "NFS Path"
-msgstr ""
-
-msgid "The NFS exported path on NFS server."
-msgstr ""
-
-msgid "iSCSI Server"
-msgstr ""
-
-msgid "Server"
-msgstr ""
-
-msgid "Port"
-msgstr ""
-
-msgid "iSCSI server IP or hostname. It should not be empty."
-msgstr ""
-
-msgid "Target"
-msgstr ""
-
-msgid "The iSCSI target on iSCSI server"
-msgstr ""
-
-msgid "Add iSCSI Authentication"
-msgstr ""
-
-msgid "iSCSI Authentication"
-msgstr ""
-
-msgid "User Name"
-msgstr ""
-
-msgid "Password"
-msgstr ""
-
-msgid "SCSI Adapter"
-msgstr ""
-
-msgid "Please, wait..."
-msgstr ""
-
-msgid "Add a Volume to Storage Pool"
-msgstr ""
-
-msgid "Fetch from remote URL"
-msgstr ""
-
-msgid "Enter the remote URL here."
-msgstr ""
-
-msgid "Upload a file"
-msgstr ""
-
-msgid "Choose the file you want to upload."
-msgstr ""
-
-msgid "Add Template"
-msgstr ""
-
-msgid "Where is the source media for this template? "
-msgstr ""
-
-msgid "Local ISO Image"
-msgstr ""
-
-msgid "Local Image File"
-msgstr ""
-
-msgid "Remote ISO Image"
-msgstr ""
-
-msgid "Search ISOs"
-msgstr ""
-
-msgid "The following ISOs are available:"
-msgstr ""
-
-msgid "OS: "
-msgstr ""
-
-msgid "Version: "
-msgstr ""
-
-msgid "Size: "
-msgstr ""
-
-msgid "Search more ISOs"
-msgstr ""
-
-msgid "Create Templates from Selected ISO"
-msgstr ""
-
-msgid "I want to use a specific ISO file"
-msgstr ""
-
-msgid "Loading default remote ISOs ..."
-msgstr ""
-
-msgid "Arch: "
-msgstr ""
-
-msgid "I want to use a custom URL"
-msgstr ""
-
-msgid "Edit Template"
-msgstr ""
-
-msgid "CDROM"
-msgstr ""
-
-msgid "Image File"
-msgstr ""
-
-msgid "Graphics"
-msgstr ""
-
-msgid "Disk(GB)"
-msgstr ""
-
-msgid "Disk Format"
-msgstr ""
-
-msgid "CPU Number"
-msgstr ""
-
-msgid "Manually set CPU topology"
-msgstr ""
-
-msgid "Cores"
-msgstr ""
-
-msgid "Threads"
-msgstr ""
-
-msgid "No templates found."
-msgstr ""
diff --git a/plugins/kimchi/po/es_ES.po b/plugins/kimchi/po/es_ES.po
deleted file mode 100644
index d71e621..0000000
--- a/plugins/kimchi/po/es_ES.po
+++ /dev/null
@@ -1,2305 +0,0 @@
-# English translations for kimchi package.
-# Copyright (C) 2013 ORGANIZATION
-#
-msgid ""
-msgstr ""
-"Project-Id-Version: kimchi 0.1\n"
-"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2015-07-01 16:11-0300\n"
-"PO-Revision-Date: 2013-07-11 17:32-0400\n"
-"Last-Translator: Cr��stian Viana <vianac(a)linux.vnet.ibm.com>\n"
-"Language-Team: English\n"
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
-"Content-Transfer-Encoding: 8bit\n"
-"Language: es_ES\n"
-"Generated-By: pygettext.py 1.5\n"
-"Plural-Forms: nplurals=2; plural=(n != 1);\n"
-
-#, python-format
-msgid "Unknown parameter %(value)s"
-msgstr ""
-
-#, python-format
-msgid "Timeout of %(seconds)s seconds expired while running task
'%(task)s."
-msgstr ""
-
-#, python-format
-msgid "User %(user_id)s not found with given LDAP settings."
-msgstr ""
-
-msgid "Unknown \"_cap\" specified"
-msgstr ""
-
-msgid "\"_passthrough\" should be \"true\" or
\"false\""
-msgstr ""
-
-msgid "\"_passthrough_affected_by\" should be a device name string"
-msgstr ""
-
-#, python-format
-msgid "Error while getting block devices. Details: %(err)s"
-msgstr ""
-"Se ha producido un error al obtener dispositivos de bloque. Detalles:
%(err)s"
-
-#, python-format
-msgid "Error while getting block device information for %(device)s."
-msgstr ""
-"Se ha producido un error al obtener informaci��n de dispositivo de bloque "
-"para %(device)s."
-
-#, python-format
-msgid "Unable to find distro file: %(filename)s"
-msgstr "No se puede encontrar el archivo distro: %(filename)s"
-
-#, python-format
-msgid ""
-"Unable to parse distro file: %(filename)s. Make sure, it is a JSON file."
-msgstr ""
-"No se puede analizar el archivo distro: %(filename)s. Aseg��rese de que es un
"
-"archivo JSON."
-
-#, python-format
-msgid "Unable to login to iSCSI host target %(portal)s. Details: %(err)s"
-msgstr ""
-"No se puede iniciar la sesi��n en %(portal)s del destino de host iSCSI. "
-"Detalles: %(err)s"
-
-#, python-format
-msgid "Unable to login to iSCSI host %(host)s target %(target)s"
-msgstr ""
-"No se puede iniciar la sesi��n en el destino %(target)s del %(host)s host de
"
-"iSCSI"
-
-#, python-format
-msgid "Unable to find ISO file %(filename)s"
-msgstr ""
-
-#, python-format
-msgid "The ISO file %(filename)s is not bootable"
-msgstr "El archivo ISO %(filename)s no es arrancable"
-
-#, python-format
-msgid "The ISO file %(filename)s does not have a valid El Torito boot record"
-msgstr ""
-"El archivo ISO %(filename)s no tiene un registro de arranque de El Torito "
-"v��lido"
-
-#, python-format
-msgid "Invalid El Torito validation entry in ISO %(filename)s"
-msgstr "Entrada de validaci��n de El Torito no v��lida en ISO %(filename)s"
-
-#, python-format
-msgid "Invalid El Torito boot indicator in ISO %(filename)s"
-msgstr "Indicador de arranque de El Torito no v��lido en ISO %(filename)s"
-
-#, python-format
-msgid "Unexpected volume type for primary volume in ISO %(filename)s"
-msgstr ""
-"Tipo de volumen inesperado para el volumen primario en ISO %(filename)s"
-
-#, python-format
-msgid "Bad format while reading volume descriptor in ISO %(filename)s"
-msgstr ""
-"Formato incorrecto mientras se le��a el descriptor de volumen en ISO %"
-"(filename)s"
-
-#, python-format
-msgid ""
-"The hypervisor doesn't have permission to use this ISO %(filename)s. "
-"Consider moving it under /var/lib/libvirt, or set the search permission to "
-"file access control lists for '%(user)s' user if possible, or add the
'%"
-"(user)s' to the ISO path group, or (not recommended) 'chmod -R o+x "
-"'path_to_iso'.Details: %(err)s"
-msgstr ""
-"El hipervisor no tiene permiso para utilizar este ISO %(filename)s. "
-"Considere moverlo a /var/lib/libvirt, o establezca el permiso de b��squeda en
"
-"listas de control de accesos de archivo para el usuario '%(user)s' si es
"
-"posible, o a��ada el '%(user)s' al grupo de v��as de acceso ISO, o (no
"
-"recomendado) 'chmod -R o+x 'path_to_iso'.Detalles: %(err)s"
-
-msgid "An error occurred when probing image OS information."
-msgstr ""
-
-msgid "No OS information found in given image."
-msgstr ""
-
-#, python-format
-msgid "Unable to read image file %(filename)s"
-msgstr ""
-
-#, python-format
-msgid ""
-"Image file must be an existing file on system. %(filename)s is not a valid "
-"input."
-msgstr ""
-
-#, python-format
-msgid "Virtual machine %(name)s already exists"
-msgstr "La m��quina virtual %(name)s ya existe"
-
-#, python-format
-msgid "Virtual machine %(name)s does not exist"
-msgstr "La m��quina virtual %(name)s no existe"
-
-#, python-format
-msgid ""
-"Unable to rename virtual machine %(name)s. The name %(new_name)s is already "
-"in use or the virtual machine is not powered off."
-msgstr ""
-
-#, python-format
-msgid "Unable to retrieve screenshot for stopped virtual machine %(name)s"
-msgstr ""
-"No se puede recuperar la captura de pantalla para la m��quina virtual "
-"detenida %(name)s"
-
-msgid "Remote ISO image is not supported by this server."
-msgstr "La imagen ISO remota no est�� soportada por este servidor."
-
-#, python-format
-msgid "Screenshot is not supported on virtual machine %(name)s"
-msgstr ""
-
-#, python-format
-msgid "Unable to create virtual machine %(name)s. Details: %(err)s"
-msgstr "No se puede crear la m��quina virtual %(name)s. Detalles: %(err)s"
-
-#, python-format
-msgid "Unable to update virtual machine %(name)s. Details: %(err)s"
-msgstr "No se puede crear la m��quina virtual %(name)s. Detalles: %(err)s"
-
-#, python-format
-msgid "Unable to retrieve virtual machine %(name)s. Details: %(err)s"
-msgstr "No se puede recuperar la m��quina virtual %(name)s. Detalles: %(err)s"
-
-#, python-format
-msgid "Unable to connect to powered off virtual machine %(name)s."
-msgstr ""
-
-msgid "Virtual machine name must be a string without slashes (/)"
-msgstr ""
-
-#, python-format
-msgid "Invalid template URI %(value)s specified for virtual machine"
-msgstr ""
-
-#, python-format
-msgid "Invalid storage pool URI %(value)s specified for virtual machine"
-msgstr ""
-
-msgid "Supported virtual machine graphics are Spice or VNC"
-msgstr ""
-
-msgid "Graphics address to listen on must be IPv4 or IPv6"
-msgstr ""
-"La direcci��n de gr��ficos en que hay que estar a la escucha debe ser IPv4 o
"
-"IPv6"
-
-msgid "Specify a template to create a virtual machine from"
-msgstr ""
-"Especifique una plantilla a partir de la que se crear�� una m��quina virtual"
-
-#, python-format
-msgid "Unable to start virtual machine %(name)s. Details: %(err)s"
-msgstr "No se puede iniciar la m��quina virtual %(name)s. Detalles: %(err)s"
-
-#, python-format
-msgid "Unable to power off virtual machine %(name)s. Details: %(err)s"
-msgstr "No se puede detener la m��quina virtual %(name)s. Detalles: %(err)s"
-
-#, python-format
-msgid "Unable to delete virtual machine %(name)s. Details: %(err)s"
-msgstr "No se puede suprimir la m��quina virtual %(name)s. Detalles: %(err)s"
-
-#, python-format
-msgid "Unable to reset virtual machine %(name)s. Details: %(err)s"
-msgstr "No se puede redenominar la m��quina virtual %(name)s. Detalles:
%(err)s"
-
-msgid "User name list must be an array"
-msgstr ""
-
-msgid "User name must be a string"
-msgstr "El nombre de red debe ser una serie"
-
-msgid "Group name list must be an array"
-msgstr ""
-
-msgid "Group name must be a string"
-msgstr "El nombre de red debe ser una serie"
-
-#, python-format
-msgid "User(s) '%(users)s' do not exist"
-msgstr "El usuario '%(users)s' no existe."
-
-#, python-format
-msgid "Group(s) '%(groups)s' do not exist"
-msgstr "El usuario '%(groups)s' no existe."
-
-#, python-format
-msgid "Unable to shutdown virtual machine %(name)s. Details: %(err)s"
-msgstr "No se puede detener la m��quina virtual %(name)s. Detalles: %(err)s"
-
-#, python-format
-msgid ""
-"Unable to get access metadata of virtual machine %(name)s. Details: %(err)s"
-msgstr "No se puede iniciar la m��quina virtual %(name)s. Detalles: %(err)s"
-
-msgid "The guest console password must be a string."
-msgstr ""
-
-msgid "The life time for the guest console password must be a number."
-msgstr ""
-
-#, python-format
-msgid "Virtual machine '%(name)s' must be stopped before cloning it."
-msgstr ""
-
-#, python-format
-msgid "Insufficient disk space to clone virtual machine '%(name)s'"
-msgstr ""
-
-#, python-format
-msgid "Unable to clone VM '%(name)s'. Details: %(err)s"
-msgstr ""
-
-#, python-format
-msgid "Invalid operation for non-persistent virtual machine %(name)s"
-msgstr ""
-
-#, python-format
-msgid "Cannot suspend VM '%(name)s' because it is not running."
-msgstr ""
-
-#, python-format
-msgid "Unable to suspend VM '%(name)s'. Details: %(err)s"
-msgstr ""
-
-#, python-format
-msgid "Cannot resume VM '%(name)s' because it is not paused."
-msgstr ""
-
-#, python-format
-msgid "Unable to resume VM '%(name)s'. Details: %(err)s"
-msgstr ""
-
-msgid "Memory assigned is higher then the maximum allowed in the host."
-msgstr ""
-
-#, python-format
-msgid ""
-"VM '%(name)s' does not support live memory update. Update the memory with
"
-"the machine offline to enable this feature."
-msgstr ""
-
-msgid "Only increase memory is allowed in active VMs"
-msgstr ""
-
-msgid ""
-"For live memory update, new memory value must be equal old memory value plus
"
-"multiples of 1024 Mib"
-msgstr ""
-
-msgid "There are not enough free slots of 1024 Mib in the guest."
-msgstr ""
-
-msgid ""
-"Host's libvirt version does not support memory devices. Libvirt must be >=
"
-"1.2.14"
-msgstr ""
-
-#, python-format
-msgid "Error attaching memory device. Details: %(error)s"
-msgstr ""
-
-#, python-format
-msgid ""
-"VM %(vmid)s does not contain directly assigned host device %(dev_name)s."
-msgstr ""
-
-#, python-format
-msgid "The host device %(dev_name)s is not allowed to directly assign to VM."
-msgstr ""
-
-msgid ""
-"No IOMMU groups found. Host PCI pass through needs IOMMU group to function "
-"correctly. Please enable Intel VT-d or AMD IOMMU in your BIOS, then verify "
-"the Kernel is compiled with IOMMU support. For Intel CPU, add intel_iommu=on
"
-"to your Kernel parameter in /boot/grub2/grub.conf. For AMD CPU, add iommu=pt
"
-"iommu=1."
-msgstr ""
-
-msgid "\"name\" should be a device name string"
-msgstr ""
-
-#, python-format
-msgid ""
-"The device %(name)s is probably in use by the host. Unable to attach it to "
-"the guest."
-msgstr ""
-
-#, python-format
-msgid "Interface %(iface)s does not exist in virtual machine %(name)s"
-msgstr "La interfaz %(iface)s no existe en la m��quina virtual %(name)s"
-
-#, python-format
-msgid ""
-"Network %(network)s specified for virtual machine %(name)s does not exist"
-msgstr ""
-"La red %(network)s especificada para la m��quina virtual %(name)s no existe"
-
-msgid "Supported virtual machine interfaces type is only network"
-msgstr "El tipo de interfaces de m��quina virtual soportado es de red
solamente"
-
-msgid "Network name for virtual machine interface must be a string"
-msgstr ""
-"El nombre de red para la interfaz de m��quina virtual debe ser una serie"
-
-msgid "Invalid network model card specified for virtual machine interface"
-msgstr ""
-"Especificada tarjeta de modelo de red no v��lida para la interfaz de m��quina
"
-"virtual"
-
-msgid "Specify type and network to add a new virtual machine interface"
-msgstr ""
-"Especifique el tipo y la red para a��adir una interfaz de m��quina virtual "
-"nueva"
-
-msgid "MAC Address must respect this format FF:FF:FF:FF:FF:FF"
-msgstr ""
-
-#, python-format
-msgid "MAC Address %(mac)s already exists in virtual machine %(name)s"
-msgstr ""
-
-msgid "Invalid MAC Address"
-msgstr ""
-
-msgid "Cannot change MAC address of a running virtual machine"
-msgstr ""
-
-#, python-format
-msgid "Template %(name)s already exists"
-msgstr "La plantilla %(name)s ya existe"
-
-#, python-format
-msgid ""
-"Network '%(network)s' specified for template %(template)s does not
exist"
-msgstr ""
-"La red '%(network)s' especificada para la plantilla %(template)s no
existe"
-
-#, python-format
-msgid ""
-"Storage pool %(pool)s specified for template %(template)s does not exist"
-msgstr ""
-"La agrupaci��n de almacenamiento %(pool)s especificada para la plantilla %"
-"(template)s no existe"
-
-#, python-format
-msgid "Storage pool %(pool)s specified for template %(template)s is not
active"
-msgstr ""
-"La agrupaci��n de almacenamiento %(pool)s especificada para la plantilla %"
-"(template)s no est�� activa"
-
-#, python-format
-msgid "Invalid parameter '%(param)s' specified for CDROM."
-msgstr "Par��metro no v��lido '%(param)s' especificado para CDROM."
-
-#, python-format
-msgid "Network %(network)s specified for template %(template)s is not active"
-msgstr ""
-"La red %(network)s especificada para la plantilla %(template)s no est��
activa"
-
-msgid "Template name must be a string"
-msgstr "El nombre de plantilla debe ser una serie"
-
-msgid "Template icon must be a path to the image"
-msgstr "El icono de plantilla debe ser una v��a de acceso a la imagen"
-
-msgid "Template distribution must be a string"
-msgstr "La distribuci��n de plantilla debe ser una serie"
-
-msgid "Template distribution version must be a string"
-msgstr "La versi��n de distribuci��n de plantilla debe ser una serie"
-
-msgid "The number of CPUs must be an integer greater than 0"
-msgstr "El n��mero de CPUs debe ser un entero"
-
-msgid "Amount of memory (MB) must be an integer greater than 512"
-msgstr "La cantidad de memoria (MB) debe ser un entero mayor que 512"
-
-msgid "Template CDROM must be a local or remote ISO file"
-msgstr "El CDROM de plantilla debe ser un archivo ISO local o remoto"
-
-#, python-format
-msgid "Invalid storage pool URI %(value)s specified for template"
-msgstr ""
-"URI de agrupaci��n de almacenamiento no v��lido %(value)s especificado para la
"
-"plantilla"
-
-msgid "Specify an ISO image as CDROM or a base image to create a template"
-msgstr "Especifique una imagen de ISO como CDROM para crear una plantilla"
-
-msgid "All networks for the template must be specified in a list."
-msgstr "Todas las redes para la plantilla deben especificarse en una lista."
-
-msgid "Specify a volume to a template when storage pool is iSCSI or SCSI"
-msgstr ""
-
-#, python-format
-msgid "The volume %(volume)s is not in storage pool %(pool)s"
-msgstr ""
-
-#, python-format
-msgid "Unable to create template due error: %(err)s"
-msgstr "No se puede crear la plantilla debido a un error: %(err)s"
-
-#, python-format
-msgid "Unable to delete template due error: %(err)s"
-msgstr "No se puede suprimir la plantilla debido a un error: %(err)s"
-
-msgid "Disk size must be an integer greater than 1GB."
-msgstr ""
-
-msgid "Template base image must be a valid local image file"
-msgstr "El CDROM de plantilla debe ser un archivo ISO local o remoto"
-
-#, python-format
-msgid "Cannot identify base image %(path)s format"
-msgstr ""
-
-msgid ""
-"When specifying CPU topology, VCPUs must be a product of sockets, cores, and
"
-"threads."
-msgstr ""
-
-msgid ""
-"When specifying CPU topology, each element must be an integer greater than "
-"zero."
-msgstr ""
-
-msgid ""
-"Invalid disk image format. Valid formats: bochs, cloop, cow, dmg, qcow, "
-"qcow2, qed, raw, vmdk, vpc."
-msgstr ""
-
-#, python-format
-msgid "Storage pool %(name)s already exists"
-msgstr "La agrupaci��n de almacenamiento %(name)s ya existe"
-
-#, python-format
-msgid "Storage pool %(name)s does not exist"
-msgstr "La agrupaci��n de almacenamiento %(name)s no existe"
-
-#, python-format
-msgid "Specify %(item)s in order to create the storage pool %(name)s"
-msgstr ""
-"Especifique %(item)s para poder crear la agrupaci��n de almacenamiento
%(name)"
-"s"
-
-#, python-format
-msgid "Unable to delete active storage pool %(name)s"
-msgstr "No se puede suprimir la agrupaci��n de almacenamiento activa %(name)s"
-
-#, python-format
-msgid "Unable to list storage pools. Details: %(err)s"
-msgstr "No se pueden listar agrupaciones de almacenamiento. Detalles: %(err)s"
-
-#, python-format
-msgid "Unable to create storage pool %(name)s. Details: %(err)s"
-msgstr ""
-"No se puede crear la agrupaci��n de almacenamiento %(name)s. Detalles:
%(err)s"
-
-#, python-format
-msgid ""
-"Unable to get number of storage volumes in storage pool %(name)s. Details: %"
-"(err)s"
-msgstr ""
-"No se puede obtener el n��mero de vol��menes de almacenamiento en la "
-"agrupaci��n de almacenamiento %(name)s. Detalles: %(err)s"
-
-#, python-format
-msgid "Unable to activate storage pool %(name)s. Details: %(err)s"
-msgstr ""
-"No se puede activar la agrupaci��n de almacenamiento %(name)s. Detalles: %"
-"(err)s"
-
-#, python-format
-msgid "Unable to deactivate storage pool %(name)s. Details: %(err)s"
-msgstr ""
-"No se puede desactivar la agrupaci��n de almacenamiento %(name)s. Detalles:
%"
-"(err)s"
-
-#, python-format
-msgid "Unable to delete storage pool %(name)s. Details: %(err)s"
-msgstr ""
-"No se puede suprimir la agrupaci��n de almacenamiento %(name)s. Detalles: %"
-"(err)s"
-
-#, python-format
-msgid ""
-"Unable to create NFS Pool as export path %(path)s may block during mount"
-msgstr ""
-"No se puede crear la agrupaci��n de NFS ya que la v��a de acceso de "
-"exportaci��n %(path)s podr��a bloquearse durante el montaje"
-
-#, python-format
-msgid "Unable to create NFS Pool as export path %(path)s mount failed"
-msgstr ""
-"No se puede crear la agrupaci��n de NFS ya que el montaje de la v��a de acceso
"
-"de exportaci��n %(path)s ha fallado"
-
-#, python-format
-msgid "Unsupported storage pool type: %(type)s"
-msgstr "Tipo de agrupaci��n de almacenamiento no soportado: %(type)s"
-
-#, python-format
-msgid "Error while retrieving storage pool XML to %(pool)s"
-msgstr ""
-
-msgid "Storage pool name must be a string without slashes (/)"
-msgstr ""
-
-msgid ""
-"Supported storage pool types are dir, netfs, logical, iscsi, isci and
kimchi-"
-"iso"
-msgstr ""
-
-msgid "Storage pool path must be a string"
-msgstr "La v��a de acceso de la agrupaci��n de almacenamiento debe ser una
serie"
-
-msgid "Storage pool host must be a IP or hostname"
-msgstr ""
-"El host de la agrupaci��n de almacenamiento debe ser un IP o nombre de host"
-
-msgid "Storage pool device must be the absolute path to the block device"
-msgstr ""
-
-msgid "Storage pool devices parameter must be a list"
-msgstr ""
-"El par��metro de los dispositivos de agrupaci��n de almacenamiento debe ser "
-"una lista"
-
-msgid "Target IQN of an iSCSI pool must be a string"
-msgstr "El IQN destino de una agrupaci��n de iSCSI debe ser una serie"
-
-msgid "Port of a remote storage server must be an integer between 1 and 65535"
-msgstr ""
-"El puerto de un servidor de almacenamiento remoto debe ser un entero entre 1
"
-"y 65535"
-
-msgid "iSCSI target username must be a string"
-msgstr ""
-
-msgid "iSCSI target password must be a string"
-msgstr ""
-
-msgid "Specify name and type to create a storage pool"
-msgstr ""
-"Especifique el nombre y el tipo para crear una agrupaci��n de almacenamiento"
-
-#, python-format
-msgid ""
-"%(disk)s is not a valid disk/partition. Could not add it to the pool %(pool)"
-"s."
-msgstr ""
-"%(disk)s no es un disco/partici��n. No se ha podido a��adir a la agrupaci��n
%"
-"(pool)s."
-
-#, python-format
-msgid "Unable to extend logical pool %(pool)s. Details: %(err)s"
-msgstr ""
-
-msgid "The parameter disks only can be updated for logical storage pool."
-msgstr ""
-"Los discos de par��metro s��lo pueden actualizarse para la agrupaci��n de "
-"almacenamiento l��gico."
-
-msgid "The SCSI host adapter name must be a string."
-msgstr "El nombre del adaptador de host SCSI debe ser una serie."
-
-msgid "The storage pool kimchi_isos is reserved for internal use"
-msgstr ""
-"La agrupaci��n de almacenamiento kimchi_isos est�� reservada para uso
interno"
-
-#, python-format
-msgid ""
-"Unable to activate NFS storage pool %(name)s. NFS server %(server)s is "
-"unreachable."
-msgstr ""
-"No se puede activar la agrupaci��n de almacenamiento NFS %(name)s. El "
-"servidor NFS %(server)s est�� fuera de alcance."
-
-#, python-format
-msgid ""
-"Unable to deactivate NFS storage pool %(name)s. NFS server %(server)s is "
-"unreachable."
-msgstr ""
-"No se puede desactivar la agrupaci��n de almacenamiento NFS %(name)s. El "
-"servidor NFS %(server)s est�� fuera de alcance."
-
-#, python-format
-msgid ""
-"Unable to deactivate pool %(name)s as it is associated with some templates"
-msgstr ""
-"No se puede desactivar la agrupaci��n %(name)s ya que est�� asociada con "
-"algunas plantillas"
-
-#, python-format
-msgid "Unable to delete pool %(name)s as it is associated with some templates"
-msgstr ""
-"No se puede suprimir la agrupaci��n %(name)s ya que est�� asociada con algunas
"
-"plantillas"
-
-#, python-format
-msgid ""
-"A volume group named '%(name)s' already exists. Please, choose another name
"
-"to create the logical pool."
-msgstr ""
-"Un grupo de vol��menes denominado '%(name)s' ya existe. Elija otro nombre
"
-"para crear la agrupaci��n l��gica."
-
-#, python-format
-msgid "Unable to update database with deep scan information due error:
%(err)s"
-msgstr ""
-"No se puede actualizar la base de datos con la informaci��n de exploraci��n "
-"profunda debido a un error: %(err)s"
-
-#, python-format
-msgid "Storage volume %(name)s already exists"
-msgstr "El volumen de almacenamiento %(name)s ya existe"
-
-#, python-format
-msgid "Storage volume %(name)s does not exist in storage pool %(pool)s"
-msgstr ""
-"El volumen de almacenamiento %(name)s no existe en la agrupaci��n de "
-"almacenamiento %(pool)s"
-
-#, python-format
-msgid ""
-"Unable to create storage volume %(volume)s because storage pool %(pool)s is "
-"not active"
-msgstr ""
-
-#, python-format
-msgid "Specify %(item)s in order to create storage volume %(volume)s"
-msgstr ""
-"Especifique %(item)s para poder crear el volumen de almacenamiento
%(volume)s"
-
-#, python-format
-msgid ""
-"Unable to list storage volumes because storage pool %(pool)s is not active"
-msgstr ""
-"No se pueden listar los vol��menes de almacenamiento porque la agrupaci��n de
"
-"almacenamiento %(pool)s no est�� activa"
-
-#, python-format
-msgid ""
-"Unable to create storage volume %(name)s in storage pool %(pool)s. Details:
%"
-"(err)s"
-msgstr ""
-"No se puede crear el volumen de almacenamiento %(name)s en la agrupaci��n de
"
-"almacenamiento %(pool)s. Detalles: %(err)s"
-
-#, python-format
-msgid ""
-"Unable to list storage volumes in storage pool %(pool)s. Details: %(err)s"
-msgstr ""
-"No se pueden listar vol��menes de almacenamiento en la agrupaci��n de "
-"almacenamiento %(pool)s. Detalles: %(err)s"
-
-#, python-format
-msgid "Unable to wipe storage volumes %(name)s. Details: %(err)s"
-msgstr ""
-"No se pueden borrar los vol��menes de almacenamiento %(name)s. Detalles: %"
-"(err)s"
-
-#, python-format
-msgid "Unable to delete storage volume %(name)s. Details: %(err)s"
-msgstr ""
-"No se puede suprimir el volumen de almacenamiento %(name)s. Detalles:
%(err)s"
-
-#, python-format
-msgid "Unable to resize storage volume %(name)s. Details: %(err)s"
-msgstr ""
-"No se puede redimensionar el volumen de almacenamiento %(name)s. Detalles: %"
-"(err)s"
-
-#, python-format
-msgid "Storage type %(type)s does not support volume create and delete"
-msgstr ""
-"El tipo de almacenamiento %(type)s no da soporte a crear y suprimir
vol��menes"
-
-msgid "Storage volume name must be a string"
-msgstr "El nombre de volumen de almacenamiento debe ser una serie"
-
-msgid "Storage volume allocation must be an integer number"
-msgstr "La asignaci��n de volumen de almacenamiento debe ser un n��mero
entero"
-
-msgid ""
-"Storage volume format not supported. Valid formats: bochs, cloop, cow, dmg, "
-"qcow, qcow2, qed, raw, vmdk, vpc."
-msgstr ""
-
-msgid "Storage volume requires a volume name"
-msgstr "El volumen de almacenamiento requiere un nombre de volumen"
-
-#, python-format
-msgid ""
-"Unable to update database with storage volume information due error: %(err)s"
-msgstr ""
-"No se puede actualizar la base de datos con la informaci��n de volumen de "
-"almacenamiento debido a un error: %(err)s"
-
-#, python-format
-msgid "Only one of parameter %(param)s can be specified"
-msgstr ""
-
-#, python-format
-msgid "Create volume from %(param)s is not supported"
-msgstr ""
-
-msgid "Storage volume capacity must be an integer number."
-msgstr ""
-
-msgid "Storage volume URL must be http://, https://, ftp:// or ftps://."
-msgstr ""
-
-#, python-format
-msgid "Unable to access file %(url)s. Please, check it."
-msgstr ""
-
-#, python-format
-msgid ""
-"Unable to clone storage volume '%(name)s' in pool '%(pool)s'.
Details: %(err)"
-"s"
-msgstr ""
-
-msgid "Specify chunk data and its size to upload a file."
-msgstr ""
-
-msgid "In order to upload a storage volume, specify the 'upload'
parameter."
-msgstr ""
-
-msgid ""
-"Unable to upload chunk data as it does not match with requested chunk size."
-msgstr ""
-
-#, python-format
-msgid "The storage volume %(vol)s is not under an upload process."
-msgstr ""
-
-msgid "The upload chunk data will exceed the storage volume size."
-msgstr ""
-
-#, python-format
-msgid "Unable to upload chunk data to storage volume. Details: %(err)s."
-msgstr ""
-
-#, python-format
-msgid "Interface %(name)s does not exist"
-msgstr "La interfaz %(name)s no existe"
-
-#, python-format
-msgid "Network %(name)s already exists"
-msgstr "La red %(name)s ya existe"
-
-#, python-format
-msgid "Network %(name)s does not exist"
-msgstr "La red %(name)s no existe"
-
-#, python-format
-msgid "Subnet %(subnet)s specified for network %(network)s is not valid."
-msgstr ""
-"La subred %(subnet)s especificada para la red %(network)s no es v��lida."
-
-#, python-format
-msgid "Specify a network interface to create bridged network %(name)s"
-msgstr "Especifique una interfaz de red para crear una red puenteada %(name)s"
-
-#, python-format
-msgid "Unable to delete active network %(name)s"
-msgstr "No se puede suprimir la red activa %(name)s"
-
-#, python-format
-msgid "Interface %(iface)s specified for network %(network)s is already in
use"
-msgstr ""
-"La interfaz %(iface)s especificada para la red %(network)s ya est�� en uso"
-
-msgid "Interface should be bare NIC, bonding or bridge device."
-msgstr "La interfaz debe ser dispositivo de puente, enlazado o NIC simple."
-
-#, python-format
-msgid "Unable to create network %(name)s. Details: %(err)s"
-msgstr "No se puede crear la red %(name)s. Detalles: %(err)s"
-
-#, python-format
-msgid "Unable to find a free IP address for network '%(name)s'"
-msgstr "No se puede encontrar una direcci��n IP libre para la red
'%(name)s'"
-
-#, python-format
-msgid "The interface %(iface)s already exists."
-msgstr "La interfaz %(iface)s ya existe"
-
-msgid "Network name must be a string without slashes (/) or quotes (\")"
-msgstr ""
-
-msgid "Supported network types are isolated, NAT and bridge"
-msgstr "Los tipos de red soportados son aislada, NAT y puente"
-
-msgid "Network subnet must be a string with IP address and prefix or netmask"
-msgstr ""
-"La subred de red debe ser una serie con direcci��n IP y prefijo o m��scara de
"
-"red"
-
-msgid "Network interface must be a string"
-msgstr "La interfaz de red debe ser una serie"
-
-msgid "Network VLAN ID must be an integer between 1 and 4094"
-msgstr "El ID de VLAN de red debe ser un entero entre 1 y 4094"
-
-msgid "Specify name and type to create a Network"
-msgstr "Especifique el nombre y el tipo para crear una red"
-
-#, python-format
-msgid ""
-"Unable to delete network %(name)s. There are some virtual machines %(vms)s "
-"and/or templates linked to this network."
-msgstr ""
-"No se puede suprimir la red %(name)s. Hay algunas m��quinas virtuales %(vms)s
"
-"y/o plantillas enlazadas a esta red."
-
-#, python-format
-msgid ""
-"Unable to deactivate network %(name)s. There are some virtual machines
%(vms)"
-"s and/or templates linked to this network."
-msgstr ""
-"No se puede desactivar la red %(name)s. Hay algunas m��quinas virtuales
%(vms)"
-"s y/o plantillas enlazadas a esta red."
-
-#, python-format
-msgid "Bridge device %(name)s can not be the trunk device of a VLAN."
-msgstr ""
-"El dispositivo de puente %(name)s no puede ser el dispositivo de conexi��n "
-"troncal de una VLAN."
-
-#, python-format
-msgid "Failed to activate interface %(iface)s: %(err)s."
-msgstr "No se puede activar la interfaz %(iface)s: %(err)s."
-
-#, python-format
-msgid ""
-"Failed to activate interface %(iface)s. Please check the physical link "
-"status."
-msgstr ""
-"No se puede activar la interfaz %(iface)s. Compruebe el estado del enlace "
-"f��sico."
-
-#, python-format
-msgid "Failed to start network %(name)s. Details: %(err)s"
-msgstr ""
-
-#, python-format
-msgid "Debug report %(name)s does not exist"
-msgstr "El informe de depuraci��n %(name)s no existe"
-
-msgid "Debug report tool not found in system"
-msgstr "Herramienta de informes de depuraci��n no encontrada en el sistema"
-
-#, python-format
-msgid "Unable to create debug report %(name)s. Details: %(err)s."
-msgstr ""
-"No se puede crear el informe de depuraci��n %(name)s. Detalles: %(err)s."
-
-#, python-format
-msgid "Can not find any debug report with the given name %(name)s"
-msgstr ""
-
-#, python-format
-msgid "Unable to generate debug report %(name)s. Details: %(err)s"
-msgstr ""
-"No se puede generar el informe de depuraci��n %(name)s. Detalles: %(err)s"
-
-msgid "You should give a name for the debug report file."
-msgstr ""
-
-msgid ""
-"Debug report name must be a string. Only letters, digits, underscore ('_')
"
-"and hyphen ('-') are allowed."
-msgstr ""
-
-#, python-format
-msgid ""
-"The debug report with specified name \"%(name)s\" already exists. Please
use "
-"another one."
-msgstr ""
-"Un grupo de vol��menes denominado '%(name)s' ya existe. Elija otro nombre
"
-"para crear la agrupaci��n l��gica."
-
-#, python-format
-msgid "Storage server %(server)s was not used by Kimchi"
-msgstr "Kimchi no utilizaba el servidor de almacenamiento %(server)s"
-
-#, python-format
-msgid "Distro '%(name)s' does not exist"
-msgstr "Distro '%(name)s' no existe"
-
-#, python-format
-msgid "Partition %(name)s does not exist in the host"
-msgstr "La partici��n %(name)s no existe en el host"
-
-msgid "Unable to shutdown host machine as there are running virtual machines"
-msgstr ""
-"No se puede concluir la m��quina host ya que hay m��quinas virtuales en "
-"ejecuci��n"
-
-msgid "Unable to reboot host machine as there are running virtual machines"
-msgstr ""
-"No se puede rearrancar la m��quina host ya que hay m��quinas virtuales en "
-"ejecuci��n"
-
-#, python-format
-msgid "Node device '%(name)s' not found"
-msgstr "No se ha encontrado el dispositivo de nodo '%(name)s'"
-
-msgid "Conflicting flag filters specified."
-msgstr ""
-
-msgid "No packages marked for update"
-msgstr "No hay paquetes marcados para su actualizaci��n"
-
-#, python-format
-msgid "Package %(name)s is not marked to be updated."
-msgstr "El paquete %(name)s no est�� marcado para su actualizaci��n."
-
-#, python-format
-msgid "Error while getting packages marked to be updated. Details: %(err)s"
-msgstr ""
-"Se ha producido un error al obtener paquetes marcados para su actualizaci��n.
"
-"Detalles: %(err)s"
-
-msgid "There is no compatible package manager for this system."
-msgstr "No hay ning��n gestor de paquetes compatible para este sistema."
-
-#, python-format
-msgid "Invalid URI %(uri)s"
-msgstr "URI %(uri)s no v��lido"
-
-msgid "Unable to choose a virtual machine name"
-msgstr ""
-
-msgid "Invalid storage type. Types supported: 'cdrom', 'disk'"
-msgstr "Tipo de almacenamiento no v��lido. Tipos soportados: 'cdrom'"
-
-#, python-format
-msgid "The path '%(value)s' is not a valid local/remote path for the
device"
-msgstr ""
-
-msgid "Only CDROM path can be update."
-msgstr ""
-
-#, python-format
-msgid ""
-"The storage device %(dev_name)s does not exist in the virtual machine %"
-"(vm_name)s"
-msgstr ""
-
-#, python-format
-msgid "Error while creating new storage device: %(error)s"
-msgstr ""
-"Se ha producido un error al crear el nuevo dispositivo de almacenamiento: %"
-"(error)s"
-
-#, python-format
-msgid "Error while updating storage device: %(error)s"
-msgstr ""
-"Se ha producido un error al actualizar el dispositivo de almacenamiento: %"
-"(error)s"
-
-#, python-format
-msgid "Error while removing storage device: %(error)s"
-msgstr ""
-"Se ha producido un error al eliminar el dispositivo de almacenamiento: %"
-"(error)s"
-
-msgid "Do not support IDE device hot plug"
-msgstr ""
-
-msgid ""
-"Specify type and path or type and pool/volume to add a new virtual machine "
-"disk"
-msgstr ""
-"Especifique el tipo y la v��a de acceso para a��adir un disco de m��quina "
-"virtual nuevo"
-
-msgid "Specify path to update virtual machine disk"
-msgstr ""
-"Especifique la v��a de acceso para actualizar el disco de m��quina virtual"
-
-#, python-format
-msgid "Controller type %(type)s limitation of %(limit)s devices reached"
-msgstr ""
-
-#, python-format
-msgid "Cannot retrieve disk path information for given pool/volume: %(error)s"
-msgstr ""
-
-msgid "Volume already in use by other virtual machine."
-msgstr ""
-
-msgid ""
-"Only one of path or pool/volume can be specified to add a new virtual "
-"machine disk"
-msgstr ""
-"Especifique el tipo y la v��a de acceso para a��adir un disco de m��quina "
-"virtual nuevo"
-
-#, python-format
-msgid ""
-"Volume chosen with format %(format)s does not fit in the storage type
%(type)"
-"s"
-msgstr ""
-
-msgid "YUM Repository ID must be one word only string."
-msgstr "El ID de repositorio YUM debe ser una serie de una sola palabra."
-
-msgid "Repository URL must be an http://, ftp:// or file:// URL."
-msgstr "El URL de repositorio debe ser http://, ftp:// o archivo:// URL."
-
-msgid ""
-"Repository configuration is a dictionary with specific values according to "
-"repository type."
-msgstr ""
-"La configuraci��n de repositorio es un diccionario con valores espec��ficos "
-"seg��n el tipo de repositorio."
-
-msgid "Distribution to DEB repository must be a string"
-msgstr "El repositorio de Distribuci��n a DEB debe ser una serie"
-
-msgid "Components to DEB repository must be listed in a array"
-msgstr "El repositorio de Componentes a DEB debe estar listado en una matriz"
-
-msgid "Components to DEB repository must be a string"
-msgstr "El repositorio de Componentes a DEB debe ser una serie"
-
-msgid "Mirror list to repository must be a string"
-msgstr ""
-
-msgid "YUM Repository name must be string."
-msgstr "El nombre del repositorio YUM debe ser una serie."
-
-msgid "GPG check must be a boolean value."
-msgstr "La comprobaci��n de GPG debe ser un valor booleano."
-
-msgid "GPG key must be a URL pointing to the ASCII-armored file."
-msgstr "La clave GPG debe ser un URL que apunta al archivo blindado por
ASCII."
-
-#, python-format
-msgid "Could not update repository %(repo_id)s."
-msgstr "No se ha podido actualizar el repositorio %(repo_id)s."
-
-#, python-format
-msgid "Repository %(repo_id)s does not exist."
-msgstr "El repositorio %(repo_id)s no existe."
-
-msgid ""
-"Specify repository base URL, mirror list or metalink in order to create or "
-"update a YUM repository."
-msgstr ""
-
-msgid "Repository management tool was not recognized for your system."
-msgstr ""
-"La herramienta de gesti��n de repositorio no se ha reconocido para su
sistema."
-
-#, python-format
-msgid "Repository %(repo_id)s is already enabled."
-msgstr "El repositorio %(repo_id)s ya est�� habilitado."
-
-#, python-format
-msgid "Repository %(repo_id)s is already disabled."
-msgstr "El repositorio %(repo_id)s ya est�� inhabilitado."
-
-#, python-format
-msgid "Could not remove repository %(repo_id)s."
-msgstr "No se ha podido eliminar el repositorio %(repo_id)s."
-
-#, python-format
-msgid "Could not write repository configuration file %(repo_file)s"
-msgstr ""
-"No se ha podido grabar el archivo de configuraci��n del repositorio %"
-"(repo_file)s"
-
-msgid "Specify repository distribution in order to create a DEB repository."
-msgstr ""
-"Especifique la distribuci��n del repositorio para crear un repositorio de
DEB."
-
-#, python-format
-msgid "Could not enable repository %(repo_id)s."
-msgstr "No se ha podido habilitar el repositorio %(repo_id)s."
-
-#, python-format
-msgid "Could not disable repository %(repo_id)s."
-msgstr "No se ha podido inhabilitar el repositorio %(repo_id)s."
-
-msgid "YUM Repository ID already exists"
-msgstr "El ID de repositorio de YUM ya existe"
-
-msgid "YUM Repository name must be a string"
-msgstr "El nombre del repositorio de YUM debe ser una serie"
-
-#, python-format
-msgid "Unable to list repositories. Details: '%(err)s'"
-msgstr "No se pueden listar repositorios. Detalles: '%(err)s'"
-
-#, python-format
-msgid "Unable to retrieve repository information. Details: '%(err)s'"
-msgstr "No se puede recuperar informaci��n del repositorio. Detalles:
'%(err)s'"
-
-#, python-format
-msgid "Unable to add repository. Details: '%(err)s'"
-msgstr "No se puede a��adir el repositorio. Detalles: '%(err)s'"
-
-#, python-format
-msgid "Unable to remove repository. Details: '%(err)s'"
-msgstr "No se puede eliminar el repositorio. Detalles: '%(err)s'"
-
-#, python-format
-msgid ""
-"Configuration items: '%(items)s' are not supported by repository
manager"
-msgstr ""
-
-msgid "Repository metalink must be an http://, ftp:// or file:// URL."
-msgstr ""
-
-msgid "Cannot specify mirrorlist and metalink at the same time."
-msgstr ""
-
-#, python-format
-msgid ""
-"Virtual machine '%(vm)s' must be stopped before creating a snapshot of
it."
-msgstr ""
-
-#, python-format
-msgid ""
-"Unable to create snapshot '%(name)s' on virtual machine '%(vm)s'.
Details: %"
-"(err)s"
-msgstr ""
-
-#, python-format
-msgid "Snapshot '%(name)s' does not exist on virtual machine
'%(vm)s'."
-msgstr ""
-
-#, python-format
-msgid ""
-"Unable to retrieve snapshot '%(name)s' on virtual machine '%(vm)s'.
Details: "
-"%(err)s"
-msgstr ""
-
-#, python-format
-msgid "Unable to list snapshots on virtual machine '%(vm)s'. Details:
%(err)s"
-msgstr ""
-
-#, python-format
-msgid ""
-"Unable to delete snapshot '%(name)s' on virtual machine '%(vm)s'.
Details: %"
-"(err)s"
-msgstr ""
-
-#, python-format
-msgid ""
-"Unable to retrieve current snapshot of virtual machine '%(vm)s'. Details:
%"
-"(err)s"
-msgstr ""
-
-#, python-format
-msgid ""
-"Unable to revert virtual machine '%(vm)s' to snapshot '%(name)s'.
Details: %"
-"(err)s"
-msgstr ""
-
-#, python-format
-msgid ""
-"Unable to create snapshot of virtual machine '%(vm)s' because it contains a
"
-"disk with format '%(format)s'; only 'qcow2' is supported."
-msgstr ""
-
-msgid "The number of vCPUs is too large for this system."
-msgstr ""
-
-msgid "Invalid vCPU/topology combination."
-msgstr ""
-
-msgid "This host (or current configuration) does not allow CPU topology."
-msgstr ""
-
-msgid "ERROR CODE"
-msgstr "C��DIGO DE ERROR"
-
-msgid "REASON"
-msgstr "RAZ��N"
-
-msgid "STACK"
-msgstr "PILA"
-
-msgid "Go to Homepage"
-msgstr "Ir a la p��gina inicial"
-
-msgid "Create a New Virtual Machine"
-msgstr "Crear una nueva m��quina virtual"
-
-msgid "Virtual Machine Name"
-msgstr "Nombre de m��quina virtual"
-
-msgid ""
-"The name used to identify the virtual machine. If omitted, a name will be "
-"chosen based on the template used."
-msgstr ""
-"El nombre que se utiliza para identificar la m��quina virtual. Si se omite, "
-"se elegir�� un nombre bas��ndose en la plantilla utilizada."
-
-msgid "Template"
-msgstr "Plantilla"
-
-msgid "Please create a template first."
-msgstr "Cree una plantilla primero."
-
-msgid "Create a Template"
-msgstr "Crear una plantilla"
-
-msgid "Please choose a template."
-msgstr "Elija una plantilla."
-
-msgid "OS"
-msgstr "SO"
-
-msgid "OS Version"
-msgstr "Versi��n del SO"
-
-msgid "CPUS"
-msgstr "CPUS"
-
-msgid "Memory"
-msgstr "Memoria"
-
-msgid "Create"
-msgstr "Crear"
-
-msgid "Creating..."
-msgstr ""
-
-msgid "Cancel"
-msgstr "Cancelar"
-
-msgid "Edit Guest"
-msgstr "Editar invitado"
-
-msgid "General"
-msgstr "General"
-
-msgid "Storage"
-msgstr "Almacenamiento"
-
-msgid "Interface"
-msgstr "Interfaz"
-
-msgid "Permission"
-msgstr "Versi��n"
-
-msgid "Host PCI Device"
-msgstr ""
-
-msgid "Snapshot"
-msgstr ""
-
-msgid "Name"
-msgstr "Nombre"
-
-msgid "CPUs"
-msgstr "CPUs"
-
-msgid "Memory (MB)"
-msgstr "Memoria"
-
-msgid "Icon"
-msgstr "Icono"
-
-msgid "Device"
-msgstr "Nombre de dispositivo"
-
-msgid "Path"
-msgstr "V��a de acceso NFS"
-
-msgid "Network"
-msgstr "Red"
-
-msgid "Type"
-msgstr "Tipo"
-
-msgid "MAC Address"
-msgstr ""
-
-msgid "Available system users and groups"
-msgstr ""
-
-msgid "Selected system users and groups"
-msgstr ""
-
-msgid "User"
-msgstr ""
-
-msgid "All"
-msgstr "Todo"
-
-msgid "To Add"
-msgstr ""
-
-msgid "Added"
-msgstr ""
-
-msgid "filter"
-msgstr ""
-
-msgid "Product"
-msgstr ""
-
-msgid "Vendor"
-msgstr "Proveedor"
-
-msgid "Created"
-msgstr ""
-
-msgid "Save"
-msgstr "Guardar"
-
-msgid "Replace"
-msgstr "Sustituir"
-
-msgid "Detach"
-msgstr "Desconectar"
-
-msgid "revert"
-msgstr ""
-
-msgid "Start"
-msgstr "Iniciar"
-
-msgid "Reset"
-msgstr "Restablecer"
-
-msgid "Pause"
-msgstr ""
-
-msgid "Resume"
-msgstr ""
-
-msgid "Power Off"
-msgstr ""
-
-msgid "Actions"
-msgstr "Acciones"
-
-msgid "Connect"
-msgstr "Conectar"
-
-msgid "Clone"
-msgstr ""
-
-msgid "Edit"
-msgstr "Editar"
-
-msgid "Shut Down"
-msgstr "Concluir"
-
-msgid "Delete"
-msgstr "Suprimir"
-
-msgid "CPU"
-msgstr "CPU"
-
-msgid "Disk I/O"
-msgstr "E/S de disco"
-
-msgid "Network I/O"
-msgstr "E/S de red"
-
-msgid "Livetile"
-msgstr "Livetile"
-
-msgid "No guests found."
-msgstr "No se ha encontrado invitados."
-
-msgid "Add a Storage Device to VM"
-msgstr "A��adir un dispositivo de almacenamiento a VM"
-
-msgid "Device Type"
-msgstr "Tipo de dispositivo"
-
-msgid "The device type. Currently, \"cdrom\" and \"disk\" are
supported."
-msgstr "El tipo de dispositivo. Actualmente s��lo est�� soportado
\"cdrom\"."
-
-msgid "Storage Pool"
-msgstr "Agrupaci��n de almacenamiento"
-
-msgid "Storage pool which volume located in"
-msgstr "La v��a de acceso de la agrupaci��n de almacenamiento debe ser una
serie"
-
-msgid "Storage Volume"
-msgstr "Nombre de agrupaci��n de almacenamiento"
-
-msgid "Storage volume to be attached"
-msgstr "El nombre de volumen de almacenamiento debe ser una serie"
-
-msgid "File Path"
-msgstr "V��a de acceso de archivo"
-
-msgid "The ISO file path in the server for CDROM."
-msgstr "La v��a de acceso del archivo ISO en el servidor para el CDROM."
-
-msgid "Attach"
-msgstr "Conectar"
-
-msgid "Shut down"
-msgstr "Concluir"
-
-msgid "Restart"
-msgstr "Reiniciar"
-
-msgid "Basic Information"
-msgstr "Informaci��n b��sica"
-
-msgid "OS Distro"
-msgstr "Distro de SO"
-
-msgid "OS Code Name"
-msgstr "Nombre de c��digo de SO"
-
-msgid "Processor"
-msgstr "Procesador"
-
-msgid "CPU(s)"
-msgstr ""
-
-msgid "System Statistics"
-msgstr "Estad��sticas del sistema"
-
-msgid "Software Updates"
-msgstr "Actualizaciones de software"
-
-msgid "Update Progress"
-msgstr "Actualizar progreso"
-
-msgid "Repositories"
-msgstr "Repositorios"
-
-msgid "Debug Reports"
-msgstr "Informes de depuraci��n"
-
-msgid "The username or password you entered is incorrect. Please try again."
-msgstr ""
-"El nombre de usuario o contrase��a que ha especificado es incorrecto. Por "
-"favor, vuelva a intentarlo."
-
-msgid "This field is required."
-msgstr "Este campo es obligatorio."
-
-msgid "Log in"
-msgstr "Iniciar sesi��n"
-
-msgid "Logging in..."
-msgstr "Iniciando sesi��n..."
-
-msgid "Host"
-msgstr "Host"
-
-msgid "Guests"
-msgstr "Invitados"
-
-msgid "Templates"
-msgstr "Plantillas"
-
-msgid "Failed to get application configuration"
-msgstr "No se ha podido obtener la configuraci��n de la aplicaci��n"
-
-msgid "This is not a valid Linux path"
-msgstr "No es una v��a de acceso de Linux v��lida"
-
-msgid "This is not a valid URL."
-msgstr "No es un URL v��lido."
-
-msgid "No such data available."
-msgstr "No hay datos de ese tipo disponibles."
-
-msgid ""
-"Can not contact the host system. Verify the host system is up and that you "
-"have network connectivity to it. HTTP request response %1. "
-msgstr ""
-"No se puede contactar con el sistema host, Verifique que el sistema host "
-"est�� activo y que tiene conectividad de red con ��l. Respuesta de solicitud
"
-"HTTP %1. "
-
-msgid "Unable to read file."
-msgstr ""
-
-msgid "Error while uploading file."
-msgstr ""
-
-msgid "Delete Confirmation"
-msgstr "Confirmaci��n de supresi��n"
-
-msgid "OK"
-msgstr "Aceptar"
-
-msgid "Confirm"
-msgstr "Confirmar"
-
-msgid "Warning"
-msgstr "Aviso"
-
-msgid "Cloning..."
-msgstr ""
-
-msgid "Loading..."
-msgstr "Cargando..."
-
-msgid "An error occurred while retrieving system information."
-msgstr ""
-
-msgid "Retry"
-msgstr "Reintentar"
-
-msgid "Detailed message:"
-msgstr "Mensaje detallado:"
-
-msgid "No ISO found"
-msgstr ""
-
-msgid "This is not a valid ISO file."
-msgstr "No es un archivo ISO v��lido."
-
-msgid "This may take a long time. Do you want to continue?"
-msgstr "Tardar�� mucho tiempo. ��Desea continuar?"
-
-msgid "This will permanently delete the template. Would you like to continue?"
-msgstr "Esto suprimir�� permanentemente la plantilla. ��Desea continuar?"
-
-msgid "Unable to shut down system as there are some virtual machines running!"
-msgstr ""
-"No se puede concluir el sistema ya que hay algunas m��quinas virtuales en "
-"ejecuci��n."
-
-msgid "Max:"
-msgstr "M��x.:"
-
-msgid "Utilization"
-msgstr "Utilizaci��n"
-
-msgid "Available"
-msgstr "Disponible"
-
-msgid "Read Rate"
-msgstr "Velocidad de lectura"
-
-msgid "Write Rate"
-msgstr "Velocidad de escritura"
-
-msgid "Received"
-msgstr "Recibido"
-
-msgid "Sent"
-msgstr "Enviado"
-
-msgid ""
-"Shutting down or restarting host will cause unsaved work lost. Continue to "
-"shut down/restarting?"
-msgstr ""
-"Concluir o reiniciar el host har�� que se pierda el trabajo no guardado. "
-"��Desea continuar para concluir/reiniciar?"
-
-msgid ""
-"Repository will be removed permanently and can't be recovered. Do you want
"
-"to continue?"
-msgstr ""
-"El repositorio se eliminar�� de forma permanente y no se puede recuperar. "
-"��Desea continuar?"
-
-msgid "ID"
-msgstr "ID"
-
-msgid "Base URL"
-msgstr "URL base"
-
-msgid "Is Mirror"
-msgstr "Es duplicado"
-
-msgid "URL Args"
-msgstr "Args de URL"
-
-msgid "Enabled"
-msgstr "Habilitado"
-
-msgid "GPG Check"
-msgstr "Comprobaci��n GPG"
-
-msgid "GPG Key"
-msgstr "Clave GPG"
-
-msgid "Add"
-msgstr "A��adir"
-
-msgid "Remove"
-msgstr "Eliminar"
-
-msgid "Enable"
-msgstr "Habilitar"
-
-msgid "Disable"
-msgstr "Inhabilitar"
-
-msgid "Package Name"
-msgstr "Nombre de paquete"
-
-msgid "Version"
-msgstr "Versi��n"
-
-msgid "Architecture"
-msgstr "Arquitectura"
-
-msgid "Repository"
-msgstr "Repositorio"
-
-msgid "Update All"
-msgstr "Actualizar todo"
-
-msgid "Updating..."
-msgstr "Actualizando..."
-
-msgid "Failed to retrieve packages update information."
-msgstr ""
-
-msgid "Failed to update package(s)."
-msgstr "No se han podido actualizar paquetes."
-
-msgid ""
-"Debug report will be removed permanently and can't be recovered. Do you want
"
-"to continue?"
-msgstr ""
-"El informe de depuraci��n se eliminar�� permanentemente y no se puede "
-"recuperar. ��Desea continuar?"
-
-msgid "Generated Time"
-msgstr "Tiempo generado"
-
-msgid "Generate"
-msgstr "Generar"
-
-msgid "Generating..."
-msgstr "Generando..."
-
-msgid "Rename"
-msgstr "Redenominar"
-
-msgid "Download"
-msgstr "Descargar"
-
-msgid ""
-"Report name should contain only letters, digits, underscore ('_') and/or
"
-"hyphen ('-')."
-msgstr ""
-"El nombre de informe debe contener s��lo letras, d��gitos y/o gui��n
('-')."
-
-msgid "Pending..."
-msgstr "Cargando..."
-
-msgid "Report name is the same as the original one."
-msgstr ""
-
-msgid ""
-"This will delete the virtual machine and its virtual disks. This operation "
-"cannot be undone. Would you like to continue?"
-msgstr ""
-"Esto suprimir�� la m��quina virtual y sus discos virtuales. Esta operaci��n no
"
-"puede deshacerse. ��Desea continuar?"
-
-msgid "Power off Confirmation"
-msgstr "Confirmaci��n de supresi��n"
-
-msgid ""
-"This action may produce undesirable results, for example unflushed disk "
-"cache in the guest. Would you like to continue?"
-msgstr ""
-
-msgid "Reset Confirmation"
-msgstr "Confirmaci��n de supresi��n"
-
-msgid ""
-"There is a risk of data loss caused by reset without the guest OS shutdown. "
-"Would you like to continue?"
-msgstr ""
-
-msgid "Shut Down Confirmation"
-msgstr "Confirmaci��n de supresi��n"
-
-msgid "Note the guest OS may ignore this request. Would you like to continue?"
-msgstr "Esto suprimir�� permanentemente la plantilla. ��Desea continuar?"
-
-msgid "Virtual Machine delete Confirmation"
-msgstr ""
-
-msgid ""
-"This virtual machine is not persistent. Power Off will delete it. Continue?"
-msgstr ""
-
-msgid ""
-"When the target guest has SCSI or iSCSI volumes, they will be cloned on "
-"default storage pool. The same will happen when the target pool does not "
-"have enough space to clone the volumes. Do you want to continue?"
-msgstr ""
-
-msgid ""
-"This CDROM will be detached permanently and you can re-attach it. Continue "
-"to detach it?"
-msgstr ""
-"Este CDROM se desconectar�� de forma permanente pero puede volver a "
-"conectarlo. ��Desea continuar para desconectarlo?"
-
-msgid "Attaching..."
-msgstr "Conectando..."
-
-msgid "Replacing..."
-msgstr "Sustituyendo..."
-
-msgid "Successfully attached!"
-msgstr "��Conectado correctamente!"
-
-msgid "Successfully replaced!"
-msgstr "��Sustituido correctamente!"
-
-msgid "Successfully detached!"
-msgstr "��Desconectado correctamente!"
-
-msgid ""
-"This disk will be detached permanently and you can re-attach it. Continue to
"
-"detach it?"
-msgstr ""
-
-msgid "interface:"
-msgstr ""
-
-msgid "address:"
-msgstr ""
-
-msgid "link_type:"
-msgstr ""
-
-msgid "block:"
-msgstr ""
-
-msgid "drive_type:"
-msgstr ""
-
-msgid "model:"
-msgstr ""
-
-msgid "Affected devices:"
-msgstr ""
-
-msgid "The VLAN id must be between 1 and 4094."
-msgstr "El ID de VLAN debe estar entre 1 y 4094."
-
-msgid "unavailable"
-msgstr "no disponible"
-
-msgid ""
-"This action will interrupt network connectivity for any virtual machine that
"
-"depend on this network."
-msgstr ""
-"Esta acci��n interrumpir�� la conectividad de red para cualquier m��quina "
-"virtual que dependa de esta red."
-
-msgid "Create a network"
-msgstr "Crear una red"
-
-msgid ""
-"This network is not persistent. Instead of stop, this action will "
-"permanently delete it. Would you like to continue?"
-msgstr ""
-"Esta agrupaci��n de almacenamiento no es persistente. En lugar de desactivar,
"
-"esta acci��n la suprimir�� permanentemente. ��Desea continuar?"
-
-msgid ""
-"The bridged VLAN tag may not work well with NetworkManager enabled. You "
-"should consider disabling it."
-msgstr ""
-
-msgid ""
-"This will permanently delete the storage pool. Would you like to continue?"
-msgstr ""
-"Esto suprimir�� permanentemente la agrupaci��n de almacenamiento. ��Desea "
-"continuar?"
-
-msgid "This storage pool is empty."
-msgstr "Esta agrupaci��n de almacenamiento est�� vac��a."
-
-msgid ""
-"It will format your disk and you will loose any data in there, are you sure "
-"to continue? "
-msgstr ""
-"Dar�� formato al disco y se perder��n los datos que tenga en ��l. ��Est�� seguro
"
-"de que desea continuar? "
-
-msgid "SCSI Fibre Channel"
-msgstr "Canal de fibra de SCSI"
-
-msgid "No SCSI adapters found."
-msgstr "No se han encontrado adaptadores SCSI."
-
-msgid "Loading iSCSI targets..."
-msgstr ""
-
-msgid "No iSCSI found. Please input one."
-msgstr ""
-
-msgid "Failed to load iSCSI targets."
-msgstr ""
-
-msgid "The storage pool name can not be blank."
-msgstr "El nombre de la agrupaci��n de almacenamiento no puede estar en
blanco."
-
-msgid "The storage pool path can not be blank."
-msgstr ""
-"La v��a de acceso de la agrupaci��n de almacenamiento no puede estar en
blanco."
-
-msgid "NFS server mount path can not be blank."
-msgstr "La v��a de acceso de montaje del servidor NFS no puede estar en
blanco."
-
-msgid "Invalid NFS mount path."
-msgstr "V��a de acceso de montaje de NFS no v��lida."
-
-msgid "No logical device selected."
-msgstr "No se ha seleccionado ning��n dispositivo l��gico."
-
-msgid "The iSCSI target can not be blank."
-msgstr "El destino iSCSI no puede estar en blanco."
-
-msgid "Server name can not be blank."
-msgstr "El nombre de servidor no puede estar en blanco."
-
-msgid "This is not a valid Server Name or IP. Please, modify it."
-msgstr ""
-
-msgid "Looking for available partitions ..."
-msgstr "Buscando particiones disponibles..."
-
-msgid "No available partitions found."
-msgstr "No se han encontrado particiones disponibles."
-
-msgid ""
-"This storage pool is not persistent. Instead of deactivate, this action will
"
-"permanently delete it. Would you like to continue?"
-msgstr ""
-"Esta agrupaci��n de almacenamiento no es persistente. En lugar de desactivar,
"
-"esta acci��n la suprimir�� permanentemente. ��Desea continuar?"
-
-msgid "Unable to retrieve partitions information."
-msgstr "No se puede recuperar informaci��n del repositorio. Detalles:
'%(err)s'"
-
-msgid "In progress..."
-msgstr ""
-
-msgid "Failed!"
-msgstr ""
-
-msgid "CDROM path needs to be a valid local/remote path and cannot be blank."
-msgstr ""
-
-msgid "Disk pool or volume cannot be blank."
-msgstr "El nombre de la agrupaci��n de almacenamiento no puede estar en
blanco."
-
-msgid "Filter"
-msgstr ""
-
-msgid "Network Name"
-msgstr "Nombre de red"
-
-msgid "State"
-msgstr "Estado"
-
-msgid "Network Type"
-msgstr "Tipo de red"
-
-msgid "Address Space"
-msgstr "Espacio de direcciones"
-
-msgid "Name should not contain '/' and '\"'."
-msgstr ""
-"Nombre de agrupaci��n de almacenamiento no v��lido. No debe contener
'/'."
-
-msgid "Isolated: no external network connection"
-msgstr "Aislado: no hay conexi��n de red f��sica"
-
-msgid "NAT: outbound physical network connection only"
-msgstr "NAT: conexi��n de red f��sica saliente solamente"
-
-msgid "Bridged: Virtual machines are connected to physical network directly"
-msgstr ""
-"Puenteado: Las m��quinas virtuales est��n conectadas a la red f��sica "
-"directamente"
-
-msgid "(No interfaces found)"
-msgstr ""
-
-msgid "Destination"
-msgstr "Destino:"
-
-msgid "Enable VLAN"
-msgstr "Habilitar VLAN:"
-
-msgid "VLAN ID"
-msgstr "ID de VLAN:"
-
-msgid "Stop"
-msgstr "Detener"
-
-msgid "Generate a New Debug Report"
-msgstr "Generar un Informe de depuraci��n nuevo"
-
-msgid "Report Name"
-msgstr "Nombre de informe"
-
-msgid ""
-"The name used to identify the report. If omitted, a name will be chosen "
-"based on current time. Name can contain: letters, digits, underscore
(\"_\") "
-"and hyphen (\"-\")."
-msgstr ""
-"El nombre que se utiliza para identificar el informe. Si se omite, se "
-"elegir�� un nombre bas��ndose en la hora actual. El nombre puede contener: "
-"letras, d��gitos y gui��n (\"-\")."
-
-msgid "Rename a Debug Report"
-msgstr "Generar un Informe de depuraci��n nuevo"
-
-msgid ""
-"The name used to identify the report. Name can contain: letters, digits and "
-"hyphen (\"-\")."
-msgstr ""
-"El nombre que se utiliza para identificar el informe. Si se omite, se "
-"elegir�� un nombre bas��ndose en la hora actual. El nombre puede contener: "
-"letras, d��gitos y gui��n (\"-\")."
-
-msgid "Submit"
-msgstr ""
-
-msgid "Add a Repository"
-msgstr "A��adir un repositorio"
-
-msgid "Identifier"
-msgstr "Identificador"
-
-msgid "Single word, unique identifier for the repository."
-msgstr "Identificador exclusivo de una sola palabra para el repositorio."
-
-msgid "Textual name for the repository."
-msgstr "Nombre textual para el repositorio."
-
-msgid "URL"
-msgstr "URL"
-
-msgid "Required Field"
-msgstr "Campo obligatorio"
-
-msgid "URL to the repository. Supported protocols are http, ftp, and file."
-msgstr "URL al repositorio. Los protocolos soportados son http, ftp y
archivo."
-
-msgid "Repository is a mirror"
-msgstr "El repositorio es un duplicado."
-
-msgid "Distribution"
-msgstr "Distribuci��n"
-
-msgid "Distribution of the DEB repository."
-msgstr "Distribuci��n del repositorio DEB."
-
-msgid "Components"
-msgstr "Componentes"
-
-msgid "List of components in DEB repository."
-msgstr "Lista de componentes en el repositorio DEB."
-
-msgid "Edit Repository"
-msgstr "Editar repositorio"
-
-msgid "Mirror List URL"
-msgstr "URL de lista duplicada"
-
-msgid "Yes"
-msgstr "S��"
-
-msgid "No"
-msgstr "No"
-
-msgid "Capacity"
-msgstr "Capacidad"
-
-msgid "Allocated"
-msgstr "Asignado"
-
-msgid "Location"
-msgstr "Ubicaci��n"
-
-msgid "Device path"
-msgstr "V��a de acceso del dispositivo"
-
-msgid "active"
-msgstr "activo"
-
-msgid "inactive"
-msgstr "inactivo"
-
-msgid "Deactivate"
-msgstr "Desactivar"
-
-msgid "Activate"
-msgstr "Activar"
-
-msgid "Add Volume"
-msgstr ""
-
-msgid "Extend"
-msgstr ""
-
-msgid "Undefine"
-msgstr "No definir"
-
-msgid "Format"
-msgstr "Formato:"
-
-msgid "Allocation"
-msgstr "Asignado:"
-
-msgid "Define a New Storage Pool"
-msgstr "Definir una agrupaci��n de almacenamiento nueva"
-
-msgid "Storage Pool Name"
-msgstr "Nombre de agrupaci��n de almacenamiento"
-
-msgid ""
-"The name used to identify the storage pools, and it should not be empty."
-msgstr ""
-"El nombre que se utiliza para identificar las agrupaciones de almacenamiento
"
-"y no debe estar vac��o."
-
-msgid "Storage Pool Type"
-msgstr "Tipo de agrupaci��n de almacenamiento"
-
-msgid "Storage Path"
-msgstr "V��a de acceso de almacenamiento"
-
-msgid ""
-"The path of the Storage Pool. Each Storage Pool must have a unique path."
-msgstr ""
-"La v��a de acceso de la agrupaci��n de almacenamiento. Cada agrupaci��n de "
-"almacenamiento debe tener una v��a de acceso exclusiva."
-
-msgid ""
-"Kimchi will try to create the directory when it does not already exist in "
-"your system."
-msgstr "Kimchi intentar�� crear el directorio cuando no existe en el sistema."
-
-msgid "NFS Server IP"
-msgstr "IP de Servidor NFS"
-
-msgid "NFS server IP or hostname. It can be input or chosen from history."
-msgstr ""
-"IP o nombre de host de servidor NFS. Puede especificarse o elegirse del "
-"historial."
-
-msgid "NFS Path"
-msgstr "V��a de acceso NFS"
-
-msgid "The NFS exported path on NFS server."
-msgstr "La v��a de acceso exportada de NFS en el servidor NFS."
-
-msgid "iSCSI Server"
-msgstr "Servidor iSCSI"
-
-msgid "Server"
-msgstr "Servidor"
-
-msgid "Port"
-msgstr "Puerto"
-
-msgid "iSCSI server IP or hostname. It should not be empty."
-msgstr "IP o nombre de host de servidor iSCSI. No debe estar vac��o."
-
-msgid "Target"
-msgstr "Destino"
-
-msgid "The iSCSI target on iSCSI server"
-msgstr "El destino iSCSI en el servidor iSCSI"
-
-msgid "Add iSCSI Authentication"
-msgstr "A��adir Autenticaci��n iSCSI"
-
-msgid "iSCSI Authentication"
-msgstr "Autenticaci��n iSCSI"
-
-msgid "User Name"
-msgstr "Nombre de usuario"
-
-msgid "Password"
-msgstr "Contrase��a"
-
-msgid "SCSI Adapter"
-msgstr "Adaptador SCSI"
-
-msgid "Please, wait..."
-msgstr "Por favor, espere..."
-
-msgid "Add a Volume to Storage Pool"
-msgstr ""
-
-msgid "Fetch from remote URL"
-msgstr ""
-
-msgid "Enter the remote URL here."
-msgstr ""
-
-msgid "Upload a file"
-msgstr ""
-
-msgid "Choose the file you want to upload."
-msgstr ""
-
-msgid "Add Template"
-msgstr "A��adir plantilla"
-
-msgid "Where is the source media for this template? "
-msgstr "��D��nde est�� el soporte de origen para esta plantilla?"
-
-msgid "Local ISO Image"
-msgstr "Imagen ISO local"
-
-msgid "Local Image File"
-msgstr ""
-
-msgid "Remote ISO Image"
-msgstr "Imagen ISO remota"
-
-msgid "Search ISOs"
-msgstr "Buscar ISOs"
-
-msgid "The following ISOs are available:"
-msgstr "Las siguientes ISO est��n disponibles:"
-
-msgid "OS: "
-msgstr "SO: "
-
-msgid "Version: "
-msgstr "Versi��n: "
-
-msgid "Size: "
-msgstr "Tama��o: "
-
-msgid "Search more ISOs"
-msgstr "Buscar m��s ISO"
-
-msgid "Create Templates from Selected ISO"
-msgstr "Crear plantillas a partir de ISO seleccionadas"
-
-msgid "I want to use a specific ISO file"
-msgstr "Deseo utilizar un archivo ISO espec��fico"
-
-msgid "Loading default remote ISOs ..."
-msgstr "Cargando ISO remotas predeterminadas ..."
-
-msgid "Arch: "
-msgstr "Arch: "
-
-msgid "I want to use a custom URL"
-msgstr "Deseo utilizar un URL personalizado"
-
-msgid "Edit Template"
-msgstr "Editar plantilla"
-
-msgid "CDROM"
-msgstr "CDROM"
-
-msgid "Image File"
-msgstr ""
-
-msgid "Graphics"
-msgstr "Gr��ficos"
-
-msgid "Disk(GB)"
-msgstr ""
-
-msgid "Disk Format"
-msgstr ""
-
-msgid "CPU Number"
-msgstr "N��mero de CPU"
-
-msgid "Manually set CPU topology"
-msgstr ""
-
-msgid "Cores"
-msgstr ""
-
-msgid "Threads"
-msgstr ""
-
-msgid "No templates found."
-msgstr "No se han encontrado plantillas."
-
-#~ msgid "Delete is not allowed for %(resource)s"
-#~ msgstr "Suprimir no est�� permitido para %(resource)s"
-
-#~ msgid "%(resource)s does not implement update method"
-#~ msgstr "%(resource)s no implementa m��todo de actualizaci��n"
-
-#~ msgid "Create is not allowed for %(resource)s"
-#~ msgstr "Crear no est�� permitido para %(resource)s"
-
-#~ msgid "Unable to parse JSON request"
-#~ msgstr "No se puede analizar la solicitud JSON"
-
-#~ msgid "This API only supports JSON"
-#~ msgstr "Esta API s��lo da soporte a JSON"
-
-#~ msgid "Datastore is not initiated in the model object."
-#~ msgstr "El almac��n de datos no se ha iniciado en el objeto de modelo."
-
-#~ msgid "Unable to start task due error: %(err)s"
-#~ msgstr "No se puede iniciar la tarea debido a un error: %(err)s"
-
-#~ msgid ""
-#~ "Authentication failed for user '%(username)s'. [Error code:
%(code)s]"
-#~ msgstr ""
-#~ "La autenticaci��n ha fallado para el usuario '%(username)s'. [C��digo de
"
-#~ "error: %(code)s]"
-
-#~ msgid "You are not authorized to access Kimchi"
-#~ msgstr "No tiene autorizaci��n para acceder a Kimchi"
-
-#~ msgid "Specify %(item)s to login into Kimchi"
-#~ msgstr "Especifique %(item)s para iniciar la sesi��n en Kimchi"
-
-#~ msgid "Unable to find %(item)s in datastore"
-#~ msgstr "No se puede encontrar %(item)s en el almac��n de datos"
-
-#~ msgid "Timeout while running command '%(cmd)s' after %(seconds)s
seconds"
-#~ msgstr ""
-#~ "Tiempo de espera excedido al ejecutar el mandato '%(cmd)s' despu��s de
%"
-#~ "(seconds)s segundos"
-
-#~ msgid "Help"
-#~ msgstr "Ayuda"
-
-#~ msgid "About"
-#~ msgstr "Acerca de"
-
-#~ msgid "Log out"
-#~ msgstr "Finalizar sesi��n"
-
-#~ msgid "Version:"
-#~ msgstr "Versi��n:"
diff --git a/plugins/kimchi/po/fr_FR.po b/plugins/kimchi/po/fr_FR.po
deleted file mode 100644
index b996e8a..0000000
--- a/plugins/kimchi/po/fr_FR.po
+++ /dev/null
@@ -1,2338 +0,0 @@
-# English translations for kimchi package.
-# Copyright (C) 2013 ORGANIZATION
-#
-msgid ""
-msgstr ""
-"Project-Id-Version: kimchi 0.1\n"
-"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2015-07-01 16:11-0300\n"
-"PO-Revision-Date: 2014-08-27 21:30+0000\n"
-"Last-Translator: BobSynfig\n"
-"Language-Team: French (
http://www.transifex.com/projects/p/kimchi/language/"
-"fr/)\n"
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
-"Content-Transfer-Encoding: 8bit\n"
-"Language: fr_FR\n"
-"Generated-By: pygettext.py 1.5\n"
-"Plural-Forms: nplurals=2; plural=(n != 1);\n"
-
-#, python-format
-msgid "Unknown parameter %(value)s"
-msgstr "Param��tre inconnu %(value)s"
-
-#, python-format
-msgid "Timeout of %(seconds)s seconds expired while running task
'%(task)s."
-msgstr ""
-
-#, python-format
-msgid "User %(user_id)s not found with given LDAP settings."
-msgstr ""
-
-msgid "Unknown \"_cap\" specified"
-msgstr "\"_cap\" sp��cifi��e inconnue"
-
-msgid "\"_passthrough\" should be \"true\" or
\"false\""
-msgstr "\"_passthrough\" doit ��tre \"true\" ou
\"false\""
-
-msgid "\"_passthrough_affected_by\" should be a device name string"
-msgstr "\"_passthrough_affected_by\" doit ��tre un nom de
p��riph��rique"
-
-#, python-format
-msgid "Error while getting block devices. Details: %(err)s"
-msgstr "Erreur durant l'acc��s aux p��riph��riques de bloc. D��tails:
%(err)s"
-
-#, python-format
-msgid "Error while getting block device information for %(device)s."
-msgstr ""
-"Erreur durant l'obtention de l'information sur le p��riph��rique de bloc
%"
-"(device)s."
-
-#, python-format
-msgid "Unable to find distro file: %(filename)s"
-msgstr "Impossible de trouver le fichier de distro: %(filename)s"
-
-#, python-format
-msgid ""
-"Unable to parse distro file: %(filename)s. Make sure, it is a JSON file."
-msgstr ""
-"Impossible de parser le fichier de distro: %(filename)s. Veuillez vous "
-"assurer qu'il s'agit d'un fichier JSON."
-
-#, python-format
-msgid "Unable to login to iSCSI host target %(portal)s. Details: %(err)s"
-msgstr ""
-"Impossible de se connecter �� l'h��te cible iSCSI %(portal)s. D��tails: %(err)s
"
-
-#, python-format
-msgid "Unable to login to iSCSI host %(host)s target %(target)s"
-msgstr "Impossible de se connecter �� l'h��te iSCSI %(host)s cible
%(target)s"
-
-#, python-format
-msgid "Unable to find ISO file %(filename)s"
-msgstr "Impossible de trouver le fichier ISO %(filename)s"
-
-#, python-format
-msgid "The ISO file %(filename)s is not bootable"
-msgstr "Le fichier ISO %(filename)s n'est pas bootable"
-
-#, python-format
-msgid "The ISO file %(filename)s does not have a valid El Torito boot record"
-msgstr ""
-"Le fichier ISO %(filename)s n'a pas d'enregistrement de boot El Torito
valide"
-
-#, python-format
-msgid "Invalid El Torito validation entry in ISO %(filename)s"
-msgstr "Entr��e de validation El Torito invalide dans l'ISO %(filename)s"
-
-#, python-format
-msgid "Invalid El Torito boot indicator in ISO %(filename)s"
-msgstr "Indicateur de boot El Torito invalide dans l'ISO %(filename)s"
-
-#, python-format
-msgid "Unexpected volume type for primary volume in ISO %(filename)s"
-msgstr ""
-"Type de volume inattendu pour le volume primaire dans l'ISO %(filename)s"
-
-#, python-format
-msgid "Bad format while reading volume descriptor in ISO %(filename)s"
-msgstr ""
-"Mauvais format durant la lecture du descripteur de volume dans l'ISO %"
-"(filename)s"
-
-#, python-format
-msgid ""
-"The hypervisor doesn't have permission to use this ISO %(filename)s. "
-"Consider moving it under /var/lib/libvirt, or set the search permission to "
-"file access control lists for '%(user)s' user if possible, or add the
'%"
-"(user)s' to the ISO path group, or (not recommended) 'chmod -R o+x "
-"'path_to_iso'.Details: %(err)s"
-msgstr ""
-"L'hyperviseur n'a pas la permission d'utiliser cet ISO %(filename)s.
"
-"Veuillez consid��rer de le d��placer sous /var/lib/libvirt,, ou de d��finir la
"
-"permission de recherche sur les listes de contrpole d'acc��s fichier pour
"
-"l'utilisateur '%(user)s' si possible, ou ajouter le '%(user)s'
au groupe de "
-"chemins d'ISO, ou (non recommand��) 'chmod -R o+x
'chemin_vers_iso'.D��tails: "
-"%(err)s"
-
-msgid "An error occurred when probing image OS information."
-msgstr ""
-"Une erreur est survenue lors de la d��tection de l'information d'OS de
"
-"l'image."
-
-msgid "No OS information found in given image."
-msgstr "Aucune information d'OS trouv��e sur l'image donn��e."
-
-#, python-format
-msgid "Unable to read image file %(filename)s"
-msgstr "Impossible de lire le fichier image %(filename)s"
-
-#, python-format
-msgid ""
-"Image file must be an existing file on system. %(filename)s is not a valid "
-"input."
-msgstr ""
-"Le fichier image doit ��tre un fichier existant sur le syst��me. %(filename)s
"
-"n'est pas une donn��e valide."
-
-#, python-format
-msgid "Virtual machine %(name)s already exists"
-msgstr "La machine virtuelle %(name)s existe d��j��"
-
-#, python-format
-msgid "Virtual machine %(name)s does not exist"
-msgstr "La machine virtuelle %(name)s n'existe pas"
-
-#, python-format
-msgid ""
-"Unable to rename virtual machine %(name)s. The name %(new_name)s is already "
-"in use or the virtual machine is not powered off."
-msgstr ""
-"Impossible de renommer la machine virtuelle %(name)s. Le nom %(new_name)s "
-"est d��ja utilis�� ou la machine virtuelle n'est pas ��teinte."
-
-#, python-format
-msgid "Unable to retrieve screenshot for stopped virtual machine %(name)s"
-msgstr ""
-"Impossible de r��cup��rer une capture d'��cran pour la machine virtuelle
"
-"stopp��e %(name)s"
-
-msgid "Remote ISO image is not supported by this server."
-msgstr "L'image ISO distante n'est pas support��e par le serveur."
-
-#, python-format
-msgid "Screenshot is not supported on virtual machine %(name)s"
-msgstr "Copie d'��cran non support��e par la machine virtuelle %(name)s"
-
-#, python-format
-msgid "Unable to create virtual machine %(name)s. Details: %(err)s"
-msgstr "Impossible de cr��er la machine virtuelle %(name)s. D��tails: %(err)s"
-
-#, python-format
-msgid "Unable to update virtual machine %(name)s. Details: %(err)s"
-msgstr ""
-"Impossible de mettre �� jour la machine virtuelle %(name)s. D��tails:
%(err)s"
-
-#, python-format
-msgid "Unable to retrieve virtual machine %(name)s. Details: %(err)s"
-msgstr ""
-"Impossible de r��cup��rer la machine virtuelle %(name)s. D��tails: %(err)s"
-
-#, python-format
-msgid "Unable to connect to powered off virtual machine %(name)s."
-msgstr "Impossible de se connecter �� la machine virtuelle ��teinte %(name)s."
-
-msgid "Virtual machine name must be a string without slashes (/)"
-msgstr ""
-
-#, python-format
-msgid "Invalid template URI %(value)s specified for virtual machine"
-msgstr ""
-
-#, python-format
-msgid "Invalid storage pool URI %(value)s specified for virtual machine"
-msgstr ""
-
-msgid "Supported virtual machine graphics are Spice or VNC"
-msgstr ""
-
-msgid "Graphics address to listen on must be IPv4 or IPv6"
-msgstr "L'adresse d'��coute du graphics doit ��tre IPv4 ou IPv6"
-
-msgid "Specify a template to create a virtual machine from"
-msgstr "Sp��cifier un mod��le �� partir duquel cr��er une machine virtuelle"
-
-#, python-format
-msgid "Unable to start virtual machine %(name)s. Details: %(err)s"
-msgstr "Impossible de d��marrer la machine virtuelle %(name)s. D��tails:
%(err)s"
-
-#, python-format
-msgid "Unable to power off virtual machine %(name)s. Details: %(err)s"
-msgstr ""
-"Impossible de mettre hors tension la machine virtuelle %(name)s. D��tails: %"
-"(err)s"
-
-#, python-format
-msgid "Unable to delete virtual machine %(name)s. Details: %(err)s"
-msgstr ""
-"Impossible de supprimer la machine virtuelle %(name)s. D��tails: %(err)s"
-
-#, python-format
-msgid "Unable to reset virtual machine %(name)s. Details: %(err)s"
-msgstr ""
-"Impossible de r��initrialiser la machine virtuelle %(name)s. D��tails:
%(err)s"
-
-msgid "User name list must be an array"
-msgstr ""
-
-msgid "User name must be a string"
-msgstr "Le nom d'utilisateur doit ��tre une cha��ne de caract��res"
-
-msgid "Group name list must be an array"
-msgstr ""
-
-msgid "Group name must be a string"
-msgstr "Le nom de groupe doit ��tre une cha��ne de caract��res"
-
-#, python-format
-msgid "User(s) '%(users)s' do not exist"
-msgstr "Le(s) utilisateur(s) '%(users)s' n'existe(nt) pas"
-
-#, python-format
-msgid "Group(s) '%(groups)s' do not exist"
-msgstr "Le(s) groupe(s) '%(groups)s' n'existe(nt) pas"
-
-#, python-format
-msgid "Unable to shutdown virtual machine %(name)s. Details: %(err)s"
-msgstr "Impossible d'��teindre la machine virtuelle %(name)s. D��tails:
%(err)s"
-
-#, python-format
-msgid ""
-"Unable to get access metadata of virtual machine %(name)s. Details: %(err)s"
-msgstr ""
-"Impossible d'acc��der aux metadata de la machine virtuelle %(name)s. D��tails:
"
-"%(err)s"
-
-msgid "The guest console password must be a string."
-msgstr "Le mot de passe de console invit��e doit ��tre une cha��ne de
caract��res."
-
-msgid "The life time for the guest console password must be a number."
-msgstr "La dur��e de vie du mot de passe de console invit��e doit ��tre un
nombre"
-
-#, python-format
-msgid "Virtual machine '%(name)s' must be stopped before cloning it."
-msgstr ""
-
-#, python-format
-msgid "Insufficient disk space to clone virtual machine '%(name)s'"
-msgstr ""
-
-#, python-format
-msgid "Unable to clone VM '%(name)s'. Details: %(err)s"
-msgstr ""
-
-#, python-format
-msgid "Invalid operation for non-persistent virtual machine %(name)s"
-msgstr ""
-
-#, python-format
-msgid "Cannot suspend VM '%(name)s' because it is not running."
-msgstr ""
-
-#, python-format
-msgid "Unable to suspend VM '%(name)s'. Details: %(err)s"
-msgstr ""
-
-#, python-format
-msgid "Cannot resume VM '%(name)s' because it is not paused."
-msgstr ""
-
-#, python-format
-msgid "Unable to resume VM '%(name)s'. Details: %(err)s"
-msgstr ""
-
-msgid "Memory assigned is higher then the maximum allowed in the host."
-msgstr ""
-
-#, python-format
-msgid ""
-"VM '%(name)s' does not support live memory update. Update the memory with
"
-"the machine offline to enable this feature."
-msgstr ""
-
-msgid "Only increase memory is allowed in active VMs"
-msgstr ""
-
-msgid ""
-"For live memory update, new memory value must be equal old memory value plus
"
-"multiples of 1024 Mib"
-msgstr ""
-
-msgid "There are not enough free slots of 1024 Mib in the guest."
-msgstr ""
-
-msgid ""
-"Host's libvirt version does not support memory devices. Libvirt must be >=
"
-"1.2.14"
-msgstr ""
-
-#, python-format
-msgid "Error attaching memory device. Details: %(error)s"
-msgstr ""
-
-#, python-format
-msgid ""
-"VM %(vmid)s does not contain directly assigned host device %(dev_name)s."
-msgstr ""
-"La machine virtuelle %(vmid)s ne peut pas contenir le p��riph��rique h��te "
-"directement assign�� %(dev_name)s."
-
-#, python-format
-msgid "The host device %(dev_name)s is not allowed to directly assign to VM."
-msgstr ""
-"The p��riph��rique h��te %(dev_name)s ne peut ��tre directement assign�� �� la
"
-"machine virtuelle"
-
-msgid ""
-"No IOMMU groups found. Host PCI pass through needs IOMMU group to function "
-"correctly. Please enable Intel VT-d or AMD IOMMU in your BIOS, then verify "
-"the Kernel is compiled with IOMMU support. For Intel CPU, add intel_iommu=on
"
-"to your Kernel parameter in /boot/grub2/grub.conf. For AMD CPU, add iommu=pt
"
-"iommu=1."
-msgstr ""
-
-msgid "\"name\" should be a device name string"
-msgstr "\"name\" doit ��tre un nom de p��riph��rique"
-
-#, python-format
-msgid ""
-"The device %(name)s is probably in use by the host. Unable to attach it to "
-"the guest."
-msgstr ""
-
-#, python-format
-msgid "Interface %(iface)s does not exist in virtual machine %(name)s"
-msgstr "L'interface %(iface)s n'existe pas dans la machine virtuelle
%(name)s"
-
-#, python-format
-msgid ""
-"Network %(network)s specified for virtual machine %(name)s does not exist"
-msgstr ""
-"Le r��seau %(network)s sp��cifi�� pour la machine virtuelle %(name)s n'existe
"
-"pas"
-
-msgid "Supported virtual machine interfaces type is only network"
-msgstr ""
-"Le type d'interface de machine virtuelle support�� est r��seau
uniquement"
-
-msgid "Network name for virtual machine interface must be a string"
-msgstr ""
-"Le nom de r��seau pour l'interface de la machine virtuelle doit ��tre une
"
-"cha��ne de caract��res"
-
-msgid "Invalid network model card specified for virtual machine interface"
-msgstr ""
-"Mod��le de carte r��seau sp��cifi�� invalide pour l'interface de machine
"
-"virtuelle"
-
-msgid "Specify type and network to add a new virtual machine interface"
-msgstr ""
-"Sp��cifier le type et le r��seau �� ajouter �� la nouvelle interface de la "
-"machine virtuelle"
-
-msgid "MAC Address must respect this format FF:FF:FF:FF:FF:FF"
-msgstr ""
-
-#, python-format
-msgid "MAC Address %(mac)s already exists in virtual machine %(name)s"
-msgstr ""
-
-msgid "Invalid MAC Address"
-msgstr ""
-
-msgid "Cannot change MAC address of a running virtual machine"
-msgstr ""
-
-#, python-format
-msgid "Template %(name)s already exists"
-msgstr "Le mod��le %(name)s existe d��j��"
-
-#, python-format
-msgid ""
-"Network '%(network)s' specified for template %(template)s does not
exist"
-msgstr ""
-"Le r��seau '%(network)s' sp��cifi�� pour le mod��le %(template)s
n'existe pas"
-
-#, python-format
-msgid ""
-"Storage pool %(pool)s specified for template %(template)s does not exist"
-msgstr ""
-"Le pool de stockage sp��cifi�� %(pool)s pour le mod��le %(template)s n'existe
"
-"pas"
-
-#, python-format
-msgid "Storage pool %(pool)s specified for template %(template)s is not
active"
-msgstr ""
-"Le pool de stockage sp��cifi�� %(pool)s pour le mod��le %(template)s n'est pas
"
-"actif"
-
-#, python-format
-msgid "Invalid parameter '%(param)s' specified for CDROM."
-msgstr "Param��tres '%(param)s' sp��cifi�� invalide pour le CDROM"
-
-#, python-format
-msgid "Network %(network)s specified for template %(template)s is not active"
-msgstr ""
-"Le r��seau %(network)s sp��cifi�� pour le mod��le %(template)s n'est pas
actif"
-
-msgid "Template name must be a string"
-msgstr "Le mod��le de nom doit ��tre une cha��ne de caract��res"
-
-msgid "Template icon must be a path to the image"
-msgstr "Le mod��le d'icone doit ��tre un chemin vers l'image"
-
-msgid "Template distribution must be a string"
-msgstr "Le mod��le de distribution doit ��tre une cha��ne de caract��res"
-
-msgid "Template distribution version must be a string"
-msgstr ""
-"Le mod��le de version de distribution doit ��tre une cha��ne de caract��res"
-
-msgid "The number of CPUs must be an integer greater than 0"
-msgstr "Le nombre de CPU doit ��tre un nombre entier sup��rieur �� 0"
-
-msgid "Amount of memory (MB) must be an integer greater than 512"
-msgstr "La quantit�� de m��moire (Mo) doit ��tre un nombre entier sup��rieur ��
512"
-
-msgid "Template CDROM must be a local or remote ISO file"
-msgstr "Le CDROM mod��le doit ��tre un fichier ISO local ou distant"
-
-#, python-format
-msgid "Invalid storage pool URI %(value)s specified for template"
-msgstr "URI %(value)s du pool de stockage sp��cifi��e invalide pour le
mod��le"
-
-msgid "Specify an ISO image as CDROM or a base image to create a template"
-msgstr ""
-"Sp��cifiez une image ISO comme CDROM ou une image de base pour cr��er un
mod��le"
-
-msgid "All networks for the template must be specified in a list."
-msgstr "Tous les r��seaux pour le mod��le doivent ��tre sp��cifi��s dans une
liste"
-
-msgid "Specify a volume to a template when storage pool is iSCSI or SCSI"
-msgstr ""
-
-#, python-format
-msgid "The volume %(volume)s is not in storage pool %(pool)s"
-msgstr "Le volume %(volume)s n'est pas dans le pool de stockage %(pool)s"
-
-#, python-format
-msgid "Unable to create template due error: %(err)s"
-msgstr "Impossible de cr��er le mod��le �� cause de l'erreur: %(err)s"
-
-#, python-format
-msgid "Unable to delete template due error: %(err)s"
-msgstr "Impossilbe de supprimer le mod��le �� cause de l'erreur: %(err)s"
-
-msgid "Disk size must be an integer greater than 1GB."
-msgstr "La taille de disque doit ��tre un entier sup��rieur �� 1Go."
-
-msgid "Template base image must be a valid local image file"
-msgstr "L'image de base de mod��le doit petre un fichier image local
valide"
-
-#, python-format
-msgid "Cannot identify base image %(path)s format"
-msgstr "Ne peut identifier le format de l'image de base %(path)s"
-
-msgid ""
-"When specifying CPU topology, VCPUs must be a product of sockets, cores, and
"
-"threads."
-msgstr ""
-
-msgid ""
-"When specifying CPU topology, each element must be an integer greater than "
-"zero."
-msgstr ""
-"Dans la topologie de CPU, chaque ��l��ment doit ��tre un entier strictement "
-"positif."
-
-msgid ""
-"Invalid disk image format. Valid formats: bochs, cloop, cow, dmg, qcow, "
-"qcow2, qed, raw, vmdk, vpc."
-msgstr ""
-
-#, python-format
-msgid "Storage pool %(name)s already exists"
-msgstr "Le pool de stockage %(name)s existe d��j��"
-
-#, python-format
-msgid "Storage pool %(name)s does not exist"
-msgstr "Le pool de stockage %(name)s n'existe pas"
-
-#, python-format
-msgid "Specify %(item)s in order to create the storage pool %(name)s"
-msgstr "Sp��cifier %(item)s afin de cr��er le pool de stockage %(name)s"
-
-#, python-format
-msgid "Unable to delete active storage pool %(name)s"
-msgstr "Impossible de supprimer le pool de stockage actif %(name)s"
-
-#, python-format
-msgid "Unable to list storage pools. Details: %(err)s"
-msgstr "Impossible de lister les pools de stockage. D��tails: %(err)s"
-
-#, python-format
-msgid "Unable to create storage pool %(name)s. Details: %(err)s"
-msgstr "Impossilble de cr��er le pool de stockage %(name)s. D��tails: %(err)s"
-
-#, python-format
-msgid ""
-"Unable to get number of storage volumes in storage pool %(name)s. Details: %"
-"(err)s"
-msgstr ""
-"Impossible d'obtenir le nombre de volumes de stockage dans le pool de "
-"stockage%(name)s. D��tails: %(err)s"
-
-#, python-format
-msgid "Unable to activate storage pool %(name)s. Details: %(err)s"
-msgstr "Impossible d'activer le pool de stockage %(name)s. D��tails:
%(err)s"
-
-#, python-format
-msgid "Unable to deactivate storage pool %(name)s. Details: %(err)s"
-msgstr ""
-"Impossible de d��sactiver le pool de stockage %(name)s. D��tails: %(err)s"
-
-#, python-format
-msgid "Unable to delete storage pool %(name)s. Details: %(err)s"
-msgstr ""
-"Impossible de supprimer le pool de stockage %(name)s. D��tails: %(err)s "
-
-#, python-format
-msgid ""
-"Unable to create NFS Pool as export path %(path)s may block during mount"
-msgstr ""
-"Impossible de cr��er le Pool NFS du fait que le chemin d'export %(path)s
"
-"pourrait se bloquer durant le montage"
-
-#, python-format
-msgid "Unable to create NFS Pool as export path %(path)s mount failed"
-msgstr ""
-"Impossible de cr��er le pool NFS du fait que le montage du chemin d'export
%"
-"(path)s a ��chou��"
-
-#, python-format
-msgid "Unsupported storage pool type: %(type)s"
-msgstr "Type de pool de stockage non support��: %(type)s"
-
-#, python-format
-msgid "Error while retrieving storage pool XML to %(pool)s"
-msgstr ""
-
-msgid "Storage pool name must be a string without slashes (/)"
-msgstr ""
-
-msgid ""
-"Supported storage pool types are dir, netfs, logical, iscsi, isci and
kimchi-"
-"iso"
-msgstr ""
-"Les types de pool de stockage support��s sont: dir, netfs, logical, iscsi, "
-"isci et kimchi-iso"
-
-msgid "Storage pool path must be a string"
-msgstr "Le chemin du pool de stockage doit ��tre une cha��ne de caract��res"
-
-msgid "Storage pool host must be a IP or hostname"
-msgstr "L'h��te du pool de stockage doit ��tre une IP ou un nom
d'h��te"
-
-msgid "Storage pool device must be the absolute path to the block device"
-msgstr ""
-
-msgid "Storage pool devices parameter must be a list"
-msgstr "Le param��tre de p��riph��rique de pool de stockage doit ��tre une
list"
-
-msgid "Target IQN of an iSCSI pool must be a string"
-msgstr "La cible IQN d'un pool iSCSI doit ��tre une cha��ne de
caract��res"
-
-msgid "Port of a remote storage server must be an integer between 1 and 65535"
-msgstr ""
-"Le port d'un serveur de stockage distant doit ��tre un nombre entier entre 1
"
-"et 65535"
-
-msgid "iSCSI target username must be a string"
-msgstr ""
-"Le nom d'utilisateur de la cible iSCSI doit ��tre une cha��ne de
caract��res"
-
-msgid "iSCSI target password must be a string"
-msgstr "Le mot de passe de la cible iSCSI doit ��tre une cha��ne de
caract��res"
-
-msgid "Specify name and type to create a storage pool"
-msgstr "Sp��cifier un nom et un type pour cr��er un pool de stockage"
-
-#, python-format
-msgid ""
-"%(disk)s is not a valid disk/partition. Could not add it to the pool %(pool)"
-"s."
-msgstr ""
-"%(disk)s n'est pas un(e) disque/partition valide. N'a pu l'ajouter au
pool %"
-"(pool)s."
-
-#, python-format
-msgid "Unable to extend logical pool %(pool)s. Details: %(err)s"
-msgstr "Impossible d'agrandir le pool logique %(pool)s. D��tails: %(err)s"
-
-msgid "The parameter disks only can be updated for logical storage pool."
-msgstr ""
-"Les disques en param��tre peuvent seulement ��tre mis �� jour pour un pool de
"
-"stockage logique."
-
-msgid "The SCSI host adapter name must be a string."
-msgstr "Le nom d'adaptateur de l'h��te SCSI doit ��tre une chapine de
caract��res"
-
-msgid "The storage pool kimchi_isos is reserved for internal use"
-msgstr "Le pool de stockage kimchi_isos est r��serv�� �� un usage interne"
-
-#, python-format
-msgid ""
-"Unable to activate NFS storage pool %(name)s. NFS server %(server)s is "
-"unreachable."
-msgstr ""
-"Impossible d'activer le pool de stockage NFS%(name)s. Le serveur NFS %"
-"(server)s n'est pas joignable."
-
-#, python-format
-msgid ""
-"Unable to deactivate NFS storage pool %(name)s. NFS server %(server)s is "
-"unreachable."
-msgstr ""
-"Impossible de d��sactiver le pool de stockage NFS%(name)s. Le serveur NFS %"
-"(server)s n'est pas joignable."
-
-#, python-format
-msgid ""
-"Unable to deactivate pool %(name)s as it is associated with some templates"
-msgstr ""
-"Impossible de d��sactiver le pool %(name)s du fait qu'il est associ�� �� des
"
-"mod��les"
-
-#, python-format
-msgid "Unable to delete pool %(name)s as it is associated with some templates"
-msgstr ""
-"Impossible de supprimer le pool %(name)s du fait qu'il est associ�� �� des
"
-"mod��les"
-
-#, python-format
-msgid ""
-"A volume group named '%(name)s' already exists. Please, choose another name
"
-"to create the logical pool."
-msgstr ""
-"Un groupe de volume appel�� '%(name)s' existe d��j��. Veuillez choisir un
autre "
-"nom pour cr��er le pool logique."
-
-#, python-format
-msgid "Unable to update database with deep scan information due error:
%(err)s"
-msgstr ""
-"Impossible de mettre �� jour la base de donn��es avec les informations de scan
"
-"profond �� cause de l'erreur: %(err)s"
-
-#, python-format
-msgid "Storage volume %(name)s already exists"
-msgstr "Le volume de stockage %(name)s existe d��j��"
-
-#, python-format
-msgid "Storage volume %(name)s does not exist in storage pool %(pool)s"
-msgstr ""
-"Le volume de stockage %(name)s n'existe pas dans le pool de stockage
%(pool)s"
-
-#, python-format
-msgid ""
-"Unable to create storage volume %(volume)s because storage pool %(pool)s is "
-"not active"
-msgstr ""
-"Impossible de cr��er le volume de stockage %(volume)s car le pool de stockage
"
-"%(pool)s n'est pas actif"
-
-#, python-format
-msgid "Specify %(item)s in order to create storage volume %(volume)s"
-msgstr "Sp��cifier %(item)s afin de cr��er le volume de stockage %(volume)s"
-
-#, python-format
-msgid ""
-"Unable to list storage volumes because storage pool %(pool)s is not active"
-msgstr ""
-"Impossible de lister les volumes de stockage car le pool de stockage %(pool)"
-"s n'est pas actif"
-
-#, python-format
-msgid ""
-"Unable to create storage volume %(name)s in storage pool %(pool)s. Details:
%"
-"(err)s"
-msgstr ""
-"Impossible de cr��er le volume de stockage %(name)s dans le pool de stockage
%"
-"(pool)s. D��tails: %(err)s"
-
-#, python-format
-msgid ""
-"Unable to list storage volumes in storage pool %(pool)s. Details: %(err)s"
-msgstr ""
-"Impossible de lister les volumes de stockage dans le pool de stockage
%(pool)"
-"s. D��tails: %(err)s"
-
-#, python-format
-msgid "Unable to wipe storage volumes %(name)s. Details: %(err)s"
-msgstr "Impossible de wiper les volumes de stockage %(name)s. D��tails:
%(err)s"
-
-#, python-format
-msgid "Unable to delete storage volume %(name)s. Details: %(err)s"
-msgstr ""
-"Impossible de supprimer le volume de stockage %(name)s. D��tails: %(err)s "
-
-#, python-format
-msgid "Unable to resize storage volume %(name)s. Details: %(err)s"
-msgstr ""
-"Impossible de redimensionner le volume de stockage %(name)s. D��tails:
%(err)s"
-
-#, python-format
-msgid "Storage type %(type)s does not support volume create and delete"
-msgstr ""
-"Le type de stockage %(type)s ne supporte pas ni la cr��ation ni la "
-"suppression de volume"
-
-msgid "Storage volume name must be a string"
-msgstr "Le nom de volume de stockage doit ��tre une cha��ne de caract��res"
-
-msgid "Storage volume allocation must be an integer number"
-msgstr "L'allocation de volume de stockage doit ��tre une nombre entier"
-
-msgid ""
-"Storage volume format not supported. Valid formats: bochs, cloop, cow, dmg, "
-"qcow, qcow2, qed, raw, vmdk, vpc."
-msgstr ""
-
-msgid "Storage volume requires a volume name"
-msgstr "Le volume de stockage requiert un nom de volume"
-
-#, python-format
-msgid ""
-"Unable to update database with storage volume information due error: %(err)s"
-msgstr ""
-"Impossible de mettre �� jour la base de donn��es avec les informations du "
-"volume de stockage �� cause de l'erreur: %(err)s"
-
-#, python-format
-msgid "Only one of parameter %(param)s can be specified"
-msgstr "Seulement un seul des param��tre %(param)s peut ��tre sp��cifi��"
-
-#, python-format
-msgid "Create volume from %(param)s is not supported"
-msgstr "La cr��ation de volume avec %(param)s n'est pas support��e"
-
-msgid "Storage volume capacity must be an integer number."
-msgstr "La capacit�� du volume de stockage doit ��tre un nombre entier."
-
-msgid "Storage volume URL must be http://, https://, ftp:// or ftps://."
-msgstr ""
-"L'URL du volume de stockage doit ��tre http://, https://, ftp:// ou
ftps://."
-
-#, python-format
-msgid "Unable to access file %(url)s. Please, check it."
-msgstr "Impossible d'acc��der au fichier %(url)s. Veuillez le v��rifier."
-
-#, python-format
-msgid ""
-"Unable to clone storage volume '%(name)s' in pool '%(pool)s'.
Details: %(err)"
-"s"
-msgstr ""
-
-msgid "Specify chunk data and its size to upload a file."
-msgstr ""
-
-msgid "In order to upload a storage volume, specify the 'upload'
parameter."
-msgstr ""
-
-msgid ""
-"Unable to upload chunk data as it does not match with requested chunk size."
-msgstr ""
-
-#, python-format
-msgid "The storage volume %(vol)s is not under an upload process."
-msgstr ""
-
-msgid "The upload chunk data will exceed the storage volume size."
-msgstr ""
-
-#, python-format
-msgid "Unable to upload chunk data to storage volume. Details: %(err)s."
-msgstr ""
-
-#, python-format
-msgid "Interface %(name)s does not exist"
-msgstr "L'interface %(name)s n'existe pas"
-
-#, python-format
-msgid "Network %(name)s already exists"
-msgstr "Le r��seau %(name)s existe d��j��"
-
-#, python-format
-msgid "Network %(name)s does not exist"
-msgstr "Le r��seau %(name)s n'existe pas"
-
-#, python-format
-msgid "Subnet %(subnet)s specified for network %(network)s is not valid."
-msgstr ""
-"Le sous-r��seau %(subnet)s sp��cifi�� pour le r��seau %(network)s n'est pas
"
-"valide"
-
-#, python-format
-msgid "Specify a network interface to create bridged network %(name)s"
-msgstr "Sp��cifier une interface r��seau pour cr��er le r��seau bridge
%(name)s"
-
-#, python-format
-msgid "Unable to delete active network %(name)s"
-msgstr "Impossible de supprimer le r��seau actif %(name)s"
-
-#, python-format
-msgid "Interface %(iface)s specified for network %(network)s is already in
use"
-msgstr ""
-"L'interface %(iface)s sp��cifi��e pour le r��seau %(network)s est d��j��
utilis��e"
-
-msgid "Interface should be bare NIC, bonding or bridge device."
-msgstr "L'interface doit ��tre un p��riph��rique NIC vide, bonding ou
bridg��."
-
-#, python-format
-msgid "Unable to create network %(name)s. Details: %(err)s"
-msgstr "Impossible de cr��er le r��seau %(name)s. D��tails: %(err)s"
-
-#, python-format
-msgid "Unable to find a free IP address for network '%(name)s'"
-msgstr "Impossible de trouver une adresse IP libre pour le r��seau
'%(name)s'"
-
-#, python-format
-msgid "The interface %(iface)s already exists."
-msgstr "L'interface %(iface)s existe d��j��"
-
-msgid "Network name must be a string without slashes (/) or quotes (\")"
-msgstr ""
-
-msgid "Supported network types are isolated, NAT and bridge"
-msgstr "Les types de r��seaux support��s sont isolated, NAT et bridge"
-
-msgid "Network subnet must be a string with IP address and prefix or netmask"
-msgstr ""
-"Le sous-r��seau doit ��tre une chaine de caract��res avec une adresse IP et un
"
-"pr��fixe ou un masque de r��seau"
-
-msgid "Network interface must be a string"
-msgstr "L'interface de r��seau doit ��tre une cha��ne de caract��res"
-
-msgid "Network VLAN ID must be an integer between 1 and 4094"
-msgstr "L'ID de VLAN du r��seau doit ��tre un nombre entier entre 1 et
4094"
-
-msgid "Specify name and type to create a Network"
-msgstr "Sp��cifiez un nom et un type pour cr��er un r��seau"
-
-#, python-format
-msgid ""
-"Unable to delete network %(name)s. There are some virtual machines %(vms)s "
-"and/or templates linked to this network."
-msgstr ""
-"Impossible de supprimer le r��seau %(name)s. Il y a des machines virtuelles
%"
-"(vms)s et/ou des mod��les li��s �� ce r��seau. "
-
-#, python-format
-msgid ""
-"Unable to deactivate network %(name)s. There are some virtual machines
%(vms)"
-"s and/or templates linked to this network."
-msgstr ""
-"Impossible de d��sactiver r��seau %(name)s. Il y a des machines virtuelles%"
-"(vms)s et/ou des mod��les li��s �� ce r��seau. "
-
-#, python-format
-msgid "Bridge device %(name)s can not be the trunk device of a VLAN."
-msgstr ""
-"Le p��riph��rique bridge %(name)s ne peut ��tre le p��riph��rique tronc d'un
VLAN."
-
-#, python-format
-msgid "Failed to activate interface %(iface)s: %(err)s."
-msgstr "��chec durant l'activation de l'interface %(iface)s: %(err)s."
-
-#, python-format
-msgid ""
-"Failed to activate interface %(iface)s. Please check the physical link "
-"status."
-msgstr ""
-"��chec durant l'activation de l'interface %(iface)s. Veuillez v��rifier le
"
-"statut du lien physique."
-
-#, python-format
-msgid "Failed to start network %(name)s. Details: %(err)s"
-msgstr ""
-
-#, python-format
-msgid "Debug report %(name)s does not exist"
-msgstr "Le rapport de d��boggage %(name)s n'existe pas"
-
-msgid "Debug report tool not found in system"
-msgstr "L'outil de rapport de d��boggage n'a pas ��t�� trouv�� dans le
syst��me"
-
-#, python-format
-msgid "Unable to create debug report %(name)s. Details: %(err)s."
-msgstr ""
-"Impossible de cr��er le rapport de d��boggage %(name)s. D��tails: %(err)s."
-
-#, python-format
-msgid "Can not find any debug report with the given name %(name)s"
-msgstr ""
-"Impossible de trouver un rapport de d��boggage avec le nom fourni %(name)s"
-
-#, python-format
-msgid "Unable to generate debug report %(name)s. Details: %(err)s"
-msgstr ""
-"Impossible de g��n��rer le rapport de d��boggage %(name)s. D��tails: %(err)s"
-
-msgid "You should give a name for the debug report file."
-msgstr "Vous devriez donner un nom au fichier de rapport de d��boggage."
-
-msgid ""
-"Debug report name must be a string. Only letters, digits, underscore ('_')
"
-"and hyphen ('-') are allowed."
-msgstr ""
-"Le nom du rapport de d��boggage doit ��tre une cha��ne de caract��res. Seulement
"
-"les lettres, chiffres, blanc soulign�� ('_') et tirets ('-') sont
accept��s."
-
-#, python-format
-msgid ""
-"The debug report with specified name \"%(name)s\" already exists. Please
use "
-"another one."
-msgstr ""
-"Le rapport de d��boggage avec le nom sp��cifi�� \"%(name)s\" existe
d��j��. "
-"Veuillez en utiliser un autre."
-
-#, python-format
-msgid "Storage server %(server)s was not used by Kimchi"
-msgstr "Le server de stockage %(server)s n'��tait pas utilis�� par Kimchi"
-
-#, python-format
-msgid "Distro '%(name)s' does not exist"
-msgstr "La distro '%(name)s' n'existe pas"
-
-#, python-format
-msgid "Partition %(name)s does not exist in the host"
-msgstr "La partition %(name)s n'existe pas sur cet h��te"
-
-msgid "Unable to shutdown host machine as there are running virtual machines"
-msgstr ""
-"Impossible d'��teindre la machine h��te car des machines virtuelles en sont
"
-"cours d'ex��cution"
-
-msgid "Unable to reboot host machine as there are running virtual machines"
-msgstr ""
-"Impossible de red��marrer la machine h��te car des machines virtuelles en sont
"
-"cours d'ex��cution"
-
-#, python-format
-msgid "Node device '%(name)s' not found"
-msgstr "P��riph��rique de noeud '%(name)s' non trouv��"
-
-msgid "Conflicting flag filters specified."
-msgstr "Filtres incompatibles sp��cifi��s."
-
-msgid "No packages marked for update"
-msgstr "Aucun paquet marqu�� pour mise �� jour"
-
-#, python-format
-msgid "Package %(name)s is not marked to be updated."
-msgstr "Le paquet %(name)s n'est pas marqu�� pour mise �� jour"
-
-#, python-format
-msgid "Error while getting packages marked to be updated. Details: %(err)s"
-msgstr ""
-"Erreur durant la r��cup��ration des paquets marqu��s pour la mise�� jour. "
-"D��tails: %(err)s"
-
-msgid "There is no compatible package manager for this system."
-msgstr "Il n'y a pas de gestionnaire de paquets compatible avec ce
syst��me."
-
-#, python-format
-msgid "Invalid URI %(uri)s"
-msgstr "URI %(uri)s invalide"
-
-msgid "Unable to choose a virtual machine name"
-msgstr "Impossible de s��lectionner un nom de machine virtuelle"
-
-msgid "Invalid storage type. Types supported: 'cdrom', 'disk'"
-msgstr "Type de stockage invalide. Les Types support��s sont: 'cdrom',
'disk'"
-
-#, python-format
-msgid "The path '%(value)s' is not a valid local/remote path for the
device"
-msgstr ""
-
-msgid "Only CDROM path can be update."
-msgstr "Seulement le chemin d'un CDROM peut ��tre modifi��."
-
-#, python-format
-msgid ""
-"The storage device %(dev_name)s does not exist in the virtual machine %"
-"(vm_name)s"
-msgstr ""
-"Le p��riph��rique de stockage %(dev_name)s n'existe pas dans la machine "
-"virtuelle %(vm_name)s"
-
-#, python-format
-msgid "Error while creating new storage device: %(error)s"
-msgstr ""
-"Erreur durant la cr��ation du nouveau p��riph��rique de stockage: %(error)s"
-
-#, python-format
-msgid "Error while updating storage device: %(error)s"
-msgstr "Erreur durant la mise �� jour du p��riph��rique de stockage:
%(error)s"
-
-#, python-format
-msgid "Error while removing storage device: %(error)s"
-msgstr "Erreur durant le retrait du p��riph��rique de stockage: %(error)s"
-
-msgid "Do not support IDE device hot plug"
-msgstr "Ne pas supporter le branchement �� chaud de p��riph��rique IDE"
-
-msgid ""
-"Specify type and path or type and pool/volume to add a new virtual machine "
-"disk"
-msgstr ""
-"Sp��cifier le type et le chemin ou le type et le pool/volume pour ajouter un
"
-"nouveau disque de machine virtuelle."
-
-msgid "Specify path to update virtual machine disk"
-msgstr "Sp��cifier un chemin pour mettre �� jour le disque de machine
virtuelle"
-
-#, python-format
-msgid "Controller type %(type)s limitation of %(limit)s devices reached"
-msgstr ""
-"La limitation de %(limit)s p��riph��riques a ��t�� atteinte pour le contr��leur
"
-"de type %(type)s "
-
-#, python-format
-msgid "Cannot retrieve disk path information for given pool/volume: %(error)s"
-msgstr ""
-
-msgid "Volume already in use by other virtual machine."
-msgstr ""
-
-msgid ""
-"Only one of path or pool/volume can be specified to add a new virtual "
-"machine disk"
-msgstr ""
-"Seul un chemin ou pool/volume peut ��tre sp��cifi�� pour ajouter un nouveau "
-"disque de machine virtuelle"
-
-#, python-format
-msgid ""
-"Volume chosen with format %(format)s does not fit in the storage type
%(type)"
-"s"
-msgstr ""
-"Le volume de format %(format)s s��lectionn�� ne correspond pas au type de "
-"stockage %(type)s"
-
-msgid "YUM Repository ID must be one word only string."
-msgstr ""
-"L'ID du d��p��t YUM doit ��tre une cha��ne de caract��res ne comportant
qu'un "
-"seul mot"
-
-msgid "Repository URL must be an http://, ftp:// or file:// URL."
-msgstr "L'URL du d��p��t doit ��tre une URL en http://, ftp:// ou
file://."
-
-msgid ""
-"Repository configuration is a dictionary with specific values according to "
-"repository type."
-msgstr ""
-"La configuration du d��p��t est un dictionaire avec des valeurs sp��cifiques en
"
-"accord avec le type de d��p��t."
-
-msgid "Distribution to DEB repository must be a string"
-msgstr ""
-"La distribution dans le nom de d��p��t DEB doit ��tre une cha��ne de
caract��res"
-
-msgid "Components to DEB repository must be listed in a array"
-msgstr "Les composants dans le d��p��t DEB doivent ��tre list��s dans un
tableau"
-
-msgid "Components to DEB repository must be a string"
-msgstr "Les composants dans le d��p��t DEB doivent ��tre une cha��ne de
caract��res"
-
-msgid "Mirror list to repository must be a string"
-msgstr ""
-
-msgid "YUM Repository name must be string."
-msgstr "Le nom du d��p��t YUM doit ��tre une cha��ne de caract��res"
-
-msgid "GPG check must be a boolean value."
-msgstr "La v��rification GPG doit ��tre une valeur bool��enne."
-
-msgid "GPG key must be a URL pointing to the ASCII-armored file."
-msgstr "La cl�� GPG doit ��tre une URL pointant vers un fichier ASCII non
arm��."
-
-#, python-format
-msgid "Could not update repository %(repo_id)s."
-msgstr "Ne peut mettre �� jour le d��p��t %(repo_id)s."
-
-#, python-format
-msgid "Repository %(repo_id)s does not exist."
-msgstr "Le d��p��t %(repo_id)s n'existe pas."
-
-msgid ""
-"Specify repository base URL, mirror list or metalink in order to create or "
-"update a YUM repository."
-msgstr ""
-
-msgid "Repository management tool was not recognized for your system."
-msgstr "L'outil de gestion de d��p��t n'a pas ��t�� reconnu pour votre
syst��me."
-
-#, python-format
-msgid "Repository %(repo_id)s is already enabled."
-msgstr "Le d��p��t %(repo_id)s est d��j�� activ��."
-
-#, python-format
-msgid "Repository %(repo_id)s is already disabled."
-msgstr "Le d��p��t %(repo_id)s est d��j�� d��sactiv��."
-
-#, python-format
-msgid "Could not remove repository %(repo_id)s."
-msgstr "Ne peut supprimer le d��p��t %(repo_id)s. "
-
-#, python-format
-msgid "Could not write repository configuration file %(repo_file)s"
-msgstr "Ne peut ��crire le fichier de configuration du d��p��t %(repo_file)s"
-
-msgid "Specify repository distribution in order to create a DEB repository."
-msgstr "Sp��cifier la distribution du d��p��t afin de cr��er un d��p��t DEB."
-
-#, python-format
-msgid "Could not enable repository %(repo_id)s."
-msgstr "Ne peut activer le d��p��t %(repo_id)s."
-
-#, python-format
-msgid "Could not disable repository %(repo_id)s."
-msgstr "Ne peut d��sactiver le d��p��t %(repo_id)s."
-
-msgid "YUM Repository ID already exists"
-msgstr "L'ID du d��p��t YUM existe d��j��"
-
-msgid "YUM Repository name must be a string"
-msgstr "Le nom du d��p��t YUM doit ��tre une cha��ne de caract��res"
-
-#, python-format
-msgid "Unable to list repositories. Details: '%(err)s'"
-msgstr "Impossible de lister les d��p��ts. D��tails: '%(err)s'"
-
-#, python-format
-msgid "Unable to retrieve repository information. Details: '%(err)s'"
-msgstr "Impossible de r��cup��rer les informations du d��p��t. D��tails:
'%(err)s'"
-
-#, python-format
-msgid "Unable to add repository. Details: '%(err)s'"
-msgstr "Impossible d'ajouter un d��p��t. D��tails: '%(err)s'"
-
-#, python-format
-msgid "Unable to remove repository. Details: '%(err)s'"
-msgstr "Impossible de supprimer un d��p��t. D��tails: '%(err)s'"
-
-#, python-format
-msgid ""
-"Configuration items: '%(items)s' are not supported by repository
manager"
-msgstr ""
-"��l��ments de configurations: %(items)s ne sont pas support��s par le "
-"gestionnaire de d��p��t"
-
-msgid "Repository metalink must be an http://, ftp:// or file:// URL."
-msgstr ""
-
-msgid "Cannot specify mirrorlist and metalink at the same time."
-msgstr ""
-
-#, python-format
-msgid ""
-"Virtual machine '%(vm)s' must be stopped before creating a snapshot of
it."
-msgstr ""
-
-#, python-format
-msgid ""
-"Unable to create snapshot '%(name)s' on virtual machine '%(vm)s'.
Details: %"
-"(err)s"
-msgstr ""
-
-#, python-format
-msgid "Snapshot '%(name)s' does not exist on virtual machine
'%(vm)s'."
-msgstr ""
-
-#, python-format
-msgid ""
-"Unable to retrieve snapshot '%(name)s' on virtual machine '%(vm)s'.
Details: "
-"%(err)s"
-msgstr ""
-
-#, python-format
-msgid "Unable to list snapshots on virtual machine '%(vm)s'. Details:
%(err)s"
-msgstr ""
-
-#, python-format
-msgid ""
-"Unable to delete snapshot '%(name)s' on virtual machine '%(vm)s'.
Details: %"
-"(err)s"
-msgstr ""
-
-#, python-format
-msgid ""
-"Unable to retrieve current snapshot of virtual machine '%(vm)s'. Details:
%"
-"(err)s"
-msgstr ""
-
-#, python-format
-msgid ""
-"Unable to revert virtual machine '%(vm)s' to snapshot '%(name)s'.
Details: %"
-"(err)s"
-msgstr ""
-
-#, python-format
-msgid ""
-"Unable to create snapshot of virtual machine '%(vm)s' because it contains a
"
-"disk with format '%(format)s'; only 'qcow2' is supported."
-msgstr ""
-
-msgid "The number of vCPUs is too large for this system."
-msgstr ""
-
-msgid "Invalid vCPU/topology combination."
-msgstr ""
-
-msgid "This host (or current configuration) does not allow CPU topology."
-msgstr ""
-
-msgid "ERROR CODE"
-msgstr "ERROR CODE"
-
-msgid "REASON"
-msgstr "REASON"
-
-msgid "STACK"
-msgstr "STACK"
-
-msgid "Go to Homepage"
-msgstr "Aller �� la page d'accueil"
-
-msgid "Create a New Virtual Machine"
-msgstr "Cr��er une nouvelle Machine Virtuelle"
-
-msgid "Virtual Machine Name"
-msgstr "Nom de Machine Virtuelle"
-
-msgid ""
-"The name used to identify the virtual machine. If omitted, a name will be "
-"chosen based on the template used."
-msgstr ""
-"Le nm est utilis�� pour identifier une machine virtuelle. Si omis, un nom "
-"sera choisi en se basant sur le mod��le utilis��."
-
-msgid "Template"
-msgstr "Mod��le"
-
-msgid "Please create a template first."
-msgstr "Veuillez d'abord cr��er un mod��le."
-
-msgid "Create a Template"
-msgstr "Cr��er un mod��le"
-
-msgid "Please choose a template."
-msgstr "Veuillez choisir un mod��le"
-
-msgid "OS"
-msgstr "OS"
-
-msgid "OS Version"
-msgstr "Version de l'OS"
-
-msgid "CPUS"
-msgstr "CPUS"
-
-msgid "Memory"
-msgstr "M��moire"
-
-msgid "Create"
-msgstr "Cr��er"
-
-msgid "Creating..."
-msgstr "Cr��ation en cours..."
-
-msgid "Cancel"
-msgstr "Annuler"
-
-msgid "Edit Guest"
-msgstr "��diter l'Invit��"
-
-msgid "General"
-msgstr "G��n��ral"
-
-msgid "Storage"
-msgstr "Stockage"
-
-msgid "Interface"
-msgstr "Interface"
-
-msgid "Permission"
-msgstr "Permission"
-
-msgid "Host PCI Device"
-msgstr "P��riph��rique PCI H��te"
-
-msgid "Snapshot"
-msgstr ""
-
-msgid "Name"
-msgstr "Nom"
-
-msgid "CPUs"
-msgstr "CPUs"
-
-msgid "Memory (MB)"
-msgstr "M��moire (Mo)"
-
-msgid "Icon"
-msgstr "Icone"
-
-msgid "Device"
-msgstr "P��riph��rique"
-
-msgid "Path"
-msgstr "Chemin"
-
-msgid "Network"
-msgstr "R��seau"
-
-msgid "Type"
-msgstr "Type"
-
-msgid "MAC Address"
-msgstr ""
-
-msgid "Available system users and groups"
-msgstr "Utilisateurs et groupes syst��mes disponibles"
-
-msgid "Selected system users and groups"
-msgstr "Utilisateurs et groupes syst��mes s��lectionn��s"
-
-msgid "User"
-msgstr ""
-
-msgid "All"
-msgstr "Tous"
-
-msgid "To Add"
-msgstr "�� Ajouter"
-
-msgid "Added"
-msgstr "Ajouter"
-
-msgid "filter"
-msgstr "Filtre"
-
-msgid "Product"
-msgstr "Produit"
-
-msgid "Vendor"
-msgstr "Vendeur"
-
-msgid "Created"
-msgstr ""
-
-msgid "Save"
-msgstr "Enregistrer"
-
-msgid "Replace"
-msgstr "Remplacer"
-
-msgid "Detach"
-msgstr "D��tacher"
-
-msgid "revert"
-msgstr ""
-
-msgid "Start"
-msgstr "D��marrer"
-
-msgid "Reset"
-msgstr "R��initialiser"
-
-msgid "Pause"
-msgstr ""
-
-msgid "Resume"
-msgstr ""
-
-msgid "Power Off"
-msgstr "Mettre hors tension"
-
-msgid "Actions"
-msgstr "Actions"
-
-msgid "Connect"
-msgstr "Connecter"
-
-msgid "Clone"
-msgstr "Cloner"
-
-msgid "Edit"
-msgstr "��diter"
-
-msgid "Shut Down"
-msgstr "��teindre"
-
-msgid "Delete"
-msgstr "Supprimer"
-
-msgid "CPU"
-msgstr "CPU"
-
-msgid "Disk I/O"
-msgstr "E/S Disque"
-
-msgid "Network I/O"
-msgstr "E/S R��seau"
-
-msgid "Livetile"
-msgstr "Livetile"
-
-msgid "No guests found."
-msgstr "Aucun invit�� trouv��."
-
-msgid "Add a Storage Device to VM"
-msgstr "Ajouter un P��riph��rique de Stockage �� la VM"
-
-msgid "Device Type"
-msgstr "Type de P��riph��rique"
-
-msgid "The device type. Currently, \"cdrom\" and \"disk\" are
supported."
-msgstr ""
-"Le type de p��riph��rique. Actuellement, \"cdrom\" et \"disk\"
sont support��s."
-
-msgid "Storage Pool"
-msgstr "Pool de Stockage"
-
-msgid "Storage pool which volume located in"
-msgstr "Pool de Stockage dans lequel le volume est situ��"
-
-msgid "Storage Volume"
-msgstr "Volume de Stockage"
-
-msgid "Storage volume to be attached"
-msgstr "Le volume de stockage �� attacher"
-
-msgid "File Path"
-msgstr "Chemin de Fichier"
-
-msgid "The ISO file path in the server for CDROM."
-msgstr "Le chemin de fichier ISO sur le serveur comme CDROM."
-
-msgid "Attach"
-msgstr "Attacher"
-
-msgid "Shut down"
-msgstr "��teindre"
-
-msgid "Restart"
-msgstr "Red��marrer"
-
-msgid "Basic Information"
-msgstr "Informations de Base"
-
-msgid "OS Distro"
-msgstr "Distro de l'OS"
-
-msgid "OS Code Name"
-msgstr "Nom de code de l'OS"
-
-msgid "Processor"
-msgstr "Processeur"
-
-msgid "CPU(s)"
-msgstr ""
-
-msgid "System Statistics"
-msgstr "Statistiques Syst��me"
-
-msgid "Software Updates"
-msgstr "Mises �� jour Logiciel"
-
-msgid "Update Progress"
-msgstr "Progr��s de la Mise �� Jour"
-
-msgid "Repositories"
-msgstr "D��p��ts"
-
-msgid "Debug Reports"
-msgstr "Rapports de D��boggage"
-
-msgid "The username or password you entered is incorrect. Please try again."
-msgstr ""
-"Le nom d'utilisateur ou le mot de passe que vous avez entr�� est incorrect.
"
-"Veuillez essayer �� nouveau."
-
-msgid "This field is required."
-msgstr "Ce champ est requis."
-
-msgid "Log in"
-msgstr "Se connecter"
-
-msgid "Logging in..."
-msgstr "En cours de connexion..."
-
-msgid "Host"
-msgstr "H��te"
-
-msgid "Guests"
-msgstr "Invit��s"
-
-msgid "Templates"
-msgstr "Mod��les"
-
-msgid "Failed to get application configuration"
-msgstr "��chec lors de l'obtention de la configuration de
l'application"
-
-msgid "This is not a valid Linux path"
-msgstr "Ce n'est pas un chemin Linux valide"
-
-msgid "This is not a valid URL."
-msgstr "Ce n'est pas une URL valide."
-
-msgid "No such data available."
-msgstr "De telles donn��es ne sont pas disponibles."
-
-msgid ""
-"Can not contact the host system. Verify the host system is up and that you "
-"have network connectivity to it. HTTP request response %1. "
-msgstr ""
-"Ne peut contacter le syst��me h��te. V��rifiez que le syst��me h��te est allum��
"
-"et que vous avez une connectivit�� r��seau avec lui. R��ponse de requ��te HTTP
%"
-"1."
-
-msgid "Unable to read file."
-msgstr ""
-
-msgid "Error while uploading file."
-msgstr ""
-
-msgid "Delete Confirmation"
-msgstr "Confirmation de Suppression"
-
-msgid "OK"
-msgstr "OK"
-
-msgid "Confirm"
-msgstr "Confirmer"
-
-msgid "Warning"
-msgstr "Avertissement"
-
-msgid "Cloning..."
-msgstr ""
-
-msgid "Loading..."
-msgstr "Chargement en cours..."
-
-msgid "An error occurred while retrieving system information."
-msgstr ""
-
-msgid "Retry"
-msgstr "Essayer �� nouveau"
-
-msgid "Detailed message:"
-msgstr "Message d��taill��:"
-
-msgid "No ISO found"
-msgstr "Aucune ISO d��tect��e"
-
-msgid "This is not a valid ISO file."
-msgstr "Ce n'est pas un fichier ISO valide."
-
-msgid "This may take a long time. Do you want to continue?"
-msgstr "Cela va prendre un long moment. Voulez-vous continuer ?"
-
-msgid "This will permanently delete the template. Would you like to continue?"
-msgstr ""
-"Cela va supprimer de mani��re permanent le mod��le. Souhaites-vous continuer
?"
-
-msgid "Unable to shut down system as there are some virtual machines running!"
-msgstr ""
-"Impossible d'��teindre le syst��me du fait que certaines machines virtuelles
"
-"sont lanc��es !"
-
-msgid "Max:"
-msgstr "Max:"
-
-msgid "Utilization"
-msgstr "Utilisation"
-
-msgid "Available"
-msgstr "Disponible"
-
-msgid "Read Rate"
-msgstr "Taux en Lecture"
-
-msgid "Write Rate"
-msgstr "Taux en ��criture"
-
-msgid "Received"
-msgstr "Re��u"
-
-msgid "Sent"
-msgstr "Envoy��"
-
-msgid ""
-"Shutting down or restarting host will cause unsaved work lost. Continue to "
-"shut down/restarting?"
-msgstr ""
-"��teindre ou red��marrer l'h��te causera la perte de tout travail non "
-"enregistr��. Continuer �� ��teindre/red��marrer ?"
-
-msgid ""
-"Repository will be removed permanently and can't be recovered. Do you want
"
-"to continue?"
-msgstr ""
-"Le d��p��t sera retir�� de fa��on permanente et ne pourra ��tre r��tabli.
Voulez-"
-"vous continuer ?"
-
-msgid "ID"
-msgstr "ID"
-
-msgid "Base URL"
-msgstr "URL de base"
-
-msgid "Is Mirror"
-msgstr "Est un miroir"
-
-msgid "URL Args"
-msgstr "Arguments d'URL"
-
-msgid "Enabled"
-msgstr "Activ��"
-
-msgid "GPG Check"
-msgstr "V��rification GPG"
-
-msgid "GPG Key"
-msgstr "Cl�� GPG"
-
-msgid "Add"
-msgstr "Ajouter"
-
-msgid "Remove"
-msgstr "Retirer"
-
-msgid "Enable"
-msgstr "Activer"
-
-msgid "Disable"
-msgstr "D��sactiver"
-
-msgid "Package Name"
-msgstr "Nom de paquet"
-
-msgid "Version"
-msgstr "Version"
-
-msgid "Architecture"
-msgstr "Architecture"
-
-msgid "Repository"
-msgstr "D��p��t"
-
-msgid "Update All"
-msgstr "Tout mettre �� jour"
-
-msgid "Updating..."
-msgstr "En cours de mise �� jour..."
-
-msgid "Failed to retrieve packages update information."
-msgstr "��chec de r��cup��ration des informations de mise-��-jour des
paquets."
-
-msgid "Failed to update package(s)."
-msgstr "��chec durant la mise �� jour du/des paquet(s)"
-
-msgid ""
-"Debug report will be removed permanently and can't be recovered. Do you want
"
-"to continue?"
-msgstr ""
-"Le rapport de d��boggage sera enlev�� de fa��on permanente et ne pourra ��tre
"
-"r��tabli. Voulez-vous continuer ?"
-
-msgid "Generated Time"
-msgstr "Horodatage de g��n��ration"
-
-msgid "Generate"
-msgstr "G��n��rer"
-
-msgid "Generating..."
-msgstr "En cours de g��n��ration..."
-
-msgid "Rename"
-msgstr "Renommer"
-
-msgid "Download"
-msgstr "T��l��charger"
-
-msgid ""
-"Report name should contain only letters, digits, underscore ('_') and/or
"
-"hyphen ('-')."
-msgstr ""
-"Le nom de rapport devrait contenir uniquement des lettres, nombres, "
-"soulignement ('_') et/ou tiret ('-')."
-
-msgid "Pending..."
-msgstr "En attente..."
-
-msgid "Report name is the same as the original one."
-msgstr "Le nom du rapport est le m��me que celui d'origine."
-
-msgid ""
-"This will delete the virtual machine and its virtual disks. This operation "
-"cannot be undone. Would you like to continue?"
-msgstr ""
-"Cela va supprimer la machine virtuelle et tous ses disques virtuels. Cette "
-"op��ration est irr��versible. Voulez-vous continuer ?"
-
-msgid "Power off Confirmation"
-msgstr "Confirmation de mise hors tension"
-
-msgid ""
-"This action may produce undesirable results, for example unflushed disk "
-"cache in the guest. Would you like to continue?"
-msgstr ""
-"Cette action pourrait produire des r��sultats ind��sirables, par exemple un "
-"cache disque non flush�� dans l'invit��. Voulez-vous continuer ?"
-
-msgid "Reset Confirmation"
-msgstr "Confirmation de R��initialisation"
-
-msgid ""
-"There is a risk of data loss caused by reset without the guest OS shutdown. "
-"Would you like to continue?"
-msgstr ""
-"Il y a un risque de perte de donn��es caus��es par une r��initialisation sans
"
-"extinction de l'OS invit��. Voulez-vous continuer ?"
-
-msgid "Shut Down Confirmation"
-msgstr "Confirmation d'Extinction"
-
-msgid "Note the guest OS may ignore this request. Would you like to continue?"
-msgstr ""
-"Noter que l'OS invit�� pourrait ignorer cette requ��te. Voulez-vous continuer
?"
-
-msgid "Virtual Machine delete Confirmation"
-msgstr "Confirmation de suppression de Machine Virtuelle"
-
-msgid ""
-"This virtual machine is not persistent. Power Off will delete it. Continue?"
-msgstr ""
-
-msgid ""
-"When the target guest has SCSI or iSCSI volumes, they will be cloned on "
-"default storage pool. The same will happen when the target pool does not "
-"have enough space to clone the volumes. Do you want to continue?"
-msgstr ""
-
-msgid ""
-"This CDROM will be detached permanently and you can re-attach it. Continue "
-"to detach it?"
-msgstr ""
-"Ce CDROM sera d��tach�� de fa��on permanente et vous pourrez le r��-attacher.
"
-"Continuer le d��tachement ?"
-
-msgid "Attaching..."
-msgstr "En cours d'attachement..."
-
-msgid "Replacing..."
-msgstr "En cours de Remplacement..."
-
-msgid "Successfully attached!"
-msgstr "Attach�� avec succ��s !"
-
-msgid "Successfully replaced!"
-msgstr "Remplac�� avec succ��s !"
-
-msgid "Successfully detached!"
-msgstr "D��tach�� avec Succ��s !"
-
-msgid ""
-"This disk will be detached permanently and you can re-attach it. Continue to
"
-"detach it?"
-msgstr ""
-"Ce disque sera d��finitivement d��tach�� et peut ��tre r��-attach��. Continuer ��
"
-"le d��tacher ?"
-
-msgid "interface:"
-msgstr ""
-
-msgid "address:"
-msgstr ""
-
-msgid "link_type:"
-msgstr ""
-
-msgid "block:"
-msgstr ""
-
-msgid "drive_type:"
-msgstr ""
-
-msgid "model:"
-msgstr ""
-
-msgid "Affected devices:"
-msgstr ""
-
-msgid "The VLAN id must be between 1 and 4094."
-msgstr "L'id du VLAN doit ��tre entre 1 et 4094."
-
-msgid "unavailable"
-msgstr "non disponible"
-
-msgid ""
-"This action will interrupt network connectivity for any virtual machine that
"
-"depend on this network."
-msgstr ""
-"Cette action va interrompre la connectivit�� r��seau pour tout machine "
-"virtuelle qui d��pend de ce r��seau."
-
-msgid "Create a network"
-msgstr "Cr��er un r��seau"
-
-msgid ""
-"This network is not persistent. Instead of stop, this action will "
-"permanently delete it. Would you like to continue?"
-msgstr ""
-"Ce r��seau n'est pas persistant. Au lieu de s'arr��ter, cette actionva le
"
-"suppromer de mani��re permanente. Voulez-vous continuer ?"
-
-msgid ""
-"The bridged VLAN tag may not work well with NetworkManager enabled. You "
-"should consider disabling it."
-msgstr ""
-
-msgid ""
-"This will permanently delete the storage pool. Would you like to continue?"
-msgstr ""
-"Cela va effacer de mani��re permanente le pool de stockage. Voulez-vous "
-"continuer ?"
-
-msgid "This storage pool is empty."
-msgstr "Ce pool de stockage est vide."
-
-msgid ""
-"It will format your disk and you will loose any data in there, are you sure "
-"to continue? "
-msgstr ""
-"Cela va formater votre disque et vous allez perdre toutes les donn��es qui "
-"s'y trouvent, ��tes-vous s��r de continuer ?"
-
-msgid "SCSI Fibre Channel"
-msgstr "Canal Fibre SCSI"
-
-msgid "No SCSI adapters found."
-msgstr "Aucun adaptateur SCSI trouv��."
-
-msgid "Loading iSCSI targets..."
-msgstr ""
-
-msgid "No iSCSI found. Please input one."
-msgstr ""
-
-msgid "Failed to load iSCSI targets."
-msgstr ""
-
-msgid "The storage pool name can not be blank."
-msgstr "Le nom de pool de stockage ne peut ��tre vierge."
-
-msgid "The storage pool path can not be blank."
-msgstr "Le chemin de pool de stockage ne peut ��tre vierge."
-
-msgid "NFS server mount path can not be blank."
-msgstr "Le chemin de montage du serveur NFS ne peut ��tre vierge."
-
-msgid "Invalid NFS mount path."
-msgstr "Chemin de montage NFS invalide."
-
-msgid "No logical device selected."
-msgstr "Aucun p��riph��rique logique s��lectionn��."
-
-msgid "The iSCSI target can not be blank."
-msgstr "La cible iSCSI ne peut ��tre vierge."
-
-msgid "Server name can not be blank."
-msgstr "Le nom de serveur ne peut ��tre vierge."
-
-msgid "This is not a valid Server Name or IP. Please, modify it."
-msgstr ""
-
-msgid "Looking for available partitions ..."
-msgstr "En cours de recherche de partitions disponibles..."
-
-msgid "No available partitions found."
-msgstr "Aucune partition disponible trouv��e."
-
-msgid ""
-"This storage pool is not persistent. Instead of deactivate, this action will
"
-"permanently delete it. Would you like to continue?"
-msgstr ""
-"Le pool de stockage n'est pas persistent. Au lieu de le d��sactiver, cette
"
-"action va le supprimer de mani��re permanente. Voulez-vous continuer ?"
-
-msgid "Unable to retrieve partitions information."
-msgstr "Impossible de r��cup��rer les informations des partitions."
-
-msgid "In progress..."
-msgstr "En cours..."
-
-msgid "Failed!"
-msgstr "��chec!"
-
-msgid "CDROM path needs to be a valid local/remote path and cannot be blank."
-msgstr ""
-"Le chemin de CDROM doit ��tre un chemin local/distant valide et ne peut ��tre
"
-"virge."
-
-msgid "Disk pool or volume cannot be blank."
-msgstr "Le pool de disque ou le volume ne peut ��tre vierge."
-
-#, fuzzy
-msgid "Filter"
-msgstr "Filtre"
-
-msgid "Network Name"
-msgstr "Nom de R��seau"
-
-msgid "State"
-msgstr "��tat"
-
-msgid "Network Type"
-msgstr "Type de R��seau"
-
-msgid "Address Space"
-msgstr "Espace d'adressage"
-
-msgid "Name should not contain '/' and '\"'."
-msgstr "Le nom ne devrait pas contenir '/' et '\"'."
-
-msgid "Isolated: no external network connection"
-msgstr "Isol��: pas de connexion �� un r��seau externe"
-
-msgid "NAT: outbound physical network connection only"
-msgstr "NAT: connexion physique au r��seau sortant uniquement"
-
-msgid "Bridged: Virtual machines are connected to physical network directly"
-msgstr ""
-"Bridg��: Les macines virtuelles sont connect��es directement au r��seau
physique"
-
-msgid "(No interfaces found)"
-msgstr "(Aucune interface trouv��e)"
-
-msgid "Destination"
-msgstr "Destination"
-
-msgid "Enable VLAN"
-msgstr "Activer le VLAN"
-
-msgid "VLAN ID"
-msgstr "ID de VLAN"
-
-msgid "Stop"
-msgstr "Arr��ter"
-
-msgid "Generate a New Debug Report"
-msgstr "G��n��rer un Nouveau Rapport de D��boggage"
-
-msgid "Report Name"
-msgstr "Nom du Rapport"
-
-msgid ""
-"The name used to identify the report. If omitted, a name will be chosen "
-"based on current time. Name can contain: letters, digits, underscore
(\"_\") "
-"and hyphen (\"-\")."
-msgstr ""
-"Le nom utilis�� pour identifier le rapport. Si omis, un nom sera choisi bas��
"
-"sur l'heure courante. Le nom peut contenir des lettres, des nombres, le "
-"soulignement (\"_\") et le tiret (\"-\")."
-
-msgid "Rename a Debug Report"
-msgstr "Renommer un Rapport de D��boggage"
-
-msgid ""
-"The name used to identify the report. Name can contain: letters, digits and "
-"hyphen (\"-\")."
-msgstr ""
-"Le nom utilis�� pour identifer le rapport. Le nom peut contenir des lettres,
"
-"nombres et tirets (\"-\")."
-
-msgid "Submit"
-msgstr "Soumettre"
-
-msgid "Add a Repository"
-msgstr "Ajouter un D��p��t"
-
-msgid "Identifier"
-msgstr "Identificateur"
-
-msgid "Single word, unique identifier for the repository."
-msgstr "Mot unique, identifiant unique pour le d��p��t."
-
-msgid "Textual name for the repository."
-msgstr "Nom textuel pour le d��p��t."
-
-msgid "URL"
-msgstr "URL"
-
-msgid "Required Field"
-msgstr "Champ requis"
-
-msgid "URL to the repository. Supported protocols are http, ftp, and file."
-msgstr "URL du d��p��t. Les protocoles support��s sont http, ftp et ficheir."
-
-msgid "Repository is a mirror"
-msgstr "Le d��p��t est un miroir"
-
-msgid "Distribution"
-msgstr "Distribution"
-
-msgid "Distribution of the DEB repository."
-msgstr "Distribution du d��p��t DEB."
-
-msgid "Components"
-msgstr "Composants"
-
-msgid "List of components in DEB repository."
-msgstr "Liste des composants dans le d��p��t DEB."
-
-msgid "Edit Repository"
-msgstr "Editer le D��p��t"
-
-msgid "Mirror List URL"
-msgstr "URL de Liste de Miroir"
-
-msgid "Yes"
-msgstr "Oui"
-
-msgid "No"
-msgstr "Non"
-
-msgid "Capacity"
-msgstr "Capacit��"
-
-msgid "Allocated"
-msgstr "Allou��"
-
-msgid "Location"
-msgstr "Emplacement"
-
-msgid "Device path"
-msgstr "Chemin du P��riph��rique"
-
-msgid "active"
-msgstr "actif"
-
-msgid "inactive"
-msgstr "inactif"
-
-msgid "Deactivate"
-msgstr "D��sactiver"
-
-msgid "Activate"
-msgstr "Activer"
-
-msgid "Add Volume"
-msgstr "Ajouter un Volume"
-
-msgid "Extend"
-msgstr "��tendre"
-
-msgid "Undefine"
-msgstr "Supprimer"
-
-msgid "Format"
-msgstr "Format"
-
-msgid "Allocation"
-msgstr "Allocation"
-
-msgid "Define a New Storage Pool"
-msgstr "D��finir un Nouveau Pool de Stockage"
-
-msgid "Storage Pool Name"
-msgstr "Nom de Pool de Stockage"
-
-msgid ""
-"The name used to identify the storage pools, and it should not be empty."
-msgstr ""
-"Le nom utilis�� pour identifier les pools de stockage, et il ne doit pas ��tre
"
-"vide."
-
-msgid "Storage Pool Type"
-msgstr "Type de Pool de Stockage"
-
-msgid "Storage Path"
-msgstr "Chemin de Stockage"
-
-msgid ""
-"The path of the Storage Pool. Each Storage Pool must have a unique path."
-msgstr ""
-"Le chemin du Pool de Stockage. Chaque Pool de Stockage doit avoir un chemin "
-"unique."
-
-msgid ""
-"Kimchi will try to create the directory when it does not already exist in "
-"your system."
-msgstr ""
-"Kimchi va essayer de cr��er un r��pertoire quand il n'existe pas d��j�� dans
"
-"votre syst��me."
-
-msgid "NFS Server IP"
-msgstr "IP du Serveur NFS"
-
-msgid "NFS server IP or hostname. It can be input or chosen from history."
-msgstr ""
-"IP du Serveur NFS ou nom d'h��te. Il peut ��tre saisi ou entr�� �� partir de
"
-"l'historique."
-
-msgid "NFS Path"
-msgstr "Chemin NFS"
-
-msgid "The NFS exported path on NFS server."
-msgstr "Le chemin NFS export�� sur le serveur NFS."
-
-msgid "iSCSI Server"
-msgstr "Serveur iSCSI"
-
-msgid "Server"
-msgstr "Serveur"
-
-msgid "Port"
-msgstr "Port"
-
-msgid "iSCSI server IP or hostname. It should not be empty."
-msgstr "IP du Serveur iSCSI ou nom d'h��te. Il ne devrait pas ��tre vide."
-
-msgid "Target"
-msgstr "Cible"
-
-msgid "The iSCSI target on iSCSI server"
-msgstr "La cible iSCSI sur le serveur iSCSI"
-
-msgid "Add iSCSI Authentication"
-msgstr "Ajouter l'Authentification iSCSI"
-
-msgid "iSCSI Authentication"
-msgstr "Authentification iSCSI"
-
-msgid "User Name"
-msgstr "Nom d'Utilisateur"
-
-msgid "Password"
-msgstr "Mot de Passe"
-
-msgid "SCSI Adapter"
-msgstr "Adaptateur SCSI"
-
-msgid "Please, wait..."
-msgstr "Veuillez patienter..."
-
-msgid "Add a Volume to Storage Pool"
-msgstr "iAjouter un Volume au Pool de Stockage"
-
-msgid "Fetch from remote URL"
-msgstr ""
-
-msgid "Enter the remote URL here."
-msgstr "Saisir une URL distante ici"
-
-msgid "Upload a file"
-msgstr "Charger un fichier"
-
-msgid "Choose the file you want to upload."
-msgstr ""
-
-msgid "Add Template"
-msgstr "Ajouter un Mod��le"
-
-msgid "Where is the source media for this template? "
-msgstr "O�� se trouve le media source pour le mod��le ?"
-
-msgid "Local ISO Image"
-msgstr "Image ISO Locale"
-
-msgid "Local Image File"
-msgstr "Fichier Image Local"
-
-msgid "Remote ISO Image"
-msgstr "Image ISO Distante"
-
-msgid "Search ISOs"
-msgstr "Rechercher des ISOs"
-
-msgid "The following ISOs are available:"
-msgstr "Les ISOs suivants sont disponibles:"
-
-msgid "OS: "
-msgstr "OS: "
-
-msgid "Version: "
-msgstr "Version: "
-
-msgid "Size: "
-msgstr "Taille: "
-
-msgid "Search more ISOs"
-msgstr "Chercher plus d'ISOs"
-
-msgid "Create Templates from Selected ISO"
-msgstr "Cr��er des mod��les depuis l'ISO s��lectionn��"
-
-msgid "I want to use a specific ISO file"
-msgstr "Je veux utiliser un fichier ISO sp��cifique"
-
-msgid "Loading default remote ISOs ..."
-msgstr "Chargement des ISOs distants par d��faut en cours..."
-
-msgid "Arch: "
-msgstr "Arch: "
-
-msgid "I want to use a custom URL"
-msgstr "Je veux utiliser une URL personnalis��e"
-
-msgid "Edit Template"
-msgstr "��diter un Mod��le"
-
-msgid "CDROM"
-msgstr "CDROM"
-
-msgid "Image File"
-msgstr "Fichier Image"
-
-msgid "Graphics"
-msgstr "Graphiques"
-
-msgid "Disk(GB)"
-msgstr ""
-
-msgid "Disk Format"
-msgstr ""
-
-msgid "CPU Number"
-msgstr "Nombre de CPU"
-
-msgid "Manually set CPU topology"
-msgstr ""
-
-msgid "Cores"
-msgstr ""
-
-msgid "Threads"
-msgstr ""
-
-msgid "No templates found."
-msgstr "Aucun mod��le trouv��."
-
-#~ msgid "Delete is not allowed for %(resource)s"
-#~ msgstr "La suppression n'est pas autoris��e pour %(resource)s"
-
-#~ msgid "%(resource)s does not implement update method"
-#~ msgstr "%(resource)s n'impl��mente pas de m��thode de mise �� jour"
-
-#~ msgid "Create is not allowed for %(resource)s"
-#~ msgstr "La cr��ation n'est pas autoris��e pour %(resource)s"
-
-#~ msgid "Unable to parse JSON request"
-#~ msgstr "Impossible de parser la requ��te JSON"
-
-#~ msgid "This API only supports JSON"
-#~ msgstr "Cette API supporte uniquement le JSON"
-
-#~ msgid "Parameters does not match requirement in schema: %(err)s"
-#~ msgstr ""
-#~ "Les param��tres ne correspondent pas �� ce qui est requis dans le sch��ma:
%"
-#~ "(err)s"
-
-#~ msgid "You don't have permission to perform this operation."
-#~ msgstr "Vous n'avez pas la permission d'effectuer cette
op��ration."
-
-#~ msgid "Datastore is not initiated in the model object."
-#~ msgstr "Le magasin de donn��es n'est pas initi�� dans l'objet
mod��le."
-
-#~ msgid "Unable to start task due error: %(err)s"
-#~ msgstr "Impossible de d��marrer la t��che �� cause de l'erreur:
%(err)s"
-
-#~ msgid ""
-#~ "Authentication failed for user '%(username)s'. [Error code:
%(code)s]"
-#~ msgstr ""
-#~ "L'authentification a ��chou�� pour l'utilisateur '%(username)s'.
[Code "
-#~ "d'Erreur: %(code)s]"
-
-#~ msgid "You are not authorized to access Kimchi"
-#~ msgstr "Vous n'��tes pas autoris�� �� acc��der �� Kimchi"
-
-#~ msgid "Specify %(item)s to login into Kimchi"
-#~ msgstr "Sp��cifiez %(item)s pour vous logguer dans Kimchi"
-
-#~ msgid "Unable to find %(item)s in datastore"
-#~ msgstr "Impossible de trouver %(item)s dans le magasin de donn��es"
-
-#~ msgid "Timeout while running command '%(cmd)s' after %(seconds)s
seconds"
-#~ msgstr ""
-#~ "Timeout durant l'ex��cution de la commande '%(cmd)s' apr��s
%(seconds)s "
-#~ "secondes"
-
-#~ msgid "Help"
-#~ msgstr "Aide"
-
-#~ msgid "About"
-#~ msgstr "A propos..."
-
-#~ msgid "Log out"
-#~ msgstr "Se d��connecter"
-
-#~ msgid "Version:"
-#~ msgstr "Version:"
-
-#~ msgid "Session timeout, please re-login."
-#~ msgstr "Session expir��e, veuillez vous reconnecter."
diff --git a/plugins/kimchi/po/gen-pot.in b/plugins/kimchi/po/gen-pot.in
deleted file mode 100644
index 0e3cd10..0000000
--- a/plugins/kimchi/po/gen-pot.in
+++ /dev/null
@@ -1,9 +0,0 @@
-#!/bin/bash
-
-for src in $@; do
- if [ ${src: -3} == ".py" ]; then
- cat $src
- else
- cat $src | @CHEETAH@ compile -
- fi
-done | xgettext --no-location -o kimchi.pot -L Python -
diff --git a/plugins/kimchi/po/it_IT.po b/plugins/kimchi/po/it_IT.po
deleted file mode 100644
index 257c306..0000000
--- a/plugins/kimchi/po/it_IT.po
+++ /dev/null
@@ -1,2274 +0,0 @@
-# English translations for kimchi package.
-# Copyright (C) 2013 ORGANIZATION
-#
-msgid ""
-msgstr ""
-"Project-Id-Version: kimchi 0.1\n"
-"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2015-07-01 16:11-0300\n"
-"PO-Revision-Date: 2013-07-11 17:32-0400\n"
-"Last-Translator: Cr��stian Viana <vianac(a)linux.vnet.ibm.com>\n"
-"Language-Team: English\n"
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
-"Content-Transfer-Encoding: 8bit\n"
-"Language: it_IT\n"
-"Generated-By: pygettext.py 1.5\n"
-"Plural-Forms: nplurals=2; plural=(n != 1);\n"
-
-#, python-format
-msgid "Unknown parameter %(value)s"
-msgstr ""
-
-#, python-format
-msgid "Timeout of %(seconds)s seconds expired while running task
'%(task)s."
-msgstr ""
-
-#, python-format
-msgid "User %(user_id)s not found with given LDAP settings."
-msgstr ""
-
-msgid "Unknown \"_cap\" specified"
-msgstr ""
-
-msgid "\"_passthrough\" should be \"true\" or
\"false\""
-msgstr ""
-
-msgid "\"_passthrough_affected_by\" should be a device name string"
-msgstr ""
-
-#, python-format
-msgid "Error while getting block devices. Details: %(err)s"
-msgstr ""
-"Errore durante il richiamo dei dispositivi del blocco. Dettagli: %(err)s"
-
-#, python-format
-msgid "Error while getting block device information for %(device)s."
-msgstr ""
-"Errore durante il richiamo delle informazioni sul dispositivo del blocco per
"
-"%(device)s."
-
-#, python-format
-msgid "Unable to find distro file: %(filename)s"
-msgstr "Impossibile trovare il file distro: %(filename)s"
-
-#, python-format
-msgid ""
-"Unable to parse distro file: %(filename)s. Make sure, it is a JSON file."
-msgstr ""
-"Impossibile analizzare il file distro: %(filename)s. Verificare che sia un "
-"file JSON."
-
-#, python-format
-msgid "Unable to login to iSCSI host target %(portal)s. Details: %(err)s"
-msgstr ""
-"Impossibile accedere a %(portal)s di destinazione host iSCSI. Dettagli: %"
-"(err)s"
-
-#, python-format
-msgid "Unable to login to iSCSI host %(host)s target %(target)s"
-msgstr "Impossibile accedere alla destinazione %(target)s host %(host)s iSCSI"
-
-#, python-format
-msgid "Unable to find ISO file %(filename)s"
-msgstr ""
-
-#, python-format
-msgid "The ISO file %(filename)s is not bootable"
-msgstr "Il file ISO %(filename)s non �� avviabile"
-
-#, python-format
-msgid "The ISO file %(filename)s does not have a valid El Torito boot record"
-msgstr "Il file ISO %(filename)s non ha un record di avvio El Torito valido"
-
-#, python-format
-msgid "Invalid El Torito validation entry in ISO %(filename)s"
-msgstr "Voce di convalida El Torito non valida in ISO %(filename)s"
-
-#, python-format
-msgid "Invalid El Torito boot indicator in ISO %(filename)s"
-msgstr "Indicatore di avvio El Torito non valido in ISO %(filename)s"
-
-#, python-format
-msgid "Unexpected volume type for primary volume in ISO %(filename)s"
-msgstr "Tipo di volume imprevisto per il volume primario in ISO %(filename)s"
-
-#, python-format
-msgid "Bad format while reading volume descriptor in ISO %(filename)s"
-msgstr ""
-"Formato non corretto durante la lettura del descrittore volume in ISO %"
-"(filename)s"
-
-#, python-format
-msgid ""
-"The hypervisor doesn't have permission to use this ISO %(filename)s. "
-"Consider moving it under /var/lib/libvirt, or set the search permission to "
-"file access control lists for '%(user)s' user if possible, or add the
'%"
-"(user)s' to the ISO path group, or (not recommended) 'chmod -R o+x "
-"'path_to_iso'.Details: %(err)s"
-msgstr ""
-"L'hypervisor non dispone dell'autorizzazione per utilizzare questo ISO
%"
-"(filename)s. Spostarlo in /var/lib/libvirt o impostare l'autorizzazione di
"
-"ricerca per gli elenchi di controllo accesso ai file per l'utente
'%(user)"
-"s', se possibile, o aggiungere '%(user)s' al gruppo percorso ISO o
(non "
-"consigliato) 'chmod -R o+x 'path_to_iso'. Dettagli: %(err)s"
-
-msgid "An error occurred when probing image OS information."
-msgstr ""
-
-msgid "No OS information found in given image."
-msgstr ""
-
-#, python-format
-msgid "Unable to read image file %(filename)s"
-msgstr ""
-
-#, python-format
-msgid ""
-"Image file must be an existing file on system. %(filename)s is not a valid "
-"input."
-msgstr ""
-
-#, python-format
-msgid "Virtual machine %(name)s already exists"
-msgstr "Macchina virtuale %(name)s gi�� esistente"
-
-#, python-format
-msgid "Virtual machine %(name)s does not exist"
-msgstr "La macchina virtuale %(name)s non esiste"
-
-#, python-format
-msgid ""
-"Unable to rename virtual machine %(name)s. The name %(new_name)s is already "
-"in use or the virtual machine is not powered off."
-msgstr ""
-
-#, python-format
-msgid "Unable to retrieve screenshot for stopped virtual machine %(name)s"
-msgstr ""
-"Impossibile richiamare l'immagine per la macchina virtuale arrestata
%(name)s"
-
-msgid "Remote ISO image is not supported by this server."
-msgstr "L'immagine ISO remota non �� supportata da questo server."
-
-#, python-format
-msgid "Screenshot is not supported on virtual machine %(name)s"
-msgstr ""
-
-#, python-format
-msgid "Unable to create virtual machine %(name)s. Details: %(err)s"
-msgstr "Impossibile creare la macchina virtuale %(name)s. Dettagli: %(err)s"
-
-#, python-format
-msgid "Unable to update virtual machine %(name)s. Details: %(err)s"
-msgstr "Impossibile creare la macchina virtuale %(name)s. Dettagli: %(err)s"
-
-#, python-format
-msgid "Unable to retrieve virtual machine %(name)s. Details: %(err)s"
-msgstr ""
-"Impossibile richiamare la macchina virtuale %(name)s. Dettagli: %(err)s"
-
-#, python-format
-msgid "Unable to connect to powered off virtual machine %(name)s."
-msgstr ""
-
-msgid "Virtual machine name must be a string without slashes (/)"
-msgstr ""
-
-#, python-format
-msgid "Invalid template URI %(value)s specified for virtual machine"
-msgstr ""
-
-#, python-format
-msgid "Invalid storage pool URI %(value)s specified for virtual machine"
-msgstr ""
-
-msgid "Supported virtual machine graphics are Spice or VNC"
-msgstr ""
-
-msgid "Graphics address to listen on must be IPv4 or IPv6"
-msgstr ""
-"L'indirizzo dei grafici su cui rimanere in ascolto deve essere IPv4 o
IPv6"
-
-msgid "Specify a template to create a virtual machine from"
-msgstr "Specificare un modello da cui creare una macchina virtuale"
-
-#, python-format
-msgid "Unable to start virtual machine %(name)s. Details: %(err)s"
-msgstr "Impossibile avviare la macchina virtuale %(name)s. Dettagli: %(err)s"
-
-#, python-format
-msgid "Unable to power off virtual machine %(name)s. Details: %(err)s"
-msgstr "Impossibile arrestare la macchina virtuale %(name)s. Dettagli:
%(err)s"
-
-#, python-format
-msgid "Unable to delete virtual machine %(name)s. Details: %(err)s"
-msgstr "Impossibile eliminare la macchina virtuale %(name)s. Dettagli:
%(err)s"
-
-#, python-format
-msgid "Unable to reset virtual machine %(name)s. Details: %(err)s"
-msgstr ""
-"Impossibile ridenominare la macchina virtuale %(name)s. Dettagli: %(err)s"
-
-msgid "User name list must be an array"
-msgstr ""
-
-msgid "User name must be a string"
-msgstr "Il nome della rete deve essere una stringa"
-
-msgid "Group name list must be an array"
-msgstr ""
-
-msgid "Group name must be a string"
-msgstr "Il nome della rete deve essere una stringa"
-
-#, python-format
-msgid "User(s) '%(users)s' do not exist"
-msgstr "L'utente '%(users)s' non esiste."
-
-#, python-format
-msgid "Group(s) '%(groups)s' do not exist"
-msgstr "L'utente '%(groups)s' non esiste."
-
-#, python-format
-msgid "Unable to shutdown virtual machine %(name)s. Details: %(err)s"
-msgstr "Impossibile arrestare la macchina virtuale %(name)s. Dettagli:
%(err)s"
-
-#, python-format
-msgid ""
-"Unable to get access metadata of virtual machine %(name)s. Details: %(err)s"
-msgstr "Impossibile avviare la macchina virtuale %(name)s. Dettagli: %(err)s"
-
-msgid "The guest console password must be a string."
-msgstr ""
-
-msgid "The life time for the guest console password must be a number."
-msgstr ""
-
-#, python-format
-msgid "Virtual machine '%(name)s' must be stopped before cloning it."
-msgstr ""
-
-#, python-format
-msgid "Insufficient disk space to clone virtual machine '%(name)s'"
-msgstr ""
-
-#, python-format
-msgid "Unable to clone VM '%(name)s'. Details: %(err)s"
-msgstr ""
-
-#, python-format
-msgid "Invalid operation for non-persistent virtual machine %(name)s"
-msgstr ""
-
-#, python-format
-msgid "Cannot suspend VM '%(name)s' because it is not running."
-msgstr ""
-
-#, python-format
-msgid "Unable to suspend VM '%(name)s'. Details: %(err)s"
-msgstr ""
-
-#, python-format
-msgid "Cannot resume VM '%(name)s' because it is not paused."
-msgstr ""
-
-#, python-format
-msgid "Unable to resume VM '%(name)s'. Details: %(err)s"
-msgstr ""
-
-msgid "Memory assigned is higher then the maximum allowed in the host."
-msgstr ""
-
-#, python-format
-msgid ""
-"VM '%(name)s' does not support live memory update. Update the memory with
"
-"the machine offline to enable this feature."
-msgstr ""
-
-msgid "Only increase memory is allowed in active VMs"
-msgstr ""
-
-msgid ""
-"For live memory update, new memory value must be equal old memory value plus
"
-"multiples of 1024 Mib"
-msgstr ""
-
-msgid "There are not enough free slots of 1024 Mib in the guest."
-msgstr ""
-
-msgid ""
-"Host's libvirt version does not support memory devices. Libvirt must be >=
"
-"1.2.14"
-msgstr ""
-
-#, python-format
-msgid "Error attaching memory device. Details: %(error)s"
-msgstr ""
-
-#, python-format
-msgid ""
-"VM %(vmid)s does not contain directly assigned host device %(dev_name)s."
-msgstr ""
-
-#, python-format
-msgid "The host device %(dev_name)s is not allowed to directly assign to VM."
-msgstr ""
-
-msgid ""
-"No IOMMU groups found. Host PCI pass through needs IOMMU group to function "
-"correctly. Please enable Intel VT-d or AMD IOMMU in your BIOS, then verify "
-"the Kernel is compiled with IOMMU support. For Intel CPU, add intel_iommu=on
"
-"to your Kernel parameter in /boot/grub2/grub.conf. For AMD CPU, add iommu=pt
"
-"iommu=1."
-msgstr ""
-
-msgid "\"name\" should be a device name string"
-msgstr ""
-
-#, python-format
-msgid ""
-"The device %(name)s is probably in use by the host. Unable to attach it to "
-"the guest."
-msgstr ""
-
-#, python-format
-msgid "Interface %(iface)s does not exist in virtual machine %(name)s"
-msgstr "L'interfaccia %(iface)s non esiste nella macchina virtuale
%(name)s"
-
-#, python-format
-msgid ""
-"Network %(network)s specified for virtual machine %(name)s does not exist"
-msgstr ""
-"La rete %(network)s specificata per la macchina virtuale %(name)s non esiste"
-
-msgid "Supported virtual machine interfaces type is only network"
-msgstr ""
-"Il tipo supportato per le interfacce della macchina virtuale �� solo rete"
-
-msgid "Network name for virtual machine interface must be a string"
-msgstr ""
-"Il nome di rete per l'interfaccia della macchina virtuale deve essere una
"
-"stringa"
-
-msgid "Invalid network model card specified for virtual machine interface"
-msgstr ""
-"Scheda modello di rete non valida per l'interfaccia della macchina
virtuale"
-
-msgid "Specify type and network to add a new virtual machine interface"
-msgstr ""
-"Specificare il tipo e la rete per aggiungere una nuova interfaccia della "
-"macchina virtuale"
-
-msgid "MAC Address must respect this format FF:FF:FF:FF:FF:FF"
-msgstr ""
-
-#, python-format
-msgid "MAC Address %(mac)s already exists in virtual machine %(name)s"
-msgstr ""
-
-msgid "Invalid MAC Address"
-msgstr ""
-
-msgid "Cannot change MAC address of a running virtual machine"
-msgstr ""
-
-#, python-format
-msgid "Template %(name)s already exists"
-msgstr "Modello %(name)s gi�� esistente"
-
-#, python-format
-msgid ""
-"Network '%(network)s' specified for template %(template)s does not
exist"
-msgstr ""
-"La rete '%(network)s' specificata per il modello %(template)s non
esiste"
-
-#, python-format
-msgid ""
-"Storage pool %(pool)s specified for template %(template)s does not exist"
-msgstr ""
-"Il pool di memoria %(pool)s specificato per il modello %(template)s non "
-"esiste"
-
-#, python-format
-msgid "Storage pool %(pool)s specified for template %(template)s is not
active"
-msgstr ""
-"Il pool di memoria %(pool)s specificato per il modello %(template)s non �� "
-"attivo"
-
-#, python-format
-msgid "Invalid parameter '%(param)s' specified for CDROM."
-msgstr "Parametro non valido %(param)s' specificato per CDROM."
-
-#, python-format
-msgid "Network %(network)s specified for template %(template)s is not active"
-msgstr ""
-"La rete %(network)s specificata per il modello %(template)s non �� attiva"
-
-msgid "Template name must be a string"
-msgstr "Il nome del modello deve essere una stringa"
-
-msgid "Template icon must be a path to the image"
-msgstr "L'icona del modello deve essere un percorso all'immagine"
-
-msgid "Template distribution must be a string"
-msgstr "La distribuzione del modello deve essere una stringa"
-
-msgid "Template distribution version must be a string"
-msgstr "La versione della distribuzione del modello deve essere una stringa"
-
-msgid "The number of CPUs must be an integer greater than 0"
-msgstr "Il numero di CPU deve essere un numero intero"
-
-msgid "Amount of memory (MB) must be an integer greater than 512"
-msgstr ""
-"La quantit�� di memoria (MB) deve essere un numero intero maggiore di 512"
-
-msgid "Template CDROM must be a local or remote ISO file"
-msgstr "Il CDROM del modello deve essere un file ISO locale o remoto"
-
-#, python-format
-msgid "Invalid storage pool URI %(value)s specified for template"
-msgstr "URI pool di memoria non valido: %(value)s specificato per il modello"
-
-msgid "Specify an ISO image as CDROM or a base image to create a template"
-msgstr "Specificare un'immagine ISO come CDROM per creare un modello"
-
-msgid "All networks for the template must be specified in a list."
-msgstr "Tutte le reti per il modello devono essere specificate in un elenco."
-
-msgid "Specify a volume to a template when storage pool is iSCSI or SCSI"
-msgstr ""
-
-#, python-format
-msgid "The volume %(volume)s is not in storage pool %(pool)s"
-msgstr ""
-
-#, python-format
-msgid "Unable to create template due error: %(err)s"
-msgstr "Impossibile creare il modello a causa dell'errore: %(err)s"
-
-#, python-format
-msgid "Unable to delete template due error: %(err)s"
-msgstr "Impossibile eliminare il modello a causa dell'errore: %(err)s"
-
-msgid "Disk size must be an integer greater than 1GB."
-msgstr ""
-
-msgid "Template base image must be a valid local image file"
-msgstr "Il CDROM del modello deve essere un file ISO locale o remoto"
-
-#, python-format
-msgid "Cannot identify base image %(path)s format"
-msgstr ""
-
-msgid ""
-"When specifying CPU topology, VCPUs must be a product of sockets, cores, and
"
-"threads."
-msgstr ""
-
-msgid ""
-"When specifying CPU topology, each element must be an integer greater than "
-"zero."
-msgstr ""
-
-msgid ""
-"Invalid disk image format. Valid formats: bochs, cloop, cow, dmg, qcow, "
-"qcow2, qed, raw, vmdk, vpc."
-msgstr ""
-
-#, python-format
-msgid "Storage pool %(name)s already exists"
-msgstr "Pool di memoria %(name)s gi�� esistente"
-
-#, python-format
-msgid "Storage pool %(name)s does not exist"
-msgstr "Il pool di memoria %(name)s non esiste"
-
-#, python-format
-msgid "Specify %(item)s in order to create the storage pool %(name)s"
-msgstr "Specificare %(item)s per poter creare il pool di memoria %(name)s"
-
-#, python-format
-msgid "Unable to delete active storage pool %(name)s"
-msgstr "Impossibile eliminare il pool di memoria attivo %(name)s"
-
-#, python-format
-msgid "Unable to list storage pools. Details: %(err)s"
-msgstr "Impossibile elencare i pool di memoria. Dettagli: %(err)s"
-
-#, python-format
-msgid "Unable to create storage pool %(name)s. Details: %(err)s"
-msgstr "Impossibile creare il pool di memoria %(name)s. Dettagli: %(err)s"
-
-#, python-format
-msgid ""
-"Unable to get number of storage volumes in storage pool %(name)s. Details: %"
-"(err)s"
-msgstr ""
-"Impossibile ottenere il numero di volumi di memoria nel pool di memoria %"
-"(name)s. Dettagli: %(err)s"
-
-#, python-format
-msgid "Unable to activate storage pool %(name)s. Details: %(err)s"
-msgstr "Impossibile attivare il pool di memoria %(name)s. Dettagli: %(err)s"
-
-#, python-format
-msgid "Unable to deactivate storage pool %(name)s. Details: %(err)s"
-msgstr "Impossibile disattivare il pool di memoria %(name)s. Dettagli:
%(err)s"
-
-#, python-format
-msgid "Unable to delete storage pool %(name)s. Details: %(err)s"
-msgstr "Impossibile eliminare il pool di memoria %(name)s. Dettagli: %(err)s"
-
-#, python-format
-msgid ""
-"Unable to create NFS Pool as export path %(path)s may block during mount"
-msgstr ""
-"Impossibile creare il pool NFS poich�� il percorso di esportazione %(path)s "
-"potrebbe bloccarsi durante il montaggio"
-
-#, python-format
-msgid "Unable to create NFS Pool as export path %(path)s mount failed"
-msgstr ""
-"Impossibile creare il pool NFS poich�� il montaggio del percorso di "
-"esportazione %(path)s ha avuto esito negativo"
-
-#, python-format
-msgid "Unsupported storage pool type: %(type)s"
-msgstr "Tipo di pool di memoria non supportato: %(type)s"
-
-#, python-format
-msgid "Error while retrieving storage pool XML to %(pool)s"
-msgstr ""
-
-msgid "Storage pool name must be a string without slashes (/)"
-msgstr ""
-
-msgid ""
-"Supported storage pool types are dir, netfs, logical, iscsi, isci and
kimchi-"
-"iso"
-msgstr ""
-
-msgid "Storage pool path must be a string"
-msgstr "Il percorso del pool di memoria deve essere una stringa"
-
-msgid "Storage pool host must be a IP or hostname"
-msgstr "L'host del pool di memoria deve essere un nome host o IP"
-
-msgid "Storage pool device must be the absolute path to the block device"
-msgstr ""
-
-msgid "Storage pool devices parameter must be a list"
-msgstr "Il parametro dispositivi pool di memoria deve essere un elenco"
-
-msgid "Target IQN of an iSCSI pool must be a string"
-msgstr "L'IQN di destinazione di un pool iSCSI deve essere una stringa"
-
-msgid "Port of a remote storage server must be an integer between 1 and 65535"
-msgstr ""
-"La porta di un server di memoria remoto deve essere un numero intero tra 1 e
"
-"65535"
-
-msgid "iSCSI target username must be a string"
-msgstr ""
-
-msgid "iSCSI target password must be a string"
-msgstr ""
-
-msgid "Specify name and type to create a storage pool"
-msgstr "Specificare nome e tipo per creare un pool di memoria"
-
-#, python-format
-msgid ""
-"%(disk)s is not a valid disk/partition. Could not add it to the pool %(pool)"
-"s."
-msgstr ""
-"%(disk)s non �� un disco/partizione valido. Impossibile aggiungerlo al pool
%"
-"(pool)s."
-
-#, python-format
-msgid "Unable to extend logical pool %(pool)s. Details: %(err)s"
-msgstr ""
-
-msgid "The parameter disks only can be updated for logical storage pool."
-msgstr ""
-"Solo il parametro dischi pu�� essere aggiornato per il pool di memoria
logico."
-
-msgid "The SCSI host adapter name must be a string."
-msgstr "Il nome adattatore host SCSI deve essere una stringa."
-
-msgid "The storage pool kimchi_isos is reserved for internal use"
-msgstr "Il pool di memoria kimchi_isos �� riservato per uso interno"
-
-#, python-format
-msgid ""
-"Unable to activate NFS storage pool %(name)s. NFS server %(server)s is "
-"unreachable."
-msgstr ""
-"Impossibile attivare il pool di memoria NFS %(name)s. Il server NFS
%(server)"
-"s �� irraggiungibile."
-
-#, python-format
-msgid ""
-"Unable to deactivate NFS storage pool %(name)s. NFS server %(server)s is "
-"unreachable."
-msgstr ""
-"Impossibile disattivare il pool di memoria NFS %(name)s. Il server NFS %"
-"(server)s �� irraggiungibile."
-
-#, python-format
-msgid ""
-"Unable to deactivate pool %(name)s as it is associated with some templates"
-msgstr ""
-"Impossibile disattivare il pool %(name)s poich�� �� associato ad alcuni
modelli"
-
-#, python-format
-msgid "Unable to delete pool %(name)s as it is associated with some templates"
-msgstr ""
-"Impossibile eliminare il pool %(name)s poich�� �� associato ad alcuni
modelli"
-
-#, python-format
-msgid ""
-"A volume group named '%(name)s' already exists. Please, choose another name
"
-"to create the logical pool."
-msgstr ""
-"Un gruppo di volumi denominato '%(name)s' esiste gi��. Scegliere un altro
"
-"nome per creare il pool logico."
-
-#, python-format
-msgid "Unable to update database with deep scan information due error:
%(err)s"
-msgstr ""
-"Impossibile aggiornare il database con informazioni approfondite sulla "
-"scansione a causa dell'errore: %(err)s"
-
-#, python-format
-msgid "Storage volume %(name)s already exists"
-msgstr "Volume di memoria %(name)s gi�� esistente"
-
-#, python-format
-msgid "Storage volume %(name)s does not exist in storage pool %(pool)s"
-msgstr "Il volume di memoria %(name)s non esiste nel pool di memoria %(pool)s"
-
-#, python-format
-msgid ""
-"Unable to create storage volume %(volume)s because storage pool %(pool)s is "
-"not active"
-msgstr ""
-
-#, python-format
-msgid "Specify %(item)s in order to create storage volume %(volume)s"
-msgstr "Specificare %(item)s per poter creare il volume di memoria %(volume)s"
-
-#, python-format
-msgid ""
-"Unable to list storage volumes because storage pool %(pool)s is not active"
-msgstr ""
-"Impossibile elencare i volumi di memoria poich�� il pool di memoria %(pool)s
"
-"non �� attivo"
-
-#, python-format
-msgid ""
-"Unable to create storage volume %(name)s in storage pool %(pool)s. Details:
%"
-"(err)s"
-msgstr ""
-"Impossibile creare il volume di memoria %(name)s nel pool di memoria %(pool)"
-"s. Dettagli: %(err)s"
-
-#, python-format
-msgid ""
-"Unable to list storage volumes in storage pool %(pool)s. Details: %(err)s"
-msgstr ""
-"Impossibile elencare i volumi di memoria nel pool di memoria %(pool)s. "
-"Dettagli: %(err)s"
-
-#, python-format
-msgid "Unable to wipe storage volumes %(name)s. Details: %(err)s"
-msgstr "Impossibile ripulire i volumi di memoria %(name)s. Dettagli: %(err)s"
-
-#, python-format
-msgid "Unable to delete storage volume %(name)s. Details: %(err)s"
-msgstr "Impossibile eliminare il volume di memoria %(name)s. Dettagli:
%(err)s"
-
-#, python-format
-msgid "Unable to resize storage volume %(name)s. Details: %(err)s"
-msgstr ""
-"Impossibile ridimensionare il volume di memoria %(name)s. Dettagli: %(err)s"
-
-#, python-format
-msgid "Storage type %(type)s does not support volume create and delete"
-msgstr ""
-"Il tipo di memoria %(type)s non supporta la creazione ed eliminazione del "
-"volume"
-
-msgid "Storage volume name must be a string"
-msgstr "Il nome del volume di memoria deve essere una stringa"
-
-msgid "Storage volume allocation must be an integer number"
-msgstr "L'assegnazione del volume di memoria deve essere un numero intero"
-
-msgid ""
-"Storage volume format not supported. Valid formats: bochs, cloop, cow, dmg, "
-"qcow, qcow2, qed, raw, vmdk, vpc."
-msgstr ""
-
-msgid "Storage volume requires a volume name"
-msgstr "Il volume di memoria richiede un nome volume"
-
-#, python-format
-msgid ""
-"Unable to update database with storage volume information due error: %(err)s"
-msgstr ""
-"Impossibile aggiornare il database con informazioni sul volume di memoria a "
-"causa dell'errore: %(err)s"
-
-#, python-format
-msgid "Only one of parameter %(param)s can be specified"
-msgstr ""
-
-#, python-format
-msgid "Create volume from %(param)s is not supported"
-msgstr ""
-
-msgid "Storage volume capacity must be an integer number."
-msgstr ""
-
-msgid "Storage volume URL must be http://, https://, ftp:// or ftps://."
-msgstr ""
-
-#, python-format
-msgid "Unable to access file %(url)s. Please, check it."
-msgstr ""
-
-#, python-format
-msgid ""
-"Unable to clone storage volume '%(name)s' in pool '%(pool)s'.
Details: %(err)"
-"s"
-msgstr ""
-
-msgid "Specify chunk data and its size to upload a file."
-msgstr ""
-
-msgid "In order to upload a storage volume, specify the 'upload'
parameter."
-msgstr ""
-
-msgid ""
-"Unable to upload chunk data as it does not match with requested chunk size."
-msgstr ""
-
-#, python-format
-msgid "The storage volume %(vol)s is not under an upload process."
-msgstr ""
-
-msgid "The upload chunk data will exceed the storage volume size."
-msgstr ""
-
-#, python-format
-msgid "Unable to upload chunk data to storage volume. Details: %(err)s."
-msgstr ""
-
-#, python-format
-msgid "Interface %(name)s does not exist"
-msgstr "L'interfaccia %(name)s non esiste"
-
-#, python-format
-msgid "Network %(name)s already exists"
-msgstr "Rete %(name)s gi�� esistente"
-
-#, python-format
-msgid "Network %(name)s does not exist"
-msgstr "La rete %(name)s non esiste"
-
-#, python-format
-msgid "Subnet %(subnet)s specified for network %(network)s is not valid."
-msgstr ""
-"La sottorete %(subnet)s specificata per la rete %(network)s non �� valida ."
-
-#, python-format
-msgid "Specify a network interface to create bridged network %(name)s"
-msgstr ""
-"Specificare un'interfaccia di rete per creare la rete con bridge
%(name)s"
-
-#, python-format
-msgid "Unable to delete active network %(name)s"
-msgstr "Impossibile eliminare la rete attiva %(name)s"
-
-#, python-format
-msgid "Interface %(iface)s specified for network %(network)s is already in
use"
-msgstr ""
-"L'interfaccia %(iface)s specificata per la rete %(network)s �� gi�� in
uso"
-
-msgid "Interface should be bare NIC, bonding or bridge device."
-msgstr ""
-"L'interfaccia deve essere un dispositivo bridge o di collegamento NIC
bare-"
-"metal."
-
-#, python-format
-msgid "Unable to create network %(name)s. Details: %(err)s"
-msgstr "Impossibile creare la rete %(name)s. Dettagli: %(err)s"
-
-#, python-format
-msgid "Unable to find a free IP address for network '%(name)s'"
-msgstr "Impossibile trovare un indirizzo IP libero per la rete
'%(name)s'"
-
-#, python-format
-msgid "The interface %(iface)s already exists."
-msgstr "L'interfaccia %(iface)s gi�� esistente."
-
-msgid "Network name must be a string without slashes (/) or quotes (\")"
-msgstr ""
-
-msgid "Supported network types are isolated, NAT and bridge"
-msgstr "I tipi di rete supportati sono isolata, NAT e bridge"
-
-msgid "Network subnet must be a string with IP address and prefix or netmask"
-msgstr ""
-"La sottorete della rete deve essere una stringa con indirizzo IP e prefisso "
-"o maschera di rete"
-
-msgid "Network interface must be a string"
-msgstr "L'interfaccia di rete deve essere una stringa"
-
-msgid "Network VLAN ID must be an integer between 1 and 4094"
-msgstr "L'ID VLAN di rete deve essere un numero intero tra 1 e 4094"
-
-msgid "Specify name and type to create a Network"
-msgstr "Specificare nome e tipo per creare una rete"
-
-#, python-format
-msgid ""
-"Unable to delete network %(name)s. There are some virtual machines %(vms)s "
-"and/or templates linked to this network."
-msgstr ""
-"Impossibile eliminare la rete %(name)s. Ci sono alcune macchine virtuali %"
-"(vms)s e/o modelli collegati a tale rete."
-
-#, python-format
-msgid ""
-"Unable to deactivate network %(name)s. There are some virtual machines
%(vms)"
-"s and/or templates linked to this network."
-msgstr ""
-"Impossibile disattivare la rete %(name)s. Ci sono alcune macchine virtualie
%"
-"(vms)s e/o modelli collegati a tale rete."
-
-#, python-format
-msgid "Bridge device %(name)s can not be the trunk device of a VLAN."
-msgstr ""
-"Il dispositivo bridge %(name)s non pu�� essere il dispositivo trunk di una "
-"VLAN."
-
-#, python-format
-msgid "Failed to activate interface %(iface)s: %(err)s."
-msgstr "Impossibile attivare l'interfaccia %(iface)s: %(err)s."
-
-#, python-format
-msgid ""
-"Failed to activate interface %(iface)s. Please check the physical link "
-"status."
-msgstr ""
-"Impossibile attivare l'interfaccia %(iface)s. Controllare lo stato del link
"
-"fisico."
-
-#, python-format
-msgid "Failed to start network %(name)s. Details: %(err)s"
-msgstr ""
-
-#, python-format
-msgid "Debug report %(name)s does not exist"
-msgstr "Il report di debug %(name)s non esiste"
-
-msgid "Debug report tool not found in system"
-msgstr "Strumento report di debug non trovato nel sistema"
-
-#, python-format
-msgid "Unable to create debug report %(name)s. Details: %(err)s."
-msgstr "Impossibile creare il report di debug %(name)s. Dettagli: %(err)s."
-
-#, python-format
-msgid "Can not find any debug report with the given name %(name)s"
-msgstr ""
-
-#, python-format
-msgid "Unable to generate debug report %(name)s. Details: %(err)s"
-msgstr "Impossibile generare il report di debug %(name)s. Dettagli: %(err)s"
-
-msgid "You should give a name for the debug report file."
-msgstr ""
-
-msgid ""
-"Debug report name must be a string. Only letters, digits, underscore ('_')
"
-"and hyphen ('-') are allowed."
-msgstr ""
-
-#, python-format
-msgid ""
-"The debug report with specified name \"%(name)s\" already exists. Please
use "
-"another one."
-msgstr ""
-"Un gruppo di volumi denominato '%(name)s' esiste gi��. Scegliere un altro
"
-"nome per creare il pool logico."
-
-#, python-format
-msgid "Storage server %(server)s was not used by Kimchi"
-msgstr "Il server di memoria %(server)s non �� stato utilizzato da Kimchi"
-
-#, python-format
-msgid "Distro '%(name)s' does not exist"
-msgstr "Distro '%(name)s' non esistente"
-
-#, python-format
-msgid "Partition %(name)s does not exist in the host"
-msgstr "La partizione %(name)s non esiste nell'host"
-
-msgid "Unable to shutdown host machine as there are running virtual machines"
-msgstr ""
-"Impossibile arrestare la macchina host poich�� sono presenti macchine "
-"virtuali in esecuzione"
-
-msgid "Unable to reboot host machine as there are running virtual machines"
-msgstr ""
-"Impossibile riavviare la macchina host poich�� sono presenti macchine "
-"virtuali in esecuzione"
-
-#, python-format
-msgid "Node device '%(name)s' not found"
-msgstr "Dispositivo nodo '%(name)s' non trovato"
-
-msgid "Conflicting flag filters specified."
-msgstr ""
-
-msgid "No packages marked for update"
-msgstr "Nessun pacchetto contrassegnato per l'aggiornamento"
-
-#, python-format
-msgid "Package %(name)s is not marked to be updated."
-msgstr "Il pacchetto %(name)s non �� contrassegnato per l'aggiornamento."
-
-#, python-format
-msgid "Error while getting packages marked to be updated. Details: %(err)s"
-msgstr ""
-"Errore durante il richiamo dei pacchetti contrassegnati per l'aggiornamento.
"
-"Dettagli: %(err)s"
-
-msgid "There is no compatible package manager for this system."
-msgstr "Non �� presente un gestore pacchetti compatibile per questo sistema."
-
-#, python-format
-msgid "Invalid URI %(uri)s"
-msgstr "URI %(uri)s non valido"
-
-msgid "Unable to choose a virtual machine name"
-msgstr ""
-
-msgid "Invalid storage type. Types supported: 'cdrom', 'disk'"
-msgstr "Tipo di memoria non valido. I tipi supportati sono: 'cdrom'"
-
-#, python-format
-msgid "The path '%(value)s' is not a valid local/remote path for the
device"
-msgstr ""
-
-msgid "Only CDROM path can be update."
-msgstr ""
-
-#, python-format
-msgid ""
-"The storage device %(dev_name)s does not exist in the virtual machine %"
-"(vm_name)s"
-msgstr ""
-
-#, python-format
-msgid "Error while creating new storage device: %(error)s"
-msgstr ""
-"Errore durante la creazione del nuovo dispositivo di memoria: %(error)s"
-
-#, python-format
-msgid "Error while updating storage device: %(error)s"
-msgstr "Errore durante l'aggiornamento del dispositivo di memoria:
%(error)s"
-
-#, python-format
-msgid "Error while removing storage device: %(error)s"
-msgstr "Errore durante la rimozione del dispositivo di memoria: %(error)s"
-
-msgid "Do not support IDE device hot plug"
-msgstr ""
-
-msgid ""
-"Specify type and path or type and pool/volume to add a new virtual machine "
-"disk"
-msgstr ""
-"Specificare tipo e percorso per aggiungere un nuovo disco della macchina "
-"virtuale"
-
-msgid "Specify path to update virtual machine disk"
-msgstr ""
-"Specificare il percorso per aggiornare il disco della macchina virtuale"
-
-#, python-format
-msgid "Controller type %(type)s limitation of %(limit)s devices reached"
-msgstr ""
-
-#, python-format
-msgid "Cannot retrieve disk path information for given pool/volume: %(error)s"
-msgstr ""
-
-msgid "Volume already in use by other virtual machine."
-msgstr ""
-
-msgid ""
-"Only one of path or pool/volume can be specified to add a new virtual "
-"machine disk"
-msgstr ""
-"Specificare tipo e percorso per aggiungere un nuovo disco della macchina "
-"virtuale"
-
-#, python-format
-msgid ""
-"Volume chosen with format %(format)s does not fit in the storage type
%(type)"
-"s"
-msgstr ""
-
-msgid "YUM Repository ID must be one word only string."
-msgstr "L'ID repository YUM deve essere una stringa di una sola parola."
-
-msgid "Repository URL must be an http://, ftp:// or file:// URL."
-msgstr "L'URL del repository deve essere http://, ftp:// o file:// URL."
-
-msgid ""
-"Repository configuration is a dictionary with specific values according to "
-"repository type."
-msgstr ""
-"La configurazione del repository �� un dizionario con valori specifici in "
-"base al tipo di repository."
-
-msgid "Distribution to DEB repository must be a string"
-msgstr "La distribuzione al repository DEB deve essere una stringa"
-
-msgid "Components to DEB repository must be listed in a array"
-msgstr "I componenti per il repository DEB devono essere elencati in un array"
-
-msgid "Components to DEB repository must be a string"
-msgstr "I componenti per il repository DEB devono essere una stringa"
-
-msgid "Mirror list to repository must be a string"
-msgstr ""
-
-msgid "YUM Repository name must be string."
-msgstr "Il nome del repository YUM deve essere una stringa."
-
-msgid "GPG check must be a boolean value."
-msgstr "Il controllo GPG deve essere un valore booleano."
-
-msgid "GPG key must be a URL pointing to the ASCII-armored file."
-msgstr "La chiave GPG deve essere un URL che punta al file blindato ASCII."
-
-#, python-format
-msgid "Could not update repository %(repo_id)s."
-msgstr "Impossibile aggiornare il repository %(repo_id)s."
-
-#, python-format
-msgid "Repository %(repo_id)s does not exist."
-msgstr "Il repository %(repo_id)s non esiste."
-
-msgid ""
-"Specify repository base URL, mirror list or metalink in order to create or "
-"update a YUM repository."
-msgstr ""
-
-msgid "Repository management tool was not recognized for your system."
-msgstr ""
-"Lo strumento di gestione del repository non �� stato riconosciuto per il "
-"sistema."
-
-#, python-format
-msgid "Repository %(repo_id)s is already enabled."
-msgstr "Il repository %(repo_id)s �� gi�� abilitato."
-
-#, python-format
-msgid "Repository %(repo_id)s is already disabled."
-msgstr "Il repository %(repo_id)s �� gi�� disabilitato."
-
-#, python-format
-msgid "Could not remove repository %(repo_id)s."
-msgstr "Impossibile rimuovere il repository %(repo_id)s."
-
-#, python-format
-msgid "Could not write repository configuration file %(repo_file)s"
-msgstr ""
-"Impossibile scrivere il file di configurazione del repository %(repo_file)s"
-
-msgid "Specify repository distribution in order to create a DEB repository."
-msgstr ""
-"Specificare la distribuzione del repository per poter creare un repository "
-"DEB."
-
-#, python-format
-msgid "Could not enable repository %(repo_id)s."
-msgstr "Impossibile abilitare il repository %(repo_id)s."
-
-#, python-format
-msgid "Could not disable repository %(repo_id)s."
-msgstr "Impossibile disabilitare il repository %(repo_id)s."
-
-msgid "YUM Repository ID already exists"
-msgstr "ID repository YUM gi�� esistente"
-
-msgid "YUM Repository name must be a string"
-msgstr "Il nome del repository YUM deve essere una stringa"
-
-#, python-format
-msgid "Unable to list repositories. Details: '%(err)s'"
-msgstr "Impossibile elencare i repository. Dettagli: '%(err)s'"
-
-#, python-format
-msgid "Unable to retrieve repository information. Details: '%(err)s'"
-msgstr ""
-"Impossibile richiamare le informazioni sul repository. Dettagli:
'%(err)s'"
-
-#, python-format
-msgid "Unable to add repository. Details: '%(err)s'"
-msgstr "Impossibile aggiungere il repository. Dettagli: '%(err)s'"
-
-#, python-format
-msgid "Unable to remove repository. Details: '%(err)s'"
-msgstr "Impossibile rimuovere il repository. Dettagli: '%(err)s'"
-
-#, python-format
-msgid ""
-"Configuration items: '%(items)s' are not supported by repository
manager"
-msgstr ""
-
-msgid "Repository metalink must be an http://, ftp:// or file:// URL."
-msgstr ""
-
-msgid "Cannot specify mirrorlist and metalink at the same time."
-msgstr ""
-
-#, python-format
-msgid ""
-"Virtual machine '%(vm)s' must be stopped before creating a snapshot of
it."
-msgstr ""
-
-#, python-format
-msgid ""
-"Unable to create snapshot '%(name)s' on virtual machine '%(vm)s'.
Details: %"
-"(err)s"
-msgstr ""
-
-#, python-format
-msgid "Snapshot '%(name)s' does not exist on virtual machine
'%(vm)s'."
-msgstr ""
-
-#, python-format
-msgid ""
-"Unable to retrieve snapshot '%(name)s' on virtual machine '%(vm)s'.
Details: "
-"%(err)s"
-msgstr ""
-
-#, python-format
-msgid "Unable to list snapshots on virtual machine '%(vm)s'. Details:
%(err)s"
-msgstr ""
-
-#, python-format
-msgid ""
-"Unable to delete snapshot '%(name)s' on virtual machine '%(vm)s'.
Details: %"
-"(err)s"
-msgstr ""
-
-#, python-format
-msgid ""
-"Unable to retrieve current snapshot of virtual machine '%(vm)s'. Details:
%"
-"(err)s"
-msgstr ""
-
-#, python-format
-msgid ""
-"Unable to revert virtual machine '%(vm)s' to snapshot '%(name)s'.
Details: %"
-"(err)s"
-msgstr ""
-
-#, python-format
-msgid ""
-"Unable to create snapshot of virtual machine '%(vm)s' because it contains a
"
-"disk with format '%(format)s'; only 'qcow2' is supported."
-msgstr ""
-
-msgid "The number of vCPUs is too large for this system."
-msgstr ""
-
-msgid "Invalid vCPU/topology combination."
-msgstr ""
-
-msgid "This host (or current configuration) does not allow CPU topology."
-msgstr ""
-
-msgid "ERROR CODE"
-msgstr "CODICE DI ERRORE"
-
-msgid "REASON"
-msgstr "CAUSA"
-
-msgid "STACK"
-msgstr "STACK"
-
-msgid "Go to Homepage"
-msgstr "Vai alla home page"
-
-msgid "Create a New Virtual Machine"
-msgstr "Crea una nuova macchina virtuale"
-
-msgid "Virtual Machine Name"
-msgstr "Nome macchina virtuale"
-
-msgid ""
-"The name used to identify the virtual machine. If omitted, a name will be "
-"chosen based on the template used."
-msgstr ""
-"Il nome utilizzato per identificare la macchina virtuale. Se il nome viene "
-"omesso ne verr�� scelto uno in base al modello utilizzato."
-
-msgid "Template"
-msgstr "Modello"
-
-msgid "Please create a template first."
-msgstr "Creare prima un modello."
-
-msgid "Create a Template"
-msgstr "Crea un modello"
-
-msgid "Please choose a template."
-msgstr "Scegliere un modello."
-
-msgid "OS"
-msgstr "SO"
-
-msgid "OS Version"
-msgstr "Versione SO"
-
-msgid "CPUS"
-msgstr "CPUS"
-
-msgid "Memory"
-msgstr "Memoria"
-
-msgid "Create"
-msgstr "Crea"
-
-msgid "Creating..."
-msgstr ""
-
-msgid "Cancel"
-msgstr "Annulla"
-
-msgid "Edit Guest"
-msgstr "Modifica guest"
-
-msgid "General"
-msgstr "Generale"
-
-msgid "Storage"
-msgstr "Memoria"
-
-msgid "Interface"
-msgstr "Interfaccia"
-
-msgid "Permission"
-msgstr "Versione"
-
-msgid "Host PCI Device"
-msgstr ""
-
-msgid "Snapshot"
-msgstr ""
-
-msgid "Name"
-msgstr "Nome"
-
-msgid "CPUs"
-msgstr "CPU"
-
-msgid "Memory (MB)"
-msgstr "Memoria"
-
-msgid "Icon"
-msgstr "Icona"
-
-msgid "Device"
-msgstr "Nome dispositivo"
-
-msgid "Path"
-msgstr "Percorso NFS"
-
-msgid "Network"
-msgstr "Rete"
-
-msgid "Type"
-msgstr "Tipo"
-
-msgid "MAC Address"
-msgstr ""
-
-msgid "Available system users and groups"
-msgstr ""
-
-msgid "Selected system users and groups"
-msgstr ""
-
-msgid "User"
-msgstr ""
-
-msgid "All"
-msgstr "Tutti"
-
-msgid "To Add"
-msgstr ""
-
-msgid "Added"
-msgstr ""
-
-msgid "filter"
-msgstr ""
-
-msgid "Product"
-msgstr ""
-
-msgid "Vendor"
-msgstr "Fornitore"
-
-msgid "Created"
-msgstr ""
-
-msgid "Save"
-msgstr "Salva"
-
-msgid "Replace"
-msgstr "Sostituisci"
-
-msgid "Detach"
-msgstr "Scollega"
-
-msgid "revert"
-msgstr ""
-
-msgid "Start"
-msgstr "Avvia"
-
-msgid "Reset"
-msgstr "Reimposta"
-
-msgid "Pause"
-msgstr ""
-
-msgid "Resume"
-msgstr ""
-
-msgid "Power Off"
-msgstr ""
-
-msgid "Actions"
-msgstr "Azioni"
-
-msgid "Connect"
-msgstr "Connetti"
-
-msgid "Clone"
-msgstr ""
-
-msgid "Edit"
-msgstr "Modifica"
-
-msgid "Shut Down"
-msgstr "Arresta"
-
-msgid "Delete"
-msgstr "Elimina"
-
-msgid "CPU"
-msgstr "CPU"
-
-msgid "Disk I/O"
-msgstr "I/O disco"
-
-msgid "Network I/O"
-msgstr "I/O di rete"
-
-msgid "Livetile"
-msgstr "Riquadro animato"
-
-msgid "No guests found."
-msgstr "Nessuna macchina guest trovata."
-
-msgid "Add a Storage Device to VM"
-msgstr "Aggiungi un dispositivo di memoria alla VM"
-
-msgid "Device Type"
-msgstr "Tipo dispositivo"
-
-msgid "The device type. Currently, \"cdrom\" and \"disk\" are
supported."
-msgstr "Il tipo di dispositivo. Attualmente, �� supportato solo
\"cdrom\"."
-
-msgid "Storage Pool"
-msgstr "Pool di memoria"
-
-msgid "Storage pool which volume located in"
-msgstr "Il percorso del pool di memoria deve essere una stringa"
-
-msgid "Storage Volume"
-msgstr "Nome pool di memoria"
-
-msgid "Storage volume to be attached"
-msgstr "Il nome del volume di memoria deve essere una stringa"
-
-msgid "File Path"
-msgstr "Percorso file"
-
-msgid "The ISO file path in the server for CDROM."
-msgstr "Il percorso file ISO nel server per CDROM."
-
-msgid "Attach"
-msgstr "Allega"
-
-msgid "Shut down"
-msgstr "Arresta"
-
-msgid "Restart"
-msgstr "Riavvia"
-
-msgid "Basic Information"
-msgstr "Informazioni di base"
-
-msgid "OS Distro"
-msgstr "Distro SO"
-
-msgid "OS Code Name"
-msgstr "Nome codice SO"
-
-msgid "Processor"
-msgstr "Processore"
-
-msgid "CPU(s)"
-msgstr ""
-
-msgid "System Statistics"
-msgstr "Statistiche di sistema"
-
-msgid "Software Updates"
-msgstr "Aggiornamenti del software"
-
-msgid "Update Progress"
-msgstr "Avanzamento aggiornamento"
-
-msgid "Repositories"
-msgstr "Repository"
-
-msgid "Debug Reports"
-msgstr "Report di debug"
-
-msgid "The username or password you entered is incorrect. Please try again."
-msgstr ""
-"Il nome utente o la password immessi non sono corretti. Ripetere "
-"l'operazione."
-
-msgid "This field is required."
-msgstr "Questo campo �� obbligatorio."
-
-msgid "Log in"
-msgstr "Accedi"
-
-msgid "Logging in..."
-msgstr "Accesso in corso..."
-
-msgid "Host"
-msgstr "Host"
-
-msgid "Guests"
-msgstr "Guest"
-
-msgid "Templates"
-msgstr "Modelli"
-
-msgid "Failed to get application configuration"
-msgstr "Richiamo della configurazione dell'applicazione non riuscito"
-
-msgid "This is not a valid Linux path"
-msgstr "Non �� un percorso Linux valido"
-
-msgid "This is not a valid URL."
-msgstr "Non �� un URL valido."
-
-msgid "No such data available."
-msgstr "Dati indicati non disponibili."
-
-msgid ""
-"Can not contact the host system. Verify the host system is up and that you "
-"have network connectivity to it. HTTP request response %1. "
-msgstr ""
-"Impossibile contattare il sistema host. Verificare che il sistema host sia "
-"attivo e che si disponga della connettivit�� di rete per tale sistema. "
-"Risposta alla richiesta HTTP %1. "
-
-msgid "Unable to read file."
-msgstr ""
-
-msgid "Error while uploading file."
-msgstr ""
-
-msgid "Delete Confirmation"
-msgstr "Conferma eliminazione"
-
-msgid "OK"
-msgstr "OK"
-
-msgid "Confirm"
-msgstr "Conferma"
-
-msgid "Warning"
-msgstr "Avvertenza"
-
-msgid "Cloning..."
-msgstr ""
-
-msgid "Loading..."
-msgstr "Caricamento in corso..."
-
-msgid "An error occurred while retrieving system information."
-msgstr ""
-
-msgid "Retry"
-msgstr "Riprova"
-
-msgid "Detailed message:"
-msgstr "Messaggio dettagliato:"
-
-msgid "No ISO found"
-msgstr ""
-
-msgid "This is not a valid ISO file."
-msgstr "Non �� un file ISO valido."
-
-msgid "This may take a long time. Do you want to continue?"
-msgstr "Richieder�� molto tempo. Continuare?"
-
-msgid "This will permanently delete the template. Would you like to continue?"
-msgstr "L'azione eliminer�� permanentemente il modello. Continuare?"
-
-msgid "Unable to shut down system as there are some virtual machines running!"
-msgstr ""
-"Impossibile arrestare il sistema poich�� sono in esecuzione alcune macchine "
-"virtuali."
-
-msgid "Max:"
-msgstr "Massimo:"
-
-msgid "Utilization"
-msgstr "Utilizzo"
-
-msgid "Available"
-msgstr "Disponibile"
-
-msgid "Read Rate"
-msgstr "Velocit�� di lettura"
-
-msgid "Write Rate"
-msgstr "Velocit�� di scrittura"
-
-msgid "Received"
-msgstr "Ricevuti"
-
-msgid "Sent"
-msgstr "Inviati"
-
-msgid ""
-"Shutting down or restarting host will cause unsaved work lost. Continue to "
-"shut down/restarting?"
-msgstr ""
-"L'arresto o il riavvio dell'host provocher�� la perdita del lavoro non
"
-"salvato. Continuare con l'arresto o il riavvio?"
-
-msgid ""
-"Repository will be removed permanently and can't be recovered. Do you want
"
-"to continue?"
-msgstr ""
-"Il repository verr�� rimosso permanentemente e non potr�� essere ripristinato.
"
-"Si desidera continuare?"
-
-msgid "ID"
-msgstr "ID"
-
-msgid "Base URL"
-msgstr "URL di base"
-
-msgid "Is Mirror"
-msgstr "�� speculare"
-
-msgid "URL Args"
-msgstr "Argomenti URL"
-
-msgid "Enabled"
-msgstr "Abilitato"
-
-msgid "GPG Check"
-msgstr "Controllo GPG"
-
-msgid "GPG Key"
-msgstr "Chiave GPG"
-
-msgid "Add"
-msgstr "Aggiungi"
-
-msgid "Remove"
-msgstr "Rimuovi"
-
-msgid "Enable"
-msgstr "Abilita"
-
-msgid "Disable"
-msgstr "Disabilita"
-
-msgid "Package Name"
-msgstr "Nome pacchetto"
-
-msgid "Version"
-msgstr "Versione"
-
-msgid "Architecture"
-msgstr "Architettura"
-
-msgid "Repository"
-msgstr "Repository"
-
-msgid "Update All"
-msgstr "Aggiorna tutto"
-
-msgid "Updating..."
-msgstr "Aggiornamento in corso..."
-
-msgid "Failed to retrieve packages update information."
-msgstr ""
-
-msgid "Failed to update package(s)."
-msgstr "Aggiornamento dei pacchetti non riuscito."
-
-msgid ""
-"Debug report will be removed permanently and can't be recovered. Do you want
"
-"to continue?"
-msgstr ""
-"Il report del debug verr�� rimosso permanentemente e non potr�� essere "
-"ripristinato. Si desidera continuare?"
-
-msgid "Generated Time"
-msgstr "Ora di creazione"
-
-msgid "Generate"
-msgstr "Crea"
-
-msgid "Generating..."
-msgstr "Creazione in corso..."
-
-msgid "Rename"
-msgstr "Ridenomina"
-
-msgid "Download"
-msgstr "Scarica"
-
-msgid ""
-"Report name should contain only letters, digits, underscore ('_') and/or
"
-"hyphen ('-')."
-msgstr ""
-"Il nome del report pu�� contenere solo lettere, cifre e/o trattini
('-')."
-
-msgid "Pending..."
-msgstr "Caricamento in corso..."
-
-msgid "Report name is the same as the original one."
-msgstr ""
-
-msgid ""
-"This will delete the virtual machine and its virtual disks. This operation "
-"cannot be undone. Would you like to continue?"
-msgstr ""
-"L'operazione eliminer�� la macchina virtuale e i relativi dischi virtuali e
"
-"non �� reversibile. Continuare?"
-
-msgid "Power off Confirmation"
-msgstr "Conferma eliminazione"
-
-msgid ""
-"This action may produce undesirable results, for example unflushed disk "
-"cache in the guest. Would you like to continue?"
-msgstr ""
-
-msgid "Reset Confirmation"
-msgstr "Conferma eliminazione"
-
-msgid ""
-"There is a risk of data loss caused by reset without the guest OS shutdown. "
-"Would you like to continue?"
-msgstr ""
-
-msgid "Shut Down Confirmation"
-msgstr "Conferma eliminazione"
-
-msgid "Note the guest OS may ignore this request. Would you like to continue?"
-msgstr "L'azione eliminer�� permanentemente il modello. Continuare?"
-
-msgid "Virtual Machine delete Confirmation"
-msgstr ""
-
-msgid ""
-"This virtual machine is not persistent. Power Off will delete it. Continue?"
-msgstr ""
-
-msgid ""
-"When the target guest has SCSI or iSCSI volumes, they will be cloned on "
-"default storage pool. The same will happen when the target pool does not "
-"have enough space to clone the volumes. Do you want to continue?"
-msgstr ""
-
-msgid ""
-"This CDROM will be detached permanently and you can re-attach it. Continue "
-"to detach it?"
-msgstr ""
-"Il CDROM verr�� scollegato permanentemente e non sar�� possibile ricollegarlo.
"
-"Continuare con lo scollegamento?"
-
-msgid "Attaching..."
-msgstr "Collegamento in corso..."
-
-msgid "Replacing..."
-msgstr "Sostituzione in corso..."
-
-msgid "Successfully attached!"
-msgstr "Collegamento riuscito."
-
-msgid "Successfully replaced!"
-msgstr "Sostituzione riuscita."
-
-msgid "Successfully detached!"
-msgstr "Scollegamento riuscito."
-
-msgid ""
-"This disk will be detached permanently and you can re-attach it. Continue to
"
-"detach it?"
-msgstr ""
-
-msgid "interface:"
-msgstr ""
-
-msgid "address:"
-msgstr ""
-
-msgid "link_type:"
-msgstr ""
-
-msgid "block:"
-msgstr ""
-
-msgid "drive_type:"
-msgstr ""
-
-msgid "model:"
-msgstr ""
-
-msgid "Affected devices:"
-msgstr ""
-
-msgid "The VLAN id must be between 1 and 4094."
-msgstr "L'ID VLAN deve essere compreso tra 1 e 4094."
-
-msgid "unavailable"
-msgstr "non disponibile"
-
-msgid ""
-"This action will interrupt network connectivity for any virtual machine that
"
-"depend on this network."
-msgstr ""
-"L'azione interromper�� la connettivit�� di rete per qualsiasi macchina "
-"virtuale che dipende da questa rete."
-
-msgid "Create a network"
-msgstr "Crea una rete"
-
-msgid ""
-"This network is not persistent. Instead of stop, this action will "
-"permanently delete it. Would you like to continue?"
-msgstr ""
-"Il pool di memoria non �� permanente. Invece di disattivarlo, l'azione lo
"
-"eliminer�� permanentemente. Continuare?"
-
-msgid ""
-"The bridged VLAN tag may not work well with NetworkManager enabled. You "
-"should consider disabling it."
-msgstr ""
-
-msgid ""
-"This will permanently delete the storage pool. Would you like to continue?"
-msgstr "L'azione eliminer�� permanentemente il pool di memoria.
Continuare?"
-
-msgid "This storage pool is empty."
-msgstr "Il pool di memoria �� vuoto."
-
-msgid ""
-"It will format your disk and you will loose any data in there, are you sure "
-"to continue? "
-msgstr ""
-"Il disco verr�� formattato e tutti i dati su di esso andranno persi, sicuri "
-"di voler continuare? "
-
-msgid "SCSI Fibre Channel"
-msgstr "Canale a fibre ottiche SCSI"
-
-msgid "No SCSI adapters found."
-msgstr "Nessun adattatore SCSI trovato."
-
-msgid "Loading iSCSI targets..."
-msgstr ""
-
-msgid "No iSCSI found. Please input one."
-msgstr ""
-
-msgid "Failed to load iSCSI targets."
-msgstr ""
-
-msgid "The storage pool name can not be blank."
-msgstr "Il campo per il nome del pool di memoria non pu�� essere vuoto."
-
-msgid "The storage pool path can not be blank."
-msgstr "Il campo per il percorso del pool di memoria non pu�� essere vuoto."
-
-msgid "NFS server mount path can not be blank."
-msgstr ""
-"Il campo per il percorso di montaggio del server NFS non pu�� essere vuoto."
-
-msgid "Invalid NFS mount path."
-msgstr "Percorso di montaggio NFS non valido."
-
-msgid "No logical device selected."
-msgstr "Nessun dispositivo logico selezionato."
-
-msgid "The iSCSI target can not be blank."
-msgstr "Il campo per la destinazione iSCSI non pu�� essere vuoto."
-
-msgid "Server name can not be blank."
-msgstr "Il campo per il nome del server non pu�� essere vuoto."
-
-msgid "This is not a valid Server Name or IP. Please, modify it."
-msgstr ""
-
-msgid "Looking for available partitions ..."
-msgstr "Ricerca di partizioni disponibili in corso..."
-
-msgid "No available partitions found."
-msgstr "Nessuna partizione disponibile trovata."
-
-msgid ""
-"This storage pool is not persistent. Instead of deactivate, this action will
"
-"permanently delete it. Would you like to continue?"
-msgstr ""
-"Il pool di memoria non �� permanente. Invece di disattivarlo, l'azione lo
"
-"eliminer�� permanentemente. Continuare?"
-
-msgid "Unable to retrieve partitions information."
-msgstr ""
-"Impossibile richiamare le informazioni sul repository. Dettagli:
'%(err)s'"
-
-msgid "In progress..."
-msgstr ""
-
-msgid "Failed!"
-msgstr ""
-
-msgid "CDROM path needs to be a valid local/remote path and cannot be blank."
-msgstr ""
-
-msgid "Disk pool or volume cannot be blank."
-msgstr "Il campo per il nome del pool di memoria non pu�� essere vuoto."
-
-msgid "Filter"
-msgstr ""
-
-msgid "Network Name"
-msgstr "Nome rete"
-
-msgid "State"
-msgstr "Stato"
-
-msgid "Network Type"
-msgstr "Tipo di Rete"
-
-msgid "Address Space"
-msgstr "Spazio indirizzo"
-
-msgid "Name should not contain '/' and '\"'."
-msgstr "Nome pool di memoria non valido. Non deve contenere '/'."
-
-msgid "Isolated: no external network connection"
-msgstr "Isolata: nessuna connessione di rete fisica"
-
-msgid "NAT: outbound physical network connection only"
-msgstr "NAT: solo connessione di rete fisica in uscita"
-
-msgid "Bridged: Virtual machines are connected to physical network directly"
-msgstr ""
-"Con bridge: le macchine virtuali sono connesse direttamente alla rete fisica"
-
-msgid "(No interfaces found)"
-msgstr ""
-
-msgid "Destination"
-msgstr "Destinazione:"
-
-msgid "Enable VLAN"
-msgstr "Abilita VLAN:"
-
-msgid "VLAN ID"
-msgstr "ID VLAN:"
-
-msgid "Stop"
-msgstr "Arresta"
-
-msgid "Generate a New Debug Report"
-msgstr "Crea un nuovo report di debug"
-
-msgid "Report Name"
-msgstr "Nome report"
-
-msgid ""
-"The name used to identify the report. If omitted, a name will be chosen "
-"based on current time. Name can contain: letters, digits, underscore
(\"_\") "
-"and hyphen (\"-\")."
-msgstr ""
-"Il nome utilizzato per identificare il report. Se il nome viene omesso, ne "
-"viene scelto uno in base all'ora corrente. Il nome pu�� contenere lettere,
"
-"cifre e trattini (\"-\")."
-
-msgid "Rename a Debug Report"
-msgstr "Crea un nuovo report di debug"
-
-msgid ""
-"The name used to identify the report. Name can contain: letters, digits and "
-"hyphen (\"-\")."
-msgstr ""
-"Il nome utilizzato per identificare il report. Se il nome viene omesso, ne "
-"viene scelto uno in base all'ora corrente. Il nome pu�� contenere lettere,
"
-"cifre e trattini (\"-\")."
-
-msgid "Submit"
-msgstr ""
-
-msgid "Add a Repository"
-msgstr "Aggiungi un repository"
-
-msgid "Identifier"
-msgstr "Identificativo"
-
-msgid "Single word, unique identifier for the repository."
-msgstr "Identificativo univoco di una sola parola per il repository."
-
-msgid "Textual name for the repository."
-msgstr "Nome in formato testo per il repository."
-
-msgid "URL"
-msgstr "URL"
-
-msgid "Required Field"
-msgstr "Campo obbligatorio"
-
-msgid "URL to the repository. Supported protocols are http, ftp, and file."
-msgstr "URL al repository. I protocolli supportati sono http, ftp e file."
-
-msgid "Repository is a mirror"
-msgstr "Il repository �� un elemento speculare."
-
-msgid "Distribution"
-msgstr "Distribuzione"
-
-msgid "Distribution of the DEB repository."
-msgstr "Distribuzione del repository DEB."
-
-msgid "Components"
-msgstr "Componenti"
-
-msgid "List of components in DEB repository."
-msgstr "Elenco di componenti nel repository DEB."
-
-msgid "Edit Repository"
-msgstr "Modifica repository"
-
-msgid "Mirror List URL"
-msgstr "URL elenco elementi speculari"
-
-msgid "Yes"
-msgstr "S��"
-
-msgid "No"
-msgstr "No"
-
-msgid "Capacity"
-msgstr "Capacit��"
-
-msgid "Allocated"
-msgstr "Assegnato"
-
-msgid "Location"
-msgstr "Ubicazione"
-
-msgid "Device path"
-msgstr "Percorso dispositivo"
-
-msgid "active"
-msgstr "attivo"
-
-msgid "inactive"
-msgstr "non attivo"
-
-msgid "Deactivate"
-msgstr "Disattiva"
-
-msgid "Activate"
-msgstr "Attiva"
-
-msgid "Add Volume"
-msgstr ""
-
-msgid "Extend"
-msgstr ""
-
-msgid "Undefine"
-msgstr "Rimuovi definizione"
-
-msgid "Format"
-msgstr "Formato:"
-
-msgid "Allocation"
-msgstr "Allocazione:"
-
-msgid "Define a New Storage Pool"
-msgstr "Definisci un nuovo pool di memoria"
-
-msgid "Storage Pool Name"
-msgstr "Nome pool di memoria"
-
-msgid ""
-"The name used to identify the storage pools, and it should not be empty."
-msgstr ""
-"Il nome utilizzato per identificare i pool di memoria; il campo non deve "
-"essere vuoto."
-
-msgid "Storage Pool Type"
-msgstr "Tipo di pool di memoria"
-
-msgid "Storage Path"
-msgstr "Percorso di memoria"
-
-msgid ""
-"The path of the Storage Pool. Each Storage Pool must have a unique path."
-msgstr ""
-"Il percorso del pool di memoria. Ogni pool di memoria deve avere un percorso
"
-"univoco."
-
-msgid ""
-"Kimchi will try to create the directory when it does not already exist in "
-"your system."
-msgstr ""
-"Kimchi tenter�� di creare la directory nel caso non esista ancora sul
sistema."
-
-msgid "NFS Server IP"
-msgstr "IP server NFS"
-
-msgid "NFS server IP or hostname. It can be input or chosen from history."
-msgstr ""
-"Il nome host o l'indirizzo IP del server NFS. �� possibile immetterlo o "
-"sceglierlo dalla cronologia."
-
-msgid "NFS Path"
-msgstr "Percorso NFS"
-
-msgid "The NFS exported path on NFS server."
-msgstr "Il percorso esportato NFS sul server NFS."
-
-msgid "iSCSI Server"
-msgstr "Server iSCSI"
-
-msgid "Server"
-msgstr "Server"
-
-msgid "Port"
-msgstr "Porta"
-
-msgid "iSCSI server IP or hostname. It should not be empty."
-msgstr ""
-"Il nome host o l'indirizzo IP del server iSCSI. Il campo non deve essere
"
-"vuoto."
-
-msgid "Target"
-msgstr "Destinazione"
-
-msgid "The iSCSI target on iSCSI server"
-msgstr "La destinazione iSCSI sul server iSCSI"
-
-msgid "Add iSCSI Authentication"
-msgstr "Aggiungi autenticazione iSCSI"
-
-msgid "iSCSI Authentication"
-msgstr "Autenticazione iSCSI"
-
-msgid "User Name"
-msgstr "Nome utente"
-
-msgid "Password"
-msgstr "Password"
-
-msgid "SCSI Adapter"
-msgstr "Adattatore SCSI"
-
-msgid "Please, wait..."
-msgstr "Attendere..."
-
-msgid "Add a Volume to Storage Pool"
-msgstr ""
-
-msgid "Fetch from remote URL"
-msgstr ""
-
-msgid "Enter the remote URL here."
-msgstr ""
-
-msgid "Upload a file"
-msgstr ""
-
-msgid "Choose the file you want to upload."
-msgstr ""
-
-msgid "Add Template"
-msgstr "Aggiungi modello"
-
-msgid "Where is the source media for this template? "
-msgstr "Dov'�� il supporto di origine per questo modello?"
-
-msgid "Local ISO Image"
-msgstr "Immagine ISO locale"
-
-msgid "Local Image File"
-msgstr ""
-
-msgid "Remote ISO Image"
-msgstr "Immagine ISO remota"
-
-msgid "Search ISOs"
-msgstr "Ricerca ISO"
-
-msgid "The following ISOs are available:"
-msgstr "Sono disponibili i seguenti file ISO:"
-
-msgid "OS: "
-msgstr "SO: "
-
-msgid "Version: "
-msgstr "Versione: "
-
-msgid "Size: "
-msgstr "Dimensione: "
-
-msgid "Search more ISOs"
-msgstr "Ricerca pi�� ISO"
-
-msgid "Create Templates from Selected ISO"
-msgstr "Crea modelli da ISO selezionato"
-
-msgid "I want to use a specific ISO file"
-msgstr "Utilizzare un file ISO specifico"
-
-msgid "Loading default remote ISOs ..."
-msgstr "Caricamento di ISO remoti predefiniti in corso..."
-
-msgid "Arch: "
-msgstr "Arch: "
-
-msgid "I want to use a custom URL"
-msgstr "Utilizzare un URL personalizzato"
-
-msgid "Edit Template"
-msgstr "Modifica modello"
-
-msgid "CDROM"
-msgstr "CDROM"
-
-msgid "Image File"
-msgstr ""
-
-msgid "Graphics"
-msgstr "Grafici"
-
-msgid "Disk(GB)"
-msgstr ""
-
-msgid "Disk Format"
-msgstr ""
-
-msgid "CPU Number"
-msgstr "Numero CPU"
-
-msgid "Manually set CPU topology"
-msgstr ""
-
-msgid "Cores"
-msgstr ""
-
-msgid "Threads"
-msgstr ""
-
-msgid "No templates found."
-msgstr "Nessun modello trovato."
-
-#~ msgid "Delete is not allowed for %(resource)s"
-#~ msgstr "Eliminazione non consentita per %(resource)s"
-
-#~ msgid "%(resource)s does not implement update method"
-#~ msgstr "%(resource)s non implementa il metodo di aggiornamento"
-
-#~ msgid "Create is not allowed for %(resource)s"
-#~ msgstr "Creazione non consentita per %(resource)s"
-
-#~ msgid "Unable to parse JSON request"
-#~ msgstr "Impossibile analizzare la richiesta JSON"
-
-#~ msgid "This API only supports JSON"
-#~ msgstr "L'API supporta solo JSON"
-
-#~ msgid "Datastore is not initiated in the model object."
-#~ msgstr "Archivio dati non inizializzato nell'oggetto modello."
-
-#~ msgid "Unable to start task due error: %(err)s"
-#~ msgstr "Impossibile avviare l'attivit�� a causa dell'errore:
%(err)s"
-
-#~ msgid ""
-#~ "Authentication failed for user '%(username)s'. [Error code:
%(code)s]"
-#~ msgstr ""
-#~ "Autenticazione non riuscita per l'utente '%(username)s'. [Codice di
"
-#~ "errore: %(code)s]"
-
-#~ msgid "You are not authorized to access Kimchi"
-#~ msgstr "Non si dispone dell'autorizzazione ad accedere a Kimchi"
-
-#~ msgid "Specify %(item)s to login into Kimchi"
-#~ msgstr "Specificare %(item)s per accedere a Kimchi"
-
-#~ msgid "Unable to find %(item)s in datastore"
-#~ msgstr "Impossibile trovare %(item)s nell'archivio dati"
-
-#~ msgid "Timeout while running command '%(cmd)s' after %(seconds)s
seconds"
-#~ msgstr ""
-#~ "�� stato raggiunto il timeout durante l'esecuzione del comando
'%(cmd)s' "
-#~ "dopo %(seconds)s secondi"
-
-#~ msgid "Help"
-#~ msgstr "Guida"
-
-#~ msgid "About"
-#~ msgstr "Info su"
-
-#~ msgid "Log out"
-#~ msgstr "Disconnetti"
-
-#~ msgid "Version:"
-#~ msgstr "Versione:"
diff --git a/plugins/kimchi/po/ja_JP.po b/plugins/kimchi/po/ja_JP.po
deleted file mode 100644
index a3d3be3..0000000
--- a/plugins/kimchi/po/ja_JP.po
+++ /dev/null
@@ -1,2269 +0,0 @@
-# English translations for kimchi package.
-# Copyright (C) 2013 ORGANIZATION
-#
-msgid ""
-msgstr ""
-"Project-Id-Version: kimchi 0.1\n"
-"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2015-07-01 16:11-0300\n"
-"PO-Revision-Date: 2013-07-11 17:32-0400\n"
-"Last-Translator: Cr��stian Viana <vianac(a)linux.vnet.ibm.com>\n"
-"Language-Team: English\n"
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
-"Content-Transfer-Encoding: 8bit\n"
-"Language: ja_JP\n"
-"Generated-By: pygettext.py 1.5\n"
-"Plural-Forms: nplurals=2; plural=(n != 1);\n"
-
-#, python-format
-msgid "Unknown parameter %(value)s"
-msgstr ""
-
-#, python-format
-msgid "Timeout of %(seconds)s seconds expired while running task
'%(task)s."
-msgstr ""
-
-#, python-format
-msgid "User %(user_id)s not found with given LDAP settings."
-msgstr ""
-
-msgid "Unknown \"_cap\" specified"
-msgstr ""
-
-msgid "\"_passthrough\" should be \"true\" or
\"false\""
-msgstr ""
-
-msgid "\"_passthrough_affected_by\" should be a device name string"
-msgstr ""
-
-#, python-format
-msgid "Error while getting block devices. Details: %(err)s"
-msgstr ""
-"������������������������������������������������������������������������������������������������:
%(err)s"
-
-#, python-format
-msgid "Error while getting block device information for %(device)s."
-msgstr ""
-"%(device)s
���������������������������������������������������������������������������������������������������"
-
-#, python-format
-msgid "Unable to find distro file: %(filename)s"
-msgstr "������������������������������������������������ %(filename)s
������������������������"
-
-#, python-format
-msgid ""
-"Unable to parse distro file: %(filename)s. Make sure, it is a JSON file."
-msgstr ""
-"������������������������������������������������ %(filename)s
���������������������������JSON ������������"
-"���������������������������������������������"
-
-#, python-format
-msgid "Unable to login to iSCSI host target %(portal)s. Details: %(err)s"
-msgstr ""
-"iSCSI ��������������������������� %(portal)s
���������������������������������������: %(err)s"
-
-#, python-format
-msgid "Unable to login to iSCSI host %(host)s target %(target)s"
-msgstr "iSCSI ��������� %(host)s ��������������� %(target)s
������������������������������"
-
-#, python-format
-msgid "Unable to find ISO file %(filename)s"
-msgstr ""
-
-#, python-format
-msgid "The ISO file %(filename)s is not bootable"
-msgstr "ISO ������������ %(filename)s
������������������������������������������"
-
-#, python-format
-msgid "The ISO file %(filename)s does not have a valid El Torito boot record"
-msgstr ""
-"ISO ������������ %(filename)s ������������������ El Torito
������������������������������������������"
-
-#, python-format
-msgid "Invalid El Torito validation entry in ISO %(filename)s"
-msgstr "��������� El Torito ������������������������ ISO %(filename)s
���������������"
-
-#, python-format
-msgid "Invalid El Torito boot indicator in ISO %(filename)s"
-msgstr "��������� El Torito ������������������������������������ ISO %(filename)s
���������������"
-
-#, python-format
-msgid "Unexpected volume type for primary volume in ISO %(filename)s"
-msgstr ""
-"1 ������������������������������������������������������������������ ISO
%(filename)s ���������������"
-
-#, python-format
-msgid "Bad format while reading volume descriptor in ISO %(filename)s"
-msgstr ""
-"��������������������������������������������� ISO %(filename)s
���������������������������������������"
-"������������������������������������"
-
-#, python-format
-msgid ""
-"The hypervisor doesn't have permission to use this ISO %(filename)s. "
-"Consider moving it under /var/lib/libvirt, or set the search permission to "
-"file access control lists for '%(user)s' user if possible, or add the
'%"
-"(user)s' to the ISO path group, or (not recommended) 'chmod -R o+x "
-"'path_to_iso'.Details: %(err)s"
-msgstr ""
-"��������������������������������� ISO %(filename)s
������������������������������������������/var/lib/"
-"libvirt
���������������������������������������������������������������%(user)s���������������������������"
-"���������������������������������������������������������%(user)s������ISO
���������������������������������"
-"���������������������chmod -R o+x path_to_iso������������ (���������������������)
���������������"
-"������������: %(err)s"
-
-msgid "An error occurred when probing image OS information."
-msgstr ""
-
-msgid "No OS information found in given image."
-msgstr ""
-
-#, python-format
-msgid "Unable to read image file %(filename)s"
-msgstr ""
-
-#, python-format
-msgid ""
-"Image file must be an existing file on system. %(filename)s is not a valid "
-"input."
-msgstr ""
-
-#, python-format
-msgid "Virtual machine %(name)s already exists"
-msgstr "��������������� %(name)s ������������������������"
-
-#, python-format
-msgid "Virtual machine %(name)s does not exist"
-msgstr "��������������� %(name)s ���������������������"
-
-#, python-format
-msgid ""
-"Unable to rename virtual machine %(name)s. The name %(new_name)s is already "
-"in use or the virtual machine is not powered off."
-msgstr ""
-
-#, python-format
-msgid "Unable to retrieve screenshot for stopped virtual machine %(name)s"
-msgstr "��������������������������������� %(name)s
���������������������������������������������������������"
-
-msgid "Remote ISO image is not supported by this server."
-msgstr "������������ ISO
������������������������������������������������������������������������������"
-
-#, python-format
-msgid "Screenshot is not supported on virtual machine %(name)s"
-msgstr ""
-
-#, python-format
-msgid "Unable to create virtual machine %(name)s. Details: %(err)s"
-msgstr "��������������� %(name)s ���������������������������������: %(err)s"
-
-#, python-format
-msgid "Unable to update virtual machine %(name)s. Details: %(err)s"
-msgstr "��������������� %(name)s ���������������������������������: %(err)s"
-
-#, python-format
-msgid "Unable to retrieve virtual machine %(name)s. Details: %(err)s"
-msgstr "��������������� %(name)s ���������������������������������: %(err)s"
-
-#, python-format
-msgid "Unable to connect to powered off virtual machine %(name)s."
-msgstr ""
-
-msgid "Virtual machine name must be a string without slashes (/)"
-msgstr ""
-
-#, python-format
-msgid "Invalid template URI %(value)s specified for virtual machine"
-msgstr ""
-
-#, python-format
-msgid "Invalid storage pool URI %(value)s specified for virtual machine"
-msgstr ""
-
-msgid "Supported virtual machine graphics are Spice or VNC"
-msgstr ""
-
-msgid "Graphics address to listen on must be IPv4 or IPv6"
-msgstr ""
-"listen ���������������������������������������������������IPv4 ��������� IPv6
���������������������������"
-"���"
-
-msgid "Specify a template to create a virtual machine from"
-msgstr
"���������������������������������������������������������������������������������"
-
-#, python-format
-msgid "Unable to start virtual machine %(name)s. Details: %(err)s"
-msgstr "��������������� %(name)s ���������������������������������: %(err)s"
-
-#, python-format
-msgid "Unable to power off virtual machine %(name)s. Details: %(err)s"
-msgstr "��������������� %(name)s ���������������������������������: %(err)s"
-
-#, python-format
-msgid "Unable to delete virtual machine %(name)s. Details: %(err)s"
-msgstr "��������������� %(name)s ���������������������������������: %(err)s"
-
-#, python-format
-msgid "Unable to reset virtual machine %(name)s. Details: %(err)s"
-msgstr "��������������� %(name)s ���������������������������������������:
%(err)s"
-
-msgid "User name list must be an array"
-msgstr ""
-
-msgid "User name must be a string"
-msgstr "���������������������������������������������������������������������"
-
-msgid "Group name list must be an array"
-msgstr ""
-
-msgid "Group name must be a string"
-msgstr "���������������������������������������������������������������������"
-
-#, python-format
-msgid "User(s) '%(users)s' do not exist"
-msgstr "���������������%(users)s���������������������������"
-
-#, python-format
-msgid "Group(s) '%(groups)s' do not exist"
-msgstr "���������������%(groups)s���������������������������"
-
-#, python-format
-msgid "Unable to shutdown virtual machine %(name)s. Details: %(err)s"
-msgstr "��������������� %(name)s ���������������������������������: %(err)s"
-
-#, python-format
-msgid ""
-"Unable to get access metadata of virtual machine %(name)s. Details: %(err)s"
-msgstr "��������������� %(name)s ���������������������������������: %(err)s"
-
-msgid "The guest console password must be a string."
-msgstr ""
-
-msgid "The life time for the guest console password must be a number."
-msgstr ""
-
-#, python-format
-msgid "Virtual machine '%(name)s' must be stopped before cloning it."
-msgstr ""
-
-#, python-format
-msgid "Insufficient disk space to clone virtual machine '%(name)s'"
-msgstr ""
-
-#, python-format
-msgid "Unable to clone VM '%(name)s'. Details: %(err)s"
-msgstr ""
-
-#, python-format
-msgid "Invalid operation for non-persistent virtual machine %(name)s"
-msgstr ""
-
-#, python-format
-msgid "Cannot suspend VM '%(name)s' because it is not running."
-msgstr ""
-
-#, python-format
-msgid "Unable to suspend VM '%(name)s'. Details: %(err)s"
-msgstr ""
-
-#, python-format
-msgid "Cannot resume VM '%(name)s' because it is not paused."
-msgstr ""
-
-#, python-format
-msgid "Unable to resume VM '%(name)s'. Details: %(err)s"
-msgstr ""
-
-msgid "Memory assigned is higher then the maximum allowed in the host."
-msgstr ""
-
-#, python-format
-msgid ""
-"VM '%(name)s' does not support live memory update. Update the memory with
"
-"the machine offline to enable this feature."
-msgstr ""
-
-msgid "Only increase memory is allowed in active VMs"
-msgstr ""
-
-msgid ""
-"For live memory update, new memory value must be equal old memory value plus
"
-"multiples of 1024 Mib"
-msgstr ""
-
-msgid "There are not enough free slots of 1024 Mib in the guest."
-msgstr ""
-
-msgid ""
-"Host's libvirt version does not support memory devices. Libvirt must be >=
"
-"1.2.14"
-msgstr ""
-
-#, python-format
-msgid "Error attaching memory device. Details: %(error)s"
-msgstr ""
-
-#, python-format
-msgid ""
-"VM %(vmid)s does not contain directly assigned host device %(dev_name)s."
-msgstr ""
-
-#, python-format
-msgid "The host device %(dev_name)s is not allowed to directly assign to VM."
-msgstr ""
-
-msgid ""
-"No IOMMU groups found. Host PCI pass through needs IOMMU group to function "
-"correctly. Please enable Intel VT-d or AMD IOMMU in your BIOS, then verify "
-"the Kernel is compiled with IOMMU support. For Intel CPU, add intel_iommu=on
"
-"to your Kernel parameter in /boot/grub2/grub.conf. For AMD CPU, add iommu=pt
"
-"iommu=1."
-msgstr ""
-
-msgid "\"name\" should be a device name string"
-msgstr ""
-
-#, python-format
-msgid ""
-"The device %(name)s is probably in use by the host. Unable to attach it to "
-"the guest."
-msgstr ""
-
-#, python-format
-msgid "Interface %(iface)s does not exist in virtual machine %(name)s"
-msgstr "������������������������ %(iface)s ������������������ %(name)s
������������������������"
-
-#, python-format
-msgid ""
-"Network %(network)s specified for virtual machine %(name)s does not exist"
-msgstr ""
-"��������������� %(name)s ��������������������������������������������� %(network)s
���������������������"
-
-msgid "Supported virtual machine interfaces type is only network"
-msgstr ""
-"������������������������������������������������������������������������������������������������������������������"
-"���"
-
-msgid "Network name for virtual machine interface must be a string"
-msgstr ""
-"������������������������������������������������������������������������������������������������������������������"
-
-msgid "Invalid network model card specified for virtual machine interface"
-msgstr ""
-"������������������������������������������������������������������������������������������������������������������"
-"���������"
-
-msgid "Specify type and network to add a new virtual machine interface"
-msgstr ""
-"������������������������������������������������������������������������������������������������������������������"
-"������"
-
-msgid "MAC Address must respect this format FF:FF:FF:FF:FF:FF"
-msgstr ""
-
-#, python-format
-msgid "MAC Address %(mac)s already exists in virtual machine %(name)s"
-msgstr ""
-
-msgid "Invalid MAC Address"
-msgstr ""
-
-msgid "Cannot change MAC address of a running virtual machine"
-msgstr ""
-
-#, python-format
-msgid "Template %(name)s already exists"
-msgstr "������������������ %(name)s ������������������������"
-
-#, python-format
-msgid ""
-"Network '%(network)s' specified for template %(template)s does not
exist"
-msgstr ""
-"������������������ %(template)s
������������������������������������������������%(network)s������������"
-"������������"
-
-#, python-format
-msgid ""
-"Storage pool %(pool)s specified for template %(template)s does not exist"
-msgstr ""
-"������������������ %(template)s
������������������������������������������������������ %(pool)s ������"
-"���������������"
-
-#, python-format
-msgid "Storage pool %(pool)s specified for template %(template)s is not
active"
-msgstr ""
-"������������������ %(template)s
������������������������������������������������������ %(pool)s ������"
-"���������������������������������"
-
-#, python-format
-msgid "Invalid parameter '%(param)s' specified for CDROM."
-msgstr "CDROM
���������������������������������������������%(param)s���������������������"
-
-#, python-format
-msgid "Network %(network)s specified for template %(template)s is not active"
-msgstr ""
-"������������������ %(template)s ���������������������������������������������
%(network)s ���������"
-"������������������������������"
-
-msgid "Template name must be a string"
-msgstr "���������������������������������������������������������������������"
-
-msgid "Template icon must be a path to the image"
-msgstr
"���������������������������������������������������������������������������������������"
-
-msgid "Template distribution must be a string"
-msgstr
"������������������������������������������������������������������������������������������������������"
-
-msgid "Template distribution version must be a string"
-msgstr ""
-"������������������������������������������������������������������������������������������������������������������"
-"������"
-
-msgid "The number of CPUs must be an integer greater than 0"
-msgstr "CPU ������������������������������������������"
-
-msgid "Amount of memory (MB) must be an integer greater than 512"
-msgstr "������������������ (MB ������) ������512
���������������������������������������������������"
-
-msgid "Template CDROM must be a local or remote ISO file"
-msgstr ""
-"������������������ CDROM ��������������������������������������� ISO
���������������������������������������"
-"���"
-
-#, python-format
-msgid "Invalid storage pool URI %(value)s specified for template"
-msgstr ""
-"������������������������������������ URI %(value)s
������������������������������������������������"
-
-msgid "Specify an ISO image as CDROM or a base image to create a template"
-msgstr ""
-"CDROM ������������������������������������������������������ ISO
���������������������������������������"
-
-msgid "All networks for the template must be specified in a list."
-msgstr
"������������������������������������������������������������������������������������������������������"
-
-msgid "Specify a volume to a template when storage pool is iSCSI or SCSI"
-msgstr ""
-
-#, python-format
-msgid "The volume %(volume)s is not in storage pool %(pool)s"
-msgstr ""
-
-#, python-format
-msgid "Unable to create template due error: %(err)s"
-msgstr "���������������������������������������������������������������������:
%(err)s"
-
-#, python-format
-msgid "Unable to delete template due error: %(err)s"
-msgstr "���������������������������������������������������������������������:
%(err)s"
-
-msgid "Disk size must be an integer greater than 1GB."
-msgstr ""
-
-msgid "Template base image must be a valid local image file"
-msgstr ""
-"������������������ CDROM ��������������������������������������� ISO
���������������������������������������"
-"���"
-
-#, python-format
-msgid "Cannot identify base image %(path)s format"
-msgstr ""
-
-msgid ""
-"When specifying CPU topology, VCPUs must be a product of sockets, cores, and
"
-"threads."
-msgstr ""
-
-msgid ""
-"When specifying CPU topology, each element must be an integer greater than "
-"zero."
-msgstr ""
-
-msgid ""
-"Invalid disk image format. Valid formats: bochs, cloop, cow, dmg, qcow, "
-"qcow2, qed, raw, vmdk, vpc."
-msgstr ""
-
-#, python-format
-msgid "Storage pool %(name)s already exists"
-msgstr "��������������������������� %(name)s ������������������������"
-
-#, python-format
-msgid "Storage pool %(name)s does not exist"
-msgstr "��������������������������� %(name)s ���������������������"
-
-#, python-format
-msgid "Specify %(item)s in order to create the storage pool %(name)s"
-msgstr ""
-"��������������������������� %(name)s ������������������������������%(item)s
���������������������������"
-
-#, python-format
-msgid "Unable to delete active storage pool %(name)s"
-msgstr "��������������������������������������������� %(name)s
������������������������"
-
-#, python-format
-msgid "Unable to list storage pools. Details: %(err)s"
-msgstr "���������������������������������������������������������������:
%(err)s"
-
-#, python-format
-msgid "Unable to create storage pool %(name)s. Details: %(err)s"
-msgstr "��������������������������� %(name)s ���������������������������������:
%(err)s"
-
-#, python-format
-msgid ""
-"Unable to get number of storage volumes in storage pool %(name)s. Details: %"
-"(err)s"
-msgstr ""
-"��������������������������� %(name)s
������������������������������������������������������������������������"
-"���:%(err)s"
-
-#, python-format
-msgid "Unable to activate storage pool %(name)s. Details: %(err)s"
-msgstr "��������������������������� %(name)s
���������������������������������������������: %(err)s"
-
-#, python-format
-msgid "Unable to deactivate storage pool %(name)s. Details: %(err)s"
-msgstr "��������������������������� %(name)s
������������������������������������������������: %(err)s"
-
-#, python-format
-msgid "Unable to delete storage pool %(name)s. Details: %(err)s"
-msgstr "��������������������������� %(name)s ���������������������������������:
%(err)s"
-
-#, python-format
-msgid ""
-"Unable to create NFS Pool as export path %(path)s may block during mount"
-msgstr ""
-"��������������������������������������������� %(path)s
���������������������������������������������������"
-"������NFS ���������������������������������"
-
-#, python-format
-msgid "Unable to create NFS Pool as export path %(path)s mount failed"
-msgstr ""
-"��������������������������� %(path)s ���������������������������������������NFS
���������������������������"
-"������"
-
-#, python-format
-msgid "Unsupported storage pool type: %(type)s"
-msgstr "���������������������������������������������������������������������:
%(type)s"
-
-#, python-format
-msgid "Error while retrieving storage pool XML to %(pool)s"
-msgstr ""
-
-msgid "Storage pool name must be a string without slashes (/)"
-msgstr ""
-
-msgid ""
-"Supported storage pool types are dir, netfs, logical, iscsi, isci and
kimchi-"
-"iso"
-msgstr ""
-
-msgid "Storage pool path must be a string"
-msgstr
"������������������������������������������������������������������������������������"
-
-msgid "Storage pool host must be a IP or hostname"
-msgstr "���������������������������������������������IP
���������������������������������������������������"
-
-msgid "Storage pool device must be the absolute path to the block device"
-msgstr ""
-
-msgid "Storage pool devices parameter must be a list"
-msgstr
"���������������������������������������������������������������������������������������������������������"
-
-msgid "Target IQN of an iSCSI pool must be a string"
-msgstr "iSCSI ��������������������������� IQN
������������������������������������������������"
-
-msgid "Port of a remote storage server must be an integer between 1 and 65535"
-msgstr ""
-"���������������������������������������������������������������1 ������ 65535
���������������������������������"
-"������������"
-
-msgid "iSCSI target username must be a string"
-msgstr ""
-
-msgid "iSCSI target password must be a string"
-msgstr ""
-
-msgid "Specify name and type to create a storage pool"
-msgstr
"������������������������������������������������������������������������������������������������"
-
-#, python-format
-msgid ""
-"%(disk)s is not a valid disk/partition. Could not add it to the pool %(pool)"
-"s."
-msgstr ""
-"%(disk)s
���������������������������/��������������������������������������������������� %(pool)s
������"
-"������������������������������"
-
-#, python-format
-msgid "Unable to extend logical pool %(pool)s. Details: %(err)s"
-msgstr ""
-
-msgid "The parameter disks only can be updated for logical storage pool."
-msgstr ""
-"���������������������������������������������������������������������������������������������������������������"
-"������"
-
-msgid "The SCSI host adapter name must be a string."
-msgstr "SCSI
���������������������������������������������������������������������������������"
-
-msgid "The storage pool kimchi_isos is reserved for internal use"
-msgstr "��������������������������� kimchi_isos
������������������������������������������������������"
-
-#, python-format
-msgid ""
-"Unable to activate NFS storage pool %(name)s. NFS server %(server)s is "
-"unreachable."
-msgstr ""
-"NFS ��������������������������� %(name)s ���������������������������������������NFS
������������ %"
-"(server)s ���������������������������"
-
-#, python-format
-msgid ""
-"Unable to deactivate NFS storage pool %(name)s. NFS server %(server)s is "
-"unreachable."
-msgstr ""
-"NFS ��������������������������� %(name)s
������������������������������������������NFS ������������ %"
-"(server)s ���������������������������"
-
-#, python-format
-msgid ""
-"Unable to deactivate pool %(name)s as it is associated with some templates"
-msgstr ""
-"��������� %(name)s
������������������������������������������������������������������������������������������"
-"���������������������"
-
-#, python-format
-msgid "Unable to delete pool %(name)s as it is associated with some templates"
-msgstr ""
-"��������� %(name)s
������������������������������������������������������������������������������������������"
-"������"
-
-#, python-format
-msgid ""
-"A volume group named '%(name)s' already exists. Please, choose another name
"
-"to create the logical pool."
-msgstr ""
-"���������%(name)s���������������������������������������������������������������������������������������������"
-"���������������������������������������������������"
-
-#, python-format
-msgid "Unable to update database with deep scan information due error:
%(err)s"
-msgstr ""
-"���������������������������������������������������������������������������������������������������������:
%"
-"(err)s"
-
-#, python-format
-msgid "Storage volume %(name)s already exists"
-msgstr "��������������������������������� %(name)s ������������������������"
-
-#, python-format
-msgid "Storage volume %(name)s does not exist in storage pool %(pool)s"
-msgstr ""
-"��������������������������������� %(name)s ���������������������������������
%(pool)s ������������������"
-"���"
-
-#, python-format
-msgid ""
-"Unable to create storage volume %(volume)s because storage pool %(pool)s is "
-"not active"
-msgstr ""
-
-#, python-format
-msgid "Specify %(item)s in order to create storage volume %(volume)s"
-msgstr ""
-"��������������������������������� %(volume)s ������������������������������%(item)s
���������������������"
-"������"
-
-#, python-format
-msgid ""
-"Unable to list storage volumes because storage pool %(pool)s is not active"
-msgstr ""
-"��������������������������� %(pool)s
������������������������������������������������������������������������"
-"���������������������������"
-
-#, python-format
-msgid ""
-"Unable to create storage volume %(name)s in storage pool %(pool)s. Details:
%"
-"(err)s"
-msgstr ""
-"��������������������������������� %(name)s ������������������������������ %(pool)s
���������������������"
-"������������: %(err)s"
-
-#, python-format
-msgid ""
-"Unable to list storage volumes in storage pool %(pool)s. Details: %(err)s"
-msgstr ""
-"��������������������������� %(pool)s
���������������������������������������������������������������������"
-"���: %(err)s"
-
-#, python-format
-msgid "Unable to wipe storage volumes %(name)s. Details: %(err)s"
-msgstr "��������������������������� %(name)s ������������������������������������:
%(err)s"
-
-#, python-format
-msgid "Unable to delete storage volume %(name)s. Details: %(err)s"
-msgstr "��������������������������������� %(name)s
���������������������������������: %(err)s"
-
-#, python-format
-msgid "Unable to resize storage volume %(name)s. Details: %(err)s"
-msgstr "��������������������������������� %(name)s
������������������������������������������: %(err)s"
-
-#, python-format
-msgid "Storage type %(type)s does not support volume create and delete"
-msgstr ""
-"��������������������������� %(type)s
������������������������������������������������������������������������"
-"���������"
-
-msgid "Storage volume name must be a string"
-msgstr
"������������������������������������������������������������������������������������"
-
-msgid "Storage volume allocation must be an integer number"
-msgstr
"������������������������������������������������������������������������������������"
-
-msgid ""
-"Storage volume format not supported. Valid formats: bochs, cloop, cow, dmg, "
-"qcow, qcow2, qed, raw, vmdk, vpc."
-msgstr ""
-
-msgid "Storage volume requires a volume name"
-msgstr
"������������������������������������������������������������������������"
-
-#, python-format
-msgid ""
-"Unable to update database with storage volume information due error: %(err)s"
-msgstr ""
-"���������������������������������������������������������������������������������������������������������������:
%"
-"(err)s"
-
-#, python-format
-msgid "Only one of parameter %(param)s can be specified"
-msgstr ""
-
-#, python-format
-msgid "Create volume from %(param)s is not supported"
-msgstr ""
-
-msgid "Storage volume capacity must be an integer number."
-msgstr ""
-
-msgid "Storage volume URL must be http://, https://, ftp:// or ftps://."
-msgstr ""
-
-#, python-format
-msgid "Unable to access file %(url)s. Please, check it."
-msgstr ""
-
-#, python-format
-msgid ""
-"Unable to clone storage volume '%(name)s' in pool '%(pool)s'.
Details: %(err)"
-"s"
-msgstr ""
-
-msgid "Specify chunk data and its size to upload a file."
-msgstr ""
-
-msgid "In order to upload a storage volume, specify the 'upload'
parameter."
-msgstr ""
-
-msgid ""
-"Unable to upload chunk data as it does not match with requested chunk size."
-msgstr ""
-
-#, python-format
-msgid "The storage volume %(vol)s is not under an upload process."
-msgstr ""
-
-msgid "The upload chunk data will exceed the storage volume size."
-msgstr ""
-
-#, python-format
-msgid "Unable to upload chunk data to storage volume. Details: %(err)s."
-msgstr ""
-
-#, python-format
-msgid "Interface %(name)s does not exist"
-msgstr "������������������������ %(name)s ���������������������"
-
-#, python-format
-msgid "Network %(name)s already exists"
-msgstr "������������������ %(name)s ������������������������"
-
-#, python-format
-msgid "Network %(name)s does not exist"
-msgstr "������������������ %(name)s ���������������������"
-
-#, python-format
-msgid "Subnet %(subnet)s specified for network %(network)s is not valid."
-msgstr ""
-"������������������ %(network)s ������������������������������������������
%(subnet)s ������������������"
-
-#, python-format
-msgid "Specify a network interface to create bridged network %(name)s"
-msgstr ""
-"������������������������������������ %(name)s
���������������������������������������������������������"
-"���������������������������������������"
-
-#, python-format
-msgid "Unable to delete active network %(name)s"
-msgstr "������������������������������������ %(name)s
������������������������"
-
-#, python-format
-msgid "Interface %(iface)s specified for network %(network)s is already in
use"
-msgstr ""
-"������������������ %(network)s ���������������������������������������������������
%(iface)s ���������"
-"���������������������������"
-
-msgid "Interface should be bare NIC, bonding or bridge device."
-msgstr ""
-"���������������������������������
NIC���������������������������������������������������������������������������"
-"������"
-
-#, python-format
-msgid "Unable to create network %(name)s. Details: %(err)s"
-msgstr "������������������ %(name)s ���������������������������������:
%(err)s"
-
-#, python-format
-msgid "Unable to find a free IP address for network '%(name)s'"
-msgstr "���������������������%(name)s��������������� IP
���������������������������������������"
-
-#, python-format
-msgid "The interface %(iface)s already exists."
-msgstr ""
-
-msgid "Network name must be a string without slashes (/) or quotes (\")"
-msgstr ""
-
-msgid "Supported network types are isolated, NAT and bridge"
-msgstr
"���������������������������������������������������������������������NAT������������������������������"
-
-msgid "Network subnet must be a string with IP address and prefix or netmask"
-msgstr ""
-"������������������������������������������IP
������������������������������������������������������������������"
-"������������������������������������������������������"
-
-msgid "Network interface must be a string"
-msgstr
"���������������������������������������������������������������������������������������������"
-
-msgid "Network VLAN ID must be an integer between 1 and 4094"
-msgstr "������������������ VLAN ID ������1 ������ 4094
���������������������������������������������"
-
-msgid "Specify name and type to create a Network"
-msgstr
"���������������������������������������������������������������������������������������"
-
-#, python-format
-msgid ""
-"Unable to delete network %(name)s. There are some virtual machines %(vms)s "
-"and/or templates linked to this network."
-msgstr ""
-
-#, python-format
-msgid ""
-"Unable to deactivate network %(name)s. There are some virtual machines
%(vms)"
-"s and/or templates linked to this network."
-msgstr ""
-
-#, python-format
-msgid "Bridge device %(name)s can not be the trunk device of a VLAN."
-msgstr ""
-"��������������������������� %(name)s ������VLAN
������������������������������������������������������������"
-"������"
-
-#, python-format
-msgid "Failed to activate interface %(iface)s: %(err)s."
-msgstr "������������������������ %(iface)s ���������������������������������:
%(err)s���"
-
-#, python-format
-msgid ""
-"Failed to activate interface %(iface)s. Please check the physical link "
-"status."
-msgstr ""
-"������������������������ %(iface)s
���������������������������������������������������������������������������"
-"������������"
-
-#, python-format
-msgid "Failed to start network %(name)s. Details: %(err)s"
-msgstr ""
-
-#, python-format
-msgid "Debug report %(name)s does not exist"
-msgstr "��������������������������� %(name)s ������������������������"
-
-msgid "Debug report tool not found in system"
-msgstr
"������������������������������������������������������������������������������"
-
-#, python-format
-msgid "Unable to create debug report %(name)s. Details: %(err)s."
-msgstr "��������������������������� %(name)s ���������������������������������:
%(err)s"
-
-#, python-format
-msgid "Can not find any debug report with the given name %(name)s"
-msgstr ""
-
-#, python-format
-msgid "Unable to generate debug report %(name)s. Details: %(err)s"
-msgstr "��������������������������� %(name)s ���������������������������������:
%(err)s"
-
-msgid "You should give a name for the debug report file."
-msgstr ""
-
-msgid ""
-"Debug report name must be a string. Only letters, digits, underscore ('_')
"
-"and hyphen ('-') are allowed."
-msgstr ""
-
-#, python-format
-msgid ""
-"The debug report with specified name \"%(name)s\" already exists. Please
use "
-"another one."
-msgstr ""
-"���������%(name)s���������������������������������������������������������������������������������������������"
-"���������������������������������������������������"
-
-#, python-format
-msgid "Storage server %(server)s was not used by Kimchi"
-msgstr ""
-"������������������������������ %(server)s ������Kimchi
������������������������������������������������"
-
-#, python-format
-msgid "Distro '%(name)s' does not exist"
-msgstr "������������������������������������%(name)s������������������������"
-
-#, python-format
-msgid "Partition %(name)s does not exist in the host"
-msgstr "��������������������� %(name)s ������������������������������������"
-
-msgid "Unable to shutdown host machine as there are running virtual machines"
-msgstr
"���������������������������������������������������������������������������������������������������������"
-
-msgid "Unable to reboot host machine as there are running virtual machines"
-msgstr
"������������������������������������������������������������������������������������������������"
-
-#, python-format
-msgid "Node device '%(name)s' not found"
-msgstr "���������������������������%(name)s���������������������������"
-
-msgid "Conflicting flag filters specified."
-msgstr ""
-
-msgid "No packages marked for update"
-msgstr
"���������������������������������������������������������������������������������"
-
-#, python-format
-msgid "Package %(name)s is not marked to be updated."
-msgstr "��������������� %(name)s
���������������������������������������������������������������"
-
-#, python-format
-msgid "Error while getting packages marked to be updated. Details: %(err)s"
-msgstr ""
-"������������������������������������������������������������������������������������������������������������������"
-"������������: %(err)s"
-
-msgid "There is no compatible package manager for this system."
-msgstr
"���������������������������������������������������������������������������������������"
-
-#, python-format
-msgid "Invalid URI %(uri)s"
-msgstr "��������� URI %(uri)s"
-
-msgid "Unable to choose a virtual machine name"
-msgstr ""
-
-msgid "Invalid storage type. Types supported: 'cdrom', 'disk'"
-msgstr ""
-"���������������������������������������������������������������������������������������cdrom������������"
-
-#, python-format
-msgid "The path '%(value)s' is not a valid local/remote path for the
device"
-msgstr ""
-
-msgid "Only CDROM path can be update."
-msgstr ""
-
-#, python-format
-msgid ""
-"The storage device %(dev_name)s does not exist in the virtual machine %"
-"(vm_name)s"
-msgstr ""
-
-#, python-format
-msgid "Error while creating new storage device: %(error)s"
-msgstr ""
-"���������������������������������������������������������������������������������������������������:
%(error)s"
-
-#, python-format
-msgid "Error while updating storage device: %(error)s"
-msgstr ""
-"������������������������������������������������������������������������������������������:
%(error)s"
-
-#, python-format
-msgid "Error while removing storage device: %(error)s"
-msgstr ""
-"������������������������������������������������������������������������������������������:
%(error)s"
-
-msgid "Do not support IDE device hot plug"
-msgstr ""
-
-msgid ""
-"Specify type and path or type and pool/volume to add a new virtual machine "
-"disk"
-msgstr
"������������������������������������������������������������������������������������������������"
-
-msgid "Specify path to update virtual machine disk"
-msgstr
"���������������������������������������������������������������������������������������"
-
-#, python-format
-msgid "Controller type %(type)s limitation of %(limit)s devices reached"
-msgstr ""
-
-#, python-format
-msgid "Cannot retrieve disk path information for given pool/volume: %(error)s"
-msgstr ""
-
-msgid "Volume already in use by other virtual machine."
-msgstr ""
-
-msgid ""
-"Only one of path or pool/volume can be specified to add a new virtual "
-"machine disk"
-msgstr
"������������������������������������������������������������������������������������������������"
-
-#, python-format
-msgid ""
-"Volume chosen with format %(format)s does not fit in the storage type
%(type)"
-"s"
-msgstr ""
-
-msgid "YUM Repository ID must be one word only string."
-msgstr "YUM ������������������ ID ������1
���������������������������������������������������������������"
-
-msgid "Repository URL must be an http://, ftp:// or file:// URL."
-msgstr ""
-"������������������ URL ��� http://���ftp://������������ file:// URL
���������������������������"
-"������"
-
-msgid ""
-"Repository configuration is a dictionary with specific values according to "
-"repository type."
-msgstr ""
-"������������������������������������������������������������������������������������������������������������������"
-"������������������"
-
-msgid "Distribution to DEB repository must be a string"
-msgstr ""
-"DEB
������������������������������������������������������������������������������������������������������������"
-
-msgid "Components to DEB repository must be listed in a array"
-msgstr ""
-"DEB
������������������������������������������������������������������������������������������������������������"
-"������"
-
-msgid "Components to DEB repository must be a string"
-msgstr "DEB
������������������������������������������������������������������������������������������������"
-
-msgid "Mirror list to repository must be a string"
-msgstr ""
-
-msgid "YUM Repository name must be string."
-msgstr "YUM
������������������������������������������������������������������������"
-
-msgid "GPG check must be a boolean value."
-msgstr "GPG ������������������������������������������������������������"
-
-msgid "GPG key must be a URL pointing to the ASCII-armored file."
-msgstr "GPG ���������ASCII ��������������������������������������� URL
���������������������������������"
-
-#, python-format
-msgid "Could not update repository %(repo_id)s."
-msgstr "������������������ %(repo_id)s ������������������������������������"
-
-#, python-format
-msgid "Repository %(repo_id)s does not exist."
-msgstr "������������������ %(repo_id)s ������������������������"
-
-msgid ""
-"Specify repository base URL, mirror list or metalink in order to create or "
-"update a YUM repository."
-msgstr ""
-
-msgid "Repository management tool was not recognized for your system."
-msgstr
"���������������������������������������������������������������������������������������"
-
-#, python-format
-msgid "Repository %(repo_id)s is already enabled."
-msgstr "������������������ %(repo_id)s
���������������������������������������"
-
-#, python-format
-msgid "Repository %(repo_id)s is already disabled."
-msgstr "������������������ %(repo_id)s
���������������������������������������"
-
-#, python-format
-msgid "Could not remove repository %(repo_id)s."
-msgstr "������������������ %(repo_id)s ������������������������������������"
-
-#, python-format
-msgid "Could not write repository configuration file %(repo_file)s"
-msgstr ""
-"������������������������������������ %(repo_file)s
������������������������������������������������"
-
-msgid "Specify repository distribution in order to create a DEB repository."
-msgstr ""
-"DEB
������������������������������������������������������������������������������������������������������������"
-"������������������������"
-
-#, python-format
-msgid "Could not enable repository %(repo_id)s."
-msgstr "������������������ %(repo_id)s
���������������������������������������"
-
-#, python-format
-msgid "Could not disable repository %(repo_id)s."
-msgstr "������������������ %(repo_id)s
���������������������������������������"
-
-msgid "YUM Repository ID already exists"
-msgstr "YUM ������������������ ID ������������������������"
-
-msgid "YUM Repository name must be a string"
-msgstr "YUM
���������������������������������������������������������������������"
-
-#, python-format
-msgid "Unable to list repositories. Details: '%(err)s'"
-msgstr "������������������������������������������������������: ���%(err)s���"
-
-#, python-format
-msgid "Unable to retrieve repository information. Details: '%(err)s'"
-msgstr "���������������������������������������������������������:
���%(err)s���"
-
-#, python-format
-msgid "Unable to add repository. Details: '%(err)s'"
-msgstr "���������������������������������������������������: ���%(err)s���"
-
-#, python-format
-msgid "Unable to remove repository. Details: '%(err)s'"
-msgstr "���������������������������������������������������: ���%(err)s���"
-
-#, python-format
-msgid ""
-"Configuration items: '%(items)s' are not supported by repository
manager"
-msgstr ""
-
-msgid "Repository metalink must be an http://, ftp:// or file:// URL."
-msgstr ""
-
-msgid "Cannot specify mirrorlist and metalink at the same time."
-msgstr ""
-
-#, python-format
-msgid ""
-"Virtual machine '%(vm)s' must be stopped before creating a snapshot of
it."
-msgstr ""
-
-#, python-format
-msgid ""
-"Unable to create snapshot '%(name)s' on virtual machine '%(vm)s'.
Details: %"
-"(err)s"
-msgstr ""
-
-#, python-format
-msgid "Snapshot '%(name)s' does not exist on virtual machine
'%(vm)s'."
-msgstr ""
-
-#, python-format
-msgid ""
-"Unable to retrieve snapshot '%(name)s' on virtual machine '%(vm)s'.
Details: "
-"%(err)s"
-msgstr ""
-
-#, python-format
-msgid "Unable to list snapshots on virtual machine '%(vm)s'. Details:
%(err)s"
-msgstr ""
-
-#, python-format
-msgid ""
-"Unable to delete snapshot '%(name)s' on virtual machine '%(vm)s'.
Details: %"
-"(err)s"
-msgstr ""
-
-#, python-format
-msgid ""
-"Unable to retrieve current snapshot of virtual machine '%(vm)s'. Details:
%"
-"(err)s"
-msgstr ""
-
-#, python-format
-msgid ""
-"Unable to revert virtual machine '%(vm)s' to snapshot '%(name)s'.
Details: %"
-"(err)s"
-msgstr ""
-
-#, python-format
-msgid ""
-"Unable to create snapshot of virtual machine '%(vm)s' because it contains a
"
-"disk with format '%(format)s'; only 'qcow2' is supported."
-msgstr ""
-
-msgid "The number of vCPUs is too large for this system."
-msgstr ""
-
-msgid "Invalid vCPU/topology combination."
-msgstr ""
-
-msgid "This host (or current configuration) does not allow CPU topology."
-msgstr ""
-
-msgid "ERROR CODE"
-msgstr "���������������������"
-
-msgid "REASON"
-msgstr "������"
-
-msgid "STACK"
-msgstr "������������"
-
-msgid "Go to Homepage"
-msgstr "������������������������������������"
-
-msgid "Create a New Virtual Machine"
-msgstr "������������������������������"
-
-msgid "Virtual Machine Name"
-msgstr "������������������"
-
-msgid ""
-"The name used to identify the virtual machine. If omitted, a name will be "
-"chosen based on the template used."
-msgstr ""
-"������������������������������������������������������������������������������������������������������������������"
-"������������������������������������������������"
-
-msgid "Template"
-msgstr "������������������"
-
-msgid "Please create a template first."
-msgstr "������������������������������������������������������"
-
-msgid "Create a Template"
-msgstr "���������������������������"
-
-msgid "Please choose a template."
-msgstr "������������������������������������������������"
-
-msgid "OS"
-msgstr "OS"
-
-msgid "OS Version"
-msgstr "OS ���������������"
-
-msgid "CPUS"
-msgstr "CPU"
-
-msgid "Memory"
-msgstr "������������"
-
-msgid "Create"
-msgstr "������"
-
-msgid "Creating..."
-msgstr ""
-
-msgid "Cancel"
-msgstr "������"
-
-msgid "Edit Guest"
-msgstr "������������������"
-
-msgid "General"
-msgstr "������"
-
-msgid "Storage"
-msgstr "���������������"
-
-msgid "Interface"
-msgstr "������������������������"
-
-msgid "Permission"
-msgstr "���������������"
-
-msgid "Host PCI Device"
-msgstr ""
-
-msgid "Snapshot"
-msgstr ""
-
-msgid "Name"
-msgstr "������"
-
-msgid "CPUs"
-msgstr "CPU"
-
-msgid "Memory (MB)"
-msgstr "������������"
-
-msgid "Icon"
-msgstr "������������"
-
-msgid "Device"
-msgstr "���������������"
-
-msgid "Path"
-msgstr "NFS ������"
-
-msgid "Network"
-msgstr " ������������������"
-
-msgid "Type"
-msgstr "���������"
-
-msgid "MAC Address"
-msgstr ""
-
-msgid "Available system users and groups"
-msgstr ""
-
-msgid "Selected system users and groups"
-msgstr ""
-
-msgid "User"
-msgstr ""
-
-msgid "All"
-msgstr "���������"
-
-msgid "To Add"
-msgstr ""
-
-msgid "Added"
-msgstr ""
-
-msgid "filter"
-msgstr ""
-
-msgid "Product"
-msgstr ""
-
-msgid "Vendor"
-msgstr "������������"
-
-msgid "Created"
-msgstr ""
-
-msgid "Save"
-msgstr "������"
-
-msgid "Replace"
-msgstr "������"
-
-msgid "Detach"
-msgstr "������������"
-
-msgid "revert"
-msgstr ""
-
-msgid "Start"
-msgstr "������"
-
-msgid "Reset"
-msgstr "������������"
-
-msgid "Pause"
-msgstr ""
-
-msgid "Resume"
-msgstr ""
-
-msgid "Power Off"
-msgstr ""
-
-msgid "Actions"
-msgstr "���������������"
-
-msgid "Connect"
-msgstr "������"
-
-msgid "Clone"
-msgstr ""
-
-msgid "Edit"
-msgstr "������"
-
-msgid "Shut Down"
-msgstr "���������������������"
-
-msgid "Delete"
-msgstr "������"
-
-msgid "CPU"
-msgstr "CPU"
-
-msgid "Disk I/O"
-msgstr "���������������������"
-
-msgid "Network I/O"
-msgstr "���������������������������"
-
-msgid "Livetile"
-msgstr "������������������"
-
-msgid "No guests found."
-msgstr "������������������������������������"
-
-msgid "Add a Storage Device to VM"
-msgstr "VM ������������������������������������������"
-
-msgid "Device Type"
-msgstr "������������������������"
-
-msgid "The device type. Currently, \"cdrom\" and \"disk\" are
supported."
-msgstr "������������������������������������������������������������������
\"cdrom\" ���������������"
-
-msgid "Storage Pool"
-msgstr "���������������������������"
-
-msgid "Storage pool which volume located in"
-msgstr
"������������������������������������������������������������������������������������"
-
-msgid "Storage Volume"
-msgstr "������������������������������"
-
-msgid "Storage volume to be attached"
-msgstr
"������������������������������������������������������������������������������������"
-
-msgid "File Path"
-msgstr "���������������������"
-
-msgid "The ISO file path in the server for CDROM."
-msgstr "��������������������� CDROM ��� ISO ������������������������"
-
-msgid "Attach"
-msgstr "������"
-
-msgid "Shut down"
-msgstr "���������������������"
-
-msgid "Restart"
-msgstr "���������"
-
-msgid "Basic Information"
-msgstr "������������"
-
-msgid "OS Distro"
-msgstr "OS ���������������������������������"
-
-msgid "OS Code Name"
-msgstr "OS ������������"
-
-msgid "Processor"
-msgstr "������������������"
-
-msgid "CPU(s)"
-msgstr ""
-
-msgid "System Statistics"
-msgstr "������������������������"
-
-msgid "Software Updates"
-msgstr "������������������������"
-
-msgid "Update Progress"
-msgstr "���������������������"
-
-msgid "Repositories"
-msgstr "������������������"
-
-msgid "Debug Reports"
-msgstr "���������������������������"
-
-msgid "The username or password you entered is incorrect. Please try again."
-msgstr
"���������������������������������������������������������������������������������������������������������"
-
-msgid "This field is required."
-msgstr "���������������������������������������"
-
-msgid "Log in"
-msgstr "������������"
-
-msgid "Logging in..."
-msgstr "���������������������������..."
-
-msgid "Host"
-msgstr "���������"
-
-msgid "Guests"
-msgstr "���������"
-
-msgid "Templates"
-msgstr "������������������"
-
-msgid "Failed to get application configuration"
-msgstr "���������������������������������������������������������������"
-
-msgid "This is not a valid Linux path"
-msgstr "��������� Linux ���������������������������"
-
-msgid "This is not a valid URL."
-msgstr "��������� URL ������������������������"
-
-msgid "No such data available."
-msgstr "���������������������������������������������"
-
-msgid ""
-"Can not contact the host system. Verify the host system is up and that you "
-"have network connectivity to it. HTTP request response %1. "
-msgstr ""
-"������������������������������������������������������������������������������������������������������������������"
-"������������������������������������������������������������������HTTP ������������
%1"
-
-msgid "Unable to read file."
-msgstr ""
-
-msgid "Error while uploading file."
-msgstr ""
-
-msgid "Delete Confirmation"
-msgstr "���������������"
-
-msgid "OK"
-msgstr "OK"
-
-msgid "Confirm"
-msgstr "������"
-
-msgid "Warning"
-msgstr "������"
-
-msgid "Cloning..."
-msgstr ""
-
-msgid "Loading..."
-msgstr "������������������������..."
-
-msgid "An error occurred while retrieving system information."
-msgstr ""
-
-msgid "Retry"
-msgstr "���������"
-
-msgid "Detailed message:"
-msgstr "���������������������:"
-
-msgid "No ISO found"
-msgstr ""
-
-msgid "This is not a valid ISO file."
-msgstr "��������� ISO ������������������������������������"
-
-msgid "This may take a long time. Do you want to continue?"
-msgstr
"������������������������������������������������������������������������?"
-
-msgid "This will permanently delete the template. Would you like to continue?"
-msgstr
"���������������������������������������������������������������������?"
-
-msgid "Unable to shut down system as there are some virtual machines running!"
-msgstr ""
-"������������������������������������������������������������������������������������������������������������������!"
-
-msgid "Max:"
-msgstr "������:"
-
-msgid "Utilization"
-msgstr "���������"
-
-msgid "Available"
-msgstr "������������"
-
-msgid "Read Rate"
-msgstr "������������������"
-
-msgid "Write Rate"
-msgstr "������������������"
-
-msgid "Received"
-msgstr "������������"
-
-msgid "Sent"
-msgstr "������������"
-
-msgid ""
-"Shutting down or restarting host will cause unsaved work lost. Continue to "
-"shut down/restarting?"
-msgstr ""
-"������������������������������������������������������������������������������������������������������������������"
-"���������������������/������������������������������?"
-
-msgid ""
-"Repository will be removed permanently and can't be recovered. Do you want
"
-"to continue?"
-msgstr ""
-"���������������������������������������������������������������������������������������������������������?"
-
-msgid "ID"
-msgstr "ID"
-
-msgid "Base URL"
-msgstr "��������� URL"
-
-msgid "Is Mirror"
-msgstr "���������"
-
-msgid "URL Args"
-msgstr "URL ������"
-
-msgid "Enabled"
-msgstr "������������"
-
-msgid "GPG Check"
-msgstr "GPG ������������"
-
-msgid "GPG Key"
-msgstr "GPG ���"
-
-msgid "Add"
-msgstr "������"
-
-msgid "Remove"
-msgstr "������"
-
-msgid "Enable"
-msgstr "������������"
-
-msgid "Disable"
-msgstr "������������"
-
-msgid "Package Name"
-msgstr "������������������"
-
-msgid "Version"
-msgstr "���������������"
-
-msgid "Architecture"
-msgstr "������������������������"
-
-msgid "Repository"
-msgstr "������������������"
-
-msgid "Update All"
-msgstr "���������������"
-
-msgid "Updating..."
-msgstr "���������������������..."
-
-msgid "Failed to retrieve packages update information."
-msgstr ""
-
-msgid "Failed to update package(s)."
-msgstr "���������������������������������������������������"
-
-msgid ""
-"Debug report will be removed permanently and can't be recovered. Do you want
"
-"to continue?"
-msgstr ""
-"������������������������������������������������������������������������������������������������������������������?"
-
-msgid "Generated Time"
-msgstr "������������"
-
-msgid "Generate"
-msgstr "������"
-
-msgid "Generating..."
-msgstr "���������������������..."
-
-msgid "Rename"
-msgstr "������������"
-
-msgid "Download"
-msgstr "������������������"
-
-msgid ""
-"Report name should contain only letters, digits, underscore ('_') and/or
"
-"hyphen ('-')."
-msgstr
"���������������������������������������������������������������������������������
(-) ���������������"
-
-msgid "Pending..."
-msgstr "������������������������..."
-
-msgid "Report name is the same as the original one."
-msgstr ""
-
-msgid ""
-"This will delete the virtual machine and its virtual disks. This operation "
-"cannot be undone. Would you like to continue?"
-msgstr ""
-"������������������������������������������������������������������������������������������������������������������"
-"������������������������?"
-
-msgid "Power off Confirmation"
-msgstr "���������������"
-
-msgid ""
-"This action may produce undesirable results, for example unflushed disk "
-"cache in the guest. Would you like to continue?"
-msgstr ""
-
-msgid "Reset Confirmation"
-msgstr "���������������"
-
-msgid ""
-"There is a risk of data loss caused by reset without the guest OS shutdown. "
-"Would you like to continue?"
-msgstr ""
-
-msgid "Shut Down Confirmation"
-msgstr "���������������"
-
-msgid "Note the guest OS may ignore this request. Would you like to continue?"
-msgstr
"���������������������������������������������������������������������?"
-
-msgid "Virtual Machine delete Confirmation"
-msgstr ""
-
-msgid ""
-"This virtual machine is not persistent. Power Off will delete it. Continue?"
-msgstr ""
-
-msgid ""
-"When the target guest has SCSI or iSCSI volumes, they will be cloned on "
-"default storage pool. The same will happen when the target pool does not "
-"have enough space to clone the volumes. Do you want to continue?"
-msgstr ""
-
-msgid ""
-"This CDROM will be detached permanently and you can re-attach it. Continue "
-"to detach it?"
-msgstr ""
-"������ CDROM
������������������������������������������������������������������������������������������������?"
-
-msgid "Attaching..."
-msgstr "���������������������..."
-
-msgid "Replacing..."
-msgstr "���������������������..."
-
-msgid "Successfully attached!"
-msgstr "���������������������������!"
-
-msgid "Successfully replaced!"
-msgstr "���������������������������!"
-
-msgid "Successfully detached!"
-msgstr "������������������������������!"
-
-msgid ""
-"This disk will be detached permanently and you can re-attach it. Continue to
"
-"detach it?"
-msgstr ""
-
-msgid "interface:"
-msgstr ""
-
-msgid "address:"
-msgstr ""
-
-msgid "link_type:"
-msgstr ""
-
-msgid "block:"
-msgstr ""
-
-msgid "drive_type:"
-msgstr ""
-
-msgid "model:"
-msgstr ""
-
-msgid "Affected devices:"
-msgstr ""
-
-msgid "The VLAN id must be between 1 and 4094."
-msgstr "VLAN ID ������1 ������ 4094 ���������������������������������������"
-
-msgid "unavailable"
-msgstr "������������"
-
-msgid ""
-"This action will interrupt network connectivity for any virtual machine that
"
-"depend on this network."
-msgstr ""
-"������������������������������������������������������������������������������������������������������������������"
-"������������������"
-
-msgid "Create a network"
-msgstr "���������������������������"
-
-msgid ""
-"This network is not persistent. Instead of stop, this action will "
-"permanently delete it. Would you like to continue?"
-msgstr ""
-"������������������������������������������������������������������������������������������������������������������"
-"���������������������������������������������������������������������������������?"
-
-msgid ""
-"The bridged VLAN tag may not work well with NetworkManager enabled. You "
-"should consider disabling it."
-msgstr ""
-
-msgid ""
-"This will permanently delete the storage pool. Would you like to continue?"
-msgstr
"������������������������������������������������������������������������������?"
-
-msgid "This storage pool is empty."
-msgstr "������������������������������������������������"
-
-msgid ""
-"It will format your disk and you will loose any data in there, are you sure "
-"to continue? "
-msgstr ""
-"���������������������������������������������������������������������������������������������������������������?"
-
-msgid "SCSI Fibre Channel"
-msgstr "SCSI ������������������������������"
-
-msgid "No SCSI adapters found."
-msgstr "SCSI ������������������������������������������"
-
-msgid "Loading iSCSI targets..."
-msgstr ""
-
-msgid "No iSCSI found. Please input one."
-msgstr ""
-
-msgid "Failed to load iSCSI targets."
-msgstr ""
-
-msgid "The storage pool name can not be blank."
-msgstr
"���������������������������������������������������������������������������������"
-
-msgid "The storage pool path can not be blank."
-msgstr
"���������������������������������������������������������������������������������������"
-
-msgid "NFS server mount path can not be blank."
-msgstr "NFS
���������������������������������������������������������������������������������������"
-
-msgid "Invalid NFS mount path."
-msgstr "NFS ���������������������������������������"
-
-msgid "No logical device selected."
-msgstr "���������������������������������������������������"
-
-msgid "The iSCSI target can not be blank."
-msgstr "iSCSI
������������������������������������������������������������������"
-
-msgid "Server name can not be blank."
-msgstr "������������������������������������������������������������������"
-
-msgid "This is not a valid Server Name or IP. Please, modify it."
-msgstr ""
-
-msgid "Looking for available partitions ..."
-msgstr "���������������������������������������������������������..."
-
-msgid "No available partitions found."
-msgstr "���������������������������������������������������������������"
-
-msgid ""
-"This storage pool is not persistent. Instead of deactivate, this action will
"
-"permanently delete it. Would you like to continue?"
-msgstr ""
-"������������������������������������������������������������������������������������������������������������������"
-"���������������������������������������������������������������������������������?"
-
-msgid "Unable to retrieve partitions information."
-msgstr "���������������������������������������������������������:
���%(err)s���"
-
-msgid "In progress..."
-msgstr ""
-
-msgid "Failed!"
-msgstr ""
-
-msgid "CDROM path needs to be a valid local/remote path and cannot be blank."
-msgstr ""
-
-msgid "Disk pool or volume cannot be blank."
-msgstr
"���������������������������������������������������������������������������������"
-
-msgid "Filter"
-msgstr ""
-
-msgid "Network Name"
-msgstr "���������������������"
-
-msgid "State"
-msgstr "������"
-
-msgid "Network Type"
-msgstr "������������������������������"
-
-msgid "Address Space"
-msgstr "���������������������������"
-
-msgid "Name should not contain '/' and '\"'."
-msgstr ""
-
-msgid "Isolated: no external network connection"
-msgstr "������: ������������������������������������"
-
-msgid "NAT: outbound physical network connection only"
-msgstr "NAT: ���������������������������������������������������������"
-
-msgid "Bridged: Virtual machines are connected to physical network directly"
-msgstr "������������:
������������������������������������������������������������������"
-
-msgid "(No interfaces found)"
-msgstr ""
-
-msgid "Destination"
-msgstr "������:"
-
-msgid "Enable VLAN"
-msgstr "VLAN ������������������������:"
-
-msgid "VLAN ID"
-msgstr "VLAN ID:"
-
-msgid "Stop"
-msgstr "������"
-
-msgid "Generate a New Debug Report"
-msgstr "������������������������������������������"
-
-msgid "Report Name"
-msgstr "���������������"
-
-msgid ""
-"The name used to identify the report. If omitted, a name will be chosen "
-"based on current time. Name can contain: letters, digits, underscore
(\"_\") "
-"and hyphen (\"-\")."
-msgstr ""
-"������������������������������������������������������������������������������������������������������������������"
-"��������������������������������������������������������������������� (-)
������������������������"
-
-msgid "Rename a Debug Report"
-msgstr "������������������������������������������"
-
-msgid ""
-"The name used to identify the report. Name can contain: letters, digits and "
-"hyphen (\"-\")."
-msgstr ""
-"������������������������������������������������������������������������������������������������������������������"
-"��������������������������������������������������������������������� (-)
������������������������"
-
-msgid "Submit"
-msgstr ""
-
-msgid "Add a Repository"
-msgstr "���������������������������"
-
-msgid "Identifier"
-msgstr "ID"
-
-msgid "Single word, unique identifier for the repository."
-msgstr "��������������������������� ID ������������������������������"
-
-msgid "Textual name for the repository."
-msgstr "���������������������������������������"
-
-msgid "URL"
-msgstr "URL"
-
-msgid "Required Field"
-msgstr "���������������������"
-
-msgid "URL to the repository. Supported protocols are http, ftp, and file."
-msgstr ""
-"��������������������� URL ���������������������������������������������������
http���ftp������������ file "
-"���������"
-
-msgid "Repository is a mirror"
-msgstr "���������������������������������������"
-
-msgid "Distribution"
-msgstr "���������������������������������"
-
-msgid "Distribution of the DEB repository."
-msgstr "DEB ���������������������������������������������������������"
-
-msgid "Components"
-msgstr "���������������������"
-
-msgid "List of components in DEB repository."
-msgstr "DEB ������������������������������������������������������������"
-
-msgid "Edit Repository"
-msgstr "���������������������������"
-
-msgid "Mirror List URL"
-msgstr "��������������������� URL"
-
-msgid "Yes"
-msgstr " ������"
-
-msgid "No"
-msgstr " ���������"
-
-msgid "Capacity"
-msgstr "������"
-
-msgid "Allocated"
-msgstr "������������������"
-
-msgid "Location"
-msgstr "������������������"
-
-msgid "Device path"
-msgstr "���������������������"
-
-msgid "active"
-msgstr "���������������"
-
-msgid "inactive"
-msgstr "������������������"
-
-msgid "Deactivate"
-msgstr "���������������������������"
-
-msgid "Activate"
-msgstr "������������������������"
-
-msgid "Add Volume"
-msgstr ""
-
-msgid "Extend"
-msgstr ""
-
-msgid "Undefine"
-msgstr "���������������������"
-
-msgid "Format"
-msgstr "������������������:"
-
-msgid "Allocation"
-msgstr "������������:"
-
-msgid "Define a New Storage Pool"
-msgstr "������������������������������������������"
-
-msgid "Storage Pool Name"
-msgstr "������������������������������"
-
-msgid ""
-"The name used to identify the storage pools, and it should not be empty."
-msgstr ""
-"������������������������������������������������������������������������������������������������������������������"
-"������"
-
-msgid "Storage Pool Type"
-msgstr "���������������������������������������"
-
-msgid "Storage Path"
-msgstr "������������������������"
-
-msgid ""
-"The path of the Storage Pool. Each Storage Pool must have a unique path."
-msgstr ""
-"���������������������������������������������������������������������������������������������������������������"
-"������"
-
-msgid ""
-"Kimchi will try to create the directory when it does not already exist in "
-"your system."
-msgstr ""
-"���������������������������������������������������������������Kimchi
���������������������������������"
-
-msgid "NFS Server IP"
-msgstr "NFS ������������ IP"
-
-msgid "NFS server IP or hostname. It can be input or chosen from history."
-msgstr ""
-"NFS ������������ IP
������������������������������������������������������������������������������������������"
-"���������������"
-
-msgid "NFS Path"
-msgstr "NFS ������"
-
-msgid "The NFS exported path on NFS server."
-msgstr "NFS ������������ NFS ������������������������������������������������"
-
-msgid "iSCSI Server"
-msgstr "iSCSI ������������"
-
-msgid "Server"
-msgstr "������������"
-
-msgid "Port"
-msgstr "���������"
-
-msgid "iSCSI server IP or hostname. It should not be empty."
-msgstr "iSCSI ������������ IP
���������������������������������������������������������������"
-
-msgid "Target"
-msgstr "���������������"
-
-msgid "The iSCSI target on iSCSI server"
-msgstr "iSCSI ������������������ iSCSI ���������������"
-
-msgid "Add iSCSI Authentication"
-msgstr "iSCSI ���������������"
-
-msgid "iSCSI Authentication"
-msgstr "iSCSI ������"
-
-msgid "User Name"
-msgstr "���������������"
-
-msgid "Password"
-msgstr "���������������"
-
-msgid "SCSI Adapter"
-msgstr "SCSI ���������������"
-
-msgid "Please, wait..."
-msgstr "���������������������..."
-
-msgid "Add a Volume to Storage Pool"
-msgstr ""
-
-msgid "Fetch from remote URL"
-msgstr ""
-
-msgid "Enter the remote URL here."
-msgstr ""
-
-msgid "Upload a file"
-msgstr ""
-
-msgid "Choose the file you want to upload."
-msgstr ""
-
-msgid "Add Template"
-msgstr "���������������������������"
-
-msgid "Where is the source media for this template? "
-msgstr
"������������������������������������������������������������������������������?"
-
-msgid "Local ISO Image"
-msgstr "������������ ISO ������������"
-
-msgid "Local Image File"
-msgstr ""
-
-msgid "Remote ISO Image"
-msgstr "������������ ISO ������������"
-
-msgid "Search ISOs"
-msgstr "ISO ���������"
-
-msgid "The following ISOs are available:"
-msgstr "������ ISO ���������������������:"
-
-msgid "OS: "
-msgstr "OS: "
-
-msgid "Version: "
-msgstr "���������������: "
-
-msgid "Size: "
-msgstr "���������: "
-
-msgid "Search more ISOs"
-msgstr "ISO ������������������"
-
-msgid "Create Templates from Selected ISO"
-msgstr "������������ ISO ���������������������������������"
-
-msgid "I want to use a specific ISO file"
-msgstr "��������� ISO ���������������������������"
-
-msgid "Loading default remote ISOs ..."
-msgstr "������������������������������ ISO ���������������������������..."
-
-msgid "Arch: "
-msgstr "������������������������: "
-
-msgid "I want to use a custom URL"
-msgstr "������������ URL ���������������"
-
-msgid "Edit Template"
-msgstr "���������������������������"
-
-msgid "CDROM"
-msgstr "CDROM"
-
-msgid "Image File"
-msgstr ""
-
-msgid "Graphics"
-msgstr "���������������������"
-
-msgid "Disk(GB)"
-msgstr ""
-
-msgid "Disk Format"
-msgstr ""
-
-msgid "CPU Number"
-msgstr "CPU ���"
-
-msgid "Manually set CPU topology"
-msgstr ""
-
-msgid "Cores"
-msgstr ""
-
-msgid "Threads"
-msgstr ""
-
-msgid "No templates found."
-msgstr "���������������������������������������������"
-
-#~ msgid "Delete is not allowed for %(resource)s"
-#~ msgstr "%(resource)s ���������������������������������"
-
-#~ msgid "%(resource)s does not implement update method"
-#~ msgstr "%(resource)s ������������������������������������������������"
-
-#~ msgid "Create is not allowed for %(resource)s"
-#~ msgstr "%(resource)s ���������������������������������"
-
-#~ msgid "Unable to parse JSON request"
-#~ msgstr "JSON ������������������������������"
-
-#~ msgid "This API only supports JSON"
-#~ msgstr "������ API ��� JSON ���������������������������"
-
-#~ msgid "Datastore is not initiated in the model object."
-#~ msgstr
"������������������������������������������������������������������������������������������"
-
-#~ msgid "Unable to start task due error: %(err)s"
-#~ msgstr "������������������������������������������������������������:
%(err)s"
-
-#~ msgid ""
-#~ "Authentication failed for user '%(username)s'. [Error code:
%(code)s]"
-#~ msgstr ""
-#~
"���������������%(username)s������������������������������������[���������������������:
%(code)s]"
-
-#~ msgid "You are not authorized to access Kimchi"
-#~ msgstr "Kimchi ������������������������������������������������"
-
-#~ msgid "Specify %(item)s to login into Kimchi"
-#~ msgstr "Kimchi ������������������������������%(item)s ������������������"
-
-#~ msgid "Unable to find %(item)s in datastore"
-#~ msgstr "%(item)s ������������������������������������������������"
-
-#~ msgid "Timeout while running command '%(cmd)s' after %(seconds)s
seconds"
-#~ msgstr ""
-#~ "���������������%(cmd)s������������������������������������%(seconds)s
������������������������������"
-#~ "������������������������"
-
-#~ msgid "Help"
-#~ msgstr "���������"
-
-#~ msgid "About"
-#~ msgstr "������������"
-
-#~ msgid "Log out"
-#~ msgstr "���������������"
-
-#~ msgid "Version:"
-#~ msgstr "���������������: "
diff --git a/plugins/kimchi/po/kimchi.pot b/plugins/kimchi/po/kimchi.pot
deleted file mode 100755
index d4605c7..0000000
--- a/plugins/kimchi/po/kimchi.pot
+++ /dev/null
@@ -1,2074 +0,0 @@
-# SOME DESCRIPTIVE TITLE.
-# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
-# This file is distributed under the same license as the PACKAGE package.
-# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
-#
-#, fuzzy
-msgid ""
-msgstr ""
-"Project-Id-Version: PACKAGE VERSION\n"
-"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2015-07-01 16:11-0300\n"
-"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
-"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
-"Language-Team: LANGUAGE <LL(a)li.org>\n"
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=CHARSET\n"
-"Content-Transfer-Encoding: 8bit\n"
-
-#, python-format
-msgid "Unknown parameter %(value)s"
-msgstr ""
-
-#, python-format
-msgid "Timeout of %(seconds)s seconds expired while running task
'%(task)s."
-msgstr ""
-
-#, python-format
-msgid "User %(user_id)s not found with given LDAP settings."
-msgstr ""
-
-msgid "Unknown \"_cap\" specified"
-msgstr ""
-
-msgid "\"_passthrough\" should be \"true\" or
\"false\""
-msgstr ""
-
-msgid "\"_passthrough_affected_by\" should be a device name string"
-msgstr ""
-
-#, python-format
-msgid "Error while getting block devices. Details: %(err)s"
-msgstr ""
-
-#, python-format
-msgid "Error while getting block device information for %(device)s."
-msgstr ""
-
-#, python-format
-msgid "Unable to find distro file: %(filename)s"
-msgstr ""
-
-#, python-format
-msgid ""
-"Unable to parse distro file: %(filename)s. Make sure, it is a JSON file."
-msgstr ""
-
-#, python-format
-msgid "Unable to login to iSCSI host target %(portal)s. Details: %(err)s"
-msgstr ""
-
-#, python-format
-msgid "Unable to login to iSCSI host %(host)s target %(target)s"
-msgstr ""
-
-#, python-format
-msgid "Unable to find ISO file %(filename)s"
-msgstr ""
-
-#, python-format
-msgid "The ISO file %(filename)s is not bootable"
-msgstr ""
-
-#, python-format
-msgid "The ISO file %(filename)s does not have a valid El Torito boot record"
-msgstr ""
-
-#, python-format
-msgid "Invalid El Torito validation entry in ISO %(filename)s"
-msgstr ""
-
-#, python-format
-msgid "Invalid El Torito boot indicator in ISO %(filename)s"
-msgstr ""
-
-#, python-format
-msgid "Unexpected volume type for primary volume in ISO %(filename)s"
-msgstr ""
-
-#, python-format
-msgid "Bad format while reading volume descriptor in ISO %(filename)s"
-msgstr ""
-
-#, python-format
-msgid ""
-"The hypervisor doesn't have permission to use this ISO %(filename)s. "
-"Consider moving it under /var/lib/libvirt, or set the search permission to "
-"file access control lists for '%(user)s' user if possible, or add the
'%"
-"(user)s' to the ISO path group, or (not recommended) 'chmod -R o+x "
-"'path_to_iso'.Details: %(err)s"
-msgstr ""
-
-msgid "An error occurred when probing image OS information."
-msgstr ""
-
-msgid "No OS information found in given image."
-msgstr ""
-
-#, python-format
-msgid "Unable to read image file %(filename)s"
-msgstr ""
-
-#, python-format
-msgid ""
-"Image file must be an existing file on system. %(filename)s is not a valid "
-"input."
-msgstr ""
-
-#, python-format
-msgid "Virtual machine %(name)s already exists"
-msgstr ""
-
-#, python-format
-msgid "Virtual machine %(name)s does not exist"
-msgstr ""
-
-#, python-format
-msgid ""
-"Unable to rename virtual machine %(name)s. The name %(new_name)s is already "
-"in use or the virtual machine is not powered off."
-msgstr ""
-
-#, python-format
-msgid "Unable to retrieve screenshot for stopped virtual machine %(name)s"
-msgstr ""
-
-msgid "Remote ISO image is not supported by this server."
-msgstr ""
-
-#, python-format
-msgid "Screenshot is not supported on virtual machine %(name)s"
-msgstr ""
-
-#, python-format
-msgid "Unable to create virtual machine %(name)s. Details: %(err)s"
-msgstr ""
-
-#, python-format
-msgid "Unable to update virtual machine %(name)s. Details: %(err)s"
-msgstr ""
-
-#, python-format
-msgid "Unable to retrieve virtual machine %(name)s. Details: %(err)s"
-msgstr ""
-
-#, python-format
-msgid "Unable to connect to powered off virtual machine %(name)s."
-msgstr ""
-
-msgid "Virtual machine name must be a string without slashes (/)"
-msgstr ""
-
-#, python-format
-msgid "Invalid template URI %(value)s specified for virtual machine"
-msgstr ""
-
-#, python-format
-msgid "Invalid storage pool URI %(value)s specified for virtual machine"
-msgstr ""
-
-msgid "Supported virtual machine graphics are Spice or VNC"
-msgstr ""
-
-msgid "Graphics address to listen on must be IPv4 or IPv6"
-msgstr ""
-
-msgid "Specify a template to create a virtual machine from"
-msgstr ""
-
-#, python-format
-msgid "Unable to start virtual machine %(name)s. Details: %(err)s"
-msgstr ""
-
-#, python-format
-msgid "Unable to power off virtual machine %(name)s. Details: %(err)s"
-msgstr ""
-
-#, python-format
-msgid "Unable to delete virtual machine %(name)s. Details: %(err)s"
-msgstr ""
-
-#, python-format
-msgid "Unable to reset virtual machine %(name)s. Details: %(err)s"
-msgstr ""
-
-msgid "User name list must be an array"
-msgstr ""
-
-msgid "User name must be a string"
-msgstr ""
-
-msgid "Group name list must be an array"
-msgstr ""
-
-msgid "Group name must be a string"
-msgstr ""
-
-#, python-format
-msgid "User(s) '%(users)s' do not exist"
-msgstr ""
-
-#, python-format
-msgid "Group(s) '%(groups)s' do not exist"
-msgstr ""
-
-#, python-format
-msgid "Unable to shutdown virtual machine %(name)s. Details: %(err)s"
-msgstr ""
-
-#, python-format
-msgid ""
-"Unable to get access metadata of virtual machine %(name)s. Details: %(err)s"
-msgstr ""
-
-msgid "The guest console password must be a string."
-msgstr ""
-
-msgid "The life time for the guest console password must be a number."
-msgstr ""
-
-#, python-format
-msgid "Virtual machine '%(name)s' must be stopped before cloning it."
-msgstr ""
-
-#, python-format
-msgid "Insufficient disk space to clone virtual machine '%(name)s'"
-msgstr ""
-
-#, python-format
-msgid "Unable to clone VM '%(name)s'. Details: %(err)s"
-msgstr ""
-
-#, python-format
-msgid "Invalid operation for non-persistent virtual machine %(name)s"
-msgstr ""
-
-#, python-format
-msgid "Cannot suspend VM '%(name)s' because it is not running."
-msgstr ""
-
-#, python-format
-msgid "Unable to suspend VM '%(name)s'. Details: %(err)s"
-msgstr ""
-
-#, python-format
-msgid "Cannot resume VM '%(name)s' because it is not paused."
-msgstr ""
-
-#, python-format
-msgid "Unable to resume VM '%(name)s'. Details: %(err)s"
-msgstr ""
-
-msgid "Memory assigned is higher then the maximum allowed in the host."
-msgstr ""
-
-#, python-format
-msgid ""
-"VM '%(name)s' does not support live memory update. Update the memory with
"
-"the machine offline to enable this feature."
-msgstr ""
-
-msgid "Only increase memory is allowed in active VMs"
-msgstr ""
-
-msgid ""
-"For live memory update, new memory value must be equal old memory value plus
"
-"multiples of 1024 Mib"
-msgstr ""
-
-msgid "There are not enough free slots of 1024 Mib in the guest."
-msgstr ""
-
-msgid ""
-"Host's libvirt version does not support memory devices. Libvirt must be >=
"
-"1.2.14"
-msgstr ""
-
-#, python-format
-msgid "Error attaching memory device. Details: %(error)s"
-msgstr ""
-
-#, python-format
-msgid ""
-"VM %(vmid)s does not contain directly assigned host device %(dev_name)s."
-msgstr ""
-
-#, python-format
-msgid "The host device %(dev_name)s is not allowed to directly assign to VM."
-msgstr ""
-
-msgid ""
-"No IOMMU groups found. Host PCI pass through needs IOMMU group to function "
-"correctly. Please enable Intel VT-d or AMD IOMMU in your BIOS, then verify "
-"the Kernel is compiled with IOMMU support. For Intel CPU, add intel_iommu=on
"
-"to your Kernel parameter in /boot/grub2/grub.conf. For AMD CPU, add iommu=pt
"
-"iommu=1."
-msgstr ""
-
-msgid "\"name\" should be a device name string"
-msgstr ""
-
-#, python-format
-msgid ""
-"The device %(name)s is probably in use by the host. Unable to attach it to "
-"the guest."
-msgstr ""
-
-#, python-format
-msgid "Interface %(iface)s does not exist in virtual machine %(name)s"
-msgstr ""
-
-#, python-format
-msgid ""
-"Network %(network)s specified for virtual machine %(name)s does not exist"
-msgstr ""
-
-msgid "Supported virtual machine interfaces type is only network"
-msgstr ""
-
-msgid "Network name for virtual machine interface must be a string"
-msgstr ""
-
-msgid "Invalid network model card specified for virtual machine interface"
-msgstr ""
-
-msgid "Specify type and network to add a new virtual machine interface"
-msgstr ""
-
-msgid "MAC Address must respect this format FF:FF:FF:FF:FF:FF"
-msgstr ""
-
-#, python-format
-msgid "MAC Address %(mac)s already exists in virtual machine %(name)s"
-msgstr ""
-
-msgid "Invalid MAC Address"
-msgstr ""
-
-msgid "Cannot change MAC address of a running virtual machine"
-msgstr ""
-
-#, python-format
-msgid "Template %(name)s already exists"
-msgstr ""
-
-#, python-format
-msgid ""
-"Network '%(network)s' specified for template %(template)s does not
exist"
-msgstr ""
-
-#, python-format
-msgid ""
-"Storage pool %(pool)s specified for template %(template)s does not exist"
-msgstr ""
-
-#, python-format
-msgid "Storage pool %(pool)s specified for template %(template)s is not
active"
-msgstr ""
-
-#, python-format
-msgid "Invalid parameter '%(param)s' specified for CDROM."
-msgstr ""
-
-#, python-format
-msgid "Network %(network)s specified for template %(template)s is not active"
-msgstr ""
-
-msgid "Template name must be a string"
-msgstr ""
-
-msgid "Template icon must be a path to the image"
-msgstr ""
-
-msgid "Template distribution must be a string"
-msgstr ""
-
-msgid "Template distribution version must be a string"
-msgstr ""
-
-msgid "The number of CPUs must be an integer greater than 0"
-msgstr ""
-
-msgid "Amount of memory (MB) must be an integer greater than 512"
-msgstr ""
-
-msgid "Template CDROM must be a local or remote ISO file"
-msgstr ""
-
-#, python-format
-msgid "Invalid storage pool URI %(value)s specified for template"
-msgstr ""
-
-msgid "Specify an ISO image as CDROM or a base image to create a template"
-msgstr ""
-
-msgid "All networks for the template must be specified in a list."
-msgstr ""
-
-msgid "Specify a volume to a template when storage pool is iSCSI or SCSI"
-msgstr ""
-
-#, python-format
-msgid "The volume %(volume)s is not in storage pool %(pool)s"
-msgstr ""
-
-#, python-format
-msgid "Unable to create template due error: %(err)s"
-msgstr ""
-
-#, python-format
-msgid "Unable to delete template due error: %(err)s"
-msgstr ""
-
-msgid "Disk size must be an integer greater than 1GB."
-msgstr ""
-
-msgid "Template base image must be a valid local image file"
-msgstr ""
-
-#, python-format
-msgid "Cannot identify base image %(path)s format"
-msgstr ""
-
-msgid ""
-"When specifying CPU topology, VCPUs must be a product of sockets, cores, and
"
-"threads."
-msgstr ""
-
-msgid ""
-"When specifying CPU topology, each element must be an integer greater than "
-"zero."
-msgstr ""
-
-msgid ""
-"Invalid disk image format. Valid formats: bochs, cloop, cow, dmg, qcow, "
-"qcow2, qed, raw, vmdk, vpc."
-msgstr ""
-
-#, python-format
-msgid "Storage pool %(name)s already exists"
-msgstr ""
-
-#, python-format
-msgid "Storage pool %(name)s does not exist"
-msgstr ""
-
-#, python-format
-msgid "Specify %(item)s in order to create the storage pool %(name)s"
-msgstr ""
-
-#, python-format
-msgid "Unable to delete active storage pool %(name)s"
-msgstr ""
-
-#, python-format
-msgid "Unable to list storage pools. Details: %(err)s"
-msgstr ""
-
-#, python-format
-msgid "Unable to create storage pool %(name)s. Details: %(err)s"
-msgstr ""
-
-#, python-format
-msgid ""
-"Unable to get number of storage volumes in storage pool %(name)s. Details: %"
-"(err)s"
-msgstr ""
-
-#, python-format
-msgid "Unable to activate storage pool %(name)s. Details: %(err)s"
-msgstr ""
-
-#, python-format
-msgid "Unable to deactivate storage pool %(name)s. Details: %(err)s"
-msgstr ""
-
-#, python-format
-msgid "Unable to delete storage pool %(name)s. Details: %(err)s"
-msgstr ""
-
-#, python-format
-msgid ""
-"Unable to create NFS Pool as export path %(path)s may block during mount"
-msgstr ""
-
-#, python-format
-msgid "Unable to create NFS Pool as export path %(path)s mount failed"
-msgstr ""
-
-#, python-format
-msgid "Unsupported storage pool type: %(type)s"
-msgstr ""
-
-#, python-format
-msgid "Error while retrieving storage pool XML to %(pool)s"
-msgstr ""
-
-msgid "Storage pool name must be a string without slashes (/)"
-msgstr ""
-
-msgid ""
-"Supported storage pool types are dir, netfs, logical, iscsi, isci and
kimchi-"
-"iso"
-msgstr ""
-
-msgid "Storage pool path must be a string"
-msgstr ""
-
-msgid "Storage pool host must be a IP or hostname"
-msgstr ""
-
-msgid "Storage pool device must be the absolute path to the block device"
-msgstr ""
-
-msgid "Storage pool devices parameter must be a list"
-msgstr ""
-
-msgid "Target IQN of an iSCSI pool must be a string"
-msgstr ""
-
-msgid "Port of a remote storage server must be an integer between 1 and 65535"
-msgstr ""
-
-msgid "iSCSI target username must be a string"
-msgstr ""
-
-msgid "iSCSI target password must be a string"
-msgstr ""
-
-msgid "Specify name and type to create a storage pool"
-msgstr ""
-
-#, python-format
-msgid ""
-"%(disk)s is not a valid disk/partition. Could not add it to the pool %(pool)"
-"s."
-msgstr ""
-
-#, python-format
-msgid "Unable to extend logical pool %(pool)s. Details: %(err)s"
-msgstr ""
-
-msgid "The parameter disks only can be updated for logical storage pool."
-msgstr ""
-
-msgid "The SCSI host adapter name must be a string."
-msgstr ""
-
-msgid "The storage pool kimchi_isos is reserved for internal use"
-msgstr ""
-
-#, python-format
-msgid ""
-"Unable to activate NFS storage pool %(name)s. NFS server %(server)s is "
-"unreachable."
-msgstr ""
-
-#, python-format
-msgid ""
-"Unable to deactivate NFS storage pool %(name)s. NFS server %(server)s is "
-"unreachable."
-msgstr ""
-
-#, python-format
-msgid ""
-"Unable to deactivate pool %(name)s as it is associated with some templates"
-msgstr ""
-
-#, python-format
-msgid "Unable to delete pool %(name)s as it is associated with some templates"
-msgstr ""
-
-#, python-format
-msgid ""
-"A volume group named '%(name)s' already exists. Please, choose another name
"
-"to create the logical pool."
-msgstr ""
-
-#, python-format
-msgid "Unable to update database with deep scan information due error:
%(err)s"
-msgstr ""
-
-#, python-format
-msgid "Storage volume %(name)s already exists"
-msgstr ""
-
-#, python-format
-msgid "Storage volume %(name)s does not exist in storage pool %(pool)s"
-msgstr ""
-
-#, python-format
-msgid ""
-"Unable to create storage volume %(volume)s because storage pool %(pool)s is "
-"not active"
-msgstr ""
-
-#, python-format
-msgid "Specify %(item)s in order to create storage volume %(volume)s"
-msgstr ""
-
-#, python-format
-msgid ""
-"Unable to list storage volumes because storage pool %(pool)s is not active"
-msgstr ""
-
-#, python-format
-msgid ""
-"Unable to create storage volume %(name)s in storage pool %(pool)s. Details:
%"
-"(err)s"
-msgstr ""
-
-#, python-format
-msgid ""
-"Unable to list storage volumes in storage pool %(pool)s. Details: %(err)s"
-msgstr ""
-
-#, python-format
-msgid "Unable to wipe storage volumes %(name)s. Details: %(err)s"
-msgstr ""
-
-#, python-format
-msgid "Unable to delete storage volume %(name)s. Details: %(err)s"
-msgstr ""
-
-#, python-format
-msgid "Unable to resize storage volume %(name)s. Details: %(err)s"
-msgstr ""
-
-#, python-format
-msgid "Storage type %(type)s does not support volume create and delete"
-msgstr ""
-
-msgid "Storage volume name must be a string"
-msgstr ""
-
-msgid "Storage volume allocation must be an integer number"
-msgstr ""
-
-msgid ""
-"Storage volume format not supported. Valid formats: bochs, cloop, cow, dmg, "
-"qcow, qcow2, qed, raw, vmdk, vpc."
-msgstr ""
-
-msgid "Storage volume requires a volume name"
-msgstr ""
-
-#, python-format
-msgid ""
-"Unable to update database with storage volume information due error: %(err)s"
-msgstr ""
-
-#, python-format
-msgid "Only one of parameter %(param)s can be specified"
-msgstr ""
-
-#, python-format
-msgid "Create volume from %(param)s is not supported"
-msgstr ""
-
-msgid "Storage volume capacity must be an integer number."
-msgstr ""
-
-msgid "Storage volume URL must be http://, https://, ftp:// or ftps://."
-msgstr ""
-
-#, python-format
-msgid "Unable to access file %(url)s. Please, check it."
-msgstr ""
-
-#, python-format
-msgid ""
-"Unable to clone storage volume '%(name)s' in pool '%(pool)s'.
Details: %(err)"
-"s"
-msgstr ""
-
-msgid "Specify chunk data and its size to upload a file."
-msgstr ""
-
-msgid "In order to upload a storage volume, specify the 'upload'
parameter."
-msgstr ""
-
-msgid ""
-"Unable to upload chunk data as it does not match with requested chunk size."
-msgstr ""
-
-#, python-format
-msgid "The storage volume %(vol)s is not under an upload process."
-msgstr ""
-
-msgid "The upload chunk data will exceed the storage volume size."
-msgstr ""
-
-#, python-format
-msgid "Unable to upload chunk data to storage volume. Details: %(err)s."
-msgstr ""
-
-#, python-format
-msgid "Interface %(name)s does not exist"
-msgstr ""
-
-#, python-format
-msgid "Network %(name)s already exists"
-msgstr ""
-
-#, python-format
-msgid "Network %(name)s does not exist"
-msgstr ""
-
-#, python-format
-msgid "Subnet %(subnet)s specified for network %(network)s is not valid."
-msgstr ""
-
-#, python-format
-msgid "Specify a network interface to create bridged network %(name)s"
-msgstr ""
-
-#, python-format
-msgid "Unable to delete active network %(name)s"
-msgstr ""
-
-#, python-format
-msgid "Interface %(iface)s specified for network %(network)s is already in
use"
-msgstr ""
-
-msgid "Interface should be bare NIC, bonding or bridge device."
-msgstr ""
-
-#, python-format
-msgid "Unable to create network %(name)s. Details: %(err)s"
-msgstr ""
-
-#, python-format
-msgid "Unable to find a free IP address for network '%(name)s'"
-msgstr ""
-
-#, python-format
-msgid "The interface %(iface)s already exists."
-msgstr ""
-
-msgid "Network name must be a string without slashes (/) or quotes (\")"
-msgstr ""
-
-msgid "Supported network types are isolated, NAT and bridge"
-msgstr ""
-
-msgid "Network subnet must be a string with IP address and prefix or netmask"
-msgstr ""
-
-msgid "Network interface must be a string"
-msgstr ""
-
-msgid "Network VLAN ID must be an integer between 1 and 4094"
-msgstr ""
-
-msgid "Specify name and type to create a Network"
-msgstr ""
-
-#, python-format
-msgid ""
-"Unable to delete network %(name)s. There are some virtual machines %(vms)s "
-"and/or templates linked to this network."
-msgstr ""
-
-#, python-format
-msgid ""
-"Unable to deactivate network %(name)s. There are some virtual machines
%(vms)"
-"s and/or templates linked to this network."
-msgstr ""
-
-#, python-format
-msgid "Bridge device %(name)s can not be the trunk device of a VLAN."
-msgstr ""
-
-#, python-format
-msgid "Failed to activate interface %(iface)s: %(err)s."
-msgstr ""
-
-#, python-format
-msgid ""
-"Failed to activate interface %(iface)s. Please check the physical link "
-"status."
-msgstr ""
-
-#, python-format
-msgid "Failed to start network %(name)s. Details: %(err)s"
-msgstr ""
-
-#, python-format
-msgid "Debug report %(name)s does not exist"
-msgstr ""
-
-msgid "Debug report tool not found in system"
-msgstr ""
-
-#, python-format
-msgid "Unable to create debug report %(name)s. Details: %(err)s."
-msgstr ""
-
-#, python-format
-msgid "Can not find any debug report with the given name %(name)s"
-msgstr ""
-
-#, python-format
-msgid "Unable to generate debug report %(name)s. Details: %(err)s"
-msgstr ""
-
-msgid "You should give a name for the debug report file."
-msgstr ""
-
-msgid ""
-"Debug report name must be a string. Only letters, digits, underscore ('_')
"
-"and hyphen ('-') are allowed."
-msgstr ""
-
-#, python-format
-msgid ""
-"The debug report with specified name \"%(name)s\" already exists. Please
use "
-"another one."
-msgstr ""
-
-#, python-format
-msgid "Storage server %(server)s was not used by Kimchi"
-msgstr ""
-
-#, python-format
-msgid "Distro '%(name)s' does not exist"
-msgstr ""
-
-#, python-format
-msgid "Partition %(name)s does not exist in the host"
-msgstr ""
-
-msgid "Unable to shutdown host machine as there are running virtual machines"
-msgstr ""
-
-msgid "Unable to reboot host machine as there are running virtual machines"
-msgstr ""
-
-#, python-format
-msgid "Node device '%(name)s' not found"
-msgstr ""
-
-msgid "Conflicting flag filters specified."
-msgstr ""
-
-msgid "No packages marked for update"
-msgstr ""
-
-#, python-format
-msgid "Package %(name)s is not marked to be updated."
-msgstr ""
-
-#, python-format
-msgid "Error while getting packages marked to be updated. Details: %(err)s"
-msgstr ""
-
-msgid "There is no compatible package manager for this system."
-msgstr ""
-
-#, python-format
-msgid "Invalid URI %(uri)s"
-msgstr ""
-
-msgid "Unable to choose a virtual machine name"
-msgstr ""
-
-msgid "Invalid storage type. Types supported: 'cdrom', 'disk'"
-msgstr ""
-
-#, python-format
-msgid "The path '%(value)s' is not a valid local/remote path for the
device"
-msgstr ""
-
-msgid "Only CDROM path can be update."
-msgstr ""
-
-#, python-format
-msgid ""
-"The storage device %(dev_name)s does not exist in the virtual machine %"
-"(vm_name)s"
-msgstr ""
-
-#, python-format
-msgid "Error while creating new storage device: %(error)s"
-msgstr ""
-
-#, python-format
-msgid "Error while updating storage device: %(error)s"
-msgstr ""
-
-#, python-format
-msgid "Error while removing storage device: %(error)s"
-msgstr ""
-
-msgid "Do not support IDE device hot plug"
-msgstr ""
-
-msgid ""
-"Specify type and path or type and pool/volume to add a new virtual machine "
-"disk"
-msgstr ""
-
-msgid "Specify path to update virtual machine disk"
-msgstr ""
-
-#, python-format
-msgid "Controller type %(type)s limitation of %(limit)s devices reached"
-msgstr ""
-
-#, python-format
-msgid "Cannot retrieve disk path information for given pool/volume: %(error)s"
-msgstr ""
-
-msgid "Volume already in use by other virtual machine."
-msgstr ""
-
-msgid ""
-"Only one of path or pool/volume can be specified to add a new virtual "
-"machine disk"
-msgstr ""
-
-#, python-format
-msgid ""
-"Volume chosen with format %(format)s does not fit in the storage type
%(type)"
-"s"
-msgstr ""
-
-msgid "YUM Repository ID must be one word only string."
-msgstr ""
-
-msgid "Repository URL must be an http://, ftp:// or file:// URL."
-msgstr ""
-
-msgid ""
-"Repository configuration is a dictionary with specific values according to "
-"repository type."
-msgstr ""
-
-msgid "Distribution to DEB repository must be a string"
-msgstr ""
-
-msgid "Components to DEB repository must be listed in a array"
-msgstr ""
-
-msgid "Components to DEB repository must be a string"
-msgstr ""
-
-msgid "Mirror list to repository must be a string"
-msgstr ""
-
-msgid "YUM Repository name must be string."
-msgstr ""
-
-msgid "GPG check must be a boolean value."
-msgstr ""
-
-msgid "GPG key must be a URL pointing to the ASCII-armored file."
-msgstr ""
-
-#, python-format
-msgid "Could not update repository %(repo_id)s."
-msgstr ""
-
-#, python-format
-msgid "Repository %(repo_id)s does not exist."
-msgstr ""
-
-msgid ""
-"Specify repository base URL, mirror list or metalink in order to create or "
-"update a YUM repository."
-msgstr ""
-
-msgid "Repository management tool was not recognized for your system."
-msgstr ""
-
-#, python-format
-msgid "Repository %(repo_id)s is already enabled."
-msgstr ""
-
-#, python-format
-msgid "Repository %(repo_id)s is already disabled."
-msgstr ""
-
-#, python-format
-msgid "Could not remove repository %(repo_id)s."
-msgstr ""
-
-#, python-format
-msgid "Could not write repository configuration file %(repo_file)s"
-msgstr ""
-
-msgid "Specify repository distribution in order to create a DEB repository."
-msgstr ""
-
-#, python-format
-msgid "Could not enable repository %(repo_id)s."
-msgstr ""
-
-#, python-format
-msgid "Could not disable repository %(repo_id)s."
-msgstr ""
-
-msgid "YUM Repository ID already exists"
-msgstr ""
-
-msgid "YUM Repository name must be a string"
-msgstr ""
-
-#, python-format
-msgid "Unable to list repositories. Details: '%(err)s'"
-msgstr ""
-
-#, python-format
-msgid "Unable to retrieve repository information. Details: '%(err)s'"
-msgstr ""
-
-#, python-format
-msgid "Unable to add repository. Details: '%(err)s'"
-msgstr ""
-
-#, python-format
-msgid "Unable to remove repository. Details: '%(err)s'"
-msgstr ""
-
-#, python-format
-msgid ""
-"Configuration items: '%(items)s' are not supported by repository
manager"
-msgstr ""
-
-msgid "Repository metalink must be an http://, ftp:// or file:// URL."
-msgstr ""
-
-msgid "Cannot specify mirrorlist and metalink at the same time."
-msgstr ""
-
-#, python-format
-msgid ""
-"Virtual machine '%(vm)s' must be stopped before creating a snapshot of
it."
-msgstr ""
-
-#, python-format
-msgid ""
-"Unable to create snapshot '%(name)s' on virtual machine '%(vm)s'.
Details: %"
-"(err)s"
-msgstr ""
-
-#, python-format
-msgid "Snapshot '%(name)s' does not exist on virtual machine
'%(vm)s'."
-msgstr ""
-
-#, python-format
-msgid ""
-"Unable to retrieve snapshot '%(name)s' on virtual machine '%(vm)s'.
Details: "
-"%(err)s"
-msgstr ""
-
-#, python-format
-msgid "Unable to list snapshots on virtual machine '%(vm)s'. Details:
%(err)s"
-msgstr ""
-
-#, python-format
-msgid ""
-"Unable to delete snapshot '%(name)s' on virtual machine '%(vm)s'.
Details: %"
-"(err)s"
-msgstr ""
-
-#, python-format
-msgid ""
-"Unable to retrieve current snapshot of virtual machine '%(vm)s'. Details:
%"
-"(err)s"
-msgstr ""
-
-#, python-format
-msgid ""
-"Unable to revert virtual machine '%(vm)s' to snapshot '%(name)s'.
Details: %"
-"(err)s"
-msgstr ""
-
-#, python-format
-msgid ""
-"Unable to create snapshot of virtual machine '%(vm)s' because it contains a
"
-"disk with format '%(format)s'; only 'qcow2' is supported."
-msgstr ""
-
-msgid "The number of vCPUs is too large for this system."
-msgstr ""
-
-msgid "Invalid vCPU/topology combination."
-msgstr ""
-
-msgid "This host (or current configuration) does not allow CPU topology."
-msgstr ""
-
-msgid "ERROR CODE"
-msgstr ""
-
-msgid "REASON"
-msgstr ""
-
-msgid "STACK"
-msgstr ""
-
-msgid "Go to Homepage"
-msgstr ""
-
-msgid "Create a New Virtual Machine"
-msgstr ""
-
-msgid "Virtual Machine Name"
-msgstr ""
-
-msgid ""
-"The name used to identify the virtual machine. If omitted, a name will be "
-"chosen based on the template used."
-msgstr ""
-
-msgid "Template"
-msgstr ""
-
-msgid "Please create a template first."
-msgstr ""
-
-msgid "Create a Template"
-msgstr ""
-
-msgid "Please choose a template."
-msgstr ""
-
-msgid "OS"
-msgstr ""
-
-msgid "OS Version"
-msgstr ""
-
-msgid "CPUS"
-msgstr ""
-
-msgid "Memory"
-msgstr ""
-
-msgid "Create"
-msgstr ""
-
-msgid "Creating..."
-msgstr ""
-
-msgid "Cancel"
-msgstr ""
-
-msgid "Edit Guest"
-msgstr ""
-
-msgid "General"
-msgstr ""
-
-msgid "Storage"
-msgstr ""
-
-msgid "Interface"
-msgstr ""
-
-msgid "Permission"
-msgstr ""
-
-msgid "Host PCI Device"
-msgstr ""
-
-msgid "Snapshot"
-msgstr ""
-
-msgid "Name"
-msgstr ""
-
-msgid "CPUs"
-msgstr ""
-
-msgid "Memory (MB)"
-msgstr ""
-
-msgid "Icon"
-msgstr ""
-
-msgid "Device"
-msgstr ""
-
-msgid "Path"
-msgstr ""
-
-msgid "Network"
-msgstr ""
-
-msgid "Type"
-msgstr ""
-
-msgid "MAC Address"
-msgstr ""
-
-msgid "Available system users and groups"
-msgstr ""
-
-msgid "Selected system users and groups"
-msgstr ""
-
-msgid "User"
-msgstr ""
-
-msgid "All"
-msgstr ""
-
-msgid "To Add"
-msgstr ""
-
-msgid "Added"
-msgstr ""
-
-msgid "filter"
-msgstr ""
-
-msgid "Product"
-msgstr ""
-
-msgid "Vendor"
-msgstr ""
-
-msgid "Created"
-msgstr ""
-
-msgid "Save"
-msgstr ""
-
-msgid "Replace"
-msgstr ""
-
-msgid "Detach"
-msgstr ""
-
-msgid "revert"
-msgstr ""
-
-msgid "Start"
-msgstr ""
-
-msgid "Reset"
-msgstr ""
-
-msgid "Pause"
-msgstr ""
-
-msgid "Resume"
-msgstr ""
-
-msgid "Power Off"
-msgstr ""
-
-msgid "Actions"
-msgstr ""
-
-msgid "Connect"
-msgstr ""
-
-msgid "Clone"
-msgstr ""
-
-msgid "Edit"
-msgstr ""
-
-msgid "Shut Down"
-msgstr ""
-
-msgid "Delete"
-msgstr ""
-
-msgid "CPU"
-msgstr ""
-
-msgid "Disk I/O"
-msgstr ""
-
-msgid "Network I/O"
-msgstr ""
-
-msgid "Livetile"
-msgstr ""
-
-msgid "No guests found."
-msgstr ""
-
-msgid "Add a Storage Device to VM"
-msgstr ""
-
-msgid "Device Type"
-msgstr ""
-
-msgid "The device type. Currently, \"cdrom\" and \"disk\" are
supported."
-msgstr ""
-
-msgid "Storage Pool"
-msgstr ""
-
-msgid "Storage pool which volume located in"
-msgstr ""
-
-msgid "Storage Volume"
-msgstr ""
-
-msgid "Storage volume to be attached"
-msgstr ""
-
-msgid "File Path"
-msgstr ""
-
-msgid "The ISO file path in the server for CDROM."
-msgstr ""
-
-msgid "Attach"
-msgstr ""
-
-msgid "Shut down"
-msgstr ""
-
-msgid "Restart"
-msgstr ""
-
-msgid "Basic Information"
-msgstr ""
-
-msgid "OS Distro"
-msgstr ""
-
-msgid "OS Code Name"
-msgstr ""
-
-msgid "Processor"
-msgstr ""
-
-msgid "CPU(s)"
-msgstr ""
-
-msgid "System Statistics"
-msgstr ""
-
-msgid "Software Updates"
-msgstr ""
-
-msgid "Update Progress"
-msgstr ""
-
-msgid "Repositories"
-msgstr ""
-
-msgid "Debug Reports"
-msgstr ""
-
-msgid "The username or password you entered is incorrect. Please try again."
-msgstr ""
-
-msgid "This field is required."
-msgstr ""
-
-msgid "Log in"
-msgstr ""
-
-msgid "Logging in..."
-msgstr ""
-
-msgid "Host"
-msgstr ""
-
-msgid "Guests"
-msgstr ""
-
-msgid "Templates"
-msgstr ""
-
-msgid "Failed to get application configuration"
-msgstr ""
-
-msgid "This is not a valid Linux path"
-msgstr ""
-
-msgid "This is not a valid URL."
-msgstr ""
-
-msgid "No such data available."
-msgstr ""
-
-msgid ""
-"Can not contact the host system. Verify the host system is up and that you "
-"have network connectivity to it. HTTP request response %1. "
-msgstr ""
-
-msgid "Unable to read file."
-msgstr ""
-
-msgid "Error while uploading file."
-msgstr ""
-
-msgid "Delete Confirmation"
-msgstr ""
-
-msgid "OK"
-msgstr ""
-
-msgid "Confirm"
-msgstr ""
-
-msgid "Warning"
-msgstr ""
-
-msgid "Cloning..."
-msgstr ""
-
-msgid "Loading..."
-msgstr ""
-
-msgid "An error occurred while retrieving system information."
-msgstr ""
-
-msgid "Retry"
-msgstr ""
-
-msgid "Detailed message:"
-msgstr ""
-
-msgid "No ISO found"
-msgstr ""
-
-msgid "This is not a valid ISO file."
-msgstr ""
-
-msgid "This may take a long time. Do you want to continue?"
-msgstr ""
-
-msgid "This will permanently delete the template. Would you like to continue?"
-msgstr ""
-
-msgid "Unable to shut down system as there are some virtual machines running!"
-msgstr ""
-
-msgid "Max:"
-msgstr ""
-
-msgid "Utilization"
-msgstr ""
-
-msgid "Available"
-msgstr ""
-
-msgid "Read Rate"
-msgstr ""
-
-msgid "Write Rate"
-msgstr ""
-
-msgid "Received"
-msgstr ""
-
-msgid "Sent"
-msgstr ""
-
-msgid ""
-"Shutting down or restarting host will cause unsaved work lost. Continue to "
-"shut down/restarting?"
-msgstr ""
-
-msgid ""
-"Repository will be removed permanently and can't be recovered. Do you want
"
-"to continue?"
-msgstr ""
-
-msgid "ID"
-msgstr ""
-
-msgid "Base URL"
-msgstr ""
-
-msgid "Is Mirror"
-msgstr ""
-
-msgid "URL Args"
-msgstr ""
-
-msgid "Enabled"
-msgstr ""
-
-msgid "GPG Check"
-msgstr ""
-
-msgid "GPG Key"
-msgstr ""
-
-msgid "Add"
-msgstr ""
-
-msgid "Remove"
-msgstr ""
-
-msgid "Enable"
-msgstr ""
-
-msgid "Disable"
-msgstr ""
-
-msgid "Package Name"
-msgstr ""
-
-msgid "Version"
-msgstr ""
-
-msgid "Architecture"
-msgstr ""
-
-msgid "Repository"
-msgstr ""
-
-msgid "Update All"
-msgstr ""
-
-msgid "Updating..."
-msgstr ""
-
-msgid "Failed to retrieve packages update information."
-msgstr ""
-
-msgid "Failed to update package(s)."
-msgstr ""
-
-msgid ""
-"Debug report will be removed permanently and can't be recovered. Do you want
"
-"to continue?"
-msgstr ""
-
-msgid "Generated Time"
-msgstr ""
-
-msgid "Generate"
-msgstr ""
-
-msgid "Generating..."
-msgstr ""
-
-msgid "Rename"
-msgstr ""
-
-msgid "Download"
-msgstr ""
-
-msgid ""
-"Report name should contain only letters, digits, underscore ('_') and/or
"
-"hyphen ('-')."
-msgstr ""
-
-msgid "Pending..."
-msgstr ""
-
-msgid "Report name is the same as the original one."
-msgstr ""
-
-msgid ""
-"This will delete the virtual machine and its virtual disks. This operation "
-"cannot be undone. Would you like to continue?"
-msgstr ""
-
-msgid "Power off Confirmation"
-msgstr ""
-
-msgid ""
-"This action may produce undesirable results, for example unflushed disk "
-"cache in the guest. Would you like to continue?"
-msgstr ""
-
-msgid "Reset Confirmation"
-msgstr ""
-
-msgid ""
-"There is a risk of data loss caused by reset without the guest OS shutdown. "
-"Would you like to continue?"
-msgstr ""
-
-msgid "Shut Down Confirmation"
-msgstr ""
-
-msgid "Note the guest OS may ignore this request. Would you like to continue?"
-msgstr ""
-
-msgid "Virtual Machine delete Confirmation"
-msgstr ""
-
-msgid ""
-"This virtual machine is not persistent. Power Off will delete it. Continue?"
-msgstr ""
-
-msgid ""
-"When the target guest has SCSI or iSCSI volumes, they will be cloned on "
-"default storage pool. The same will happen when the target pool does not "
-"have enough space to clone the volumes. Do you want to continue?"
-msgstr ""
-
-msgid ""
-"This CDROM will be detached permanently and you can re-attach it. Continue "
-"to detach it?"
-msgstr ""
-
-msgid "Attaching..."
-msgstr ""
-
-msgid "Replacing..."
-msgstr ""
-
-msgid "Successfully attached!"
-msgstr ""
-
-msgid "Successfully replaced!"
-msgstr ""
-
-msgid "Successfully detached!"
-msgstr ""
-
-msgid ""
-"This disk will be detached permanently and you can re-attach it. Continue to
"
-"detach it?"
-msgstr ""
-
-msgid "interface:"
-msgstr ""
-
-msgid "address:"
-msgstr ""
-
-msgid "link_type:"
-msgstr ""
-
-msgid "block:"
-msgstr ""
-
-msgid "drive_type:"
-msgstr ""
-
-msgid "model:"
-msgstr ""
-
-msgid "Affected devices:"
-msgstr ""
-
-msgid "The VLAN id must be between 1 and 4094."
-msgstr ""
-
-msgid "unavailable"
-msgstr ""
-
-msgid ""
-"This action will interrupt network connectivity for any virtual machine that
"
-"depend on this network."
-msgstr ""
-
-msgid "Create a network"
-msgstr ""
-
-msgid ""
-"This network is not persistent. Instead of stop, this action will "
-"permanently delete it. Would you like to continue?"
-msgstr ""
-
-msgid ""
-"The bridged VLAN tag may not work well with NetworkManager enabled. You "
-"should consider disabling it."
-msgstr ""
-
-msgid ""
-"This will permanently delete the storage pool. Would you like to continue?"
-msgstr ""
-
-msgid "This storage pool is empty."
-msgstr ""
-
-msgid ""
-"It will format your disk and you will loose any data in there, are you sure "
-"to continue? "
-msgstr ""
-
-msgid "SCSI Fibre Channel"
-msgstr ""
-
-msgid "No SCSI adapters found."
-msgstr ""
-
-msgid "Loading iSCSI targets..."
-msgstr ""
-
-msgid "No iSCSI found. Please input one."
-msgstr ""
-
-msgid "Failed to load iSCSI targets."
-msgstr ""
-
-msgid "The storage pool name can not be blank."
-msgstr ""
-
-msgid "The storage pool path can not be blank."
-msgstr ""
-
-msgid "NFS server mount path can not be blank."
-msgstr ""
-
-msgid "Invalid NFS mount path."
-msgstr ""
-
-msgid "No logical device selected."
-msgstr ""
-
-msgid "The iSCSI target can not be blank."
-msgstr ""
-
-msgid "Server name can not be blank."
-msgstr ""
-
-msgid "This is not a valid Server Name or IP. Please, modify it."
-msgstr ""
-
-msgid "Looking for available partitions ..."
-msgstr ""
-
-msgid "No available partitions found."
-msgstr ""
-
-msgid ""
-"This storage pool is not persistent. Instead of deactivate, this action will
"
-"permanently delete it. Would you like to continue?"
-msgstr ""
-
-msgid "Unable to retrieve partitions information."
-msgstr ""
-
-msgid "In progress..."
-msgstr ""
-
-msgid "Failed!"
-msgstr ""
-
-msgid "CDROM path needs to be a valid local/remote path and cannot be blank."
-msgstr ""
-
-msgid "Disk pool or volume cannot be blank."
-msgstr ""
-
-msgid "Filter"
-msgstr ""
-
-msgid "Network Name"
-msgstr ""
-
-msgid "State"
-msgstr ""
-
-msgid "Network Type"
-msgstr ""
-
-msgid "Address Space"
-msgstr ""
-
-msgid "Name should not contain '/' and '\"'."
-msgstr ""
-
-msgid "Isolated: no external network connection"
-msgstr ""
-
-msgid "NAT: outbound physical network connection only"
-msgstr ""
-
-msgid "Bridged: Virtual machines are connected to physical network directly"
-msgstr ""
-
-msgid "(No interfaces found)"
-msgstr ""
-
-msgid "Destination"
-msgstr ""
-
-msgid "Enable VLAN"
-msgstr ""
-
-msgid "VLAN ID"
-msgstr ""
-
-msgid "Stop"
-msgstr ""
-
-msgid "Generate a New Debug Report"
-msgstr ""
-
-msgid "Report Name"
-msgstr ""
-
-msgid ""
-"The name used to identify the report. If omitted, a name will be chosen "
-"based on current time. Name can contain: letters, digits, underscore
(\"_\") "
-"and hyphen (\"-\")."
-msgstr ""
-
-msgid "Rename a Debug Report"
-msgstr ""
-
-msgid ""
-"The name used to identify the report. Name can contain: letters, digits and "
-"hyphen (\"-\")."
-msgstr ""
-
-msgid "Submit"
-msgstr ""
-
-msgid "Add a Repository"
-msgstr ""
-
-msgid "Identifier"
-msgstr ""
-
-msgid "Single word, unique identifier for the repository."
-msgstr ""
-
-msgid "Textual name for the repository."
-msgstr ""
-
-msgid "URL"
-msgstr ""
-
-msgid "Required Field"
-msgstr ""
-
-msgid "URL to the repository. Supported protocols are http, ftp, and file."
-msgstr ""
-
-msgid "Repository is a mirror"
-msgstr ""
-
-msgid "Distribution"
-msgstr ""
-
-msgid "Distribution of the DEB repository."
-msgstr ""
-
-msgid "Components"
-msgstr ""
-
-msgid "List of components in DEB repository."
-msgstr ""
-
-msgid "Edit Repository"
-msgstr ""
-
-msgid "Mirror List URL"
-msgstr ""
-
-msgid "Yes"
-msgstr ""
-
-msgid "No"
-msgstr ""
-
-msgid "Capacity"
-msgstr ""
-
-msgid "Allocated"
-msgstr ""
-
-msgid "Location"
-msgstr ""
-
-msgid "Device path"
-msgstr ""
-
-msgid "active"
-msgstr ""
-
-msgid "inactive"
-msgstr ""
-
-msgid "Deactivate"
-msgstr ""
-
-msgid "Activate"
-msgstr ""
-
-msgid "Add Volume"
-msgstr ""
-
-msgid "Extend"
-msgstr ""
-
-msgid "Undefine"
-msgstr ""
-
-msgid "Format"
-msgstr ""
-
-msgid "Allocation"
-msgstr ""
-
-msgid "Define a New Storage Pool"
-msgstr ""
-
-msgid "Storage Pool Name"
-msgstr ""
-
-msgid ""
-"The name used to identify the storage pools, and it should not be empty."
-msgstr ""
-
-msgid "Storage Pool Type"
-msgstr ""
-
-msgid "Storage Path"
-msgstr ""
-
-msgid ""
-"The path of the Storage Pool. Each Storage Pool must have a unique path."
-msgstr ""
-
-msgid ""
-"Kimchi will try to create the directory when it does not already exist in "
-"your system."
-msgstr ""
-
-msgid "NFS Server IP"
-msgstr ""
-
-msgid "NFS server IP or hostname. It can be input or chosen from history."
-msgstr ""
-
-msgid "NFS Path"
-msgstr ""
-
-msgid "The NFS exported path on NFS server."
-msgstr ""
-
-msgid "iSCSI Server"
-msgstr ""
-
-msgid "Server"
-msgstr ""
-
-msgid "Port"
-msgstr ""
-
-msgid "iSCSI server IP or hostname. It should not be empty."
-msgstr ""
-
-msgid "Target"
-msgstr ""
-
-msgid "The iSCSI target on iSCSI server"
-msgstr ""
-
-msgid "Add iSCSI Authentication"
-msgstr ""
-
-msgid "iSCSI Authentication"
-msgstr ""
-
-msgid "User Name"
-msgstr ""
-
-msgid "Password"
-msgstr ""
-
-msgid "SCSI Adapter"
-msgstr ""
-
-msgid "Please, wait..."
-msgstr ""
-
-msgid "Add a Volume to Storage Pool"
-msgstr ""
-
-msgid "Fetch from remote URL"
-msgstr ""
-
-msgid "Enter the remote URL here."
-msgstr ""
-
-msgid "Upload a file"
-msgstr ""
-
-msgid "Choose the file you want to upload."
-msgstr ""
-
-msgid "Add Template"
-msgstr ""
-
-msgid "Where is the source media for this template? "
-msgstr ""
-
-msgid "Local ISO Image"
-msgstr ""
-
-msgid "Local Image File"
-msgstr ""
-
-msgid "Remote ISO Image"
-msgstr ""
-
-msgid "Search ISOs"
-msgstr ""
-
-msgid "The following ISOs are available:"
-msgstr ""
-
-msgid "OS: "
-msgstr ""
-
-msgid "Version: "
-msgstr ""
-
-msgid "Size: "
-msgstr ""
-
-msgid "Search more ISOs"
-msgstr ""
-
-msgid "Create Templates from Selected ISO"
-msgstr ""
-
-msgid "I want to use a specific ISO file"
-msgstr ""
-
-msgid "Loading default remote ISOs ..."
-msgstr ""
-
-msgid "Arch: "
-msgstr ""
-
-msgid "I want to use a custom URL"
-msgstr ""
-
-msgid "Edit Template"
-msgstr ""
-
-msgid "CDROM"
-msgstr ""
-
-msgid "Image File"
-msgstr ""
-
-msgid "Graphics"
-msgstr ""
-
-msgid "Disk(GB)"
-msgstr ""
-
-msgid "Disk Format"
-msgstr ""
-
-msgid "CPU Number"
-msgstr ""
-
-msgid "Manually set CPU topology"
-msgstr ""
-
-msgid "Cores"
-msgstr ""
-
-msgid "Threads"
-msgstr ""
-
-msgid "No templates found."
-msgstr ""
diff --git a/plugins/kimchi/po/ko_KR.po b/plugins/kimchi/po/ko_KR.po
deleted file mode 100644
index 08bf222..0000000
--- a/plugins/kimchi/po/ko_KR.po
+++ /dev/null
@@ -1,2197 +0,0 @@
-# English translations for kimchi package.
-# Copyright (C) 2013 ORGANIZATION
-#
-msgid ""
-msgstr ""
-"Project-Id-Version: kimchi 0.1\n"
-"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2015-07-01 16:11-0300\n"
-"PO-Revision-Date: 2013-07-11 17:32-0400\n"
-"Last-Translator: Cr��stian Viana <vianac(a)linux.vnet.ibm.com>\n"
-"Language-Team: English\n"
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
-"Content-Transfer-Encoding: 8bit\n"
-"Language: ko_KR\n"
-"Generated-By: pygettext.py 1.5\n"
-"Plural-Forms: nplurals=2; plural=(n != 1);\n"
-
-#, python-format
-msgid "Unknown parameter %(value)s"
-msgstr ""
-
-#, python-format
-msgid "Timeout of %(seconds)s seconds expired while running task
'%(task)s."
-msgstr ""
-
-#, python-format
-msgid "User %(user_id)s not found with given LDAP settings."
-msgstr ""
-
-msgid "Unknown \"_cap\" specified"
-msgstr ""
-
-msgid "\"_passthrough\" should be \"true\" or
\"false\""
-msgstr ""
-
-msgid "\"_passthrough_affected_by\" should be a device name string"
-msgstr ""
-
-#, python-format
-msgid "Error while getting block devices. Details: %(err)s"
-msgstr "������ ��������� ������������ ������ ��������� ������������������.
������������: %(err)s"
-
-#, python-format
-msgid "Error while getting block device information for %(device)s."
-msgstr "%(device)s��� ������ ������ ������ ��������� ������������ ������ ���������
������������������."
-
-#, python-format
-msgid "Unable to find distro file: %(filename)s"
-msgstr "distro ��������� ������ ��� ������: %(filename)s"
-
-#, python-format
-msgid ""
-"Unable to parse distro file: %(filename)s. Make sure, it is a JSON file."
-msgstr ""
-"distro ������(%(filename)s)��� ������ ��������� ��� ������������. JSON ������������
���������������"
-"���."
-
-#, python-format
-msgid "Unable to login to iSCSI host target %(portal)s. Details: %(err)s"
-msgstr "iSCSI ��������� ������ %(portal)s��� ������������ ��� ������������.
������������: %(err)s"
-
-#, python-format
-msgid "Unable to login to iSCSI host %(host)s target %(target)s"
-msgstr "iSCSI host %(host)s ������ %(target)s��� ������������ ���
������������."
-
-#, python-format
-msgid "Unable to find ISO file %(filename)s"
-msgstr ""
-
-#, python-format
-msgid "The ISO file %(filename)s is not bootable"
-msgstr "ISO ������ %(filename)s���(���) ������ ������������ ������������."
-
-#, python-format
-msgid "The ISO file %(filename)s does not have a valid El Torito boot record"
-msgstr "ISO ������ %(filename)s��� ��������� El Torito ������ ������������
������������."
-
-#, python-format
-msgid "Invalid El Torito validation entry in ISO %(filename)s"
-msgstr ""
-"ISO %(filename)s��� ������������ ������ El Torito ��������� ������ ���������
������������."
-
-#, python-format
-msgid "Invalid El Torito boot indicator in ISO %(filename)s"
-msgstr "ISO %(filename)s��� ������������ ������ El Torito ������ ������������
������������."
-
-#, python-format
-msgid "Unexpected volume type for primary volume in ISO %(filename)s"
-msgstr "ISO %(filename)s������ ������ ��������� ��������� ������ ������
���������������."
-
-#, python-format
-msgid "Bad format while reading volume descriptor in ISO %(filename)s"
-msgstr ""
-"ISO %(filename)s������ ������ ������������������ ������ ������ ��������� ���������
������������������"
-"���."
-
-#, python-format
-msgid ""
-"The hypervisor doesn't have permission to use this ISO %(filename)s. "
-"Consider moving it under /var/lib/libvirt, or set the search permission to "
-"file access control lists for '%(user)s' user if possible, or add the
'%"
-"(user)s' to the ISO path group, or (not recommended) 'chmod -R o+x "
-"'path_to_iso'.Details: %(err)s"
-msgstr ""
-"��������������������� ��� ISO %(filename)s���(���) ��������� ���������
������������. ������ /var/"
-"lib/libvirt ��������� ������������������, (��������� ������) ������ ���������
'%(user)s' ���������"
-"��� ������ ��������� ������ ��������� ���������������, '%(user)s'���(���)
ISO ������ ��������� ������"
-"���������, 'chmod -R o+x 'path_to_iso'(������������ ������)���
������������������. ������������: "
-"%(err)s"
-
-msgid "An error occurred when probing image OS information."
-msgstr ""
-
-msgid "No OS information found in given image."
-msgstr ""
-
-#, python-format
-msgid "Unable to read image file %(filename)s"
-msgstr ""
-
-#, python-format
-msgid ""
-"Image file must be an existing file on system. %(filename)s is not a valid "
-"input."
-msgstr ""
-
-#, python-format
-msgid "Virtual machine %(name)s already exists"
-msgstr "������ ������ %(name)s���(���) ������ ���������������."
-
-#, python-format
-msgid "Virtual machine %(name)s does not exist"
-msgstr "������ ������ %(name)s���(���) ������������."
-
-#, python-format
-msgid ""
-"Unable to rename virtual machine %(name)s. The name %(new_name)s is already "
-"in use or the virtual machine is not powered off."
-msgstr ""
-
-#, python-format
-msgid "Unable to retrieve screenshot for stopped virtual machine %(name)s"
-msgstr "��������� ������ ������ %(name)s��� ������ ��������������� ��������� ���
������������."
-
-msgid "Remote ISO image is not supported by this server."
-msgstr "������ ISO ������������ ��� ������������ ������������ ������������."
-
-#, python-format
-msgid "Screenshot is not supported on virtual machine %(name)s"
-msgstr ""
-
-#, python-format
-msgid "Unable to create virtual machine %(name)s. Details: %(err)s"
-msgstr "������ ������ %(name)s���(���) ��������� ��� ������������. ������������:
%(err)s"
-
-#, python-format
-msgid "Unable to update virtual machine %(name)s. Details: %(err)s"
-msgstr "������ ������ %(name)s���(���) ��������� ��� ������������. ������������:
%(err)s"
-
-#, python-format
-msgid "Unable to retrieve virtual machine %(name)s. Details: %(err)s"
-msgstr "������ ������ %(name)s���(���) ��������� ��� ������������. ������������:
%(err)s"
-
-#, python-format
-msgid "Unable to connect to powered off virtual machine %(name)s."
-msgstr ""
-
-msgid "Virtual machine name must be a string without slashes (/)"
-msgstr ""
-
-#, python-format
-msgid "Invalid template URI %(value)s specified for virtual machine"
-msgstr ""
-
-#, python-format
-msgid "Invalid storage pool URI %(value)s specified for virtual machine"
-msgstr ""
-
-msgid "Supported virtual machine graphics are Spice or VNC"
-msgstr ""
-
-msgid "Graphics address to listen on must be IPv4 or IPv6"
-msgstr "������ ������ ��������� ��������� IPv4 ������ IPv6������ ���������."
-
-msgid "Specify a template to create a virtual machine from"
-msgstr "������ ��������� ������������ ������ ���������������
������������������."
-
-#, python-format
-msgid "Unable to start virtual machine %(name)s. Details: %(err)s"
-msgstr "������ ������ %(name)s���(���) ��������� ��� ������������. ������������:
%(err)s"
-
-#, python-format
-msgid "Unable to power off virtual machine %(name)s. Details: %(err)s"
-msgstr "������ ������ %(name)s���(���) ��������� ��� ������������. ������������:
%(err)s"
-
-#, python-format
-msgid "Unable to delete virtual machine %(name)s. Details: %(err)s"
-msgstr "������ ������ %(name)s���(���) ��������� ��� ������������. ������������:
%(err)s"
-
-#, python-format
-msgid "Unable to reset virtual machine %(name)s. Details: %(err)s"
-msgstr "������ ������ %(name)s��� ��������� ������ ��� ������������. ������������:
%(err)s"
-
-msgid "User name list must be an array"
-msgstr ""
-
-msgid "User name must be a string"
-msgstr "������������ ��������� ������������������ ���������."
-
-msgid "Group name list must be an array"
-msgstr ""
-
-msgid "Group name must be a string"
-msgstr "������������ ��������� ������������������ ���������."
-
-#, python-format
-msgid "User(s) '%(users)s' do not exist"
-msgstr "'%(users)s' ������������ ������������."
-
-#, python-format
-msgid "Group(s) '%(groups)s' do not exist"
-msgstr "'%(groups)s' ������������ ������������."
-
-#, python-format
-msgid "Unable to shutdown virtual machine %(name)s. Details: %(err)s"
-msgstr "������ ������ %(name)s���(���) ��������� ��� ������������. ������������:
%(err)s"
-
-#, python-format
-msgid ""
-"Unable to get access metadata of virtual machine %(name)s. Details: %(err)s"
-msgstr "������ ������ %(name)s���(���) ��������� ��� ������������. ������������:
%(err)s"
-
-msgid "The guest console password must be a string."
-msgstr ""
-
-msgid "The life time for the guest console password must be a number."
-msgstr ""
-
-#, python-format
-msgid "Virtual machine '%(name)s' must be stopped before cloning it."
-msgstr ""
-
-#, python-format
-msgid "Insufficient disk space to clone virtual machine '%(name)s'"
-msgstr ""
-
-#, python-format
-msgid "Unable to clone VM '%(name)s'. Details: %(err)s"
-msgstr ""
-
-#, python-format
-msgid "Invalid operation for non-persistent virtual machine %(name)s"
-msgstr ""
-
-#, python-format
-msgid "Cannot suspend VM '%(name)s' because it is not running."
-msgstr ""
-
-#, python-format
-msgid "Unable to suspend VM '%(name)s'. Details: %(err)s"
-msgstr ""
-
-#, python-format
-msgid "Cannot resume VM '%(name)s' because it is not paused."
-msgstr ""
-
-#, python-format
-msgid "Unable to resume VM '%(name)s'. Details: %(err)s"
-msgstr ""
-
-msgid "Memory assigned is higher then the maximum allowed in the host."
-msgstr ""
-
-#, python-format
-msgid ""
-"VM '%(name)s' does not support live memory update. Update the memory with
"
-"the machine offline to enable this feature."
-msgstr ""
-
-msgid "Only increase memory is allowed in active VMs"
-msgstr ""
-
-msgid ""
-"For live memory update, new memory value must be equal old memory value plus
"
-"multiples of 1024 Mib"
-msgstr ""
-
-msgid "There are not enough free slots of 1024 Mib in the guest."
-msgstr ""
-
-msgid ""
-"Host's libvirt version does not support memory devices. Libvirt must be >=
"
-"1.2.14"
-msgstr ""
-
-#, python-format
-msgid "Error attaching memory device. Details: %(error)s"
-msgstr ""
-
-#, python-format
-msgid ""
-"VM %(vmid)s does not contain directly assigned host device %(dev_name)s."
-msgstr ""
-
-#, python-format
-msgid "The host device %(dev_name)s is not allowed to directly assign to VM."
-msgstr ""
-
-msgid ""
-"No IOMMU groups found. Host PCI pass through needs IOMMU group to function "
-"correctly. Please enable Intel VT-d or AMD IOMMU in your BIOS, then verify "
-"the Kernel is compiled with IOMMU support. For Intel CPU, add intel_iommu=on
"
-"to your Kernel parameter in /boot/grub2/grub.conf. For AMD CPU, add iommu=pt
"
-"iommu=1."
-msgstr ""
-
-msgid "\"name\" should be a device name string"
-msgstr ""
-
-#, python-format
-msgid ""
-"The device %(name)s is probably in use by the host. Unable to attach it to "
-"the guest."
-msgstr ""
-
-#, python-format
-msgid "Interface %(iface)s does not exist in virtual machine %(name)s"
-msgstr "������ ������ %(name)s��� %(iface)s ������������������ ������������."
-
-#, python-format
-msgid ""
-"Network %(network)s specified for virtual machine %(name)s does not exist"
-msgstr "������ ������ %(name)s��� ������ ��������� %(network)s ���������������
������������."
-
-msgid "Supported virtual machine interfaces type is only network"
-msgstr "������������ ������ ������ ��������������� ���������
������������������������."
-
-msgid "Network name for virtual machine interface must be a string"
-msgstr "������ ������ ������������������ ������������ ��������� ������������������
���������."
-
-msgid "Invalid network model card specified for virtual machine interface"
-msgstr ""
-"������ ������ ������������������ ������ ������������ ������ ������������ ������
��������� ������������������"
-"���."
-
-msgid "Specify type and network to add a new virtual machine interface"
-msgstr "��� ������ ������ ������������������ ��������� ������ ��� ���������������
������������������."
-
-msgid "MAC Address must respect this format FF:FF:FF:FF:FF:FF"
-msgstr ""
-
-#, python-format
-msgid "MAC Address %(mac)s already exists in virtual machine %(name)s"
-msgstr ""
-
-msgid "Invalid MAC Address"
-msgstr ""
-
-msgid "Cannot change MAC address of a running virtual machine"
-msgstr ""
-
-#, python-format
-msgid "Template %(name)s already exists"
-msgstr "������������ %(name)s���(���) ������ ���������������."
-
-#, python-format
-msgid ""
-"Network '%(network)s' specified for template %(template)s does not
exist"
-msgstr "������������ %(template)s��� ������ ��������� '%(network)s'
��������������� ������������."
-
-#, python-format
-msgid ""
-"Storage pool %(pool)s specified for template %(template)s does not exist"
-msgstr ""
-"������������ %(template)s��� ������ ��������� ������������ ��� %(pool)s���(���)
������������."
-
-#, python-format
-msgid "Storage pool %(pool)s specified for template %(template)s is not
active"
-msgstr ""
-"������������ %(template)s��� ������ ��������� ������������ ��� %(pool)s���(���)
��������� ���������"
-"���."
-
-#, python-format
-msgid "Invalid parameter '%(param)s' specified for CDROM."
-msgstr "CDROM��� ������ ������������ ������ ������������ '%(param)s'���(���)
���������������������."
-
-#, python-format
-msgid "Network %(network)s specified for template %(template)s is not active"
-msgstr ""
-"������������ %(template)s��� ������ ��������� %(network)s ��������������� ���������
������������."
-
-msgid "Template name must be a string"
-msgstr "������������ ��������� ������������������ ���������."
-
-msgid "Template icon must be a path to the image"
-msgstr "������������ ������������ ������������ ������������ ���������."
-
-msgid "Template distribution must be a string"
-msgstr "������������ ��������� ������������������ ���������."
-
-msgid "Template distribution version must be a string"
-msgstr "������������ ������ ��������� ������������������ ���������."
-
-msgid "The number of CPUs must be an integer greater than 0"
-msgstr "CPU ������ ������������ ���������."
-
-msgid "Amount of memory (MB) must be an integer greater than 512"
-msgstr "��������� ������(MB)��� 512������ ��� ������������ ���������."
-
-msgid "Template CDROM must be a local or remote ISO file"
-msgstr "������������ CDROM��� ������ ������ ������ ISO ���������������
���������."
-
-#, python-format
-msgid "Invalid storage pool URI %(value)s specified for template"
-msgstr ""
-"��������������� ������ ������������ ������ ������������ ��� URI %(value)s���(���)
���������������������."
-
-msgid "Specify an ISO image as CDROM or a base image to create a template"
-msgstr "��������������� ��������������� ISO ������������ CDROM������
������������������."
-
-msgid "All networks for the template must be specified in a list."
-msgstr "��������������� ������ ��������������� ��������� ���������������
���������."
-
-msgid "Specify a volume to a template when storage pool is iSCSI or SCSI"
-msgstr ""
-
-#, python-format
-msgid "The volume %(volume)s is not in storage pool %(pool)s"
-msgstr ""
-
-#, python-format
-msgid "Unable to create template due error: %(err)s"
-msgstr "������ ��������� ��������������� ��������� ��� ������: %(err)s"
-
-#, python-format
-msgid "Unable to delete template due error: %(err)s"
-msgstr "������ ��������� ��������������� ��������� ��� ������: %(err)s"
-
-msgid "Disk size must be an integer greater than 1GB."
-msgstr ""
-
-msgid "Template base image must be a valid local image file"
-msgstr "������������ CDROM��� ������ ������ ������ ISO ���������������
���������."
-
-#, python-format
-msgid "Cannot identify base image %(path)s format"
-msgstr ""
-
-msgid ""
-"When specifying CPU topology, VCPUs must be a product of sockets, cores, and
"
-"threads."
-msgstr ""
-
-msgid ""
-"When specifying CPU topology, each element must be an integer greater than "
-"zero."
-msgstr ""
-
-msgid ""
-"Invalid disk image format. Valid formats: bochs, cloop, cow, dmg, qcow, "
-"qcow2, qed, raw, vmdk, vpc."
-msgstr ""
-
-#, python-format
-msgid "Storage pool %(name)s already exists"
-msgstr "������������ ��� %(name)s���(���) ������ ���������������."
-
-#, python-format
-msgid "Storage pool %(name)s does not exist"
-msgstr "������������ ��� %(name)s���(���) ������������."
-
-#, python-format
-msgid "Specify %(item)s in order to create the storage pool %(name)s"
-msgstr "������������ ��� %(name)s���(���) ��������������� %(item)s���(���)
������������������."
-
-#, python-format
-msgid "Unable to delete active storage pool %(name)s"
-msgstr "������ ������������ ��� %(name)s���(���) ��������� ��� ������������."
-
-#, python-format
-msgid "Unable to list storage pools. Details: %(err)s"
-msgstr "������������ ������ ��������� ��� ������������. ������������: %(err)s"
-
-#, python-format
-msgid "Unable to create storage pool %(name)s. Details: %(err)s"
-msgstr "������������ ��� %(name)s���(���) ��������� ��� ������������. ������������:
%(err)s"
-
-#, python-format
-msgid ""
-"Unable to get number of storage volumes in storage pool %(name)s. Details: %"
-"(err)s"
-msgstr ""
-"������������ ��� %(name)s��� ������ ������������ ��������� ������ ��������� ���
������������. ���������"
-"���: %(err)s"
-
-#, python-format
-msgid "Unable to activate storage pool %(name)s. Details: %(err)s"
-msgstr "������������ ��� %(name)s���(���) ������������ ��� ������������.
������������: %(err)s"
-
-#, python-format
-msgid "Unable to deactivate storage pool %(name)s. Details: %(err)s"
-msgstr "������������ ��� %(name)s���(���) ��������������� ��� ������������.
������������: %(err)s"
-
-#, python-format
-msgid "Unable to delete storage pool %(name)s. Details: %(err)s"
-msgstr "������������ ��� %(name)s���(���) ��������� ��� ������������. ������������:
%(err)s"
-
-#, python-format
-msgid ""
-"Unable to create NFS Pool as export path %(path)s may block during mount"
-msgstr ""
-"������������ ������ %(path)s���(���) ��������� ������ ��������� ��� ������������
NFS ������ ��������� "
-"��� ������������."
-
-#, python-format
-msgid "Unable to create NFS Pool as export path %(path)s mount failed"
-msgstr ""
-"������������ ������ %(path)s ������������ ������������������ NFS ������ ���������
��� ������������."
-
-#, python-format
-msgid "Unsupported storage pool type: %(type)s"
-msgstr "������������ ������ ������������ ��� ������: %(type)s"
-
-#, python-format
-msgid "Error while retrieving storage pool XML to %(pool)s"
-msgstr ""
-
-msgid "Storage pool name must be a string without slashes (/)"
-msgstr ""
-
-msgid ""
-"Supported storage pool types are dir, netfs, logical, iscsi, isci and
kimchi-"
-"iso"
-msgstr ""
-
-msgid "Storage pool path must be a string"
-msgstr "������������ ��� ��������� ������������������ ���������."
-
-msgid "Storage pool host must be a IP or hostname"
-msgstr "������������ ��� ������������ IP ������ ��������� ���������������
���������."
-
-msgid "Storage pool device must be the absolute path to the block device"
-msgstr ""
-
-msgid "Storage pool devices parameter must be a list"
-msgstr "������������ ��� ��������� ��������������� ���������."
-
-msgid "Target IQN of an iSCSI pool must be a string"
-msgstr "iSCSI ������ ������ IQN��� ������������������ ���������."
-
-msgid "Port of a remote storage server must be an integer between 1 and 65535"
-msgstr "������ ������������ ��������� ��������� 1��� 65535 ��������� ������������
���������."
-
-msgid "iSCSI target username must be a string"
-msgstr ""
-
-msgid "iSCSI target password must be a string"
-msgstr ""
-
-msgid "Specify name and type to create a storage pool"
-msgstr "������������ ������ ��������������� ������ ��� ���������
������������������."
-
-#, python-format
-msgid ""
-"%(disk)s is not a valid disk/partition. Could not add it to the pool %(pool)"
-"s."
-msgstr ""
-"%(disk)s���(���) ��������� ���������/������������ ������������. ������ %(pool)s
������ ��������� ��� "
-"������������."
-
-#, python-format
-msgid "Unable to extend logical pool %(pool)s. Details: %(err)s"
-msgstr ""
-
-msgid "The parameter disks only can be updated for logical storage pool."
-msgstr "������ ������������ ������ ������������ ������������ ��������������� ���
������������."
-
-msgid "The SCSI host adapter name must be a string."
-msgstr "SCSI ��������� ��������� ��������� ������������������ ���������."
-
-msgid "The storage pool kimchi_isos is reserved for internal use"
-msgstr "������������ ��� kimchi_isos��� ������ ���������
���������������������."
-
-#, python-format
-msgid ""
-"Unable to activate NFS storage pool %(name)s. NFS server %(server)s is "
-"unreachable."
-msgstr ""
-"NFS ������������ ��� %(name)s���(���) ������������ ��� ������������. NFS ������
%(server)s��� ���"
-"������ ��� ������������."
-
-#, python-format
-msgid ""
-"Unable to deactivate NFS storage pool %(name)s. NFS server %(server)s is "
-"unreachable."
-msgstr ""
-"NFS ������������ ��� %(name)s���(���) ��������������� ��� ������������. NFS ������
%(server)s��� "
-"��������� ��� ������������."
-
-#, python-format
-msgid ""
-"Unable to deactivate pool %(name)s as it is associated with some templates"
-msgstr ""
-"������ ��������������� ������������ ������������ %(name)s ������ ���������������
��� ������������."
-
-#, python-format
-msgid "Unable to delete pool %(name)s as it is associated with some templates"
-msgstr "������ ��������������� ������������ ������������ %(name)s ������ ���������
��� ������������."
-
-#, python-format
-msgid ""
-"A volume group named '%(name)s' already exists. Please, choose another name
"
-"to create the logical pool."
-msgstr ""
-"��������� '%(name)s'��� ������ ��������� ������ ���������������. ������
������ ��������������� ������ ���"
-"������ ������������������."
-
-#, python-format
-msgid "Unable to update database with deep scan information due error:
%(err)s"
-msgstr ""
-"������ ��������� ��������� ������ ��������� ��������������������� ���������������
��� ������: %(err)s"
-
-#, python-format
-msgid "Storage volume %(name)s already exists"
-msgstr "������������ ������ %(name)s���(���) ������ ���������������."
-
-#, python-format
-msgid "Storage volume %(name)s does not exist in storage pool %(pool)s"
-msgstr "������������ ������ %(name)s���(���) ������������ ��� %(pool)s���
������������."
-
-#, python-format
-msgid ""
-"Unable to create storage volume %(volume)s because storage pool %(pool)s is "
-"not active"
-msgstr ""
-
-#, python-format
-msgid "Specify %(item)s in order to create storage volume %(volume)s"
-msgstr "������������ ������ %(volume)s���(���) ��������������� %(item)s���(���)
������������������."
-
-#, python-format
-msgid ""
-"Unable to list storage volumes because storage pool %(pool)s is not active"
-msgstr ""
-"������������ ��� %(pool)s���(���) ��������� ������������ ������������ ���������
��������� ��� ���������"
-"���."
-
-#, python-format
-msgid ""
-"Unable to create storage volume %(name)s in storage pool %(pool)s. Details:
%"
-"(err)s"
-msgstr ""
-"������������ ������ %(name)s���(���) ������������ ��� %(pool)s��� ��������� ���
������������. ������"
-"������: %(err)s"
-
-#, python-format
-msgid ""
-"Unable to list storage volumes in storage pool %(pool)s. Details: %(err)s"
-msgstr ""
-"������������ ��� %(pool)s��� ������������ ��������� ��������� ��� ������������.
������������: %(err)s"
-
-#, python-format
-msgid "Unable to wipe storage volumes %(name)s. Details: %(err)s"
-msgstr "������������ ��� %(name)s���(���) ��������� ��� ������������. ������������:
%(err)s"
-
-#, python-format
-msgid "Unable to delete storage volume %(name)s. Details: %(err)s"
-msgstr "������������ ������ %(name)s���(���) ��������� ��� ������������.
������������: %(err)s"
-
-#, python-format
-msgid "Unable to resize storage volume %(name)s. Details: %(err)s"
-msgstr "������������ ������ %(name)s��� ��������� ��������� ��� ������������.
������������: %(err)s"
-
-#, python-format
-msgid "Storage type %(type)s does not support volume create and delete"
-msgstr "������������ ������ %(type)s���(���) ������ ������ ��� ���������
������������ ������������."
-
-msgid "Storage volume name must be a string"
-msgstr "������������ ������ ��������� ������������������ ���������."
-
-msgid "Storage volume allocation must be an integer number"
-msgstr "������������ ������ ��������� ������������ ���������."
-
-msgid ""
-"Storage volume format not supported. Valid formats: bochs, cloop, cow, dmg, "
-"qcow, qcow2, qed, raw, vmdk, vpc."
-msgstr ""
-
-msgid "Storage volume requires a volume name"
-msgstr "������������ ��������� ������ ��������� ���������������."
-
-#, python-format
-msgid ""
-"Unable to update database with storage volume information due error: %(err)s"
-msgstr ""
-"������ ��������� ������������ ������ ��������� ���������������������
��������������� ��� ������: %(err)s"
-
-#, python-format
-msgid "Only one of parameter %(param)s can be specified"
-msgstr ""
-
-#, python-format
-msgid "Create volume from %(param)s is not supported"
-msgstr ""
-
-msgid "Storage volume capacity must be an integer number."
-msgstr ""
-
-msgid "Storage volume URL must be http://, https://, ftp:// or ftps://."
-msgstr ""
-
-#, python-format
-msgid "Unable to access file %(url)s. Please, check it."
-msgstr ""
-
-#, python-format
-msgid ""
-"Unable to clone storage volume '%(name)s' in pool '%(pool)s'.
Details: %(err)"
-"s"
-msgstr ""
-
-msgid "Specify chunk data and its size to upload a file."
-msgstr ""
-
-msgid "In order to upload a storage volume, specify the 'upload'
parameter."
-msgstr ""
-
-msgid ""
-"Unable to upload chunk data as it does not match with requested chunk size."
-msgstr ""
-
-#, python-format
-msgid "The storage volume %(vol)s is not under an upload process."
-msgstr ""
-
-msgid "The upload chunk data will exceed the storage volume size."
-msgstr ""
-
-#, python-format
-msgid "Unable to upload chunk data to storage volume. Details: %(err)s."
-msgstr ""
-
-#, python-format
-msgid "Interface %(name)s does not exist"
-msgstr "��������������� %(name)s���(���) ������������."
-
-#, python-format
-msgid "Network %(name)s already exists"
-msgstr "������������ %(name)s���(���) ������ ���������������."
-
-#, python-format
-msgid "Network %(name)s does not exist"
-msgstr "������������ %(name)s���(���) ������������."
-
-#, python-format
-msgid "Subnet %(subnet)s specified for network %(network)s is not valid."
-msgstr ""
-"������������ %(network)s��� ������ ��������� ��������� %(subnet)s���(���)
������������ ������������."
-
-#, python-format
-msgid "Specify a network interface to create bridged network %(name)s"
-msgstr ""
-"������������ ������������ %(name)s���(���) ��������� ������������
������������������ ������������������."
-
-#, python-format
-msgid "Unable to delete active network %(name)s"
-msgstr "������ ������������ %(name)s���(���) ��������� ��� ������������."
-
-#, python-format
-msgid "Interface %(iface)s specified for network %(network)s is already in
use"
-msgstr ""
-"������������ %(network)s��� ������ ��������� ��������������� %(iface)s���(���)
������ ������ ������"
-"������."
-
-msgid "Interface should be bare NIC, bonding or bridge device."
-msgstr "������������������ ������ NIC, ������ ������ ��������� ������������
���������."
-
-#, python-format
-msgid "Unable to create network %(name)s. Details: %(err)s"
-msgstr "������������ %(name)s���(���) ��������� ��� ������������. ������������:
%(err)s"
-
-#, python-format
-msgid "Unable to find a free IP address for network '%(name)s'"
-msgstr "������������ '%(name)s'��� ������ ������ IP ��������� ������ ���
������������."
-
-#, python-format
-msgid "The interface %(iface)s already exists."
-msgstr ""
-
-msgid "Network name must be a string without slashes (/) or quotes (\")"
-msgstr ""
-
-msgid "Supported network types are isolated, NAT and bridge"
-msgstr "������������ ������������ ��������� ������, NAT ���
������������������."
-
-msgid "Network subnet must be a string with IP address and prefix or netmask"
-msgstr ""
-"������������ ������������ IP ������ ��� ��������� ������ ��������������� ������
������������������ ���������."
-
-msgid "Network interface must be a string"
-msgstr "������������ ������������������ ������������������ ���������."
-
-msgid "Network VLAN ID must be an integer between 1 and 4094"
-msgstr "������������ VLAN ID��� 1��� 4094 ��������� ������������ ���������."
-
-msgid "Specify name and type to create a Network"
-msgstr "��������������� ��������������� ������ ��� ���������
������������������."
-
-#, python-format
-msgid ""
-"Unable to delete network %(name)s. There are some virtual machines %(vms)s "
-"and/or templates linked to this network."
-msgstr ""
-
-#, python-format
-msgid ""
-"Unable to deactivate network %(name)s. There are some virtual machines
%(vms)"
-"s and/or templates linked to this network."
-msgstr ""
-
-#, python-format
-msgid "Bridge device %(name)s can not be the trunk device of a VLAN."
-msgstr "��������� ������ %(name)s���(���) VLAN��� ��������� ��������� ��� ���
������������."
-
-#, python-format
-msgid "Failed to activate interface %(iface)s: %(err)s."
-msgstr "%(iface)s ������������������ ��������������� ������: %(err)s."
-
-#, python-format
-msgid ""
-"Failed to activate interface %(iface)s. Please check the physical link "
-"status."
-msgstr ""
-"%(iface)s ������������������ ��������������� ���������������. ��������� ������
��������� ���������������"
-"���."
-
-#, python-format
-msgid "Failed to start network %(name)s. Details: %(err)s"
-msgstr ""
-
-#, python-format
-msgid "Debug report %(name)s does not exist"
-msgstr "��������� ��������� %(name)s���(���) ������������."
-
-msgid "Debug report tool not found in system"
-msgstr "��������� ��������� ��������� ������������ ������������."
-
-#, python-format
-msgid "Unable to create debug report %(name)s. Details: %(err)s."
-msgstr "��������� ��������� %(name)s���(���) ��������� ��� ������������.
������������: %(err)s"
-
-#, python-format
-msgid "Can not find any debug report with the given name %(name)s"
-msgstr ""
-
-#, python-format
-msgid "Unable to generate debug report %(name)s. Details: %(err)s"
-msgstr "��������� ��������� %(name)s���(���) ��������� ��� ������������.
������������: %(err)s"
-
-msgid "You should give a name for the debug report file."
-msgstr ""
-
-msgid ""
-"Debug report name must be a string. Only letters, digits, underscore ('_')
"
-"and hyphen ('-') are allowed."
-msgstr ""
-
-#, python-format
-msgid ""
-"The debug report with specified name \"%(name)s\" already exists. Please
use "
-"another one."
-msgstr ""
-"��������� '%(name)s'��� ������ ��������� ������ ���������������. ������
������ ��������������� ������ ���"
-"������ ������������������."
-
-#, python-format
-msgid "Storage server %(server)s was not used by Kimchi"
-msgstr "������������ ������ %(server)s���(���) Kimchi������ ������������
���������������."
-
-#, python-format
-msgid "Distro '%(name)s' does not exist"
-msgstr "Distro '%(name)s'���(���) ������������."
-
-#, python-format
-msgid "Partition %(name)s does not exist in the host"
-msgstr "��������� %(name)s���(���) ������������ ������������."
-
-msgid "Unable to shutdown host machine as there are running virtual machines"
-msgstr "������ ��������� ������ ������ ��������� ��������� ��������� ���
������������."
-
-msgid "Unable to reboot host machine as there are running virtual machines"
-msgstr "������ ��������� ������ ������ ��������� ��������� ������ ��������� ���
������������."
-
-#, python-format
-msgid "Node device '%(name)s' not found"
-msgstr "������ ������ '%(name)s'���(���) ������������."
-
-msgid "Conflicting flag filters specified."
-msgstr ""
-
-msgid "No packages marked for update"
-msgstr "������������ ��������� ������������ ������������."
-
-#, python-format
-msgid "Package %(name)s is not marked to be updated."
-msgstr "��������� %(name)s���(���) ��������������������� ������������
���������������."
-
-#, python-format
-msgid "Error while getting packages marked to be updated. Details: %(err)s"
-msgstr ""
-"��������������������� ��������� ������������ ������������ ������ ���������
������������������. ������������: %"
-"(err)s"
-
-msgid "There is no compatible package manager for this system."
-msgstr "��� ������������ ������ ������ ��������� ��������� ������������
������������."
-
-#, python-format
-msgid "Invalid URI %(uri)s"
-msgstr "������������ ������ URI %(uri)s"
-
-msgid "Unable to choose a virtual machine name"
-msgstr ""
-
-msgid "Invalid storage type. Types supported: 'cdrom', 'disk'"
-msgstr "������������ ������ ������������ ���������������. ������������ ������:
'cdrom'"
-
-#, python-format
-msgid "The path '%(value)s' is not a valid local/remote path for the
device"
-msgstr ""
-
-msgid "Only CDROM path can be update."
-msgstr ""
-
-#, python-format
-msgid ""
-"The storage device %(dev_name)s does not exist in the virtual machine %"
-"(vm_name)s"
-msgstr ""
-
-#, python-format
-msgid "Error while creating new storage device: %(error)s"
-msgstr "��� ������������ ��������� ������������ ������ ������ ������:
%(error)s"
-
-#, python-format
-msgid "Error while updating storage device: %(error)s"
-msgstr "������������ ��������� ������������������ ������ ������ ������:
%(error)s"
-
-#, python-format
-msgid "Error while removing storage device: %(error)s"
-msgstr "������������ ��������� ������������ ������ ������ ������: %(error)s"
-
-msgid "Do not support IDE device hot plug"
-msgstr ""
-
-msgid ""
-"Specify type and path or type and pool/volume to add a new virtual machine "
-"disk"
-msgstr "��� ������ ������ ������������ ��������� ������ ��� ���������
������������������."
-
-msgid "Specify path to update virtual machine disk"
-msgstr "������ ������ ������������ ��������������� ���������
������������������."
-
-#, python-format
-msgid "Controller type %(type)s limitation of %(limit)s devices reached"
-msgstr ""
-
-#, python-format
-msgid "Cannot retrieve disk path information for given pool/volume: %(error)s"
-msgstr ""
-
-msgid "Volume already in use by other virtual machine."
-msgstr ""
-
-msgid ""
-"Only one of path or pool/volume can be specified to add a new virtual "
-"machine disk"
-msgstr "��� ������ ������ ������������ ��������� ������ ��� ���������
������������������."
-
-#, python-format
-msgid ""
-"Volume chosen with format %(format)s does not fit in the storage type
%(type)"
-"s"
-msgstr ""
-
-msgid "YUM Repository ID must be one word only string."
-msgstr "YUM ��������� ID��� ������ ��������� ������������������ ���������."
-
-msgid "Repository URL must be an http://, ftp:// or file:// URL."
-msgstr "��������� URL��� http://, ftp:// ������ file:// URL���������
���������."
-
-msgid ""
-"Repository configuration is a dictionary with specific values according to "
-"repository type."
-msgstr "��������� ��������� ��������� ��������� ������ ������ ������ ������
���������������."
-
-msgid "Distribution to DEB repository must be a string"
-msgstr "DEB ������������ ������ ��������� ������������������ ���������."
-
-msgid "Components to DEB repository must be listed in a array"
-msgstr "DEB ������������ ������ ��������������� ��������� ���������������
���������."
-
-msgid "Components to DEB repository must be a string"
-msgstr "DEB ������������ ������ ��������������� ������������������ ���������."
-
-msgid "Mirror list to repository must be a string"
-msgstr ""
-
-msgid "YUM Repository name must be string."
-msgstr "YUM ��������� ��������� ������������������ ���������."
-
-msgid "GPG check must be a boolean value."
-msgstr "GPG ��������� ������ ������������ ���������."
-
-msgid "GPG key must be a URL pointing to the ASCII-armored file."
-msgstr "GPG ������ ASCII ������ ��������� ������������ URL���������
���������."
-
-#, python-format
-msgid "Could not update repository %(repo_id)s."
-msgstr "%(repo_id)s ������������ ��������������� ��� ������������."
-
-#, python-format
-msgid "Repository %(repo_id)s does not exist."
-msgstr "%(repo_id)s ������������ ������������."
-
-msgid ""
-"Specify repository base URL, mirror list or metalink in order to create or "
-"update a YUM repository."
-msgstr ""
-
-msgid "Repository management tool was not recognized for your system."
-msgstr "������ ������������ ������ ��������� ������ ��������� ������������
���������������."
-
-#, python-format
-msgid "Repository %(repo_id)s is already enabled."
-msgstr "%(repo_id)s ������������ ������ ������������ ������������
������������."
-
-#, python-format
-msgid "Repository %(repo_id)s is already disabled."
-msgstr "%(repo_id)s ������������ ������ ������ ������������ ������������
������������."
-
-#, python-format
-msgid "Could not remove repository %(repo_id)s."
-msgstr "%(repo_id)s ������������ ��������� ��� ������������."
-
-#, python-format
-msgid "Could not write repository configuration file %(repo_file)s"
-msgstr "��������� ������ ������ %(repo_file)s���(���) ��������� ���
������������."
-
-msgid "Specify repository distribution in order to create a DEB repository."
-msgstr "DEB ������������ ��������������� ��������� ���������
������������������."
-
-#, python-format
-msgid "Could not enable repository %(repo_id)s."
-msgstr "%(repo_id)s ������������ ������������ ��������� ��� ������������."
-
-#, python-format
-msgid "Could not disable repository %(repo_id)s."
-msgstr "%(repo_id)s ������������ ������ ������������ ��������� ���
������������."
-
-msgid "YUM Repository ID already exists"
-msgstr "YUM ��������� ID��� ������ ���������������."
-
-msgid "YUM Repository name must be a string"
-msgstr "YUM ��������� ��������� ������������������ ���������."
-
-#, python-format
-msgid "Unable to list repositories. Details: '%(err)s'"
-msgstr "������������ ��������� ��� ������������. ������������:
'%(err)s'"
-
-#, python-format
-msgid "Unable to retrieve repository information. Details: '%(err)s'"
-msgstr "��������� ��������� ��������� ��� ������������. ������������:
'%(err)s'"
-
-#, python-format
-msgid "Unable to add repository. Details: '%(err)s'"
-msgstr "������������ ��������� ��� ������������. ������������:
'%(err)s'"
-
-#, python-format
-msgid "Unable to remove repository. Details: '%(err)s'"
-msgstr "������������ ��������� ��� ������������. ������������:
'%(err)s'"
-
-#, python-format
-msgid ""
-"Configuration items: '%(items)s' are not supported by repository
manager"
-msgstr ""
-
-msgid "Repository metalink must be an http://, ftp:// or file:// URL."
-msgstr ""
-
-msgid "Cannot specify mirrorlist and metalink at the same time."
-msgstr ""
-
-#, python-format
-msgid ""
-"Virtual machine '%(vm)s' must be stopped before creating a snapshot of
it."
-msgstr ""
-
-#, python-format
-msgid ""
-"Unable to create snapshot '%(name)s' on virtual machine '%(vm)s'.
Details: %"
-"(err)s"
-msgstr ""
-
-#, python-format
-msgid "Snapshot '%(name)s' does not exist on virtual machine
'%(vm)s'."
-msgstr ""
-
-#, python-format
-msgid ""
-"Unable to retrieve snapshot '%(name)s' on virtual machine '%(vm)s'.
Details: "
-"%(err)s"
-msgstr ""
-
-#, python-format
-msgid "Unable to list snapshots on virtual machine '%(vm)s'. Details:
%(err)s"
-msgstr ""
-
-#, python-format
-msgid ""
-"Unable to delete snapshot '%(name)s' on virtual machine '%(vm)s'.
Details: %"
-"(err)s"
-msgstr ""
-
-#, python-format
-msgid ""
-"Unable to retrieve current snapshot of virtual machine '%(vm)s'. Details:
%"
-"(err)s"
-msgstr ""
-
-#, python-format
-msgid ""
-"Unable to revert virtual machine '%(vm)s' to snapshot '%(name)s'.
Details: %"
-"(err)s"
-msgstr ""
-
-#, python-format
-msgid ""
-"Unable to create snapshot of virtual machine '%(vm)s' because it contains a
"
-"disk with format '%(format)s'; only 'qcow2' is supported."
-msgstr ""
-
-msgid "The number of vCPUs is too large for this system."
-msgstr ""
-
-msgid "Invalid vCPU/topology combination."
-msgstr ""
-
-msgid "This host (or current configuration) does not allow CPU topology."
-msgstr ""
-
-msgid "ERROR CODE"
-msgstr "������ ������"
-
-msgid "REASON"
-msgstr "������"
-
-msgid "STACK"
-msgstr "������"
-
-msgid "Go to Homepage"
-msgstr "��� ������������ ������"
-
-msgid "Create a New Virtual Machine"
-msgstr "��� ������ ������ ������"
-
-msgid "Virtual Machine Name"
-msgstr "������ ������ ������"
-
-msgid ""
-"The name used to identify the virtual machine. If omitted, a name will be "
-"chosen based on the template used."
-msgstr ""
-"������ ��������� ������������ ��� ������������ ���������������. ������������
��������� ��������� ������������"
-"��� ������������ ���������������."
-
-msgid "Template"
-msgstr "������������"
-
-msgid "Please create a template first."
-msgstr "��������������� ������ ������������������."
-
-msgid "Create a Template"
-msgstr "������������ ������"
-
-msgid "Please choose a template."
-msgstr "��������������� ������������������."
-
-msgid "OS"
-msgstr "OS"
-
-msgid "OS Version"
-msgstr "OS ������"
-
-msgid "CPUS"
-msgstr "CPUS"
-
-msgid "Memory"
-msgstr "���������"
-
-msgid "Create"
-msgstr "������"
-
-msgid "Creating..."
-msgstr ""
-
-msgid "Cancel"
-msgstr "������"
-
-msgid "Edit Guest"
-msgstr "��������� ������"
-
-msgid "General"
-msgstr "������"
-
-msgid "Storage"
-msgstr "������������"
-
-msgid "Interface"
-msgstr "���������������"
-
-msgid "Permission"
-msgstr "������"
-
-msgid "Host PCI Device"
-msgstr ""
-
-msgid "Snapshot"
-msgstr ""
-
-msgid "Name"
-msgstr "������"
-
-msgid "CPUs"
-msgstr "CPU"
-
-msgid "Memory (MB)"
-msgstr "���������"
-
-msgid "Icon"
-msgstr "���������"
-
-msgid "Device"
-msgstr "������ ������"
-
-msgid "Path"
-msgstr "NFS ������"
-
-msgid "Network"
-msgstr "������������"
-
-msgid "Type"
-msgstr "������"
-
-msgid "MAC Address"
-msgstr ""
-
-msgid "Available system users and groups"
-msgstr ""
-
-msgid "Selected system users and groups"
-msgstr ""
-
-msgid "User"
-msgstr ""
-
-msgid "All"
-msgstr "������"
-
-msgid "To Add"
-msgstr ""
-
-msgid "Added"
-msgstr ""
-
-msgid "filter"
-msgstr ""
-
-msgid "Product"
-msgstr ""
-
-msgid "Vendor"
-msgstr "������������"
-
-msgid "Created"
-msgstr ""
-
-msgid "Save"
-msgstr "������"
-
-msgid "Replace"
-msgstr "������"
-
-msgid "Detach"
-msgstr "������"
-
-msgid "revert"
-msgstr ""
-
-msgid "Start"
-msgstr "������"
-
-msgid "Reset"
-msgstr "������ ������"
-
-msgid "Pause"
-msgstr ""
-
-msgid "Resume"
-msgstr ""
-
-msgid "Power Off"
-msgstr ""
-
-msgid "Actions"
-msgstr "������"
-
-msgid "Connect"
-msgstr "������"
-
-msgid "Clone"
-msgstr ""
-
-msgid "Edit"
-msgstr "������"
-
-msgid "Shut Down"
-msgstr "��������� ������"
-
-msgid "Delete"
-msgstr "������"
-
-msgid "CPU"
-msgstr "CPU"
-
-msgid "Disk I/O"
-msgstr "��������� I/O"
-
-msgid "Network I/O"
-msgstr "������������ I/O"
-
-msgid "Livetile"
-msgstr "���������������"
-
-msgid "No guests found."
-msgstr "������������ ������������."
-
-msgid "Add a Storage Device to VM"
-msgstr "������������ ��������� VM��� ������"
-
-msgid "Device Type"
-msgstr "������ ������"
-
-msgid "The device type. Currently, \"cdrom\" and \"disk\" are
supported."
-msgstr "������ ���������������. ������ \"cdrom\"���
���������������."
-
-msgid "Storage Pool"
-msgstr "������������ ���"
-
-msgid "Storage pool which volume located in"
-msgstr "������������ ��� ��������� ������������������ ���������."
-
-msgid "Storage Volume"
-msgstr "������������ ��� ������"
-
-msgid "Storage volume to be attached"
-msgstr "������������ ������ ��������� ������������������ ���������."
-
-msgid "File Path"
-msgstr "������ ������"
-
-msgid "The ISO file path in the server for CDROM."
-msgstr "CDROM��� ������ ��������� ISO ������ ���������������."
-
-msgid "Attach"
-msgstr "������"
-
-msgid "Shut down"
-msgstr "��������� ������"
-
-msgid "Restart"
-msgstr "������ ������"
-
-msgid "Basic Information"
-msgstr "������ ������"
-
-msgid "OS Distro"
-msgstr "OS Distro"
-
-msgid "OS Code Name"
-msgstr "OS ������ ������"
-
-msgid "Processor"
-msgstr "������������"
-
-msgid "CPU(s)"
-msgstr ""
-
-msgid "System Statistics"
-msgstr "��������� ������"
-
-msgid "Software Updates"
-msgstr "��������������� ������������"
-
-msgid "Update Progress"
-msgstr "������������ ������������"
-
-msgid "Repositories"
-msgstr "���������"
-
-msgid "Debug Reports"
-msgstr "��������� ���������"
-
-msgid "The username or password you entered is incorrect. Please try again."
-msgstr ""
-"��������� ��������� ������ ������ ��������������� ������������ ������������. ������
������������������."
-
-msgid "This field is required."
-msgstr "��� ��������� ���������������."
-
-msgid "Log in"
-msgstr "���������"
-
-msgid "Logging in..."
-msgstr "��������� ���..."
-
-msgid "Host"
-msgstr "���������"
-
-msgid "Guests"
-msgstr "���������"
-
-msgid "Templates"
-msgstr "������������"
-
-msgid "Failed to get application configuration"
-msgstr "������������������ ��������� ������������ ���������������."
-
-msgid "This is not a valid Linux path"
-msgstr "��������� Linux ��������� ������������."
-
-msgid "This is not a valid URL."
-msgstr "��������� URL��� ������������."
-
-msgid "No such data available."
-msgstr "������ ������������ ������������."
-
-msgid ""
-"Can not contact the host system. Verify the host system is up and that you "
-"have network connectivity to it. HTTP request response %1. "
-msgstr ""
-"��������� ������������ ��������� ��� ������������. ��������� ������������
��������������� ������ ������ ������"
-"������ ��������� ��������� ������������������. HTTP ������ ������ %1. "
-
-msgid "Unable to read file."
-msgstr ""
-
-msgid "Error while uploading file."
-msgstr ""
-
-msgid "Delete Confirmation"
-msgstr "������ ������"
-
-msgid "OK"
-msgstr "������"
-
-msgid "Confirm"
-msgstr "������"
-
-msgid "Warning"
-msgstr "������"
-
-msgid "Cloning..."
-msgstr ""
-
-msgid "Loading..."
-msgstr "������ ���..."
-
-msgid "An error occurred while retrieving system information."
-msgstr ""
-
-msgid "Retry"
-msgstr "���������"
-
-msgid "Detailed message:"
-msgstr "������ ���������:"
-
-msgid "No ISO found"
-msgstr ""
-
-msgid "This is not a valid ISO file."
-msgstr "��������� ISO ��������� ������������."
-
-msgid "This may take a long time. Do you want to continue?"
-msgstr "��������� ������ ������������. ������������������������?"
-
-msgid "This will permanently delete the template. Would you like to continue?"
-msgstr "��������������� ��������������� ���������������.
������������������������?"
-
-msgid "Unable to shut down system as there are some virtual machines running!"
-msgstr "������ ������ ��������� ������ ������������ ������������ ��������� ���
������������."
-
-msgid "Max:"
-msgstr "������:"
-
-msgid "Utilization"
-msgstr "���������"
-
-msgid "Available"
-msgstr "������ ������"
-
-msgid "Read Rate"
-msgstr "������ ������"
-
-msgid "Write Rate"
-msgstr "������ ������"
-
-msgid "Received"
-msgstr "������"
-
-msgid "Sent"
-msgstr "������"
-
-msgid ""
-"Shutting down or restarting host will cause unsaved work lost. Continue to "
-"shut down/restarting?"
-msgstr ""
-"������������ ��������������� ������ ������������ ������������ ������ ���������
���������������. ��������� ���"
-"���/������ ��������� ������������������������?"
-
-msgid ""
-"Repository will be removed permanently and can't be recovered. Do you want
"
-"to continue?"
-msgstr "������������ ��������������� ������������ ��������� ��� ������������.
������������������������?"
-
-msgid "ID"
-msgstr "ID"
-
-msgid "Base URL"
-msgstr "������ URL"
-
-msgid "Is Mirror"
-msgstr "���������"
-
-msgid "URL Args"
-msgstr "URL ������"
-
-msgid "Enabled"
-msgstr "���������"
-
-msgid "GPG Check"
-msgstr "GPG ������"
-
-msgid "GPG Key"
-msgstr "GPG ���"
-
-msgid "Add"
-msgstr "������"
-
-msgid "Remove"
-msgstr "������"
-
-msgid "Enable"
-msgstr "������"
-
-msgid "Disable"
-msgstr "������ ������"
-
-msgid "Package Name"
-msgstr "��������� ������"
-
-msgid "Version"
-msgstr "������"
-
-msgid "Architecture"
-msgstr "������������"
-
-msgid "Repository"
-msgstr "���������"
-
-msgid "Update All"
-msgstr "������ ������������"
-
-msgid "Updating..."
-msgstr "������������ ���..."
-
-msgid "Failed to retrieve packages update information."
-msgstr ""
-
-msgid "Failed to update package(s)."
-msgstr "������������ ������������������ ���������������."
-
-msgid ""
-"Debug report will be removed permanently and can't be recovered. Do you want
"
-"to continue?"
-msgstr ""
-"��������� ������������ ��������������� ������������ ��������� ��� ������������.
������������������������?"
-
-msgid "Generated Time"
-msgstr "������ ������"
-
-msgid "Generate"
-msgstr "������"
-
-msgid "Generating..."
-msgstr "������ ���..."
-
-msgid "Rename"
-msgstr "������ ���������"
-
-msgid "Download"
-msgstr "������������"
-
-msgid ""
-"Report name should contain only letters, digits, underscore ('_') and/or
"
-"hyphen ('-')."
-msgstr "��������� ������������ ������, ������ ���/������ ���������('-')���
��������������� ���������."
-
-msgid "Pending..."
-msgstr "������ ���..."
-
-msgid "Report name is the same as the original one."
-msgstr ""
-
-msgid ""
-"This will delete the virtual machine and its virtual disks. This operation "
-"cannot be undone. Would you like to continue?"
-msgstr ""
-"������ ������ ��� ������ ������ ������������ ���������������. ��� ��������� ������
��������� ��� ���������"
-"���. ������������������������?"
-
-msgid "Power off Confirmation"
-msgstr "������ ������"
-
-msgid ""
-"This action may produce undesirable results, for example unflushed disk "
-"cache in the guest. Would you like to continue?"
-msgstr ""
-
-msgid "Reset Confirmation"
-msgstr "������ ������"
-
-msgid ""
-"There is a risk of data loss caused by reset without the guest OS shutdown. "
-"Would you like to continue?"
-msgstr ""
-
-msgid "Shut Down Confirmation"
-msgstr "������ ������"
-
-msgid "Note the guest OS may ignore this request. Would you like to continue?"
-msgstr "��������������� ��������������� ���������������.
������������������������?"
-
-msgid "Virtual Machine delete Confirmation"
-msgstr ""
-
-msgid ""
-"This virtual machine is not persistent. Power Off will delete it. Continue?"
-msgstr ""
-
-msgid ""
-"When the target guest has SCSI or iSCSI volumes, they will be cloned on "
-"default storage pool. The same will happen when the target pool does not "
-"have enough space to clone the volumes. Do you want to continue?"
-msgstr ""
-
-msgid ""
-"This CDROM will be detached permanently and you can re-attach it. Continue "
-"to detach it?"
-msgstr ""
-"��� CDROM��� ��������������� ������������ ������ ��������� ��� ������������.
��������� ���������������������"
-"���?"
-
-msgid "Attaching..."
-msgstr "������ ���..."
-
-msgid "Replacing..."
-msgstr "������ ���..."
-
-msgid "Successfully attached!"
-msgstr "���������������������."
-
-msgid "Successfully replaced!"
-msgstr "���������������������."
-
-msgid "Successfully detached!"
-msgstr "���������������������."
-
-msgid ""
-"This disk will be detached permanently and you can re-attach it. Continue to
"
-"detach it?"
-msgstr ""
-
-msgid "interface:"
-msgstr ""
-
-msgid "address:"
-msgstr ""
-
-msgid "link_type:"
-msgstr ""
-
-msgid "block:"
-msgstr ""
-
-msgid "drive_type:"
-msgstr ""
-
-msgid "model:"
-msgstr ""
-
-msgid "Affected devices:"
-msgstr ""
-
-msgid "The VLAN id must be between 1 and 4094."
-msgstr "VLAN ID��� 1��� 4094 ������������ ���������."
-
-msgid "unavailable"
-msgstr "������ ���������"
-
-msgid ""
-"This action will interrupt network connectivity for any virtual machine that
"
-"depend on this network."
-msgstr ""
-"��� ��������� ��� ��������������� ������������ ������ ��������� ������������
��������� ���������������������."
-
-msgid "Create a network"
-msgstr "������������ ������"
-
-msgid ""
-"This network is not persistent. Instead of stop, this action will "
-"permanently delete it. Would you like to continue?"
-msgstr ""
-"��� ������������ ������ ��������������� ������������. ��� ��������� ������
������������������ ������ ���������"
-"������ ���������������. ������������������������?"
-
-msgid ""
-"The bridged VLAN tag may not work well with NetworkManager enabled. You "
-"should consider disabling it."
-msgstr ""
-
-msgid ""
-"This will permanently delete the storage pool. Would you like to continue?"
-msgstr "������������ ������ ��������������� ���������������.
������������������������?"
-
-msgid "This storage pool is empty."
-msgstr "��� ������������ ������ ������ ������������."
-
-msgid ""
-"It will format your disk and you will loose any data in there, are you sure "
-"to continue? "
-msgstr "������������ ������������ ������������ ���������������.
������������������������? "
-
-msgid "SCSI Fibre Channel"
-msgstr "SCSI ��������� ������"
-
-msgid "No SCSI adapters found."
-msgstr "SCSI ������������ ������������."
-
-msgid "Loading iSCSI targets..."
-msgstr ""
-
-msgid "No iSCSI found. Please input one."
-msgstr ""
-
-msgid "Failed to load iSCSI targets."
-msgstr ""
-
-msgid "The storage pool name can not be blank."
-msgstr "������������ ��� ��������� ��������� ��� ������������."
-
-msgid "The storage pool path can not be blank."
-msgstr "������������ ��� ��������� ��������� ��� ������������."
-
-msgid "NFS server mount path can not be blank."
-msgstr "NFS ������ ��������� ��������� ��������� ��� ������������."
-
-msgid "Invalid NFS mount path."
-msgstr "������������ ������ NFS ��������� ���������������."
-
-msgid "No logical device selected."
-msgstr "������ ��������� ������������ ���������������."
-
-msgid "The iSCSI target can not be blank."
-msgstr "iSCSI ��������� ��������� ��� ������������."
-
-msgid "Server name can not be blank."
-msgstr "������ ��������� ��������� ��� ������������."
-
-msgid "This is not a valid Server Name or IP. Please, modify it."
-msgstr ""
-
-msgid "Looking for available partitions ..."
-msgstr "������ ��������� ������������ ������ ���..."
-
-msgid "No available partitions found."
-msgstr "������ ��������� ������������ ������������."
-
-msgid ""
-"This storage pool is not persistent. Instead of deactivate, this action will
"
-"permanently delete it. Would you like to continue?"
-msgstr ""
-"��� ������������ ������ ��������������� ������������. ��� ��������� ������
������������������ ������ ���������"
-"������ ���������������. ������������������������?"
-
-msgid "Unable to retrieve partitions information."
-msgstr "��������� ��������� ��������� ��� ������������. ������������:
'%(err)s'"
-
-msgid "In progress..."
-msgstr ""
-
-msgid "Failed!"
-msgstr ""
-
-msgid "CDROM path needs to be a valid local/remote path and cannot be blank."
-msgstr ""
-
-msgid "Disk pool or volume cannot be blank."
-msgstr "������������ ��� ��������� ��������� ��� ������������."
-
-msgid "Filter"
-msgstr ""
-
-msgid "Network Name"
-msgstr "������������ ������"
-
-msgid "State"
-msgstr "������"
-
-msgid "Network Type"
-msgstr "������������ ������"
-
-msgid "Address Space"
-msgstr "������ ������"
-
-msgid "Name should not contain '/' and '\"'."
-msgstr "������������ ������ ������������ ��� ���������������. '/'���
������������ ��������� ���������."
-
-msgid "Isolated: no external network connection"
-msgstr "���������: ��������� ������������ ������ ������"
-
-msgid "NAT: outbound physical network connection only"
-msgstr "NAT: ��������������� ��������� ������������ ���������"
-
-msgid "Bridged: Virtual machines are connected to physical network directly"
-msgstr "������������: ������ ��������� ��������� ��������������� ������
���������"
-
-msgid "(No interfaces found)"
-msgstr ""
-
-msgid "Destination"
-msgstr "������:"
-
-msgid "Enable VLAN"
-msgstr "VLAN ������:"
-
-msgid "VLAN ID"
-msgstr "VLAN ID:"
-
-msgid "Stop"
-msgstr "������"
-
-msgid "Generate a New Debug Report"
-msgstr "��� ��������� ��������� ������"
-
-msgid "Report Name"
-msgstr "��������� ������"
-
-msgid ""
-"The name used to identify the report. If omitted, a name will be chosen "
-"based on current time. Name can contain: letters, digits, underscore
(\"_\") "
-"and hyphen (\"-\")."
-msgstr ""
-"������������ ������������ ��� ������������ ���������������. ������������ ���������
������ ��������� ���������"
-"��� ���������������. ��������� ������, ������ ��� ���������(\"-\")���
��������� ��� ������������."
-
-msgid "Rename a Debug Report"
-msgstr "��� ��������� ��������� ������"
-
-msgid ""
-"The name used to identify the report. Name can contain: letters, digits and "
-"hyphen (\"-\")."
-msgstr ""
-"������������ ������������ ��� ������������ ���������������. ������������ ���������
������ ��������� ���������"
-"��� ���������������. ��������� ������, ������ ��� ���������(\"-\")���
��������� ��� ������������."
-
-msgid "Submit"
-msgstr ""
-
-msgid "Add a Repository"
-msgstr "��������� ������"
-
-msgid "Identifier"
-msgstr "ID"
-
-msgid "Single word, unique identifier for the repository."
-msgstr "������������ ������ ������ ��������� ������ ID���������."
-
-msgid "Textual name for the repository."
-msgstr "������������ ������ ��������� ���������������."
-
-msgid "URL"
-msgstr "URL"
-
-msgid "Required Field"
-msgstr "������ ������"
-
-msgid "URL to the repository. Supported protocols are http, ftp, and file."
-msgstr "������������ ������ URL���������. ������������ ��������������� http, ftp ���
file���������."
-
-msgid "Repository is a mirror"
-msgstr "������������ ���������������."
-
-msgid "Distribution"
-msgstr "������"
-
-msgid "Distribution of the DEB repository."
-msgstr "DEB ������������ ���������������."
-
-msgid "Components"
-msgstr "������������"
-
-msgid "List of components in DEB repository."
-msgstr "DEB ������������ ������������ ���������������."
-
-msgid "Edit Repository"
-msgstr "��������� ������"
-
-msgid "Mirror List URL"
-msgstr "������ ������ URL"
-
-msgid "Yes"
-msgstr "���"
-
-msgid "No"
-msgstr "���������"
-
-msgid "Capacity"
-msgstr "������"
-
-msgid "Allocated"
-msgstr "���������"
-
-msgid "Location"
-msgstr "������"
-
-msgid "Device path"
-msgstr "������ ������"
-
-msgid "active"
-msgstr "������"
-
-msgid "inactive"
-msgstr "���������"
-
-msgid "Deactivate"
-msgstr "������������"
-
-msgid "Activate"
-msgstr "���������"
-
-msgid "Add Volume"
-msgstr ""
-
-msgid "Extend"
-msgstr ""
-
-msgid "Undefine"
-msgstr "������ ������"
-
-msgid "Format"
-msgstr "������:"
-
-msgid "Allocation"
-msgstr "������:"
-
-msgid "Define a New Storage Pool"
-msgstr "��� ������������ ��� ������"
-
-msgid "Storage Pool Name"
-msgstr "������������ ��� ������"
-
-msgid ""
-"The name used to identify the storage pools, and it should not be empty."
-msgstr "������������ ������ ������������ ��� ������������ ������������ ������ ������
��������� ���������."
-
-msgid "Storage Pool Type"
-msgstr "������������ ��� ������"
-
-msgid "Storage Path"
-msgstr "������������ ������"
-
-msgid ""
-"The path of the Storage Pool. Each Storage Pool must have a unique path."
-msgstr "������������ ������ ���������������. ��� ������������ ������ ������
��������� ��������� ���������."
-
-msgid ""
-"Kimchi will try to create the directory when it does not already exist in "
-"your system."
-msgstr ""
-"��������������� ������������ ������ ������������ ��������� Kimchi��� ������������
��������� ���������������."
-
-msgid "NFS Server IP"
-msgstr "NFS ������ IP"
-
-msgid "NFS server IP or hostname. It can be input or chosen from history."
-msgstr ""
-"NFS ������ IP ������ ��������� ���������������. ��������� ���������������
������������������ ��������� ��� "
-"������������."
-
-msgid "NFS Path"
-msgstr "NFS ������"
-
-msgid "The NFS exported path on NFS server."
-msgstr "NFS ������������ NFS��� ��������� ���������������."
-
-msgid "iSCSI Server"
-msgstr "iSCSI ������"
-
-msgid "Server"
-msgstr "������"
-
-msgid "Port"
-msgstr "������"
-
-msgid "iSCSI server IP or hostname. It should not be empty."
-msgstr "iSCSI ������ IP ������ ��������� ���������������. ������ ������ ���������
���������."
-
-msgid "Target"
-msgstr "������"
-
-msgid "The iSCSI target on iSCSI server"
-msgstr "iSCSI ��������� iSCSI ������"
-
-msgid "Add iSCSI Authentication"
-msgstr "iSCSI ������ ������"
-
-msgid "iSCSI Authentication"
-msgstr "iSCSI ������"
-
-msgid "User Name"
-msgstr "��������� ������"
-
-msgid "Password"
-msgstr "������������"
-
-msgid "SCSI Adapter"
-msgstr "SCSI ���������"
-
-msgid "Please, wait..."
-msgstr "������ ��������� ������������."
-
-msgid "Add a Volume to Storage Pool"
-msgstr ""
-
-msgid "Fetch from remote URL"
-msgstr ""
-
-msgid "Enter the remote URL here."
-msgstr ""
-
-msgid "Upload a file"
-msgstr ""
-
-msgid "Choose the file you want to upload."
-msgstr ""
-
-msgid "Add Template"
-msgstr "������������ ������"
-
-msgid "Where is the source media for this template? "
-msgstr "��� ��������������� ������ ��������� ��������� ������������?"
-
-msgid "Local ISO Image"
-msgstr "������ ISO ���������"
-
-msgid "Local Image File"
-msgstr ""
-
-msgid "Remote ISO Image"
-msgstr "������ ISO ���������"
-
-msgid "Search ISOs"
-msgstr "ISO ������"
-
-msgid "The following ISOs are available:"
-msgstr "������ ISO��� ������ ���������������."
-
-msgid "OS: "
-msgstr "OS: "
-
-msgid "Version: "
-msgstr "������: "
-
-msgid "Size: "
-msgstr "������: "
-
-msgid "Search more ISOs"
-msgstr "������ ISO ������"
-
-msgid "Create Templates from Selected ISO"
-msgstr "��������� ISO��������� ������������ ������"
-
-msgid "I want to use a specific ISO file"
-msgstr "������ ISO ��������� ��������������� ���������."
-
-msgid "Loading default remote ISOs ..."
-msgstr "������ ������ ISO ������ ���..."
-
-msgid "Arch: "
-msgstr "Arch: "
-
-msgid "I want to use a custom URL"
-msgstr "��������� ������ URL��� ��������������� ���������."
-
-msgid "Edit Template"
-msgstr "������������ ������"
-
-msgid "CDROM"
-msgstr "CDROM"
-
-msgid "Image File"
-msgstr ""
-
-msgid "Graphics"
-msgstr "���������"
-
-msgid "Disk(GB)"
-msgstr ""
-
-msgid "Disk Format"
-msgstr ""
-
-msgid "CPU Number"
-msgstr "CPU ������"
-
-msgid "Manually set CPU topology"
-msgstr ""
-
-msgid "Cores"
-msgstr ""
-
-msgid "Threads"
-msgstr ""
-
-msgid "No templates found."
-msgstr "��������������� ������������."
-
-#~ msgid "Delete is not allowed for %(resource)s"
-#~ msgstr "%(resource)s��� ��������� ������������ ������"
-
-#~ msgid "%(resource)s does not implement update method"
-#~ msgstr "%(resource)s��������� ������������ ������������ ������������
������"
-
-#~ msgid "Create is not allowed for %(resource)s"
-#~ msgstr "%(resource)s��� ��������� ������������ ������"
-
-#~ msgid "Unable to parse JSON request"
-#~ msgstr "JSON ��������� ������ ��������� ��� ������������."
-
-#~ msgid "This API only supports JSON"
-#~ msgstr "��� API��� JSON��� ���������������."
-
-#~ msgid "Datastore is not initiated in the model object."
-#~ msgstr "��������� ������������ ������ ������������������ ������������
���������������."
-
-#~ msgid "Unable to start task due error: %(err)s"
-#~ msgstr "������ ��������� ��������� ��������� ��� ������: %(err)s"
-
-#~ msgid ""
-#~ "Authentication failed for user '%(username)s'. [Error code:
%(code)s]"
-#~ msgstr "��������� '%(username)s'��� ��������� ������������������. [������
������: %(code)s]"
-
-#~ msgid "You are not authorized to access Kimchi"
-#~ msgstr "Kimchi��� ������������ ��������� ������������."
-
-#~ msgid "Specify %(item)s to login into Kimchi"
-#~ msgstr "Kimchi��� ������������������ %(item)s���(���) ������������������."
-
-#~ msgid "Unable to find %(item)s in datastore"
-#~ msgstr "��������� ��������������� %(item)s���(���) ������ ���
������������."
-
-#~ msgid "Timeout while running command '%(cmd)s' after %(seconds)s
seconds"
-#~ msgstr ""
-#~ "%(seconds)s��� ������ '%(cmd)s' ������ ������ ��� ���������������
���������������������."
-
-#~ msgid "Help"
-#~ msgstr "���������"
-
-#~ msgid "About"
-#~ msgstr "������"
-
-#~ msgid "Log out"
-#~ msgstr "������������"
-
-#~ msgid "Version:"
-#~ msgstr "������: "
diff --git a/plugins/kimchi/po/pt_BR.po b/plugins/kimchi/po/pt_BR.po
deleted file mode 100644
index c2cb4e9..0000000
--- a/plugins/kimchi/po/pt_BR.po
+++ /dev/null
@@ -1,2369 +0,0 @@
-# i18n portable object for kimchi.
-# Copyright (C) IBM, Corp. 2013-2014
-# ShaoHe Feng <shaohef(a)linux.vnet.ibm.com>, 2013-04-18.
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-#
-msgid ""
-msgstr ""
-"Project-Id-Version: kimchi 1.0\n"
-"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2015-07-01 16:11-0300\n"
-"PO-Revision-Date: 2015-03-23 12:57+0000\n"
-"Last-Translator: Cr��stian Deives dos Santos Viana <cristiandeives(a)gmail."
-"com>\n"
-"Language-Team: Portuguese (Brazil) (
http://www.transifex.com/projects/p/"
-"kimchi/language/pt_BR/)\n"
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
-"Content-Transfer-Encoding: 8bit\n"
-"Language: pt_BR\n"
-"Plural-Forms: nplurals=2; plural=(n > 1);\n"
-
-#, python-format
-msgid "Unknown parameter %(value)s"
-msgstr "Par��metro desconhecido: %(value)s"
-
-#, python-format
-msgid "Timeout of %(seconds)s seconds expired while running task
'%(task)s."
-msgstr ""
-"Limite de tempo de %(seconds)s segundos expirado ao executar a tarefa '%"
-"(task)s'."
-
-#, python-format
-msgid "User %(user_id)s not found with given LDAP settings."
-msgstr "Usu��rio %(user_id)s n��o encontrado com as configura����es LDAP
dadas."
-
-msgid "Unknown \"_cap\" specified"
-msgstr "\"_cap\" desconhecido especificado"
-
-msgid "\"_passthrough\" should be \"true\" or
\"false\""
-msgstr "\"_passthrough\" deve ser \"true\" ou
\"false\""
-
-msgid "\"_passthrough_affected_by\" should be a device name string"
-msgstr "\"_passthrough_affected_by\" deve ser um texto do nome do
dispositivo"
-
-#, python-format
-msgid "Error while getting block devices. Details: %(err)s"
-msgstr "Erro ao consultar block devices. Detalhes %(err)s"
-
-#, python-format
-msgid "Error while getting block device information for %(device)s."
-msgstr "Erro ao consultar informa����es de block devices para %(device)s."
-
-#, python-format
-msgid "Unable to find distro file: %(filename)s"
-msgstr "N��o foi poss��vel encontrar o arquivo da distribui����o:
%(filename)s"
-
-#, python-format
-msgid ""
-"Unable to parse distro file: %(filename)s. Make sure, it is a JSON file."
-msgstr ""
-"N��o foi poss��vel ler o arquivo da distribui����o: %(filename)s. Confirme se ��
"
-"um arquivo JSON."
-
-#, python-format
-msgid "Unable to login to iSCSI host target %(portal)s. Details: %(err)s"
-msgstr ""
-"N��o foi poss��vel logar na m��quina alvo do iSCSI %(portal)s. Detalhes:
%(err)s"
-
-#, python-format
-msgid "Unable to login to iSCSI host %(host)s target %(target)s"
-msgstr "N��o foi poss��vel logar na m��quina %(host)s alvo %(target)s do
iSCSI"
-
-#, python-format
-msgid "Unable to find ISO file %(filename)s"
-msgstr "N��o foi poss��vel encontrar a ISO %(filename)s"
-
-#, python-format
-msgid "The ISO file %(filename)s is not bootable"
-msgstr "A ISO %(filename)s n��o �� boot��vel"
-
-#, python-format
-msgid "The ISO file %(filename)s does not have a valid El Torito boot record"
-msgstr "A ISO %(filename)s n��o possui uma grava����o v��lida de boot El
Torito"
-
-#, python-format
-msgid "Invalid El Torito validation entry in ISO %(filename)s"
-msgstr "Valida����o El Torito inv��lida na ISO %(filename)s"
-
-#, python-format
-msgid "Invalid El Torito boot indicator in ISO %(filename)s"
-msgstr "Indicador de boot El Torito inv��lido na ISO %(filename)s"
-
-#, python-format
-msgid "Unexpected volume type for primary volume in ISO %(filename)s"
-msgstr ""
-"Tipo de volume n��o esperado para um volume prim��rio na ISO %(filename)s"
-
-#, python-format
-msgid "Bad format while reading volume descriptor in ISO %(filename)s"
-msgstr "Formato errado na leitura do descritor de volume na ISO %(filename)s"
-
-#, python-format
-msgid ""
-"The hypervisor doesn't have permission to use this ISO %(filename)s. "
-"Consider moving it under /var/lib/libvirt, or set the search permission to "
-"file access control lists for '%(user)s' user if possible, or add the
'%"
-"(user)s' to the ISO path group, or (not recommended) 'chmod -R o+x "
-"'path_to_iso'.Details: %(err)s"
-msgstr ""
-"O servidor n��o tem permiss��o para acessar a ISO %(filename)s. Considere
mud��-"
-"la para o diret��rio /var/lib/libvirt, ou mude as permiss��es para que o "
-"usu��rio '%(user)s' tenha acesso, ou, adicione o usu��rio
'%(user)s' no grupo "
-"do caminho da ISO, ou (n��o recomendado) 'chmod -R o+x
'caminho_para_iso'. "
-"Detalhes: %(err)s"
-
-msgid "An error occurred when probing image OS information."
-msgstr "Ocorreu um erro ao identificar o sistema operacional da imagem."
-
-msgid "No OS information found in given image."
-msgstr ""
-"Nenhuma informa����o de sistema operacional encontrada na imagem fornecida."
-
-#, python-format
-msgid "Unable to read image file %(filename)s"
-msgstr "N��o foi poss��vel ler o arquivo de imagem %(filename)s."
-
-#, python-format
-msgid ""
-"Image file must be an existing file on system. %(filename)s is not a valid "
-"input."
-msgstr ""
-"Arquivo de imagem deve ser um arquivo existente no sistema. %(filename)s n��o
"
-"�� uma entrada v��lida."
-
-#, python-format
-msgid "Virtual machine %(name)s already exists"
-msgstr "M��quina virtual %(name)s j�� existe"
-
-#, python-format
-msgid "Virtual machine %(name)s does not exist"
-msgstr "M��quina virtual %(name)s n��o existe"
-
-#, python-format
-msgid ""
-"Unable to rename virtual machine %(name)s. The name %(new_name)s is already "
-"in use or the virtual machine is not powered off."
-msgstr ""
-"N��o foi poss��vel renomear a m��quina virtual %(name)s. O nome %(new_name)s j��
"
-"est�� em uso ou a m��quina virtual n��o est�� ligada."
-
-#, python-format
-msgid "Unable to retrieve screenshot for stopped virtual machine %(name)s"
-msgstr ""
-"N��o foi poss��vel tirar uma foto da tela para a m��quina virtual %(name)s que
"
-"est�� desligada"
-
-msgid "Remote ISO image is not supported by this server."
-msgstr "Imagem de ISO remota n��o �� suportada por esse servidor."
-
-#, python-format
-msgid "Screenshot is not supported on virtual machine %(name)s"
-msgstr "Foto da tela n��o �� suportado na m��quina virtual %(name)s"
-
-#, python-format
-msgid "Unable to create virtual machine %(name)s. Details: %(err)s"
-msgstr "N��o foi poss��vel criar a m��quina virtual %(name)s. Detalhes:
%(err)s"
-
-#, python-format
-msgid "Unable to update virtual machine %(name)s. Details: %(err)s"
-msgstr ""
-"N��o foi poss��vel atualizar a m��quina virtual %(name)s. Detalhes: %(err)s"
-
-#, python-format
-msgid "Unable to retrieve virtual machine %(name)s. Details: %(err)s"
-msgstr ""
-"N��o foi poss��vel encontrar a m��quina virtual %(name)s. Detalhes: %(err)s"
-
-#, python-format
-msgid "Unable to connect to powered off virtual machine %(name)s."
-msgstr "N��o foi poss��vel conectar �� m��quina virtual desligada %(name)s."
-
-msgid "Virtual machine name must be a string without slashes (/)"
-msgstr ""
-
-#, python-format
-msgid "Invalid template URI %(value)s specified for virtual machine"
-msgstr "URI do Modelo inv��lida %(value)s especificada para m��quina virtual"
-
-#, python-format
-msgid "Invalid storage pool URI %(value)s specified for virtual machine"
-msgstr ""
-"URI do Storage pool URI inv��lida %(value)s especificada para m��quina
virtual"
-
-msgid "Supported virtual machine graphics are Spice or VNC"
-msgstr "Gr��ficos suportados para a m��quina virtual s��o Spice ou VNC"
-
-msgid "Graphics address to listen on must be IPv4 or IPv6"
-msgstr "Endere��o para receber eventos gr��ficos deve ser IPv4 ou IPv6"
-
-msgid "Specify a template to create a virtual machine from"
-msgstr "Especifique um modelo para ser base da cria����o da m��quina virtual"
-
-#, python-format
-msgid "Unable to start virtual machine %(name)s. Details: %(err)s"
-msgstr "N��o foi poss��vel iniciar a m��quina virtual %(name)s. Detalhes:
%(err)s"
-
-#, python-format
-msgid "Unable to power off virtual machine %(name)s. Details: %(err)s"
-msgstr ""
-"N��o foi poss��vel for��ar o desligamento da m��quina virtual %(name)s. "
-"Detalhes: %(err)s"
-
-#, python-format
-msgid "Unable to delete virtual machine %(name)s. Details: %(err)s"
-msgstr "N��o foi poss��vel remover a m��quina virtual %(name)s. Detalhes:
%(err)s"
-
-#, python-format
-msgid "Unable to reset virtual machine %(name)s. Details: %(err)s"
-msgstr ""
-"N��o foi poss��vel reiniciar a m��quina virtual %(name)s. Detalhes: %(err)s"
-
-msgid "User name list must be an array"
-msgstr "Lista de nomes de usu��rio deve ser um array"
-
-msgid "User name must be a string"
-msgstr "Nome de usu��rio deve ser um texto"
-
-msgid "Group name list must be an array"
-msgstr "Lista de nomes de grupo deve ser um array"
-
-msgid "Group name must be a string"
-msgstr "Nome de grupo deve ser um texto"
-
-#, python-format
-msgid "User(s) '%(users)s' do not exist"
-msgstr "Usu��rio(s) '%(users)s' n��o existe(m)"
-
-#, python-format
-msgid "Group(s) '%(groups)s' do not exist"
-msgstr "Grupo(s) '%(groups)s' n��o existe(m)"
-
-#, python-format
-msgid "Unable to shutdown virtual machine %(name)s. Details: %(err)s"
-msgstr ""
-"N��o foi poss��vel desligar a m��quina virtual %(name)s. Detalhes: %(err)s"
-
-#, python-format
-msgid ""
-"Unable to get access metadata of virtual machine %(name)s. Details: %(err)s"
-msgstr ""
-"N��o foi poss��vel acessar os metadados da m��quina virtual %(name)s. Detalhes:
"
-"%(err)s"
-
-msgid "The guest console password must be a string."
-msgstr "A senha para o console do guest deve ser um texto."
-
-msgid "The life time for the guest console password must be a number."
-msgstr "O tempo de vida da senha do console do guest deve ser um n��mero."
-
-#, python-format
-msgid "Virtual machine '%(name)s' must be stopped before cloning it."
-msgstr "A m��quina virtual '%(name)s' deve estar parada antes de
clon��-la."
-
-#, python-format
-msgid "Insufficient disk space to clone virtual machine '%(name)s'"
-msgstr "Espa��o em disco insuficiente para clonar a m��quina virtual
'%(name)s'"
-
-#, python-format
-msgid "Unable to clone VM '%(name)s'. Details: %(err)s"
-msgstr "N��o foi poss��vel clonar a VM '%(name)s'. Detalhes: %(err)s"
-
-#, python-format
-msgid "Invalid operation for non-persistent virtual machine %(name)s"
-msgstr "Opera����o inv��lida para m��quina virtual n��o-persistente %(name)s"
-
-#, python-format
-msgid "Cannot suspend VM '%(name)s' because it is not running."
-msgstr ""
-
-#, python-format
-msgid "Unable to suspend VM '%(name)s'. Details: %(err)s"
-msgstr ""
-
-#, python-format
-msgid "Cannot resume VM '%(name)s' because it is not paused."
-msgstr ""
-
-#, python-format
-msgid "Unable to resume VM '%(name)s'. Details: %(err)s"
-msgstr ""
-
-msgid "Memory assigned is higher then the maximum allowed in the host."
-msgstr ""
-
-#, python-format
-msgid ""
-"VM '%(name)s' does not support live memory update. Update the memory with
"
-"the machine offline to enable this feature."
-msgstr ""
-
-msgid "Only increase memory is allowed in active VMs"
-msgstr ""
-
-msgid ""
-"For live memory update, new memory value must be equal old memory value plus
"
-"multiples of 1024 Mib"
-msgstr ""
-
-msgid "There are not enough free slots of 1024 Mib in the guest."
-msgstr ""
-
-msgid ""
-"Host's libvirt version does not support memory devices. Libvirt must be >=
"
-"1.2.14"
-msgstr ""
-
-#, python-format
-msgid "Error attaching memory device. Details: %(error)s"
-msgstr ""
-
-#, python-format
-msgid ""
-"VM %(vmid)s does not contain directly assigned host device %(dev_name)s."
-msgstr ""
-"A VM %(vmid)s n��o cont��m o dispositivo de host atribu��do diretamente %"
-"(dev_name)s."
-
-#, python-format
-msgid "The host device %(dev_name)s is not allowed to directly assign to VM."
-msgstr ""
-"N��o �� permitido atribuir diretamente o dispositivo de host %(dev_name)s."
-
-msgid ""
-"No IOMMU groups found. Host PCI pass through needs IOMMU group to function "
-"correctly. Please enable Intel VT-d or AMD IOMMU in your BIOS, then verify "
-"the Kernel is compiled with IOMMU support. For Intel CPU, add intel_iommu=on
"
-"to your Kernel parameter in /boot/grub2/grub.conf. For AMD CPU, add iommu=pt
"
-"iommu=1."
-msgstr ""
-"Nenhum grupo IOMMU encontrado. Passthrough de host PCI necessita do grupo "
-"IOMMU para funcionar corretamente. Por favor, habilite o suporte ao Intel
VT-"
-"d ou AMD IOMMU. Para uma CPU Intel, adicione \"intel_iommu=on\" nos seus
"
-"par��metros de kernel em \"/boot/grub2/grub.conf\". Para uma CPU AMD,
"
-"adicione \"iommu=pt iommu=1\"."
-
-msgid "\"name\" should be a device name string"
-msgstr "\"nome\" deve ser um texto do nome do dispositivo."
-
-#, python-format
-msgid ""
-"The device %(name)s is probably in use by the host. Unable to attach it to "
-"the guest."
-msgstr ""
-
-#, python-format
-msgid "Interface %(iface)s does not exist in virtual machine %(name)s"
-msgstr "Interface %(iface)s n��o existe na m��quina virtual %(name)s"
-
-#, python-format
-msgid ""
-"Network %(network)s specified for virtual machine %(name)s does not exist"
-msgstr ""
-"Rede %(network)s especificada para a m��quina virtual %(name)s n��o existe"
-
-msgid "Supported virtual machine interfaces type is only network"
-msgstr "Tipo de interface suportado das m��quinas virtuais �� somente rede"
-
-msgid "Network name for virtual machine interface must be a string"
-msgstr "Nome da rede para a interface da m��quina virtual deve ser texto"
-
-msgid "Invalid network model card specified for virtual machine interface"
-msgstr "Modelo de placa de rede inv��lido para a interface da m��quina
virtual"
-
-msgid "Specify type and network to add a new virtual machine interface"
-msgstr ""
-"Especifique o tipo e a rede para adicionar uma nova interface da m��quina "
-"virtual"
-
-msgid "MAC Address must respect this format FF:FF:FF:FF:FF:FF"
-msgstr ""
-
-#, python-format
-msgid "MAC Address %(mac)s already exists in virtual machine %(name)s"
-msgstr ""
-
-msgid "Invalid MAC Address"
-msgstr ""
-
-msgid "Cannot change MAC address of a running virtual machine"
-msgstr ""
-
-#, python-format
-msgid "Template %(name)s already exists"
-msgstr "Modelo %(name)s j�� existe"
-
-#, python-format
-msgid ""
-"Network '%(network)s' specified for template %(template)s does not
exist"
-msgstr "Rede '%(network)s' especificada para o modelo %(template)s n��o
existe"
-
-#, python-format
-msgid ""
-"Storage pool %(pool)s specified for template %(template)s does not exist"
-msgstr ""
-"Storage pool %(pool)s especificado para o modelo %(template)s n��o existe"
-
-#, python-format
-msgid "Storage pool %(pool)s specified for template %(template)s is not
active"
-msgstr ""
-"Storage pool %(pool)s especificado para o modelo %(template)s n��o est��
ativo"
-
-#, python-format
-msgid "Invalid parameter '%(param)s' specified for CDROM."
-msgstr "Par��metro inv��lido '%(param)s' especificado para CDROM"
-
-#, python-format
-msgid "Network %(network)s specified for template %(template)s is not active"
-msgstr "Rede %(network)s especificada para modelo %(template)s n��o est��
ativa"
-
-msgid "Template name must be a string"
-msgstr "Nome do modelo deve ser um texto"
-
-msgid "Template icon must be a path to the image"
-msgstr "��cone do modelo deve ser um caminho para uma imagem"
-
-msgid "Template distribution must be a string"
-msgstr "Distribui����o do modelo deve ser um texto"
-
-msgid "Template distribution version must be a string"
-msgstr "Vers��o da distribui����o do modelo deve ser um texto"
-
-msgid "The number of CPUs must be an integer greater than 0"
-msgstr "O n��mero de CPUs deve ser um inteiro maior do que 0"
-
-msgid "Amount of memory (MB) must be an integer greater than 512"
-msgstr "Quantidade de mem��ria (MB) deve ser um inteiro maior que 512"
-
-msgid "Template CDROM must be a local or remote ISO file"
-msgstr "Modelo do CDROM deve ser um arquivo ISO local ou remoto"
-
-#, python-format
-msgid "Invalid storage pool URI %(value)s specified for template"
-msgstr "URI de storage pool inv��lido %(value)s especificado para modelo"
-
-msgid "Specify an ISO image as CDROM or a base image to create a template"
-msgstr ""
-"Especifique uma imagem ISO como CD-ROM ou uma imagem base para criar um "
-"modelo"
-
-msgid "All networks for the template must be specified in a list."
-msgstr "Todas redes para o modelo devem ser especificadas em uma lista"
-
-msgid "Specify a volume to a template when storage pool is iSCSI or SCSI"
-msgstr ""
-"Especifique um volume para o template quando o storage pool for iSCSI or
SCSI"
-
-#, python-format
-msgid "The volume %(volume)s is not in storage pool %(pool)s"
-msgstr "O volume %(volume)s n��o est�� no storage pool %(pool)s"
-
-#, python-format
-msgid "Unable to create template due error: %(err)s"
-msgstr "N��o foi poss��vel criar o modelo devido a um erro: %(err)s"
-
-#, python-format
-msgid "Unable to delete template due error: %(err)s"
-msgstr "N��o foi poss��vel remover o modelo devido a um erro: %(err)s"
-
-msgid "Disk size must be an integer greater than 1GB."
-msgstr "O tamanho do disco deve ser um n��mero inteiro maior que 1GB."
-
-msgid "Template base image must be a valid local image file"
-msgstr "Imagem base do modelo deve ser um arquivo de imagem local v��lido"
-
-#, python-format
-msgid "Cannot identify base image %(path)s format"
-msgstr "N��o foi poss��vel identificar o formato da imagem base %(path)s"
-
-msgid ""
-"When specifying CPU topology, VCPUs must be a product of sockets, cores, and
"
-"threads."
-msgstr ""
-"Ao especificar a topologia de CPU, VCPUs deve ser um produto de sockets, "
-"cores e threads."
-
-msgid ""
-"When specifying CPU topology, each element must be an integer greater than "
-"zero."
-msgstr ""
-"Ao especificar a topologia de CPU, cada elemento deve ser um n��mero inteiro
"
-"maior do que zero."
-
-msgid ""
-"Invalid disk image format. Valid formats: bochs, cloop, cow, dmg, qcow, "
-"qcow2, qed, raw, vmdk, vpc."
-msgstr ""
-"Formato de imagem de disco inv��lido. Formatos v��lidos: bochs, cloop, cow, "
-"dmg, qcow, qcow2, qed, raw, vmdk, vpc."
-
-#, python-format
-msgid "Storage pool %(name)s already exists"
-msgstr "Storage pool %(name)s j�� existe"
-
-#, python-format
-msgid "Storage pool %(name)s does not exist"
-msgstr "Storage pool %(name)s n��o existe"
-
-#, python-format
-msgid "Specify %(item)s in order to create the storage pool %(name)s"
-msgstr "Especifique %(item)s para criar o storage pool %(name)s"
-
-#, python-format
-msgid "Unable to delete active storage pool %(name)s"
-msgstr "N��o foi poss��vel remover o storage pool ativo %(name)s"
-
-#, python-format
-msgid "Unable to list storage pools. Details: %(err)s"
-msgstr "N��o foi poss��vel listar os storage pools. Detalhes: %(err)s"
-
-#, python-format
-msgid "Unable to create storage pool %(name)s. Details: %(err)s"
-msgstr "N��o foi poss��vel criar o storage pool %(name)s. Detalhes: %(err)s"
-
-#, python-format
-msgid ""
-"Unable to get number of storage volumes in storage pool %(name)s. Details: %"
-"(err)s"
-msgstr ""
-"N��o foi poss��vel saber o n��mero de volumes no storage pool %(name)s. "
-"Detalhes: %(err)s"
-
-#, python-format
-msgid "Unable to activate storage pool %(name)s. Details: %(err)s"
-msgstr "N��o foi possivel ativar o storage pool %(name)s. Detalhes: %(err)s"
-
-#, python-format
-msgid "Unable to deactivate storage pool %(name)s. Details: %(err)s"
-msgstr "N��o foi possivel desativar o storage pool %(name)s. Detalhes:
%(err)s"
-
-#, python-format
-msgid "Unable to delete storage pool %(name)s. Details: %(err)s"
-msgstr "N��o foi possivel remover o storage pool %(name)s. Detalhes: %(err)s"
-
-#, python-format
-msgid ""
-"Unable to create NFS Pool as export path %(path)s may block during mount"
-msgstr ""
-"N��o foi poss��vel criar Pool NFS uma vez que o caminho de exporta����o %(path)s
"
-"pode bloquear durante a montagem"
-
-#, python-format
-msgid "Unable to create NFS Pool as export path %(path)s mount failed"
-msgstr ""
-"N��o foi poss��vel criar NFS Pool uma vez que a montagem do caminho de "
-"exporta����o %(path)s falhou"
-
-#, python-format
-msgid "Unsupported storage pool type: %(type)s"
-msgstr "Tipo de storage pool n��o suportado: %(type)s"
-
-#, python-format
-msgid "Error while retrieving storage pool XML to %(pool)s"
-msgstr "Erro durante a leitura do XML do storage pool %(pool)s"
-
-msgid "Storage pool name must be a string without slashes (/)"
-msgstr ""
-
-msgid ""
-"Supported storage pool types are dir, netfs, logical, iscsi, isci and
kimchi-"
-"iso"
-msgstr ""
-"Tipos de storage pool supportados s��o dir, netfs, logical, iscsi, scsi e "
-"kimchi-iso"
-
-msgid "Storage pool path must be a string"
-msgstr "Caminho para storage pool deve ser um texto"
-
-msgid "Storage pool host must be a IP or hostname"
-msgstr "Host do storage pool deve ser um IP ou um hostname"
-
-msgid "Storage pool device must be the absolute path to the block device"
-msgstr ""
-"Dispositivo do storage pool deve ser o caminho absoluto para o block device"
-
-msgid "Storage pool devices parameter must be a list"
-msgstr "Par��metro dos dispositivos do storage pool devem ser uma lista"
-
-msgid "Target IQN of an iSCSI pool must be a string"
-msgstr "Alvo IQN de um pool iSCSI deve ser um texto"
-
-msgid "Port of a remote storage server must be an integer between 1 and 65535"
-msgstr ""
-"Porta de um servidor remoto de storage deve ser um inteiro entre 1 e 65535"
-
-msgid "iSCSI target username must be a string"
-msgstr "Usu��rio do iSCSI target deve ser um texto"
-
-msgid "iSCSI target password must be a string"
-msgstr "Senha do iSCSI target deve ser um texto"
-
-msgid "Specify name and type to create a storage pool"
-msgstr "Especifique o nome e o tipo para criar um storage pool"
-
-#, python-format
-msgid ""
-"%(disk)s is not a valid disk/partition. Could not add it to the pool %(pool)"
-"s."
-msgstr ""
-"%(disk)s n��o �� um disco/parti����o v��lido. N��o foi poss��vel adicion��-lo ao
"
-"pool %(pool)s."
-
-#, python-format
-msgid "Unable to extend logical pool %(pool)s. Details: %(err)s"
-msgstr "N��o foi poss��vel extender o pool l��gico %(pool)s. Detalhes:
%(err)s"
-
-msgid "The parameter disks only can be updated for logical storage pool."
-msgstr ""
-"O par��metro discos somente pode ser atualizado para storage pool l��gicos."
-
-msgid "The SCSI host adapter name must be a string."
-msgstr "O nome do adaptador SCSI host deve ser um texto"
-
-msgid "The storage pool kimchi_isos is reserved for internal use"
-msgstr "O storage pool kimchi_isos �� reservado para uso interno"
-
-#, python-format
-msgid ""
-"Unable to activate NFS storage pool %(name)s. NFS server %(server)s is "
-"unreachable."
-msgstr ""
-"N��o foi poss��vel ativar o storage pool NFS %(name)s. Servidor NFS %(server)s
"
-"est�� inacess��vel."
-
-#, python-format
-msgid ""
-"Unable to deactivate NFS storage pool %(name)s. NFS server %(server)s is "
-"unreachable."
-msgstr ""
-"N��o foi poss��vel desativar o storage pool NFS %(name)s. Servidor NFS %"
-"(server)s est�� inacess��vel."
-
-#, python-format
-msgid ""
-"Unable to deactivate pool %(name)s as it is associated with some templates"
-msgstr ""
-"N��o foi poss��vel desativar o pool %(name)s uma vez que ele est�� associado
"
-"com algum dos modelos"
-
-#, python-format
-msgid "Unable to delete pool %(name)s as it is associated with some templates"
-msgstr ""
-"N��o foi poss��vel remover o pool %(name)s uma vez que ele est�� associado com
"
-"algum dos modelos"
-
-#, python-format
-msgid ""
-"A volume group named '%(name)s' already exists. Please, choose another name
"
-"to create the logical pool."
-msgstr ""
-"Um grupo de volume chamado '%(name)s' j�� existe. Por favor, escolha outro
"
-"nome para criar o pool l��gico."
-
-#, python-format
-msgid "Unable to update database with deep scan information due error:
%(err)s"
-msgstr ""
-"N��o foi poss��vel atualizar a base de dados com informa����es de mais ISOs "
-"devido a um erro: %(err)s"
-
-#, python-format
-msgid "Storage volume %(name)s already exists"
-msgstr "Volume de storage %(name)s j�� existe"
-
-#, python-format
-msgid "Storage volume %(name)s does not exist in storage pool %(pool)s"
-msgstr "Volume de storage %(name)s n��o existe no storage pool %(pool)s"
-
-#, python-format
-msgid ""
-"Unable to create storage volume %(volume)s because storage pool %(pool)s is "
-"not active"
-msgstr ""
-"N��o foi poss��vel criar o storaget volume %(volume)s pois o storage pool %"
-"(pool)s n��o est�� ativo"
-
-#, python-format
-msgid "Specify %(item)s in order to create storage volume %(volume)s"
-msgstr "Especifique %(item)s para poder criar o volume %(volume)s"
-
-#, python-format
-msgid ""
-"Unable to list storage volumes because storage pool %(pool)s is not active"
-msgstr ""
-"N��o foi poss��vel listar volumes pois o storage pool %(pool)s n��o est��
ativo"
-
-#, python-format
-msgid ""
-"Unable to create storage volume %(name)s in storage pool %(pool)s. Details:
%"
-"(err)s"
-msgstr ""
-"N��o foi poss��vel criar o volume %(name)s no storage pool %(pool)s. Detalhes:
"
-"%(err)s"
-
-#, python-format
-msgid ""
-"Unable to list storage volumes in storage pool %(pool)s. Details: %(err)s"
-msgstr ""
-"N��o foi poss��vel listar os volumes do storage pool %(pool)s. Detalhes:
%(err)"
-"s"
-
-#, python-format
-msgid "Unable to wipe storage volumes %(name)s. Details: %(err)s"
-msgstr "N��o foi poss��vel limpar o volume %(name)s. Detalhes: %(err)s"
-
-#, python-format
-msgid "Unable to delete storage volume %(name)s. Details: %(err)s"
-msgstr "N��o foi poss��vel remover o volume %(name)s. Detalhes: %(err)s"
-
-#, python-format
-msgid "Unable to resize storage volume %(name)s. Details: %(err)s"
-msgstr "N��o foi poss��vel redimensionar o volume %(name)s. Detalhes: %(err)s"
-
-#, python-format
-msgid "Storage type %(type)s does not support volume create and delete"
-msgstr "Storage do tipo %(type)s n��o suporta cria����o ou remo����o de
volume"
-
-msgid "Storage volume name must be a string"
-msgstr "Nome do volume deve ser um texto"
-
-msgid "Storage volume allocation must be an integer number"
-msgstr "Aloca����o do volume de storage deve ser um n��mero inteiro"
-
-msgid ""
-"Storage volume format not supported. Valid formats: bochs, cloop, cow, dmg, "
-"qcow, qcow2, qed, raw, vmdk, vpc."
-msgstr ""
-"Formato de volume de storage inv��lido. Formatos v��lidos: bochs, cloop, cow,
"
-"dmg, qcow, qcow2, qed, raw, vmdk, vpc."
-
-msgid "Storage volume requires a volume name"
-msgstr "Volume de storage requer um nome"
-
-#, python-format
-msgid ""
-"Unable to update database with storage volume information due error: %(err)s"
-msgstr ""
-"N��o foi poss��vel atualizar a base de dados com informa����es de volume de "
-"storage devido a um erro: %(err)s"
-
-#, python-format
-msgid "Only one of parameter %(param)s can be specified"
-msgstr "Somente um par��metro %(param)s pode ser especificado"
-
-#, python-format
-msgid "Create volume from %(param)s is not supported"
-msgstr "Criar um volume a partir de %(param)s n��o �� suportado"
-
-msgid "Storage volume capacity must be an integer number."
-msgstr "A capacidade do storage volume deve ser um n��mero inteiro."
-
-msgid "Storage volume URL must be http://, https://, ftp:// or ftps://."
-msgstr ""
-"URL para o storage volume deve ser http://, https://, ftp:// ou ftps://."
-
-#, python-format
-msgid "Unable to access file %(url)s. Please, check it."
-msgstr "Erro ao acessar arquivo %(url)s. Por favor, verifique isso."
-
-#, python-format
-msgid ""
-"Unable to clone storage volume '%(name)s' in pool '%(pool)s'.
Details: %(err)"
-"s"
-msgstr ""
-"N��o foi poss��vel clonar o volume de storage '%(name)s' no pool
'%(pool)s'. "
-"Detalhes: %(err)s"
-
-msgid "Specify chunk data and its size to upload a file."
-msgstr ""
-
-msgid "In order to upload a storage volume, specify the 'upload'
parameter."
-msgstr ""
-
-msgid ""
-"Unable to upload chunk data as it does not match with requested chunk size."
-msgstr ""
-
-#, python-format
-msgid "The storage volume %(vol)s is not under an upload process."
-msgstr ""
-
-msgid "The upload chunk data will exceed the storage volume size."
-msgstr ""
-
-#, python-format
-msgid "Unable to upload chunk data to storage volume. Details: %(err)s."
-msgstr ""
-
-#, python-format
-msgid "Interface %(name)s does not exist"
-msgstr "Interface %(name)s n��o existe"
-
-#, python-format
-msgid "Network %(name)s already exists"
-msgstr "Rede %(name)s j�� existe"
-
-#, python-format
-msgid "Network %(name)s does not exist"
-msgstr "Rede %(name)s n��o existe"
-
-#, python-format
-msgid "Subnet %(subnet)s specified for network %(network)s is not valid."
-msgstr ""
-"A subrede %(subnet)s especificada para a rede %(network)s n��o �� v��lida."
-
-#, python-format
-msgid "Specify a network interface to create bridged network %(name)s"
-msgstr "Especifique uma interface de rede para criar a rede de bridge
%(name)s"
-
-#, python-format
-msgid "Unable to delete active network %(name)s"
-msgstr "N��o foi poss��vel remover a rede ativa %(name)s"
-
-#, python-format
-msgid "Interface %(iface)s specified for network %(network)s is already in
use"
-msgstr ""
-"A interface %(iface)s especificada para a rede %(network)s j�� est�� em uso"
-
-msgid "Interface should be bare NIC, bonding or bridge device."
-msgstr "Interface deve ser 'bare NIC', 'bonding' ou 'dispositivo
de bridge'."
-
-#, python-format
-msgid "Unable to create network %(name)s. Details: %(err)s"
-msgstr "N��o foi poss��vel criar a rede %(name)s. Detalhes: %(err)s"
-
-#, python-format
-msgid "Unable to find a free IP address for network '%(name)s'"
-msgstr "N��o foi poss��vel encontrar um endere��o IP livre para a rede
'%(name)s'"
-
-#, python-format
-msgid "The interface %(iface)s already exists."
-msgstr "A interface %(iface)s j�� existe"
-
-msgid "Network name must be a string without slashes (/) or quotes (\")"
-msgstr ""
-
-msgid "Supported network types are isolated, NAT and bridge"
-msgstr "Tipos de rede suportados s��o isolada, NAT e bridge"
-
-msgid "Network subnet must be a string with IP address and prefix or netmask"
-msgstr ""
-"Subrede deve ser um texto com endere��o IP e prefixo, ou m��scara de rede"
-
-msgid "Network interface must be a string"
-msgstr "Interface de rede deve ser um texto"
-
-msgid "Network VLAN ID must be an integer between 1 and 4094"
-msgstr "ID da rede VLAN deve ser um inteiro entre 1 e 4094"
-
-msgid "Specify name and type to create a Network"
-msgstr "Especifique o nome e o tipo para criar uma rede"
-
-#, python-format
-msgid ""
-"Unable to delete network %(name)s. There are some virtual machines %(vms)s "
-"and/or templates linked to this network."
-msgstr ""
-"N��o foi poss��vel desativar a rede %(name)s. H�� alguma m��quina virtual
%(vms)"
-"s e/ou modelo associados a esta rede."
-
-#, python-format
-msgid ""
-"Unable to deactivate network %(name)s. There are some virtual machines
%(vms)"
-"s and/or templates linked to this network."
-msgstr ""
-"N��o foi poss��vel desativar a rede %(name)s. H�� alguma m��quina virtual
%(vms)"
-"s e/ou modelo associados a esta rede."
-
-#, python-format
-msgid "Bridge device %(name)s can not be the trunk device of a VLAN."
-msgstr ""
-"Dispositivo da bridge %(name)s n��o pode ser um dispositivo vinculado a uma "
-"VLAN."
-
-#, python-format
-msgid "Failed to activate interface %(iface)s: %(err)s."
-msgstr "N��o foi poss��vel ativar a interface %(iface)s: %(err)s."
-
-#, python-format
-msgid ""
-"Failed to activate interface %(iface)s. Please check the physical link "
-"status."
-msgstr ""
-"N��o foi poss��vel ativar a interface %(iface)s. Por favor, verifique o status
"
-"da conex��o f��sica."
-
-#, python-format
-msgid "Failed to start network %(name)s. Details: %(err)s"
-msgstr "N��o foi poss��vel iniciar a rede %(name)s. Detalhes: %(err)s"
-
-#, python-format
-msgid "Debug report %(name)s does not exist"
-msgstr "Relat��rio de debug %(name)s n��o existe"
-
-msgid "Debug report tool not found in system"
-msgstr "Ferramenta de relat��rio de debug n��o encontrada no sistema"
-
-#, python-format
-msgid "Unable to create debug report %(name)s. Details: %(err)s."
-msgstr ""
-"N��o foi poss��vel criar o relat��rio de debug %(name)s. Detalhes: %(err)s."
-
-#, python-format
-msgid "Can not find any debug report with the given name %(name)s"
-msgstr "N��o foi poss��vel encontrar nenhum relat��rio com o nome %(name)s"
-
-#, python-format
-msgid "Unable to generate debug report %(name)s. Details: %(err)s"
-msgstr ""
-"N��o foi poss��vel gerar o relat��rio de debug %(name)s. Detalhes: %(err)s"
-
-msgid "You should give a name for the debug report file."
-msgstr "Voc�� deve dar um nome para o arquivo do relat��rio de debug."
-
-msgid ""
-"Debug report name must be a string. Only letters, digits, underscore ('_')
"
-"and hyphen ('-') are allowed."
-msgstr ""
-"Nome do relat��rio deve ser um texto. Somente letras, digitos, underscore "
-"('_') e h��fem ('-') s��o permitidos."
-
-#, python-format
-msgid ""
-"The debug report with specified name \"%(name)s\" already exists. Please
use "
-"another one."
-msgstr ""
-"O relat��rio de debug com o nome especificado \"%(name)s\" j�� existe.
Por "
-"favor, use outro nome."
-
-#, python-format
-msgid "Storage server %(server)s was not used by Kimchi"
-msgstr "Servidor de storage %(server)s n��o foi usado pelo Kimchi"
-
-#, python-format
-msgid "Distro '%(name)s' does not exist"
-msgstr "Distribui����o '%(name)s' n��o existe"
-
-#, python-format
-msgid "Partition %(name)s does not exist in the host"
-msgstr "Parti����o %(name)s n��o existe no host"
-
-msgid "Unable to shutdown host machine as there are running virtual machines"
-msgstr ""
-"N��o foi poss��vel desligar o host uma vez que h�� m��quinas virtuais
ligadas"
-
-msgid "Unable to reboot host machine as there are running virtual machines"
-msgstr ""
-"N��o foi poss��vel resetar o host uma vez que h�� m��quinas virtuais ligadas"
-
-#, python-format
-msgid "Node device '%(name)s' not found"
-msgstr "Dispositivo de n�� '%(name)s' n��o encontrado"
-
-msgid "Conflicting flag filters specified."
-msgstr "Foram especificados filtros de flag com conflito."
-
-msgid "No packages marked for update"
-msgstr "Nenhum pacote marcado para atualiza����o"
-
-#, python-format
-msgid "Package %(name)s is not marked to be updated."
-msgstr "Pacote %(name)s n��o est�� marcado para atualiza����o."
-
-#, python-format
-msgid "Error while getting packages marked to be updated. Details: %(err)s"
-msgstr "Erro ao buscar pacotes marcados para atualiza����o. Detalhes: %(err)s"
-
-msgid "There is no compatible package manager for this system."
-msgstr "N��o h�� gerenciador de pacotes compat��vel para este sistema."
-
-#, python-format
-msgid "Invalid URI %(uri)s"
-msgstr "URI %(uri)s inv��lida"
-
-msgid "Unable to choose a virtual machine name"
-msgstr "N��o foi poss��vel escolher um nome para a m��quina virtual"
-
-msgid "Invalid storage type. Types supported: 'cdrom', 'disk'"
-msgstr "Tipo de storage inv��lido. Tipos suportados: 'cdrom',
'disco'"
-
-#, python-format
-msgid "The path '%(value)s' is not a valid local/remote path for the
device"
-msgstr ""
-"O caminho '%(value)s' n��o �� um caminho local/remoto v��lido para este
"
-"dispositivo"
-
-msgid "Only CDROM path can be update."
-msgstr "Apenas o caminho do CD-ROM pode ser atualizado."
-
-#, python-format
-msgid ""
-"The storage device %(dev_name)s does not exist in the virtual machine %"
-"(vm_name)s"
-msgstr "O disco %(dev_name)s n��o existe na m��quina virtual %(vm_name)s"
-
-#, python-format
-msgid "Error while creating new storage device: %(error)s"
-msgstr "Erro ao criar novo dispositivo de storage: %(error)s"
-
-#, python-format
-msgid "Error while updating storage device: %(error)s"
-msgstr "Erro ao atualizar dispositivo de storage: %(error)s"
-
-#, python-format
-msgid "Error while removing storage device: %(error)s"
-msgstr "Erro ao remover dispositivo de storage: %(error)s"
-
-msgid "Do not support IDE device hot plug"
-msgstr "Dispositivo IDE hot plug n��o �� suportado"
-
-msgid ""
-"Specify type and path or type and pool/volume to add a new virtual machine "
-"disk"
-msgstr ""
-"Especifique o tipo e o caminho, ou o tipo e o pool/volume, para adicionar um
"
-"novo disco da m��quina virtual"
-
-msgid "Specify path to update virtual machine disk"
-msgstr "Especifique o caminho para atualizar o disco da m��quina virtual"
-
-#, python-format
-msgid "Controller type %(type)s limitation of %(limit)s devices reached"
-msgstr ""
-"Limita����o do tipo do controlador %(type)s de %(limit)s dispositivos foi "
-"alcan��ada"
-
-#, python-format
-msgid "Cannot retrieve disk path information for given pool/volume: %(error)s"
-msgstr ""
-"N��o foi poss��vel buscar informa����es do caminho do disco para o pool/volume
"
-"dado: %(error)s"
-
-msgid "Volume already in use by other virtual machine."
-msgstr "Volume j�� em uso por outra m��quina virtual."
-
-msgid ""
-"Only one of path or pool/volume can be specified to add a new virtual "
-"machine disk"
-msgstr ""
-"Somente um caminho ou pool/volume pode ser especificado para adicionar um "
-"novo disco da m��quina virtual."
-
-#, python-format
-msgid ""
-"Volume chosen with format %(format)s does not fit in the storage type
%(type)"
-"s"
-msgstr ""
-"Volume escolhido com formato %(format)s n��o se enquadra no tipo de storage
%"
-"(type)s"
-
-msgid "YUM Repository ID must be one word only string."
-msgstr "ID do reposit��rio YUM deve ser apenas uma palavra."
-
-msgid "Repository URL must be an http://, ftp:// or file:// URL."
-msgstr "URL do reposit��rio deve ser uma URL http://, ftp:// ou file://."
-
-msgid ""
-"Repository configuration is a dictionary with specific values according to "
-"repository type."
-msgstr ""
-"Configura����o do reposit��rio �� um dicion��rio com valores espec��ficos de
"
-"acordo com o tipo do reposit��rio."
-
-msgid "Distribution to DEB repository must be a string"
-msgstr "Distribui����o para o reposit��rio DEB deve ser um texto"
-
-msgid "Components to DEB repository must be listed in a array"
-msgstr "Componentes para o reposit��rio DEB deve ser um array"
-
-msgid "Components to DEB repository must be a string"
-msgstr "Componentes para o reposit��rio DEB deve ser um texto"
-
-msgid "Mirror list to repository must be a string"
-msgstr ""
-
-msgid "YUM Repository name must be string."
-msgstr "Nome do reposit��rio YUM deve ser um texto."
-
-msgid "GPG check must be a boolean value."
-msgstr "Verifica����o de GPG deve ser um valor booleano."
-
-msgid "GPG key must be a URL pointing to the ASCII-armored file."
-msgstr ""
-"Chave GPG deve ser uma URL apontando para o arquivo no formato ASCII-armor."
-
-#, python-format
-msgid "Could not update repository %(repo_id)s."
-msgstr "N��o foi poss��vel atualizar o reposit��rio %(repo_id)s."
-
-#, python-format
-msgid "Repository %(repo_id)s does not exist."
-msgstr "Reposit��rio %(repo_id)s n��o existe."
-
-msgid ""
-"Specify repository base URL, mirror list or metalink in order to create or "
-"update a YUM repository."
-msgstr ""
-
-msgid "Repository management tool was not recognized for your system."
-msgstr ""
-"Ferramenta de gerenciamento de reposit��rio n��o foi reconhecida no seu "
-"sistema."
-
-#, python-format
-msgid "Repository %(repo_id)s is already enabled."
-msgstr "Reposit��rio %(repo_id)s j�� est�� habilitado."
-
-#, python-format
-msgid "Repository %(repo_id)s is already disabled."
-msgstr "Reposit��rio %(repo_id)s j�� est�� desabilitado."
-
-#, python-format
-msgid "Could not remove repository %(repo_id)s."
-msgstr "N��o foi poss��vel remover o reposit��rio %(repo_id)s."
-
-#, python-format
-msgid "Could not write repository configuration file %(repo_file)s"
-msgstr ""
-"N��o foi poss��vel gravar o arquivo de configura����o do reposit��rio
%(repo_file)"
-"s"
-
-msgid "Specify repository distribution in order to create a DEB repository."
-msgstr ""
-"Especificar o reposit��rio de distribui����o para poder criar o reposit��rio
DEB."
-
-#, python-format
-msgid "Could not enable repository %(repo_id)s."
-msgstr "N��o foi poss��vel habilitar o reposit��rio %(repo_id)s."
-
-#, python-format
-msgid "Could not disable repository %(repo_id)s."
-msgstr "N��o foi poss��vel desabilitar o reposit��rio %(repo_id)s."
-
-msgid "YUM Repository ID already exists"
-msgstr "ID do reposit��rio YUM j�� existe"
-
-msgid "YUM Repository name must be a string"
-msgstr "Nome do reposit��rio YUM deve ser um texto"
-
-#, python-format
-msgid "Unable to list repositories. Details: '%(err)s'"
-msgstr "N��o �� poss��vel listar os reposit��rios. Detalhes:
'%(err)s'"
-
-#, python-format
-msgid "Unable to retrieve repository information. Details: '%(err)s'"
-msgstr ""
-"N��o foi poss��vel carregar as informa����es do reposit��rio. Detalhes:
'%(err)s'"
-
-#, python-format
-msgid "Unable to add repository. Details: '%(err)s'"
-msgstr "N��o foi poss��vel adicionar o reposit��rio. Detalhes:
'%(err)s'"
-
-#, python-format
-msgid "Unable to remove repository. Details: '%(err)s'"
-msgstr "N��o foi poss��vel remover o reposit��rio. Detalhes:
'%(err)s'"
-
-#, python-format
-msgid ""
-"Configuration items: '%(items)s' are not supported by repository
manager"
-msgstr ""
-"Itens de configura����o '%(items)s' n��o s��o suportados pelo gerenciador
de "
-"reposit��rios."
-
-msgid "Repository metalink must be an http://, ftp:// or file:// URL."
-msgstr ""
-
-msgid "Cannot specify mirrorlist and metalink at the same time."
-msgstr ""
-
-#, python-format
-msgid ""
-"Virtual machine '%(vm)s' must be stopped before creating a snapshot of
it."
-msgstr ""
-"A m��quina virtual '%(vm)s' deve estar parada antes de criar um snapshot
dela"
-
-#, python-format
-msgid ""
-"Unable to create snapshot '%(name)s' on virtual machine '%(vm)s'.
Details: %"
-"(err)s"
-msgstr ""
-"N��o foi poss��vel criar o snapshot '%(name)s' na m��quina virtual
'%(vm)s'. "
-"Detalhes: %(err)s"
-
-#, python-format
-msgid "Snapshot '%(name)s' does not exist on virtual machine
'%(vm)s'."
-msgstr "O snapshot '%(name)s' n��o existe na m��quina virtual
'%(vm)s'."
-
-#, python-format
-msgid ""
-"Unable to retrieve snapshot '%(name)s' on virtual machine '%(vm)s'.
Details: "
-"%(err)s"
-msgstr ""
-"N��o foi poss��vel recuperar o snapshot '%(name)s' da m��quina virtual
'%(vm)"
-"s'. Detalhes: %(err)s"
-
-#, python-format
-msgid "Unable to list snapshots on virtual machine '%(vm)s'. Details:
%(err)s"
-msgstr ""
-"N��o foi poss��vel listar os snapshots da m��quina virtual '%(vm)s'.
Detalhes: %"
-"(err)s"
-
-#, python-format
-msgid ""
-"Unable to delete snapshot '%(name)s' on virtual machine '%(vm)s'.
Details: %"
-"(err)s"
-msgstr ""
-"N��o foi poss��vel remover o snapshot '%(name)s' da m��quina virtual
'%(vm)s'. "
-"Detalhes: %(err)s"
-
-#, python-format
-msgid ""
-"Unable to retrieve current snapshot of virtual machine '%(vm)s'. Details:
%"
-"(err)s"
-msgstr ""
-"N��o foi poss��vel recuperar o snapshot atual da m��quina virtual '%(vm)s'.
"
-"Detalhes: %(err)s."
-
-#, python-format
-msgid ""
-"Unable to revert virtual machine '%(vm)s' to snapshot '%(name)s'.
Details: %"
-"(err)s"
-msgstr ""
-"N��o foi poss��vel reverter a m��quina virtual '%(vm)s' para o snapshot
'%(name)"
-"s'. Detalhes: %(err)s"
-
-#, python-format
-msgid ""
-"Unable to create snapshot of virtual machine '%(vm)s' because it contains a
"
-"disk with format '%(format)s'; only 'qcow2' is supported."
-msgstr ""
-"N��o foi poss��vel criar o snapshot para a m��quina virtual '%(vm)s' porque
ela "
-"cont��m discos no formato '%(format)s'; somente 'qcow2' ��
suportado."
-
-msgid "The number of vCPUs is too large for this system."
-msgstr "O n��mero de VCPUs �� grande demais para esse sistema."
-
-msgid "Invalid vCPU/topology combination."
-msgstr "Combina����o inv��lida de VCPU/topologia."
-
-msgid "This host (or current configuration) does not allow CPU topology."
-msgstr "Este host (ou configura����o atual) n��o permite topologia de CPU."
-
-msgid "ERROR CODE"
-msgstr "C��DIGO DE ERRO"
-
-msgid "REASON"
-msgstr "MOTIVO"
-
-msgid "STACK"
-msgstr "PILHA"
-
-msgid "Go to Homepage"
-msgstr "Ir para a P��gina Inicial"
-
-msgid "Create a New Virtual Machine"
-msgstr "Criar nova M��quina Virtual"
-
-msgid "Virtual Machine Name"
-msgstr "Nome da M��quina Virtual"
-
-msgid ""
-"The name used to identify the virtual machine. If omitted, a name will be "
-"chosen based on the template used."
-msgstr ""
-"O nome usado para identificar a m��quina virtual. Se ele for omitido, a "
-"escolha ser�� baseada no modelo selecionado."
-
-msgid "Template"
-msgstr "Modelo"
-
-msgid "Please create a template first."
-msgstr "Por favor, crie um modelo primeiro."
-
-msgid "Create a Template"
-msgstr "Criar um Modelo"
-
-msgid "Please choose a template."
-msgstr "Por favor, escolha um modelo."
-
-msgid "OS"
-msgstr "Sistema Operacional"
-
-msgid "OS Version"
-msgstr "Vers��o do Sistema Speracional"
-
-msgid "CPUS"
-msgstr "CPUS"
-
-msgid "Memory"
-msgstr "Mem��ria"
-
-msgid "Create"
-msgstr "Criar"
-
-msgid "Creating..."
-msgstr "Criando..."
-
-msgid "Cancel"
-msgstr "Cancelar"
-
-msgid "Edit Guest"
-msgstr "Editar Guest"
-
-msgid "General"
-msgstr "Geral"
-
-msgid "Storage"
-msgstr "Storage"
-
-msgid "Interface"
-msgstr "Interface"
-
-msgid "Permission"
-msgstr "Permiss��o"
-
-msgid "Host PCI Device"
-msgstr "Dispositivo de host PCI"
-
-msgid "Snapshot"
-msgstr "Snapshot"
-
-msgid "Name"
-msgstr "Nome"
-
-msgid "CPUs"
-msgstr "CPUs"
-
-msgid "Memory (MB)"
-msgstr "Mem��ria (MB)"
-
-msgid "Icon"
-msgstr "��cone"
-
-msgid "Device"
-msgstr "Dispositivo"
-
-msgid "Path"
-msgstr "Caminho"
-
-msgid "Network"
-msgstr "Rede"
-
-msgid "Type"
-msgstr "Tipo"
-
-msgid "MAC Address"
-msgstr ""
-
-msgid "Available system users and groups"
-msgstr "Usu��rios e grupos de sistema dispon��veis"
-
-msgid "Selected system users and groups"
-msgstr "Usu��rios e grupos de sistema selecionados"
-
-msgid "User"
-msgstr "Usu��rio"
-
-msgid "All"
-msgstr "Todos"
-
-msgid "To Add"
-msgstr "Para adicionar"
-
-msgid "Added"
-msgstr "Adicionado"
-
-msgid "filter"
-msgstr "filtro"
-
-msgid "Product"
-msgstr "Produto"
-
-msgid "Vendor"
-msgstr "Vendor"
-
-msgid "Created"
-msgstr "Criado"
-
-msgid "Save"
-msgstr "Salvar"
-
-msgid "Replace"
-msgstr "Substituir"
-
-msgid "Detach"
-msgstr "Remover"
-
-msgid "revert"
-msgstr "Reverter"
-
-msgid "Start"
-msgstr "Iniciar"
-
-msgid "Reset"
-msgstr "Reiniciar"
-
-msgid "Pause"
-msgstr ""
-
-msgid "Resume"
-msgstr ""
-
-msgid "Power Off"
-msgstr "For��ar desligamento"
-
-msgid "Actions"
-msgstr "A����es"
-
-msgid "Connect"
-msgstr "Conectar"
-
-msgid "Clone"
-msgstr "Clonar"
-
-msgid "Edit"
-msgstr "Editar"
-
-msgid "Shut Down"
-msgstr "Desligar"
-
-msgid "Delete"
-msgstr "Remover"
-
-msgid "CPU"
-msgstr "CPU"
-
-msgid "Disk I/O"
-msgstr "Disco E/S"
-
-msgid "Network I/O"
-msgstr "Rede E/S"
-
-msgid "Livetile"
-msgstr "Tela ao vivo"
-
-msgid "No guests found."
-msgstr "Nenhum guest encontrado."
-
-msgid "Add a Storage Device to VM"
-msgstr "Adicionar um dispositivo de storage �� VM"
-
-msgid "Device Type"
-msgstr "Tipo do Dispositivo"
-
-msgid "The device type. Currently, \"cdrom\" and \"disk\" are
supported."
-msgstr ""
-"O tipo do dispositivo. Atualmente, \"cdrom\" e \"disco\" s��o
suportados."
-
-msgid "Storage Pool"
-msgstr "Storage Pool"
-
-msgid "Storage pool which volume located in"
-msgstr "Storage pool no qual o volume est�� localizado"
-
-msgid "Storage Volume"
-msgstr "Volume de storage"
-
-msgid "Storage volume to be attached"
-msgstr "Volume de storage a ser adicionado"
-
-msgid "File Path"
-msgstr "Caminho do Arquivo"
-
-msgid "The ISO file path in the server for CDROM."
-msgstr "O caminho do arquivo ISO para o CDROM no servidor."
-
-msgid "Attach"
-msgstr "Adicionar"
-
-msgid "Shut down"
-msgstr "Desligar"
-
-msgid "Restart"
-msgstr "Reiniciar"
-
-msgid "Basic Information"
-msgstr "Informa����es b��sicas"
-
-msgid "OS Distro"
-msgstr "Distribui����o"
-
-msgid "OS Code Name"
-msgstr "Nome-c��digo do sistema operacional"
-
-msgid "Processor"
-msgstr "Processador"
-
-msgid "CPU(s)"
-msgstr "CPU(s)"
-
-msgid "System Statistics"
-msgstr "Estat��sticas do sistema"
-
-msgid "Software Updates"
-msgstr "Atualiza����es de software"
-
-msgid "Update Progress"
-msgstr "Progresso da atualiza����o"
-
-msgid "Repositories"
-msgstr "Reposit��rios"
-
-msgid "Debug Reports"
-msgstr "Relat��rios de Debug"
-
-msgid "The username or password you entered is incorrect. Please try again."
-msgstr ""
-"O usu��rio ou senha inseridos est��o incorretos. Por favor, tente novamente."
-
-msgid "This field is required."
-msgstr "Esse campo �� obrigat��rio."
-
-msgid "Log in"
-msgstr "Entrar"
-
-msgid "Logging in..."
-msgstr "Entrando..."
-
-msgid "Host"
-msgstr "Host"
-
-msgid "Guests"
-msgstr "Guests"
-
-msgid "Templates"
-msgstr "Modelos"
-
-msgid "Failed to get application configuration"
-msgstr "N��o foi poss��vel carregar as configura����es da aplica����o"
-
-msgid "This is not a valid Linux path"
-msgstr "Este n��o �� um caminho v��lido no Linux"
-
-msgid "This is not a valid URL."
-msgstr "Essa n��o �� uma URL v��lida."
-
-msgid "No such data available."
-msgstr "N��o h�� dados dispon��veis."
-
-msgid ""
-"Can not contact the host system. Verify the host system is up and that you "
-"have network connectivity to it. HTTP request response %1. "
-msgstr ""
-"N��o foi poss��vel contactar o sistema host. Verique se o sistema do host est��
"
-"ligado e se voc�� possui conectividade de rede com ele. Resposta da "
-"requisi����o HTTP %1. "
-
-msgid "Unable to read file."
-msgstr ""
-
-msgid "Error while uploading file."
-msgstr ""
-
-msgid "Delete Confirmation"
-msgstr "Confirma����o de remo����o"
-
-msgid "OK"
-msgstr "OK"
-
-msgid "Confirm"
-msgstr "Confirmar"
-
-msgid "Warning"
-msgstr "Aviso"
-
-msgid "Cloning..."
-msgstr ""
-
-msgid "Loading..."
-msgstr "Carregando..."
-
-msgid "An error occurred while retrieving system information."
-msgstr "Ocorreu um erro ao recuperar informa����es do sistema."
-
-msgid "Retry"
-msgstr "Tentar novamente"
-
-msgid "Detailed message:"
-msgstr "Mensagem detalhada:"
-
-msgid "No ISO found"
-msgstr "Nenhuma ISO encontrada"
-
-msgid "This is not a valid ISO file."
-msgstr "Esse n��o �� um arquivo ISO v��lido."
-
-msgid "This may take a long time. Do you want to continue?"
-msgstr "Isso vai levar um longo tempo. Deseja continuar?"
-
-msgid "This will permanently delete the template. Would you like to continue?"
-msgstr "O modelo vai ser permanentemente removido. Deseja continuar?"
-
-msgid "Unable to shut down system as there are some virtual machines running!"
-msgstr ""
-"N��o foi poss��vel desligar o sistema porque algumas m��quinas virtuais est��o
"
-"ligadas!"
-
-msgid "Max:"
-msgstr "M��ximo:"
-
-msgid "Utilization"
-msgstr "Utiliza����o"
-
-msgid "Available"
-msgstr "Dispon��vel"
-
-msgid "Read Rate"
-msgstr "Taxa de leitura"
-
-msgid "Write Rate"
-msgstr "Taxa de escrita"
-
-msgid "Received"
-msgstr "Recebido"
-
-msgid "Sent"
-msgstr "Enviado"
-
-msgid ""
-"Shutting down or restarting host will cause unsaved work lost. Continue to "
-"shut down/restarting?"
-msgstr ""
-"Desligar ou reiniciar o host causar�� perda de trabalho que n��o foi salvo. "
-"Continuar o processo de desligar/reiniciar?"
-
-msgid ""
-"Repository will be removed permanently and can't be recovered. Do you want
"
-"to continue?"
-msgstr ""
-"Reposit��rio ser�� removido permanentemente e n��o poder�� ser recuperado. "
-"Deseja continuar?"
-
-msgid "ID"
-msgstr "ID"
-
-msgid "Base URL"
-msgstr "URL Base"
-
-msgid "Is Mirror"
-msgstr "�� mirror"
-
-msgid "URL Args"
-msgstr "Argumentos da URL"
-
-msgid "Enabled"
-msgstr "Ativado"
-
-msgid "GPG Check"
-msgstr "Verifica����o GPG"
-
-msgid "GPG Key"
-msgstr "Chave GPG"
-
-msgid "Add"
-msgstr "Adicionar"
-
-msgid "Remove"
-msgstr "Remover"
-
-msgid "Enable"
-msgstr "Ativar"
-
-msgid "Disable"
-msgstr "Desativar"
-
-msgid "Package Name"
-msgstr "Nome do pacote"
-
-msgid "Version"
-msgstr "Vers��o"
-
-msgid "Architecture"
-msgstr "Arquitetura"
-
-msgid "Repository"
-msgstr "Reposit��rio"
-
-msgid "Update All"
-msgstr "Atualizar todos"
-
-msgid "Updating..."
-msgstr "Atualizando..."
-
-msgid "Failed to retrieve packages update information."
-msgstr "N��o foi poss��vel recuperar as informa����es de atualiza����o de
pacoates."
-
-msgid "Failed to update package(s)."
-msgstr "Erro ao atualizar pacote(s)."
-
-msgid ""
-"Debug report will be removed permanently and can't be recovered. Do you want
"
-"to continue?"
-msgstr ""
-"Relat��rio de debug ser�� permanentemente removido e n��o poder�� ser "
-"recuperado. Deseja continuar?"
-
-msgid "Generated Time"
-msgstr "Tempo gerado"
-
-msgid "Generate"
-msgstr "Gerar"
-
-msgid "Generating..."
-msgstr "Gerando..."
-
-msgid "Rename"
-msgstr "Renomear"
-
-msgid "Download"
-msgstr "Baixar"
-
-msgid ""
-"Report name should contain only letters, digits, underscore ('_') and/or
"
-"hyphen ('-')."
-msgstr ""
-"Nome do relat��rio deve apenas conter letras, n��meros, underscore ('_')
e/ou "
-"h��fen ('-')."
-
-msgid "Pending..."
-msgstr "Pendente..."
-
-msgid "Report name is the same as the original one."
-msgstr "Nome do relat��rio �� o mesmo que o original."
-
-msgid ""
-"This will delete the virtual machine and its virtual disks. This operation "
-"cannot be undone. Would you like to continue?"
-msgstr ""
-"A m��quina virtual vai ser removida com todos seus discos. Essa opera����o ��
"
-"irrevers��vel. Deseja continuar?"
-
-msgid "Power off Confirmation"
-msgstr "Confirma����o de desligamento for��ado"
-
-msgid ""
-"This action may produce undesirable results, for example unflushed disk "
-"cache in the guest. Would you like to continue?"
-msgstr ""
-"Essa a����o pode produzir resultados n��o desej��veis, como por exemplo cache de
"
-"disco n��o-atualizado no guest. Deseja continuar?"
-
-msgid "Reset Confirmation"
-msgstr "Confirma����o de reinicializa����o"
-
-msgid ""
-"There is a risk of data loss caused by reset without the guest OS shutdown. "
-"Would you like to continue?"
-msgstr ""
-"Existe um risco de perda de dados causado pela reinicializa����o sem o "
-"desligamento do sistema operacional do guest. Deseja continuar?"
-
-msgid "Shut Down Confirmation"
-msgstr "Confirma����o de desligamento"
-
-msgid "Note the guest OS may ignore this request. Would you like to continue?"
-msgstr ""
-"O sistema operacional do guest pode ignorar essa requisi����o. Deseja "
-"continuar?"
-
-msgid "Virtual Machine delete Confirmation"
-msgstr "Confirma����o de Remo����o da M��quina Virtual"
-
-msgid ""
-"This virtual machine is not persistent. Power Off will delete it. Continue?"
-msgstr ""
-"Essa m��quina virtual n��o �� persistente. O desligamento ir�� remov��-la. Deseja
"
-"continuar?"
-
-msgid ""
-"When the target guest has SCSI or iSCSI volumes, they will be cloned on "
-"default storage pool. The same will happen when the target pool does not "
-"have enough space to clone the volumes. Do you want to continue?"
-msgstr ""
-"Quando o guest de destino tiver volumes SCSI ou iSCSI, eles ser��o clonados "
-"no storage pool padr��o. O mesmo vai acontecer quando o pool de destino n��o
"
-"tiver espa��o suficiente para clonar os volumes. Voc�� deseja continuar?"
-
-msgid ""
-"This CDROM will be detached permanently and you can re-attach it. Continue "
-"to detach it?"
-msgstr ""
-"Esse CDROM ser�� desconectado permanentemente e voc�� pode reconect��-lo. "
-"Deseja continuar a remo����o? "
-
-msgid "Attaching..."
-msgstr "Adicionando..."
-
-msgid "Replacing..."
-msgstr "Substituindo..."
-
-msgid "Successfully attached!"
-msgstr "Adicionado com sucesso!"
-
-msgid "Successfully replaced!"
-msgstr "Substitu��do com sucesso!"
-
-msgid "Successfully detached!"
-msgstr "Removido com sucesso!"
-
-msgid ""
-"This disk will be detached permanently and you can re-attach it. Continue to
"
-"detach it?"
-msgstr ""
-"Esse disco ser�� desconectado permanentemente e voc�� pode reconect��-lo. "
-"Deseja continuar a remo����o? "
-
-msgid "interface:"
-msgstr "interface:"
-
-msgid "address:"
-msgstr "endere��o:"
-
-msgid "link_type:"
-msgstr "tipo do link:"
-
-msgid "block:"
-msgstr "bloco:"
-
-msgid "drive_type:"
-msgstr "tipo do drive:"
-
-msgid "model:"
-msgstr "modelo:"
-
-msgid "Affected devices:"
-msgstr "Dispositivos afetados:"
-
-msgid "The VLAN id must be between 1 and 4094."
-msgstr "ID da VLAN deve ser um n��mero entre 1 e 4094."
-
-msgid "unavailable"
-msgstr "indispon��vel"
-
-msgid ""
-"This action will interrupt network connectivity for any virtual machine that
"
-"depend on this network."
-msgstr ""
-"Esta a����o ir�� interromper a conectividade da rede para qualquer m��quina "
-"virtual que depende dessa rede."
-
-msgid "Create a network"
-msgstr "Criar uma rede"
-
-msgid ""
-"This network is not persistent. Instead of stop, this action will "
-"permanently delete it. Would you like to continue?"
-msgstr ""
-"Essa rede n��o �� persistente. Ao inv��s de parar, essa a����o ir�� remov��-la
"
-"permantemente. Deseja continuar?"
-
-msgid ""
-"The bridged VLAN tag may not work well with NetworkManager enabled. You "
-"should consider disabling it."
-msgstr ""
-
-msgid ""
-"This will permanently delete the storage pool. Would you like to continue?"
-msgstr "O storage pool vai ser permanentemente removido. Deseja continuar?"
-
-msgid "This storage pool is empty."
-msgstr "Esse storage pool est�� vazio."
-
-msgid ""
-"It will format your disk and you will loose any data in there, are you sure "
-"to continue? "
-msgstr ""
-"Isso formatar�� seu disco e voc�� perder�� toda informa����o, voc�� tem certeza
"
-"que quer continuar?"
-
-msgid "SCSI Fibre Channel"
-msgstr "SCSI Fibre Channel"
-
-msgid "No SCSI adapters found."
-msgstr "Nenhum adaptador SCSI encontrado."
-
-msgid "Loading iSCSI targets..."
-msgstr "Carregando iSCSI targets..."
-
-msgid "No iSCSI found. Please input one."
-msgstr "Nenhum iSCSI encontrado. Por favor, forne��a um."
-
-msgid "Failed to load iSCSI targets."
-msgstr "Erro ao carregar iSCSI targets."
-
-msgid "The storage pool name can not be blank."
-msgstr "O nome do storage pool n��o pode ser vazio."
-
-msgid "The storage pool path can not be blank."
-msgstr "O caminho do storage pool n��o pode ser vazio."
-
-msgid "NFS server mount path can not be blank."
-msgstr "Caminho de montagem do servidor de NFS n��o pode ser vazio."
-
-msgid "Invalid NFS mount path."
-msgstr "Caminho de montagem do NFS inv��lido."
-
-msgid "No logical device selected."
-msgstr "Nenhum dispositivo l��gico selecionado."
-
-msgid "The iSCSI target can not be blank."
-msgstr "O alvo iSCSI n��o pode ser vazio."
-
-msgid "Server name can not be blank."
-msgstr "Nome do servidor n��o pode ser vazio."
-
-msgid "This is not a valid Server Name or IP. Please, modify it."
-msgstr "Este n��o �� um nome ou IP de servidor v��lido. Por favor,
modifique-o."
-
-msgid "Looking for available partitions ..."
-msgstr "Procurando por parti����es dispon��veis ..."
-
-msgid "No available partitions found."
-msgstr "Nenhuma parti����o dispon��vel encontrada."
-
-msgid ""
-"This storage pool is not persistent. Instead of deactivate, this action will
"
-"permanently delete it. Would you like to continue?"
-msgstr ""
-"O storage pool n��o �� persistente. Ao inv��s de desativar, essa a����o vai "
-"remov��-lo permanentemente. Deseja continuar?"
-
-msgid "Unable to retrieve partitions information."
-msgstr "N��o foi poss��vel recuperar as informa����es das parti����es."
-
-msgid "In progress..."
-msgstr "Em progresso..."
-
-msgid "Failed!"
-msgstr "Falhou!"
-
-msgid "CDROM path needs to be a valid local/remote path and cannot be blank."
-msgstr ""
-"Caminho do CDROM precisa ser um caminho local v��lido e n��o pode ser vazio."
-
-msgid "Disk pool or volume cannot be blank."
-msgstr "Pool ou volume do disco n��o pode ser vazio."
-
-#, fuzzy
-msgid "Filter"
-msgstr "filtro"
-
-msgid "Network Name"
-msgstr "Nome da rede"
-
-msgid "State"
-msgstr "Estado"
-
-msgid "Network Type"
-msgstr "Tipo da rede"
-
-msgid "Address Space"
-msgstr "Espa��o de endere��o"
-
-msgid "Name should not contain '/' and '\"'."
-msgstr "O nome n��o deve conter '/' and '\"'."
-
-msgid "Isolated: no external network connection"
-msgstr "Isolada: nenhuma conex��o externa"
-
-msgid "NAT: outbound physical network connection only"
-msgstr "NAT: somente conex��o de rede f��sica de sa��da"
-
-msgid "Bridged: Virtual machines are connected to physical network directly"
-msgstr ""
-"Bridged: M��quinas virtuais est��o conectadas diretamente com a rede f��sica"
-
-msgid "(No interfaces found)"
-msgstr "(Nenhuma interface encontrada)"
-
-msgid "Destination"
-msgstr "Destino"
-
-msgid "Enable VLAN"
-msgstr "Habilitar VLAN"
-
-msgid "VLAN ID"
-msgstr "ID da VLAN"
-
-msgid "Stop"
-msgstr "Parar"
-
-msgid "Generate a New Debug Report"
-msgstr "Gerar um novo Relat��rio de Debug"
-
-msgid "Report Name"
-msgstr "Nome do Relat��rio"
-
-msgid ""
-"The name used to identify the report. If omitted, a name will be chosen "
-"based on current time. Name can contain: letters, digits, underscore
(\"_\") "
-"and hyphen (\"-\")."
-msgstr ""
-"O nome usado para identificar o relat��rio. Se omitido, um nome ser�� "
-"escolhido baseado no hor��rio atual. O nome pode conter: letras, n��meros, "
-"underscore ('_') e h��fen ('-')."
-
-msgid "Rename a Debug Report"
-msgstr "Renomear um Relat��rio de Debug"
-
-msgid ""
-"The name used to identify the report. Name can contain: letters, digits and "
-"hyphen (\"-\")."
-msgstr ""
-"O nome usado para identificar o relat��rio. O nome pode conter: letras, "
-"d��gitos e h��fen (\"-\")."
-
-msgid "Submit"
-msgstr "Enviar"
-
-msgid "Add a Repository"
-msgstr "Adicionar um Reposit��rio"
-
-msgid "Identifier"
-msgstr "Identificador"
-
-msgid "Single word, unique identifier for the repository."
-msgstr "Uma ��nica palavra, identificador ��nico para o reposit��rio."
-
-msgid "Textual name for the repository."
-msgstr "Nome textual para o reposit��rio."
-
-msgid "URL"
-msgstr "URL"
-
-msgid "Required Field"
-msgstr "Campo Obrigat��rio"
-
-msgid "URL to the repository. Supported protocols are http, ftp, and file."
-msgstr "URL para o reposit��rio. Protocolos suportados s��o http, ftp e file."
-
-msgid "Repository is a mirror"
-msgstr "Reposit��rio �� um mirror"
-
-msgid "Distribution"
-msgstr "Distribui����o"
-
-msgid "Distribution of the DEB repository."
-msgstr "Distribui����o para o reposit��rio DEB."
-
-msgid "Components"
-msgstr "Componentes"
-
-msgid "List of components in DEB repository."
-msgstr "Lista de componentes para o reposit��rio DEB."
-
-msgid "Edit Repository"
-msgstr "Editar Reposit��rio"
-
-msgid "Mirror List URL"
-msgstr "URL para a lista de mirror"
-
-msgid "Yes"
-msgstr "Sim"
-
-msgid "No"
-msgstr "N��o"
-
-msgid "Capacity"
-msgstr "Capacidade"
-
-msgid "Allocated"
-msgstr "Alocado"
-
-msgid "Location"
-msgstr "Localiza����o"
-
-msgid "Device path"
-msgstr "Caminho do dispositivo"
-
-msgid "active"
-msgstr "ativo"
-
-msgid "inactive"
-msgstr "inativo"
-
-msgid "Deactivate"
-msgstr "Desativar"
-
-msgid "Activate"
-msgstr "Ativar"
-
-msgid "Add Volume"
-msgstr "Adicionar volume"
-
-msgid "Extend"
-msgstr "Aumentar"
-
-msgid "Undefine"
-msgstr "Indefinir"
-
-msgid "Format"
-msgstr "Formato"
-
-msgid "Allocation"
-msgstr "Aloca����o"
-
-msgid "Define a New Storage Pool"
-msgstr "Definir novo Storage Pool"
-
-msgid "Storage Pool Name"
-msgstr "Nome do Storage Pool"
-
-msgid ""
-"The name used to identify the storage pools, and it should not be empty."
-msgstr "O nome usado para identificar o storage pool e n��o deve ser vazio."
-
-msgid "Storage Pool Type"
-msgstr "Tipo do Storage Pool"
-
-msgid "Storage Path"
-msgstr "Caminho do storage"
-
-msgid ""
-"The path of the Storage Pool. Each Storage Pool must have a unique path."
-msgstr ""
-"O caminho do Storage Pool. Cada Storage Pool deve ter um caminho ��nico."
-
-msgid ""
-"Kimchi will try to create the directory when it does not already exist in "
-"your system."
-msgstr ""
-"O Kimchi vai tentar criar o diret��rio se ainda n��o existir no seu sistema."
-
-msgid "NFS Server IP"
-msgstr "IP do servidor NFS"
-
-msgid "NFS server IP or hostname. It can be input or chosen from history."
-msgstr ""
-"IP ou hostname do servidor NFS. Pode ser inserido ou escolhido do
hist��rico."
-
-msgid "NFS Path"
-msgstr "Caminho do NFS"
-
-msgid "The NFS exported path on NFS server."
-msgstr "O caminho exportado do servidor NFS."
-
-msgid "iSCSI Server"
-msgstr "Servidor iSCSI"
-
-msgid "Server"
-msgstr "Servidor"
-
-msgid "Port"
-msgstr "Porta"
-
-msgid "iSCSI server IP or hostname. It should not be empty."
-msgstr "IP ou hostname do servidor iSCSI. N��o deve ser vazio."
-
-msgid "Target"
-msgstr "Alvo"
-
-msgid "The iSCSI target on iSCSI server"
-msgstr "O alvo iSCSI no servidor iSCSI"
-
-msgid "Add iSCSI Authentication"
-msgstr "Adicionar as credenciais do iSCSI"
-
-msgid "iSCSI Authentication"
-msgstr "Credenciais do iSCSI"
-
-msgid "User Name"
-msgstr "Usu��rio"
-
-msgid "Password"
-msgstr "Senha"
-
-msgid "SCSI Adapter"
-msgstr "Adaptador SCSI"
-
-msgid "Please, wait..."
-msgstr "Por favor, aguarde..."
-
-msgid "Add a Volume to Storage Pool"
-msgstr "Adicionar um volume ao Storage Pool"
-
-msgid "Fetch from remote URL"
-msgstr "Fazer download de uma URL remota"
-
-msgid "Enter the remote URL here."
-msgstr "Digite a URL remota aqui."
-
-msgid "Upload a file"
-msgstr "Fazer upload de um arquivo"
-
-msgid "Choose the file you want to upload."
-msgstr "Escolha o arquivo que voc�� quer fazer upload."
-
-msgid "Add Template"
-msgstr "Adicionar Modelo"
-
-msgid "Where is the source media for this template? "
-msgstr "Onde est�� a m��dia de origem desse modelo? "
-
-msgid "Local ISO Image"
-msgstr "Imagem ISO Local"
-
-msgid "Local Image File"
-msgstr "Arquivo de Imagem Local"
-
-msgid "Remote ISO Image"
-msgstr "Imagem ISO Remota"
-
-msgid "Search ISOs"
-msgstr "Procurar ISOs"
-
-msgid "The following ISOs are available:"
-msgstr "As seguintes ISOs est��o dispon��veis:"
-
-msgid "OS: "
-msgstr "Sistema Operacional: "
-
-msgid "Version: "
-msgstr "Vers��o: "
-
-msgid "Size: "
-msgstr "Tamanho: "
-
-msgid "Search more ISOs"
-msgstr "Procurar por mais ISOs"
-
-msgid "Create Templates from Selected ISO"
-msgstr "Criar Modelos a partir das ISOs selecionadas"
-
-msgid "I want to use a specific ISO file"
-msgstr "Eu quero usar um arquivo ISO espec��fico"
-
-msgid "Loading default remote ISOs ..."
-msgstr "Carregando ISOs remotas ..."
-
-msgid "Arch: "
-msgstr "Arquitetura: "
-
-msgid "I want to use a custom URL"
-msgstr "Eu quero usar uma URL personalizada"
-
-msgid "Edit Template"
-msgstr "Editar Modelo"
-
-msgid "CDROM"
-msgstr "CD-ROM"
-
-msgid "Image File"
-msgstr "Arquivo de imagem"
-
-msgid "Graphics"
-msgstr "Gr��ficos"
-
-msgid "Disk(GB)"
-msgstr "Disco (GB)"
-
-msgid "Disk Format"
-msgstr ""
-
-msgid "CPU Number"
-msgstr "Quantidade de CPUs"
-
-msgid "Manually set CPU topology"
-msgstr "Configurar manualmente a topologia de CPU"
-
-msgid "Cores"
-msgstr "Cores"
-
-msgid "Threads"
-msgstr "Threads"
-
-msgid "No templates found."
-msgstr "Nenhum modelo encontrado."
-
-#~ msgid "Delete is not allowed for %(resource)s"
-#~ msgstr "M��todo de remo����o n��o �� permitido em %(resource)s"
-
-#~ msgid "%(resource)s does not implement update method"
-#~ msgstr "%(resource)s n��o implementa m��todo de atualiza����o"
-
-#~ msgid "Create is not allowed for %(resource)s"
-#~ msgstr "M��todo de cria����o n��o �� permitido em %(resource)s"
-
-#~ msgid "Unable to parse JSON request"
-#~ msgstr "N��o �� poss��vel realizar a leitura da requisi����o do JSON"
-
-#~ msgid "This API only supports JSON"
-#~ msgstr "Essa API suporta apenas JSON"
-
-#~ msgid "Parameters does not match requirement in schema: %(err)s"
-#~ msgstr "Par��metros n��o correspondem �� especifica����o do esquema:
%(err)s"
-
-#~ msgid "You don't have permission to perform this operation."
-#~ msgstr "Voc�� n��o tem permiss��o para executar esta opera����o."
-
-#~ msgid "Datastore is not initiated in the model object."
-#~ msgstr "Datastore n��o est�� inicializado no objeto modelo."
-
-#~ msgid "Unable to start task due error: %(err)s"
-#~ msgstr "N��o foi poss��vel iniciar a tarefa devido a um erro: %(err)s"
-
-#~ msgid ""
-#~ "Authentication failed for user '%(username)s'. [Error code:
%(code)s]"
-#~ msgstr ""
-#~ "Autentica����o falhou para o usu��rio '%(username)s'. [C��digo de erro:
%"
-#~ "(code)s]"
-
-#~ msgid "You are not authorized to access Kimchi"
-#~ msgstr "Voc�� n��o est�� autorizado para acessar o Kimchi"
-
-#~ msgid "Specify %(item)s to login into Kimchi"
-#~ msgstr "Especifique %(item)s para autenticar no Kimchi"
-
-#~ msgid "Invalid LDAP configuration: %(item)s : %(value)s"
-#~ msgstr "Configura����es LDAP inv��lidas: %(item)s : %(value)s"
-
-#~ msgid "Unable to find %(item)s in datastore"
-#~ msgstr "N��o foi poss��vel encontrar %(item)s no datastore"
-
-#~ msgid "Timeout while running command '%(cmd)s' after %(seconds)s
seconds"
-#~ msgstr ""
-#~ "Fim do limite de tempo ao rodar comando '%(cmd)s' ap��s %(seconds)s
"
-#~ "segundos"
-
-#~ msgid "Invalid data value '%(value)s'"
-#~ msgstr "Valor inv��lido '%(value)s'"
-
-#~ msgid "Invalid data unit '%(unit)s'"
-#~ msgstr "Unidade inv��lida '%(unit)s'"
-
-#~ msgid "Peers"
-#~ msgstr "Peers"
-
-#~ msgid "Searching"
-#~ msgstr "Procurando"
-
-#~ msgid "No peers found."
-#~ msgstr "Nenhum peer encontrado."
-
-#~ msgid "Help"
-#~ msgstr "Ajuda"
-
-#~ msgid "About"
-#~ msgstr "Sobre"
-
-#~ msgid "Log out"
-#~ msgstr "Sair"
-
-#~ msgid "Version:"
-#~ msgstr "Vers��o:"
-
-#~ msgid "Session timeout, please re-login."
-#~ msgstr ""
-#~ "Fim do limite do tempo da sess��o, por favor se autentique novamente."
diff --git a/plugins/kimchi/po/ru_RU.po b/plugins/kimchi/po/ru_RU.po
deleted file mode 100644
index a5dec2e..0000000
--- a/plugins/kimchi/po/ru_RU.po
+++ /dev/null
@@ -1,2198 +0,0 @@
-# English translations for kimchi package.
-# Copyright (C) 2013 ORGANIZATION
-#
-msgid ""
-msgstr ""
-"Project-Id-Version: kimchi 0.1\n"
-"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2015-07-01 16:11-0300\n"
-"PO-Revision-Date: 2014-08-28 17:32+0000\n"
-"Last-Translator: Aline Manera <aline.manera(a)gmail.com>\n"
-"Language-Team: Russian (
http://www.transifex.com/projects/p/kimchi/language/"
-"ru/)\n"
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
-"Content-Transfer-Encoding: 8bit\n"
-"Language: ru_RU\n"
-"Generated-By: pygettext.py 1.5\n"
-"Plural-Forms: nplurals=2; plural=(n != 1);\n"
-
-#, python-format
-msgid "Unknown parameter %(value)s"
-msgstr ""
-
-#, python-format
-msgid "Timeout of %(seconds)s seconds expired while running task
'%(task)s."
-msgstr ""
-
-#, python-format
-msgid "User %(user_id)s not found with given LDAP settings."
-msgstr ""
-
-msgid "Unknown \"_cap\" specified"
-msgstr ""
-
-msgid "\"_passthrough\" should be \"true\" or
\"false\""
-msgstr ""
-
-msgid "\"_passthrough_affected_by\" should be a device name string"
-msgstr ""
-
-#, python-format
-msgid "Error while getting block devices. Details: %(err)s"
-msgstr "������������ ������������������ �������������� ������������������.
����������������: %(err)s"
-
-#, python-format
-msgid "Error while getting block device information for %(device)s."
-msgstr "������������ ������������������ �������������������� �� ��������������
���������������������� ������ %(device)s."
-
-#, python-format
-msgid "Unable to find distro file: %(filename)s"
-msgstr "���� ������������ �������� ���������������� ����: %(filename)s"
-
-#, python-format
-msgid ""
-"Unable to parse distro file: %(filename)s. Make sure, it is a JSON file."
-msgstr ""
-"������������ �������������� ���������� ���������������� ���� %(filename)s.
������������������, ������ ������ �������� JSON."
-
-#, python-format
-msgid "Unable to login to iSCSI host target %(portal)s. Details: %(err)s"
-msgstr "���� �������������� ���������� �� �������������� %(portal)s ����������
iSCSI. ����������������: %(err)s"
-
-#, python-format
-msgid "Unable to login to iSCSI host %(host)s target %(target)s"
-msgstr "���� �������������� ���������� �� �������������� %(target)s ���������� iSCSI
%(host)s"
-
-#, python-format
-msgid "Unable to find ISO file %(filename)s"
-msgstr ""
-
-#, python-format
-msgid "The ISO file %(filename)s is not bootable"
-msgstr "�������� ISO %(filename)s ���� ����������������������"
-
-#, python-format
-msgid "The ISO file %(filename)s does not have a valid El Torito boot record"
-msgstr ""
-"�������� ISO %(filename)s ���� ���������������� ��������������������
���������������������� ������������ El Torito"
-
-#, python-format
-msgid "Invalid El Torito validation entry in ISO %(filename)s"
-msgstr "������������������������ ������������ ���������������� El Torito ��
������������ ISO %(filename)s"
-
-#, python-format
-msgid "Invalid El Torito boot indicator in ISO %(filename)s"
-msgstr "������������������������ ������������������ ���������������� El Torito ��
������������ ISO %(filename)s"
-
-#, python-format
-msgid "Unexpected volume type for primary volume in ISO %(filename)s"
-msgstr "���������������������� ������ �������� ������ ���������������� �������� ��
������������ ISO %(filename)s"
-
-#, python-format
-msgid "Bad format while reading volume descriptor in ISO %(filename)s"
-msgstr "���������������� ������������ ���������������������� �������� ��
������������ ISO %(filename)s"
-
-#, python-format
-msgid ""
-"The hypervisor doesn't have permission to use this ISO %(filename)s. "
-"Consider moving it under /var/lib/libvirt, or set the search permission to "
-"file access control lists for '%(user)s' user if possible, or add the
'%"
-"(user)s' to the ISO path group, or (not recommended) 'chmod -R o+x "
-"'path_to_iso'.Details: %(err)s"
-msgstr ""
-"�� ���������������������� ������ �������� �������������� ������
�������������������������� ���������� ������������ ISO %(filename)"
-"s. ���������������������� ������ �� �������������� /var/lib/libvirt,
���������������� �������������������� ���� ���������� "
-"�� ������������ ���������������� �������������� ������ ������������������������
%(user)s, �������� ������ ����������������, "
-"���������������� %(user)s �� ������������ �������� �� ������������ ISO ������ (����
��������������������������) "
-"������������������ �������������� 'chmod -R o+x 'path_to_iso'.
����������������: %(err)s"
-
-msgid "An error occurred when probing image OS information."
-msgstr ""
-
-msgid "No OS information found in given image."
-msgstr ""
-
-#, python-format
-msgid "Unable to read image file %(filename)s"
-msgstr ""
-
-#, python-format
-msgid ""
-"Image file must be an existing file on system. %(filename)s is not a valid "
-"input."
-msgstr ""
-
-#, python-format
-msgid "Virtual machine %(name)s already exists"
-msgstr "���������������������� ������������ %(name)s ������
��������������������"
-
-#, python-format
-msgid "Virtual machine %(name)s does not exist"
-msgstr "���������������������� ������������ %(name)s ����
��������������������"
-
-#, python-format
-msgid ""
-"Unable to rename virtual machine %(name)s. The name %(new_name)s is already "
-"in use or the virtual machine is not powered off."
-msgstr ""
-
-#, python-format
-msgid "Unable to retrieve screenshot for stopped virtual machine %(name)s"
-msgstr ""
-"���� �������������� ���������������� ������������ ������������ ������
�������������������������� ���������������������� ������������ %"
-"(name)s"
-
-msgid "Remote ISO image is not supported by this server."
-msgstr "������������������ ���������� ISO ���� ���������������������������� ��������
����������������."
-
-#, python-format
-msgid "Screenshot is not supported on virtual machine %(name)s"
-msgstr ""
-
-#, python-format
-msgid "Unable to create virtual machine %(name)s. Details: %(err)s"
-msgstr "���� �������������� �������������� ���������������������� ������������
%(name)s. ����������������: %(err)s"
-
-#, python-format
-msgid "Unable to update virtual machine %(name)s. Details: %(err)s"
-msgstr "���� �������������� �������������� ���������������������� ������������
%(name)s. ����������������: %(err)s"
-
-#, python-format
-msgid "Unable to retrieve virtual machine %(name)s. Details: %(err)s"
-msgstr "���� �������������� ���������������� ���������������������� ������������
%(name)s. ����������������: %(err)s"
-
-#, python-format
-msgid "Unable to connect to powered off virtual machine %(name)s."
-msgstr ""
-
-msgid "Virtual machine name must be a string without slashes (/)"
-msgstr ""
-
-#, python-format
-msgid "Invalid template URI %(value)s specified for virtual machine"
-msgstr ""
-
-#, python-format
-msgid "Invalid storage pool URI %(value)s specified for virtual machine"
-msgstr ""
-
-msgid "Supported virtual machine graphics are Spice or VNC"
-msgstr ""
-
-msgid "Graphics address to listen on must be IPv4 or IPv6"
-msgstr ""
-"���������� ������������ ���������������� ������ ����������������������
�������������������� ������������ �������� IPv4 ������ IPv6"
-
-msgid "Specify a template to create a virtual machine from"
-msgstr "�������������� ������������ ������ ���������������� ����������������������
������������"
-
-#, python-format
-msgid "Unable to start virtual machine %(name)s. Details: %(err)s"
-msgstr "���� �������������� ������������������ ���������������������� ������������
%(name)s. ����������������: %(err)s"
-
-#, python-format
-msgid "Unable to power off virtual machine %(name)s. Details: %(err)s"
-msgstr "���� �������������� �������������������� ���������������������� ������������
%(name)s. ����������������: %(err)s"
-
-#, python-format
-msgid "Unable to delete virtual machine %(name)s. Details: %(err)s"
-msgstr "���� �������������� �������������� ���������������������� ������������
%(name)s. ����������������: %(err)s"
-
-#, python-format
-msgid "Unable to reset virtual machine %(name)s. Details: %(err)s"
-msgstr ""
-"���� �������������� �������������������������� ���������������������� ������������
%(name)s. ����������������: %(err)s"
-
-msgid "User name list must be an array"
-msgstr ""
-
-msgid "User name must be a string"
-msgstr "������ �������� ������������ �������� ��������������"
-
-msgid "Group name list must be an array"
-msgstr ""
-
-msgid "Group name must be a string"
-msgstr "������ �������� ������������ �������� ��������������"
-
-#, python-format
-msgid "User(s) '%(users)s' do not exist"
-msgstr "������������������������ %(users)s ���� ��������������������."
-
-#, python-format
-msgid "Group(s) '%(groups)s' do not exist"
-msgstr "������������������������ %(groups)s ���� ��������������������."
-
-#, python-format
-msgid "Unable to shutdown virtual machine %(name)s. Details: %(err)s"
-msgstr "���� �������������� �������������������� ���������������������� ������������
%(name)s. ����������������: %(err)s"
-
-#, python-format
-msgid ""
-"Unable to get access metadata of virtual machine %(name)s. Details: %(err)s"
-msgstr "���� �������������� ������������������ ���������������������� ������������
%(name)s. ����������������: %(err)s"
-
-msgid "The guest console password must be a string."
-msgstr ""
-
-msgid "The life time for the guest console password must be a number."
-msgstr ""
-
-#, python-format
-msgid "Virtual machine '%(name)s' must be stopped before cloning it."
-msgstr ""
-
-#, python-format
-msgid "Insufficient disk space to clone virtual machine '%(name)s'"
-msgstr ""
-
-#, python-format
-msgid "Unable to clone VM '%(name)s'. Details: %(err)s"
-msgstr ""
-
-#, python-format
-msgid "Invalid operation for non-persistent virtual machine %(name)s"
-msgstr ""
-
-#, python-format
-msgid "Cannot suspend VM '%(name)s' because it is not running."
-msgstr ""
-
-#, python-format
-msgid "Unable to suspend VM '%(name)s'. Details: %(err)s"
-msgstr ""
-
-#, python-format
-msgid "Cannot resume VM '%(name)s' because it is not paused."
-msgstr ""
-
-#, python-format
-msgid "Unable to resume VM '%(name)s'. Details: %(err)s"
-msgstr ""
-
-msgid "Memory assigned is higher then the maximum allowed in the host."
-msgstr ""
-
-#, python-format
-msgid ""
-"VM '%(name)s' does not support live memory update. Update the memory with
"
-"the machine offline to enable this feature."
-msgstr ""
-
-msgid "Only increase memory is allowed in active VMs"
-msgstr ""
-
-msgid ""
-"For live memory update, new memory value must be equal old memory value plus
"
-"multiples of 1024 Mib"
-msgstr ""
-
-msgid "There are not enough free slots of 1024 Mib in the guest."
-msgstr ""
-
-msgid ""
-"Host's libvirt version does not support memory devices. Libvirt must be >=
"
-"1.2.14"
-msgstr ""
-
-#, python-format
-msgid "Error attaching memory device. Details: %(error)s"
-msgstr ""
-
-#, python-format
-msgid ""
-"VM %(vmid)s does not contain directly assigned host device %(dev_name)s."
-msgstr ""
-
-#, python-format
-msgid "The host device %(dev_name)s is not allowed to directly assign to VM."
-msgstr ""
-
-msgid ""
-"No IOMMU groups found. Host PCI pass through needs IOMMU group to function "
-"correctly. Please enable Intel VT-d or AMD IOMMU in your BIOS, then verify "
-"the Kernel is compiled with IOMMU support. For Intel CPU, add intel_iommu=on
"
-"to your Kernel parameter in /boot/grub2/grub.conf. For AMD CPU, add iommu=pt
"
-"iommu=1."
-msgstr ""
-
-msgid "\"name\" should be a device name string"
-msgstr ""
-
-#, python-format
-msgid ""
-"The device %(name)s is probably in use by the host. Unable to attach it to "
-"the guest."
-msgstr ""
-
-#, python-format
-msgid "Interface %(iface)s does not exist in virtual machine %(name)s"
-msgstr "������������������ %(iface)s ���� �������������������� ��
���������������������� ������������ %(name)s"
-
-#, python-format
-msgid ""
-"Network %(network)s specified for virtual machine %(name)s does not exist"
-msgstr ""
-"�������� %(network)s, ������������������ ������ ���������������������� ������������
%(name)s, ���� ��������������������"
-
-msgid "Supported virtual machine interfaces type is only network"
-msgstr "���������������������������� ������������ �������� ������
���������������������� ���������������������� ������������ - ��������"
-
-msgid "Network name for virtual machine interface must be a string"
-msgstr "������ �������� ������ �������������������� ����������������������
������������ ������������ �������� ��������������"
-
-msgid "Invalid network model card specified for virtual machine interface"
-msgstr ""
-"�������������� ������������������������ ���������� ������������ �������� ������
�������������������� ���������������������� ������������"
-
-msgid "Specify type and network to add a new virtual machine interface"
-msgstr "�������������� ������ �� �������� ������ �������������������� ������������
�������������������� ���������������������� ������������"
-
-msgid "MAC Address must respect this format FF:FF:FF:FF:FF:FF"
-msgstr ""
-
-#, python-format
-msgid "MAC Address %(mac)s already exists in virtual machine %(name)s"
-msgstr ""
-
-msgid "Invalid MAC Address"
-msgstr ""
-
-msgid "Cannot change MAC address of a running virtual machine"
-msgstr ""
-
-#, python-format
-msgid "Template %(name)s already exists"
-msgstr "������������ %(name)s ������ ��������������������"
-
-#, python-format
-msgid ""
-"Network '%(network)s' specified for template %(template)s does not
exist"
-msgstr "�������� %(network)s, ������������������ ������ �������������� %(template)s,
���� ��������������������"
-
-#, python-format
-msgid ""
-"Storage pool %(pool)s specified for template %(template)s does not exist"
-msgstr "������ ������������ %(pool)s, ������������������ ������ ��������������
%(template)s, ���� ��������������������"
-
-#, python-format
-msgid "Storage pool %(pool)s specified for template %(template)s is not
active"
-msgstr "������ ������������ %(pool)s, ������������������ ������ ��������������
%(template)s, ���� ��������������"
-
-#, python-format
-msgid "Invalid parameter '%(param)s' specified for CDROM."
-msgstr "������������ ������������������������ ���������������� %(param)s ������
CDROM."
-
-#, python-format
-msgid "Network %(network)s specified for template %(template)s is not active"
-msgstr "�������� %(network)s, ������������������ ������ �������������� %(template)s,
���� ��������������"
-
-msgid "Template name must be a string"
-msgstr "������ �������������� ������������ �������� ��������������"
-
-msgid "Template icon must be a path to the image"
-msgstr "������������ �������������� ������������ �������� ���������� ��
������������"
-
-msgid "Template distribution must be a string"
-msgstr "�������������� �������������� ������������ �������� ��������������"
-
-msgid "Template distribution version must be a string"
-msgstr "������������ ���������������� �������������� ������������ ��������
��������������"
-
-msgid "The number of CPUs must be an integer greater than 0"
-msgstr "���������� ���������������������� ������������ �������� ����������
������������"
-
-msgid "Amount of memory (MB) must be an integer greater than 512"
-msgstr "���������� ������������ (����) ������������ �������� ���������� ������������
������������ 512"
-
-msgid "Template CDROM must be a local or remote ISO file"
-msgstr "CDROM �������������� ������������ �������� ������������������ ������
������������������ ������������ ISO"
-
-#, python-format
-msgid "Invalid storage pool URI %(value)s specified for template"
-msgstr "������ �������������� ������������ ������������������������ URI ��������
������������ %(value)s"
-
-msgid "Specify an ISO image as CDROM or a base image to create a template"
-msgstr "�������������� ���������� ISO �� ���������������� CDROM ������
���������������� ��������������"
-
-msgid "All networks for the template must be specified in a list."
-msgstr "������ �������� ������ �������������� ������������ �������� ��������������
�� ������������."
-
-msgid "Specify a volume to a template when storage pool is iSCSI or SCSI"
-msgstr ""
-
-#, python-format
-msgid "The volume %(volume)s is not in storage pool %(pool)s"
-msgstr ""
-
-#, python-format
-msgid "Unable to create template due error: %(err)s"
-msgstr "���� �������������� �������������� ������������ ����-���� ������������
%(err)s"
-
-#, python-format
-msgid "Unable to delete template due error: %(err)s"
-msgstr "���� �������������� �������������� ������������ ����-���� ������������
%(err)s"
-
-msgid "Disk size must be an integer greater than 1GB."
-msgstr ""
-
-msgid "Template base image must be a valid local image file"
-msgstr "CDROM �������������� ������������ �������� ������������������ ������
������������������ ������������ ISO"
-
-#, python-format
-msgid "Cannot identify base image %(path)s format"
-msgstr ""
-
-msgid ""
-"When specifying CPU topology, VCPUs must be a product of sockets, cores, and
"
-"threads."
-msgstr ""
-
-msgid ""
-"When specifying CPU topology, each element must be an integer greater than "
-"zero."
-msgstr ""
-
-msgid ""
-"Invalid disk image format. Valid formats: bochs, cloop, cow, dmg, qcow, "
-"qcow2, qed, raw, vmdk, vpc."
-msgstr ""
-
-#, python-format
-msgid "Storage pool %(name)s already exists"
-msgstr "������ ������������ %(name)s ������ ��������������������"
-
-#, python-format
-msgid "Storage pool %(name)s does not exist"
-msgstr "������ ������������ %(name)s ���� ��������������������"
-
-#, python-format
-msgid "Specify %(item)s in order to create the storage pool %(name)s"
-msgstr "�������������� %(item)s ������ ���������������� �������� ������������
%(name)s"
-
-#, python-format
-msgid "Unable to delete active storage pool %(name)s"
-msgstr "���� �������������� �������������� ���������������� ������ ������������
%(name)s"
-
-#, python-format
-msgid "Unable to list storage pools. Details: %(err)s"
-msgstr "���� �������������� �������������� ������������ ���������� ������������.
����������������: %(err)s"
-
-#, python-format
-msgid "Unable to create storage pool %(name)s. Details: %(err)s"
-msgstr "���� �������������� �������������� ������ ������������ %(name)s.
����������������: %(err)s"
-
-#, python-format
-msgid ""
-"Unable to get number of storage volumes in storage pool %(name)s. Details: %"
-"(err)s"
-msgstr ""
-"���� �������������� ���������������� ���������� ���������� �� �������� ������������
%(name)s. ����������������: %(err)s"
-
-#, python-format
-msgid "Unable to activate storage pool %(name)s. Details: %(err)s"
-msgstr "���� �������������� ������������������������ ������ ������������ %(name)s.
����������������: %(err)s"
-
-#, python-format
-msgid "Unable to deactivate storage pool %(name)s. Details: %(err)s"
-msgstr "���� �������������� ���������������������������� ������ ������������
%(name)s. ����������������: %(err)s"
-
-#, python-format
-msgid "Unable to delete storage pool %(name)s. Details: %(err)s"
-msgstr "���� �������������� �������������� ������ ������������ %(name)s.
����������������: %(err)s"
-
-#, python-format
-msgid ""
-"Unable to create NFS Pool as export path %(path)s may block during mount"
-msgstr ""
-"���� �������������� �������������� ������ NFS: ��������������������������������
�������� %(path)s ������ �������� "
-"������������������������ ���� ���������� ������������������������"
-
-#, python-format
-msgid "Unable to create NFS Pool as export path %(path)s mount failed"
-msgstr ""
-"���� �������������� �������������� ������ NFS: ���� ��������������
������������������������ �������������������������������� �������� %"
-"(path)s"
-
-#, python-format
-msgid "Unsupported storage pool type: %(type)s"
-msgstr "�������������������������������� ������ �������� ������������:
%(type)s"
-
-#, python-format
-msgid "Error while retrieving storage pool XML to %(pool)s"
-msgstr ""
-
-msgid "Storage pool name must be a string without slashes (/)"
-msgstr ""
-
-msgid ""
-"Supported storage pool types are dir, netfs, logical, iscsi, isci and
kimchi-"
-"iso"
-msgstr ""
-
-msgid "Storage pool path must be a string"
-msgstr "�������� �� �������� ������������ ������������ ��������
��������������"
-
-msgid "Storage pool host must be a IP or hostname"
-msgstr "�������� �������� ������������ ������������ �������� IP-��������������
������ ������������ ����������"
-
-msgid "Storage pool device must be the absolute path to the block device"
-msgstr ""
-
-msgid "Storage pool devices parameter must be a list"
-msgstr "���������������� ������������������ �������� ������������ ������������
�������� ��������������"
-
-msgid "Target IQN of an iSCSI pool must be a string"
-msgstr "�������������� IQN �������� iSCSI ������������ ��������
��������������"
-
-msgid "Port of a remote storage server must be an integer between 1 and 65535"
-msgstr "�������� �������������������� �������������� ������������ ������������
�������� ���������� ������������ ���� 1 ���� 65535"
-
-msgid "iSCSI target username must be a string"
-msgstr ""
-
-msgid "iSCSI target password must be a string"
-msgstr ""
-
-msgid "Specify name and type to create a storage pool"
-msgstr "�������������� ������ �� ������ ������ ���������������� ��������
������������"
-
-#, python-format
-msgid ""
-"%(disk)s is not a valid disk/partition. Could not add it to the pool %(pool)"
-"s."
-msgstr ""
-"%(disk)s ���� ���������������� �������������������� ������������/����������������.
���� �������������� ���������������� ������ �� "
-"������ %(pool)s."
-
-#, python-format
-msgid "Unable to extend logical pool %(pool)s. Details: %(err)s"
-msgstr ""
-
-msgid "The parameter disks only can be updated for logical storage pool."
-msgstr "���������� �������������������� ���������� ������������������ ������������
������ ���������������������� �������� ������������."
-
-msgid "The SCSI host adapter name must be a string."
-msgstr "������ ���������������� ���������� SCSI ������������ ��������
��������������."
-
-msgid "The storage pool kimchi_isos is reserved for internal use"
-msgstr "kimchi_isos �������� ������������ ���������������������������� ������
���������������������� ��������������������������"
-
-#, python-format
-msgid ""
-"Unable to activate NFS storage pool %(name)s. NFS server %(server)s is "
-"unreachable."
-msgstr ""
-"���� �������������� ������������������������ ������ ������������ NFS %(name)s.
������������ NFS %(server)s "
-"��������������������."
-
-#, python-format
-msgid ""
-"Unable to deactivate NFS storage pool %(name)s. NFS server %(server)s is "
-"unreachable."
-msgstr ""
-"���� �������������� ���������������������������� ������ ������������ NFS %(name)s.
������������ NFS %(server)s "
-"��������������������."
-
-#, python-format
-msgid ""
-"Unable to deactivate pool %(name)s as it is associated with some templates"
-msgstr ""
-"���� �������������� ���������������������������� ������ %(name)s: ������
������������ �� �������������������� ������������������"
-
-#, python-format
-msgid "Unable to delete pool %(name)s as it is associated with some templates"
-msgstr "���� �������������� �������������� ������ %(name)s: ������ ������������ ��
�������������������� ������������������"
-
-#, python-format
-msgid ""
-"A volume group named '%(name)s' already exists. Please, choose another name
"
-"to create the logical pool."
-msgstr ""
-"������������ ���������� �� ������������ %(name)s ������ ��������������������.
���������������� ������������ ������ ������ "
-"���������������� ���������������������� ��������."
-
-#, python-format
-msgid "Unable to update database with deep scan information due error:
%(err)s"
-msgstr ""
-"���� �������������� ���������������� �������� ������������ ��
���������������������� ������������������ ������������������������ ����-���� "
-"������������ %(err)s"
-
-#, python-format
-msgid "Storage volume %(name)s already exists"
-msgstr "������ %(name)s ������ ��������������������"
-
-#, python-format
-msgid "Storage volume %(name)s does not exist in storage pool %(pool)s"
-msgstr "������ %(name)s ���� �������������������� �� �������� ������������
%(pool)s"
-
-#, python-format
-msgid ""
-"Unable to create storage volume %(volume)s because storage pool %(pool)s is "
-"not active"
-msgstr ""
-
-#, python-format
-msgid "Specify %(item)s in order to create storage volume %(volume)s"
-msgstr "�������������� %(item)s ������ ���������������� �������� %(volume)s"
-
-#, python-format
-msgid ""
-"Unable to list storage volumes because storage pool %(pool)s is not active"
-msgstr "���� �������������� �������������� ������������ ����������: ������
������������ %(pool)s ���� ��������������"
-
-#, python-format
-msgid ""
-"Unable to create storage volume %(name)s in storage pool %(pool)s. Details:
%"
-"(err)s"
-msgstr ""
-"���� �������������� �������������� ������ %(name)s �� �������� ������������
%(pool)s. ����������������: %(err)s"
-
-#, python-format
-msgid ""
-"Unable to list storage volumes in storage pool %(pool)s. Details: %(err)s"
-msgstr ""
-"���� �������������� �������������� ������������ ���������� �� �������� ������������
%(pool)s. ����������������: %(err)s"
-
-#, python-format
-msgid "Unable to wipe storage volumes %(name)s. Details: %(err)s"
-msgstr "���� �������������� �������������� �������� %(name)s. ����������������:
%(err)s"
-
-#, python-format
-msgid "Unable to delete storage volume %(name)s. Details: %(err)s"
-msgstr "���� �������������� �������������� ������ %(name)s. ����������������:
%(err)s"
-
-#, python-format
-msgid "Unable to resize storage volume %(name)s. Details: %(err)s"
-msgstr "���� �������������� ���������������� ������������ �������� %(name)s.
����������������: %(err)s"
-
-#, python-format
-msgid "Storage type %(type)s does not support volume create and delete"
-msgstr "������ ������������ %(type)s ���� ������������������������ ����������������
�� ���������������� ����������"
-
-msgid "Storage volume name must be a string"
-msgstr "������ �������� ������������ �������� ��������������"
-
-msgid "Storage volume allocation must be an integer number"
-msgstr "������������������ �������� ������������ �������� ����������
������������"
-
-msgid ""
-"Storage volume format not supported. Valid formats: bochs, cloop, cow, dmg, "
-"qcow, qcow2, qed, raw, vmdk, vpc."
-msgstr ""
-
-msgid "Storage volume requires a volume name"
-msgstr "�������� ������������������ ������"
-
-#, python-format
-msgid ""
-"Unable to update database with storage volume information due error: %(err)s"
-msgstr ""
-"���� �������������� ���������������� �������� ������������ ��
���������������������� �� ���������� ����-���� ������������ %(err)s"
-
-#, python-format
-msgid "Only one of parameter %(param)s can be specified"
-msgstr ""
-
-#, python-format
-msgid "Create volume from %(param)s is not supported"
-msgstr ""
-
-msgid "Storage volume capacity must be an integer number."
-msgstr ""
-
-msgid "Storage volume URL must be http://, https://, ftp:// or ftps://."
-msgstr ""
-
-#, python-format
-msgid "Unable to access file %(url)s. Please, check it."
-msgstr ""
-
-#, python-format
-msgid ""
-"Unable to clone storage volume '%(name)s' in pool '%(pool)s'.
Details: %(err)"
-"s"
-msgstr ""
-
-msgid "Specify chunk data and its size to upload a file."
-msgstr ""
-
-msgid "In order to upload a storage volume, specify the 'upload'
parameter."
-msgstr ""
-
-msgid ""
-"Unable to upload chunk data as it does not match with requested chunk size."
-msgstr ""
-
-#, python-format
-msgid "The storage volume %(vol)s is not under an upload process."
-msgstr ""
-
-msgid "The upload chunk data will exceed the storage volume size."
-msgstr ""
-
-#, python-format
-msgid "Unable to upload chunk data to storage volume. Details: %(err)s."
-msgstr ""
-
-#, python-format
-msgid "Interface %(name)s does not exist"
-msgstr "������������������ %(name)s ���� ��������������������"
-
-#, python-format
-msgid "Network %(name)s already exists"
-msgstr "�������� %(name)s ������ ��������������������"
-
-#, python-format
-msgid "Network %(name)s does not exist"
-msgstr "�������� %(name)s ���� ��������������������"
-
-#, python-format
-msgid "Subnet %(subnet)s specified for network %(network)s is not valid."
-msgstr "�������������� %(subnet)s, ������������������ ������ �������� %(network)s,
����������������������."
-
-#, python-format
-msgid "Specify a network interface to create bridged network %(name)s"
-msgstr ""
-"�������������� �������������� ������������������ ������ ���������������� ��������
%(name)s �� ���������������� ���������� ��������"
-
-#, python-format
-msgid "Unable to delete active network %(name)s"
-msgstr "���� �������������� �������������� ���������������� �������� %(name)s"
-
-#, python-format
-msgid "Interface %(iface)s specified for network %(network)s is already in
use"
-msgstr "������������������ %(iface)s, ������������������ ������ ��������
%(network)s, ������ ������������������������"
-
-msgid "Interface should be bare NIC, bonding or bridge device."
-msgstr ""
-"������������������ ������������ �������� �������������� ������������,
���������������������� ���������� ������ ������������������ "
-"����������������������."
-
-#, python-format
-msgid "Unable to create network %(name)s. Details: %(err)s"
-msgstr "���� �������������� �������������� �������� %(name)s. ����������������:
%(err)s"
-
-#, python-format
-msgid "Unable to find a free IP address for network '%(name)s'"
-msgstr "���� ������������ ������������������ IP-���������� ������ ��������
%(name)s"
-
-#, python-format
-msgid "The interface %(iface)s already exists."
-msgstr ""
-
-msgid "Network name must be a string without slashes (/) or quotes (\")"
-msgstr ""
-
-msgid "Supported network types are isolated, NAT and bridge"
-msgstr "���������������������������� �������� ����������: isolated, NAT ��
bridge"
-
-msgid "Network subnet must be a string with IP address and prefix or netmask"
-msgstr ""
-"�������������� �������� ������������ �������� ��������������, ��������������������
IP-����������, �������������� ������ ���������� ��������"
-
-msgid "Network interface must be a string"
-msgstr "�������������� ������������������ ������������ ��������
��������������"
-
-msgid "Network VLAN ID must be an integer between 1 and 4094"
-msgstr "�������������� ���� VLAN ������������ �������� ���������� ������������ ����
1 ���� 4094"
-
-msgid "Specify name and type to create a Network"
-msgstr "�������������� ������ �� ������ ������ ���������������� ��������"
-
-#, python-format
-msgid ""
-"Unable to delete network %(name)s. There are some virtual machines %(vms)s "
-"and/or templates linked to this network."
-msgstr ""
-
-#, python-format
-msgid ""
-"Unable to deactivate network %(name)s. There are some virtual machines
%(vms)"
-"s and/or templates linked to this network."
-msgstr ""
-
-#, python-format
-msgid "Bridge device %(name)s can not be the trunk device of a VLAN."
-msgstr ""
-"�������������������� ���������� %(name)s ���� ���������� ��������
�������������������������� ���������������������� VLAN."
-
-#, python-format
-msgid "Failed to activate interface %(iface)s: %(err)s."
-msgstr "���� �������������� ������������������������ ������������������ %(iface)s:
%(err)s."
-
-#, python-format
-msgid ""
-"Failed to activate interface %(iface)s. Please check the physical link "
-"status."
-msgstr ""
-"���� ������������ ������������������������ ������������������ %(iface)s.
������������������ ������������������ �������������������� "
-"���������� ����������. "
-
-#, python-format
-msgid "Failed to start network %(name)s. Details: %(err)s"
-msgstr ""
-
-#, python-format
-msgid "Debug report %(name)s does not exist"
-msgstr "�������������������� ���������� %(name)s ���� ��������������������"
-
-msgid "Debug report tool not found in system"
-msgstr "�������������������� ���������������������� ������������ ���� ������������
�� ��������������"
-
-#, python-format
-msgid "Unable to create debug report %(name)s. Details: %(err)s."
-msgstr "���� �������������� �������������� �������������������� ���������� %(name)s.
����������������: %(err)s."
-
-#, python-format
-msgid "Can not find any debug report with the given name %(name)s"
-msgstr ""
-
-#, python-format
-msgid "Unable to generate debug report %(name)s. Details: %(err)s"
-msgstr "���� �������������� �������������� �������������������� ���������� %(name)s.
����������������: %(err)s"
-
-msgid "You should give a name for the debug report file."
-msgstr ""
-
-msgid ""
-"Debug report name must be a string. Only letters, digits, underscore ('_')
"
-"and hyphen ('-') are allowed."
-msgstr ""
-
-#, python-format
-msgid ""
-"The debug report with specified name \"%(name)s\" already exists. Please
use "
-"another one."
-msgstr ""
-"������������ ���������� �� ������������ %(name)s ������ ��������������������.
���������������� ������������ ������ ������ "
-"���������������� ���������������������� ��������."
-
-#, python-format
-msgid "Storage server %(server)s was not used by Kimchi"
-msgstr "������������ ������������ %(server)s ���� ��������������������������
Kimchi"
-
-#, python-format
-msgid "Distro '%(name)s' does not exist"
-msgstr "�������������� ���� %(name)s ���� ��������������������"
-
-#, python-format
-msgid "Partition %(name)s does not exist in the host"
-msgstr "������������ %(name)s ���� �������������������� ���� ����������"
-
-msgid "Unable to shutdown host machine as there are running virtual machines"
-msgstr ""
-"���� �������������� ������������������ ������������ �������������� ����������:
���������������������� ���������������������� ������������"
-
-msgid "Unable to reboot host machine as there are running virtual machines"
-msgstr "���� �������������� �������������������������� �������������� ����������:
���������������������� ���������������������� ������������"
-
-#, python-format
-msgid "Node device '%(name)s' not found"
-msgstr "�������������������� %(name)s �������� ���� ��������������"
-
-msgid "Conflicting flag filters specified."
-msgstr ""
-
-msgid "No packages marked for update"
-msgstr "������ ��������������, �������������������� ������
��������������������"
-
-#, python-format
-msgid "Package %(name)s is not marked to be updated."
-msgstr "���������� %(name)s ���� �������������� ������ ��������������������."
-
-#, python-format
-msgid "Error while getting packages marked to be updated. Details: %(err)s"
-msgstr "������������ ������������������ ��������������, �������������������� ������
��������������������. ����������������: %(err)s"
-
-msgid "There is no compatible package manager for this system."
-msgstr "������ ������������������������ ���������������������������� ��������������
������ �������� ��������������."
-
-#, python-format
-msgid "Invalid URI %(uri)s"
-msgstr "������������������������ URI %(uri)s"
-
-msgid "Unable to choose a virtual machine name"
-msgstr ""
-
-msgid "Invalid storage type. Types supported: 'cdrom', 'disk'"
-msgstr "������������������������ ������ ������������. ����������������������������
��������: cdrom"
-
-#, python-format
-msgid "The path '%(value)s' is not a valid local/remote path for the
device"
-msgstr ""
-
-msgid "Only CDROM path can be update."
-msgstr ""
-
-#, python-format
-msgid ""
-"The storage device %(dev_name)s does not exist in the virtual machine %"
-"(vm_name)s"
-msgstr ""
-
-#, python-format
-msgid "Error while creating new storage device: %(error)s"
-msgstr "������������ ���������������� �������������������� ����������������:
%(error)s"
-
-#, python-format
-msgid "Error while updating storage device: %(error)s"
-msgstr "������������ �������������������� �������������������� ����������������:
%(error)s"
-
-#, python-format
-msgid "Error while removing storage device: %(error)s"
-msgstr "������������ ���������������� �������������������� ����������������:
%(error)s"
-
-msgid "Do not support IDE device hot plug"
-msgstr ""
-
-msgid ""
-"Specify type and path or type and pool/volume to add a new virtual machine "
-"disk"
-msgstr "�������������� ������ �� �������� ������ �������������������� ������������
���������� ���������������������� ������������"
-
-msgid "Specify path to update virtual machine disk"
-msgstr "�������������� �������� ������ �������������������� ����������
���������������������� ������������"
-
-#, python-format
-msgid "Controller type %(type)s limitation of %(limit)s devices reached"
-msgstr ""
-
-#, python-format
-msgid "Cannot retrieve disk path information for given pool/volume: %(error)s"
-msgstr ""
-
-msgid "Volume already in use by other virtual machine."
-msgstr ""
-
-msgid ""
-"Only one of path or pool/volume can be specified to add a new virtual "
-"machine disk"
-msgstr "�������������� ������ �� �������� ������ �������������������� ������������
���������� ���������������������� ������������"
-
-#, python-format
-msgid ""
-"Volume chosen with format %(format)s does not fit in the storage type
%(type)"
-"s"
-msgstr ""
-
-msgid "YUM Repository ID must be one word only string."
-msgstr ""
-"���� ������������������ YUM ������������ �������� ��������������,
������������������ ������������ ���� ������������ ����������."
-
-msgid "Repository URL must be an http://, ftp:// or file:// URL."
-msgstr "URL ������������������ ������������ �������� http://, ftp:// ������ file://
."
-
-msgid ""
-"Repository configuration is a dictionary with specific values according to "
-"repository type."
-msgstr ""
-"������������������������ ������������������ ������������������������ ����������
�������������� ����������������, ������������������������ "
-"���������� ������������������."
-
-msgid "Distribution to DEB repository must be a string"
-msgstr "�������������� ������ ������������������ DEB ������������ ��������
��������������"
-
-msgid "Components to DEB repository must be listed in a array"
-msgstr "�������������������� ������ ������������������ DEB ������������ ��������
���������������������� �� ��������������"
-
-msgid "Components to DEB repository must be a string"
-msgstr "�������������������� ������ ������������������ DEB ������������ ��������
��������������"
-
-msgid "Mirror list to repository must be a string"
-msgstr ""
-
-msgid "YUM Repository name must be string."
-msgstr "������ ������������������ YUM ������������ �������� ��������������."
-
-msgid "GPG check must be a boolean value."
-msgstr "���������������� GPG ������������ �������� ������������������
������������������."
-
-msgid "GPG key must be a URL pointing to the ASCII-armored file."
-msgstr ""
-"�������� GPG ������������ �������� URL, ���������������������� ����
�������������������� �������� �� ������������������������ "
-"ASCII."
-
-#, python-format
-msgid "Could not update repository %(repo_id)s."
-msgstr "���� �������������� ���������������� ������������������ %(repo_id)s."
-
-#, python-format
-msgid "Repository %(repo_id)s does not exist."
-msgstr "������������������ %(repo_id)s ���� ��������������������."
-
-msgid ""
-"Specify repository base URL, mirror list or metalink in order to create or "
-"update a YUM repository."
-msgstr ""
-
-msgid "Repository management tool was not recognized for your system."
-msgstr "���� ������������������ �������������������� ��������������������
�������������������� ������ ��������������."
-
-#, python-format
-msgid "Repository %(repo_id)s is already enabled."
-msgstr "������������������ %(repo_id)s ������ ����������������."
-
-#, python-format
-msgid "Repository %(repo_id)s is already disabled."
-msgstr "������������������ %(repo_id)s ������ ������������������."
-
-#, python-format
-msgid "Could not remove repository %(repo_id)s."
-msgstr "���� �������������� �������������� ������������������ %(repo_id)s."
-
-#, python-format
-msgid "Could not write repository configuration file %(repo_file)s"
-msgstr "���� �������������� ���������������� �� �������� ������������������������
������������������ %(repo_file)s"
-
-msgid "Specify repository distribution in order to create a DEB repository."
-msgstr "�������������� �������������� ������������������ ������ ����������������
������������������ DEB."
-
-#, python-format
-msgid "Could not enable repository %(repo_id)s."
-msgstr "���� �������������� ���������������� ������������������ %(repo_id)s."
-
-#, python-format
-msgid "Could not disable repository %(repo_id)s."
-msgstr "���� �������������� ������������������ ������������������
%(repo_id)s."
-
-msgid "YUM Repository ID already exists"
-msgstr "���� ������������������ YUM ������ ��������������������"
-
-msgid "YUM Repository name must be a string"
-msgstr "������ ������������������ YUM ������������ �������� ��������������"
-
-#, python-format
-msgid "Unable to list repositories. Details: '%(err)s'"
-msgstr "���� �������������� �������������� ������������ ����������������.
����������������: %(err)s"
-
-#, python-format
-msgid "Unable to retrieve repository information. Details: '%(err)s'"
-msgstr "���� �������������� ���������������� �������������������� ��
������������������. ����������������: %(err)s"
-
-#, python-format
-msgid "Unable to add repository. Details: '%(err)s'"
-msgstr "���� �������������� ���������������� ������������������. ����������������:
%(err)s"
-
-#, python-format
-msgid "Unable to remove repository. Details: '%(err)s'"
-msgstr "���� �������������� �������������� ������������������. ����������������:
%(err)s"
-
-#, python-format
-msgid ""
-"Configuration items: '%(items)s' are not supported by repository
manager"
-msgstr ""
-
-msgid "Repository metalink must be an http://, ftp:// or file:// URL."
-msgstr ""
-
-msgid "Cannot specify mirrorlist and metalink at the same time."
-msgstr ""
-
-#, python-format
-msgid ""
-"Virtual machine '%(vm)s' must be stopped before creating a snapshot of
it."
-msgstr ""
-
-#, python-format
-msgid ""
-"Unable to create snapshot '%(name)s' on virtual machine '%(vm)s'.
Details: %"
-"(err)s"
-msgstr ""
-
-#, python-format
-msgid "Snapshot '%(name)s' does not exist on virtual machine
'%(vm)s'."
-msgstr ""
-
-#, python-format
-msgid ""
-"Unable to retrieve snapshot '%(name)s' on virtual machine '%(vm)s'.
Details: "
-"%(err)s"
-msgstr ""
-
-#, python-format
-msgid "Unable to list snapshots on virtual machine '%(vm)s'. Details:
%(err)s"
-msgstr ""
-
-#, python-format
-msgid ""
-"Unable to delete snapshot '%(name)s' on virtual machine '%(vm)s'.
Details: %"
-"(err)s"
-msgstr ""
-
-#, python-format
-msgid ""
-"Unable to retrieve current snapshot of virtual machine '%(vm)s'. Details:
%"
-"(err)s"
-msgstr ""
-
-#, python-format
-msgid ""
-"Unable to revert virtual machine '%(vm)s' to snapshot '%(name)s'.
Details: %"
-"(err)s"
-msgstr ""
-
-#, python-format
-msgid ""
-"Unable to create snapshot of virtual machine '%(vm)s' because it contains a
"
-"disk with format '%(format)s'; only 'qcow2' is supported."
-msgstr ""
-
-msgid "The number of vCPUs is too large for this system."
-msgstr ""
-
-msgid "Invalid vCPU/topology combination."
-msgstr ""
-
-msgid "This host (or current configuration) does not allow CPU topology."
-msgstr ""
-
-msgid "ERROR CODE"
-msgstr "������ ������������"
-
-msgid "REASON"
-msgstr "��������������"
-
-msgid "STACK"
-msgstr "��������"
-
-msgid "Go to Homepage"
-msgstr "�������������� ���� �������������� ����������������"
-
-msgid "Create a New Virtual Machine"
-msgstr "�������������� ���������� ���������������������� ������������"
-
-msgid "Virtual Machine Name"
-msgstr "������ ���������������������� ������������"
-
-msgid ""
-"The name used to identify the virtual machine. If omitted, a name will be "
-"chosen based on the template used."
-msgstr ""
-"������ ������ �������������������������� ���������������������� ������������.
�������� ���� ��������������, ������ ���������� �������������� "
-"�� ���������������������� ���� �������������������������� ��������������."
-
-msgid "Template"
-msgstr "������������"
-
-msgid "Please create a template first."
-msgstr "��������������������, ���������������� ������������ �� ������������
��������������."
-
-msgid "Create a Template"
-msgstr "�������������� ������������"
-
-msgid "Please choose a template."
-msgstr "��������������������, ���������������� ������������."
-
-msgid "OS"
-msgstr "����"
-
-msgid "OS Version"
-msgstr "������������ ����"
-
-msgid "CPUS"
-msgstr "��������������������"
-
-msgid "Memory"
-msgstr "������������"
-
-msgid "Create"
-msgstr "��������������"
-
-msgid "Creating..."
-msgstr ""
-
-msgid "Cancel"
-msgstr "������������"
-
-msgid "Edit Guest"
-msgstr "���������������� ���������������� ��������������"
-
-msgid "General"
-msgstr "����������"
-
-msgid "Storage"
-msgstr "������������������"
-
-msgid "Interface"
-msgstr "������������������"
-
-msgid "Permission"
-msgstr "������������"
-
-msgid "Host PCI Device"
-msgstr ""
-
-msgid "Snapshot"
-msgstr ""
-
-msgid "Name"
-msgstr "������"
-
-msgid "CPUs"
-msgstr "��������������������"
-
-msgid "Memory (MB)"
-msgstr "������������ (����)"
-
-msgid "Icon"
-msgstr "������������"
-
-msgid "Device"
-msgstr "������ ��������������������"
-
-msgid "Path"
-msgstr "�������� NFS"
-
-msgid "Network"
-msgstr "��������"
-
-msgid "Type"
-msgstr "������"
-
-msgid "MAC Address"
-msgstr ""
-
-msgid "Available system users and groups"
-msgstr ""
-
-msgid "Selected system users and groups"
-msgstr ""
-
-msgid "User"
-msgstr ""
-
-msgid "All"
-msgstr "������"
-
-msgid "To Add"
-msgstr ""
-
-msgid "Added"
-msgstr ""
-
-msgid "filter"
-msgstr ""
-
-msgid "Product"
-msgstr ""
-
-msgid "Vendor"
-msgstr "������������"
-
-msgid "Created"
-msgstr ""
-
-msgid "Save"
-msgstr "������������������"
-
-msgid "Replace"
-msgstr "����������������"
-
-msgid "Detach"
-msgstr "������������������"
-
-msgid "revert"
-msgstr ""
-
-msgid "Start"
-msgstr "������������������"
-
-msgid "Reset"
-msgstr "����������������"
-
-msgid "Pause"
-msgstr ""
-
-msgid "Resume"
-msgstr ""
-
-msgid "Power Off"
-msgstr "������������������"
-
-msgid "Actions"
-msgstr "����������������"
-
-msgid "Connect"
-msgstr "��������������������"
-
-msgid "Clone"
-msgstr "����������������������"
-
-msgid "Edit"
-msgstr "��������������������������"
-
-msgid "Shut Down"
-msgstr "������������������ ������������"
-
-msgid "Delete"
-msgstr "��������������"
-
-msgid "CPU"
-msgstr "������������������"
-
-msgid "Disk I/O"
-msgstr "���������������� ��������-����������"
-
-msgid "Network I/O"
-msgstr "�������������� ��������-����������"
-
-msgid "Livetile"
-msgstr "Livetile"
-
-msgid "No guests found."
-msgstr "���� �������������� ���������������� ��������������."
-
-msgid "Add a Storage Device to VM"
-msgstr "���������������� �������������������� ���������������� �� VM"
-
-msgid "Device Type"
-msgstr "������ ��������������������"
-
-msgid "The device type. Currently, \"cdrom\" and \"disk\" are
supported."
-msgstr "������ ��������������������. �� ������������ ������������
���������������������������� ������������ \"cdrom\"."
-
-msgid "Storage Pool"
-msgstr "������ ������������"
-
-msgid "Storage pool which volume located in"
-msgstr "�������� �� �������� ������������ ������������ ��������
��������������"
-
-msgid "Storage Volume"
-msgstr "������ �������� ������������"
-
-msgid "Storage volume to be attached"
-msgstr "������ �������� ������������ �������� ��������������"
-
-msgid "File Path"
-msgstr "�������� �� ����������"
-
-msgid "The ISO file path in the server for CDROM."
-msgstr "�������� �� ���������� ISO ������ CDROM ���� ��������������."
-
-msgid "Attach"
-msgstr "��������������������"
-
-msgid "Shut down"
-msgstr "����������������"
-
-msgid "Restart"
-msgstr "��������������������"
-
-msgid "Basic Information"
-msgstr "�������������� ��������������������"
-
-msgid "OS Distro"
-msgstr "�������������� ����"
-
-msgid "OS Code Name"
-msgstr "�������������� ������ ����"
-
-msgid "Processor"
-msgstr "������������������"
-
-msgid "CPU(s)"
-msgstr ""
-
-msgid "System Statistics"
-msgstr "������������������ ��������������������"
-
-msgid "Software Updates"
-msgstr "�������������������� ������������������������ ����������������������"
-
-msgid "Update Progress"
-msgstr "������ ��������������������"
-
-msgid "Repositories"
-msgstr "������������������"
-
-msgid "Debug Reports"
-msgstr "�������������������� ������������"
-
-msgid "The username or password you entered is incorrect. Please try again."
-msgstr "�������������� ���������������� ������ ������������������������ ������
������������. �������������� ������ ������."
-
-msgid "This field is required."
-msgstr "������ ������������������������ ��������."
-
-msgid "Log in"
-msgstr "����������"
-
-msgid "Logging in..."
-msgstr "��������..."
-
-msgid "Host"
-msgstr "��������"
-
-msgid "Guests"
-msgstr "���������������� ��������������"
-
-msgid "Templates"
-msgstr "��������������"
-
-msgid "Failed to get application configuration"
-msgstr "���� �������������� ���������������� ������������������������
��������������������"
-
-msgid "This is not a valid Linux path"
-msgstr "�������� ������������������������ �������� �� Linux"
-
-msgid "This is not a valid URL."
-msgstr "������ ������������������������ URL."
-
-msgid "No such data available."
-msgstr "������ ���������� ������������."
-
-msgid ""
-"Can not contact the host system. Verify the host system is up and that you "
-"have network connectivity to it. HTTP request response %1. "
-msgstr ""
-"������ ���������� �� ���������������� ����������. ������������������, ������
�������������� ���������� ���������������� �� ���������������� "
-"������ ����������������������. ���������� ���� ������������ HTTP: %1. "
-
-msgid "Unable to read file."
-msgstr ""
-
-msgid "Error while uploading file."
-msgstr ""
-
-msgid "Delete Confirmation"
-msgstr "�������������������������� ����������������"
-
-msgid "OK"
-msgstr "OK"
-
-msgid "Confirm"
-msgstr "����������������������"
-
-msgid "Warning"
-msgstr "����������������������������"
-
-msgid "Cloning..."
-msgstr ""
-
-msgid "Loading..."
-msgstr "����������������������..."
-
-msgid "An error occurred while retrieving system information."
-msgstr ""
-
-msgid "Retry"
-msgstr "������������������"
-
-msgid "Detailed message:"
-msgstr "������������������ ������������������:"
-
-msgid "No ISO found"
-msgstr ""
-
-msgid "This is not a valid ISO file."
-msgstr "�������� �������� ���� ���������������� �������������������� ��������������
ISO."
-
-msgid "This may take a long time. Do you want to continue?"
-msgstr "������ ������������ ���������� ��������������. ��������������������?"
-
-msgid "This will permanently delete the template. Would you like to continue?"
-msgstr "������������ ���������� ������������������������ ������������.
��������������������?"
-
-msgid "Unable to shut down system as there are some virtual machines running!"
-msgstr ""
-"�������������������� ������������������ ������������ ��������������,
������������������ �� ������ ���������������� ���������������������� "
-"������������!"
-
-msgid "Max:"
-msgstr "��������.:"
-
-msgid "Utilization"
-msgstr "��������������������������"
-
-msgid "Available"
-msgstr "����������������"
-
-msgid "Read Rate"
-msgstr "���������������� ������������"
-
-msgid "Write Rate"
-msgstr "���������������� ������������"
-
-msgid "Received"
-msgstr "����������������"
-
-msgid "Sent"
-msgstr "��������������������"
-
-msgid ""
-"Shutting down or restarting host will cause unsaved work lost. Continue to "
-"shut down/restarting?"
-msgstr ""
-"�������������������� ������������ �� �������������������� ����������
���������������� �� ������������ �������������������������� ������������. "
-"�������������������� �������������������� ������������/��������������������?"
-
-msgid ""
-"Repository will be removed permanently and can't be recovered. Do you want
"
-"to continue?"
-msgstr "������������������ ���������� �������������� ������ ����������������������
����������������������������. ��������������������?"
-
-msgid "ID"
-msgstr "����"
-
-msgid "Base URL"
-msgstr "�������������� URL"
-
-msgid "Is Mirror"
-msgstr "�������������������� ����������"
-
-msgid "URL Args"
-msgstr "������������������ URL"
-
-msgid "Enabled"
-msgstr "����������������"
-
-msgid "GPG Check"
-msgstr "���������������� GPG"
-
-msgid "GPG Key"
-msgstr "�������� GPG"
-
-msgid "Add"
-msgstr "����������������"
-
-msgid "Remove"
-msgstr "��������������"
-
-msgid "Enable"
-msgstr "����������������"
-
-msgid "Disable"
-msgstr "������������������"
-
-msgid "Package Name"
-msgstr "������ ������������"
-
-msgid "Version"
-msgstr "������������"
-
-msgid "Architecture"
-msgstr "����������������������"
-
-msgid "Repository"
-msgstr "������������������"
-
-msgid "Update All"
-msgstr "���������������� ������"
-
-msgid "Updating..."
-msgstr "��������������������..."
-
-msgid "Failed to retrieve packages update information."
-msgstr ""
-
-msgid "Failed to update package(s)."
-msgstr "���� �������������� ���������������� ������������."
-
-msgid ""
-"Debug report will be removed permanently and can't be recovered. Do you want
"
-"to continue?"
-msgstr ""
-"�������������������� ���������� ���������� ������������ ������
���������������������� ����������������������������. ��������������������?"
-
-msgid "Generated Time"
-msgstr "���������� ����������������"
-
-msgid "Generate"
-msgstr "��������������"
-
-msgid "Generating..."
-msgstr "����������������..."
-
-msgid "Rename"
-msgstr "��������������������������"
-
-msgid "Download"
-msgstr "������������������"
-
-msgid ""
-"Report name should contain only letters, digits, underscore ('_') and/or
"
-"hyphen ('-')."
-msgstr "������ ������������ ������������ ������������������ ������������ ����������,
���������� �� ������������ ('-')."
-
-msgid "Pending..."
-msgstr "����������������������..."
-
-msgid "Report name is the same as the original one."
-msgstr ""
-
-msgid ""
-"This will delete the virtual machine and its virtual disks. This operation "
-"cannot be undone. Would you like to continue?"
-msgstr ""
-"���������� �������������� ���������������������� ������������ ������������ ����
������������ ������������������������ ��������������. ������ "
-"���������������������� ����������������. ��������������������?"
-
-msgid "Power off Confirmation"
-msgstr "�������������������������� ����������������"
-
-msgid ""
-"This action may produce undesirable results, for example unflushed disk "
-"cache in the guest. Would you like to continue?"
-msgstr ""
-
-msgid "Reset Confirmation"
-msgstr "�������������������������� ����������������"
-
-msgid ""
-"There is a risk of data loss caused by reset without the guest OS shutdown. "
-"Would you like to continue?"
-msgstr ""
-
-msgid "Shut Down Confirmation"
-msgstr "�������������������������� ����������������"
-
-msgid "Note the guest OS may ignore this request. Would you like to continue?"
-msgstr "������������ ���������� ������������������������ ������������.
��������������������?"
-
-msgid "Virtual Machine delete Confirmation"
-msgstr ""
-
-msgid ""
-"This virtual machine is not persistent. Power Off will delete it. Continue?"
-msgstr ""
-
-msgid ""
-"When the target guest has SCSI or iSCSI volumes, they will be cloned on "
-"default storage pool. The same will happen when the target pool does not "
-"have enough space to clone the volumes. Do you want to continue?"
-msgstr ""
-
-msgid ""
-"This CDROM will be detached permanently and you can re-attach it. Continue "
-"to detach it?"
-msgstr ""
-"�������� CDROM ���������� ����������������. ������ ���������� ���������� ����������
��������������������. ������������������?"
-
-msgid "Attaching..."
-msgstr "����������������������..."
-
-msgid "Replacing..."
-msgstr "������������..."
-
-msgid "Successfully attached!"
-msgstr "�������������� ������������������!"
-
-msgid "Successfully replaced!"
-msgstr "�������������� ��������������!"
-
-msgid "Successfully detached!"
-msgstr "�������������� ����������������!"
-
-msgid ""
-"This disk will be detached permanently and you can re-attach it. Continue to
"
-"detach it?"
-msgstr ""
-
-msgid "interface:"
-msgstr ""
-
-msgid "address:"
-msgstr ""
-
-msgid "link_type:"
-msgstr ""
-
-msgid "block:"
-msgstr ""
-
-msgid "drive_type:"
-msgstr ""
-
-msgid "model:"
-msgstr ""
-
-msgid "Affected devices:"
-msgstr ""
-
-msgid "The VLAN id must be between 1 and 4094."
-msgstr "���� VLAN ������������ �������� ���� 1 ���� 4094."
-
-msgid "unavailable"
-msgstr "��������������������"
-
-msgid ""
-"This action will interrupt network connectivity for any virtual machine that
"
-"depend on this network."
-msgstr ""
-"������ ���������������� �������������� �������������� �������������������� ��
�������� ���������������������� ����������, �������������� "
-"�������������� ���� �������� ��������."
-
-msgid "Create a network"
-msgstr "�������������� ��������"
-
-msgid ""
-"This network is not persistent. Instead of stop, this action will "
-"permanently delete it. Would you like to continue?"
-msgstr ""
-"�������� ������ ������������ ���� ��������������������. ������������
����������������������, ������ ���������������� ������������������������ "
-"������ ������������. ��������������������?"
-
-msgid ""
-"The bridged VLAN tag may not work well with NetworkManager enabled. You "
-"should consider disabling it."
-msgstr ""
-
-msgid ""
-"This will permanently delete the storage pool. Would you like to continue?"
-msgstr "������ ������������ ���������� ������������������������ ������������.
��������������������?"
-
-msgid "This storage pool is empty."
-msgstr "�������� ������ ������������ ������������."
-
-msgid ""
-"It will format your disk and you will loose any data in there, are you sure "
-"to continue? "
-msgstr ""
-"�������� ���������� ����������������������������, �� ������ ������������ ����
������ ���������� ����������������. ���� "
-"�������������������������� ������������ ��������������������? "
-
-msgid "SCSI Fibre Channel"
-msgstr "SCSI Fibre Channel"
-
-msgid "No SCSI adapters found."
-msgstr "���� �������������� ���������������� SCSI."
-
-msgid "Loading iSCSI targets..."
-msgstr ""
-
-msgid "No iSCSI found. Please input one."
-msgstr ""
-
-msgid "Failed to load iSCSI targets."
-msgstr ""
-
-msgid "The storage pool name can not be blank."
-msgstr "���� �������������� ������ �������� ������������."
-
-msgid "The storage pool path can not be blank."
-msgstr "���� ������������ �������� �� �������� ������������."
-
-msgid "NFS server mount path can not be blank."
-msgstr "���� ������������ �������� ������������������������ ��������������
NFS."
-
-msgid "Invalid NFS mount path."
-msgstr "������������������������ �������� ������������������������ NFS."
-
-msgid "No logical device selected."
-msgstr "���� �������������� �������������������� ��������������������."
-
-msgid "The iSCSI target can not be blank."
-msgstr "���� ������������ �������������� ������������ iSCSI."
-
-msgid "Server name can not be blank."
-msgstr "���� �������������� ������ ��������������."
-
-msgid "This is not a valid Server Name or IP. Please, modify it."
-msgstr ""
-
-msgid "Looking for available partitions ..."
-msgstr "���������� ������������������ ����������������..."
-
-msgid "No available partitions found."
-msgstr "���� �������������� ������������������ ��������������."
-
-msgid ""
-"This storage pool is not persistent. Instead of deactivate, this action will
"
-"permanently delete it. Would you like to continue?"
-msgstr ""
-"�������� ������ ������������ ���� ��������������������. ������������
����������������������, ������ ���������������� ������������������������ "
-"������ ������������. ��������������������?"
-
-msgid "Unable to retrieve partitions information."
-msgstr "���� �������������� ���������������� �������������������� ��
������������������. ����������������: %(err)s"
-
-msgid "In progress..."
-msgstr ""
-
-msgid "Failed!"
-msgstr ""
-
-msgid "CDROM path needs to be a valid local/remote path and cannot be blank."
-msgstr ""
-
-msgid "Disk pool or volume cannot be blank."
-msgstr "���� �������������� ������ �������� ������������."
-
-msgid "Filter"
-msgstr ""
-
-msgid "Network Name"
-msgstr "������ ��������"
-
-msgid "State"
-msgstr "������������������"
-
-msgid "Network Type"
-msgstr "������ ��������"
-
-msgid "Address Space"
-msgstr "���������������� ������������������������"
-
-msgid "Name should not contain '/' and '\"'."
-msgstr "������������������������ ������ �������� ������������. �� ���������� ����
������������ �������� ���������������� '/'."
-
-msgid "Isolated: no external network connection"
-msgstr "�������������������������� (������ �������������������� ��������������
��������������������)"
-
-msgid "NAT: outbound physical network connection only"
-msgstr "NAT (������������ ������������������ �������������������� ��������������
��������������������)"
-
-msgid "Bridged: Virtual machines are connected to physical network directly"
-msgstr "���������� �������� (������������ ����������������������
���������������������� ���������� �� �������������������� ��������)"
-
-msgid "(No interfaces found)"
-msgstr ""
-
-msgid "Destination"
-msgstr "�������������� ������������������������:"
-
-msgid "Enable VLAN"
-msgstr "���������������� VLAN:"
-
-msgid "VLAN ID"
-msgstr ""
-
-msgid "Stop"
-msgstr "������������������"
-
-msgid "Generate a New Debug Report"
-msgstr "�������������� ���������� �������������������� ����������"
-
-msgid "Report Name"
-msgstr "������ ������������"
-
-msgid ""
-"The name used to identify the report. If omitted, a name will be chosen "
-"based on current time. Name can contain: letters, digits, underscore
(\"_\") "
-"and hyphen (\"-\")."
-msgstr ""
-"������ ������ �������������������������� ������������. �������� ����
��������������, ������ ���������� ������������������������ ���� "
-"������������ ���������������� ��������������. ������ ���������� ������������������:
����������, ���������� �� ������������ (\"-\")."
-
-msgid "Rename a Debug Report"
-msgstr "�������������� ���������� �������������������� ����������"
-
-msgid ""
-"The name used to identify the report. Name can contain: letters, digits and "
-"hyphen (\"-\")."
-msgstr ""
-"������ ������ �������������������������� ������������. �������� ����
��������������, ������ ���������� ������������������������ ���� "
-"������������ ���������������� ��������������. ������ ���������� ������������������:
����������, ���������� �� ������������ (\"-\")."
-
-msgid "Submit"
-msgstr "����������������������"
-
-msgid "Add a Repository"
-msgstr "���������������� ������������������"
-
-msgid "Identifier"
-msgstr "��������������������������"
-
-msgid "Single word, unique identifier for the repository."
-msgstr "������������������ ���������� - ��������������������
�������������������������� ������������������."
-
-msgid "Textual name for the repository."
-msgstr "������������������ ������ ������������������."
-
-msgid "URL"
-msgstr "URL"
-
-msgid "Required Field"
-msgstr "������������������������ ��������"
-
-msgid "URL to the repository. Supported protocols are http, ftp, and file."
-msgstr "URL ������������������. ���������������������������� ������������������:
http, ftp, file."
-
-msgid "Repository is a mirror"
-msgstr "������������������ ���������������� ��������������������
������������."
-
-msgid "Distribution"
-msgstr "��������������"
-
-msgid "Distribution of the DEB repository."
-msgstr "�������������� ������������������ DEB."
-
-msgid "Components"
-msgstr "��������������������"
-
-msgid "List of components in DEB repository."
-msgstr "������������ ���������������������� �� ������������������ DEB."
-
-msgid "Edit Repository"
-msgstr "���������������� ������������������"
-
-msgid "Mirror List URL"
-msgstr "URL ������������ �������������������� ����������"
-
-msgid "Yes"
-msgstr "����"
-
-msgid "No"
-msgstr "������"
-
-msgid "Capacity"
-msgstr "��������������"
-
-msgid "Allocated"
-msgstr "����������������"
-
-msgid "Location"
-msgstr "������������������������"
-
-msgid "Device path"
-msgstr "�������� �� ��������������������"
-
-msgid "active"
-msgstr "��������������"
-
-msgid "inactive"
-msgstr "������������������"
-
-msgid "Deactivate"
-msgstr "������������������"
-
-msgid "Activate"
-msgstr "������������������������"
-
-msgid "Add Volume"
-msgstr ""
-
-msgid "Extend"
-msgstr ""
-
-msgid "Undefine"
-msgstr "��������������"
-
-msgid "Format"
-msgstr "������������:"
-
-msgid "Allocation"
-msgstr "������������������ ����������������:"
-
-msgid "Define a New Storage Pool"
-msgstr "�������������� ������ ������������"
-
-msgid "Storage Pool Name"
-msgstr "������ �������� ������������"
-
-msgid ""
-"The name used to identify the storage pools, and it should not be empty."
-msgstr "������ ������ �������������������������� ���������� ������������. ����
���������� �������� ������������."
-
-msgid "Storage Pool Type"
-msgstr "������ �������� ������������"
-
-msgid "Storage Path"
-msgstr "�������� �� ����������"
-
-msgid ""
-"The path of the Storage Pool. Each Storage Pool must have a unique path."
-msgstr "�������� �� �������� ������������. ������������ ������ ������������
������������ ���������� �������������������� ��������."
-
-msgid ""
-"Kimchi will try to create the directory when it does not already exist in "
-"your system."
-msgstr "Kimchi �������������������� �������������� ��������������, �������� ����
���� �������������������� �� ��������������."
-
-msgid "NFS Server IP"
-msgstr "IP-���������� �������������� NFS"
-
-msgid "NFS server IP or hostname. It can be input or chosen from history."
-msgstr ""
-"IP-���������� ������ ������ ���������� �������������� NFS. ������ ����������
������������ ������ �������������� �� "
-"��������������������."
-
-msgid "NFS Path"
-msgstr "�������� NFS"
-
-msgid "The NFS exported path on NFS server."
-msgstr "�������������������������������� �������� NFS ���� ��������������
NFS."
-
-msgid "iSCSI Server"
-msgstr "������������ iSCSI"
-
-msgid "Server"
-msgstr "������������"
-
-msgid "Port"
-msgstr "��������"
-
-msgid "iSCSI server IP or hostname. It should not be empty."
-msgstr "IP-���������� ������ ������ ���������� �������������� iSCSI. ���� ����������
�������� ������������."
-
-msgid "Target"
-msgstr "�������������� ������������"
-
-msgid "The iSCSI target on iSCSI server"
-msgstr "�������������� ������������ iSCSI ���� �������������� iSCSI"
-
-msgid "Add iSCSI Authentication"
-msgstr "���������������� �������������������������� iSCSI"
-
-msgid "iSCSI Authentication"
-msgstr "�������������������������� iSCSI"
-
-msgid "User Name"
-msgstr "������ ������������������������"
-
-msgid "Password"
-msgstr "������������"
-
-msgid "SCSI Adapter"
-msgstr "�������������� SCSI"
-
-msgid "Please, wait..."
-msgstr "������������������..."
-
-msgid "Add a Volume to Storage Pool"
-msgstr ""
-
-msgid "Fetch from remote URL"
-msgstr ""
-
-msgid "Enter the remote URL here."
-msgstr ""
-
-msgid "Upload a file"
-msgstr ""
-
-msgid "Choose the file you want to upload."
-msgstr ""
-
-msgid "Add Template"
-msgstr "���������������� ������������"
-
-msgid "Where is the source media for this template? "
-msgstr "������ ������������������ ���������������� ���������������� ������
���������� ��������������?"
-
-msgid "Local ISO Image"
-msgstr "������������������ ���������� ISO"
-
-msgid "Local Image File"
-msgstr ""
-
-msgid "Remote ISO Image"
-msgstr "������������������ ���������� ISO"
-
-msgid "Search ISOs"
-msgstr "���������� �������������� ISO"
-
-msgid "The following ISOs are available:"
-msgstr "������������������ ������������ ISO:"
-
-msgid "OS: "
-msgstr "����: "
-
-msgid "Version: "
-msgstr "������������: "
-
-msgid "Size: "
-msgstr "������������: "
-
-msgid "Search more ISOs"
-msgstr "���������� ���������������������������� �������������� ISO"
-
-msgid "Create Templates from Selected ISO"
-msgstr "�������������� �������������� ���� ������������������ ��������������
ISO"
-
-msgid "I want to use a specific ISO file"
-msgstr "������������������������ �������������������� �������� ISO"
-
-msgid "Loading default remote ISOs ..."
-msgstr "���������������� ������������������ ISO ���� ������������������..."
-
-msgid "Arch: "
-msgstr "����������������������: "
-
-msgid "I want to use a custom URL"
-msgstr "������������������������ ������������ URL"
-
-msgid "Edit Template"
-msgstr "���������������� ������������"
-
-msgid "CDROM"
-msgstr "CDROM"
-
-msgid "Image File"
-msgstr ""
-
-msgid "Graphics"
-msgstr "��������������"
-
-msgid "Disk(GB)"
-msgstr ""
-
-msgid "Disk Format"
-msgstr ""
-
-msgid "CPU Number"
-msgstr "�������������������� ����������������������"
-
-msgid "Manually set CPU topology"
-msgstr ""
-
-msgid "Cores"
-msgstr ""
-
-msgid "Threads"
-msgstr ""
-
-msgid "No templates found."
-msgstr "���� �������������� ��������������."
-
-#~ msgid "Delete is not allowed for %(resource)s"
-#~ msgstr "���������������� ������������������ ������ %(resource)s"
-
-#~ msgid "%(resource)s does not implement update method"
-#~ msgstr "%(resource)s ���� ������������������ ����������
��������������������"
-
-#~ msgid "Create is not allowed for %(resource)s"
-#~ msgstr "���������������� ������������������ ������ %(resource)s"
-
-#~ msgid "Unable to parse JSON request"
-#~ msgstr "������������ �������������� �������������� JSON"
-
-#~ msgid "This API only supports JSON"
-#~ msgstr "������ �������������� API ������������������������ ������������
JSON"
-
-#~ msgid "Datastore is not initiated in the model object."
-#~ msgstr "������������������ ������������ �� �������������� ������������ ����
��������������������������������."
-
-#~ msgid "Unable to start task due error: %(err)s"
-#~ msgstr "���� �������������� ������������������ ������������ ����-����
������������ %(err)s"
-
-#~ msgid ""
-#~ "Authentication failed for user '%(username)s'. [Error code:
%(code)s]"
-#~ msgstr ""
-#~ "�������� �������������������������� ������������������������ %(username)s.
[������ ������������: %(code)s]"
-
-#~ msgid "You are not authorized to access Kimchi"
-#~ msgstr "������ �������� �������������� �� Kimchi"
-
-#~ msgid "Specify %(item)s to login into Kimchi"
-#~ msgstr "�������������� %(item)s ������ ���������� �� Kimchi"
-
-#~ msgid "Unable to find %(item)s in datastore"
-#~ msgstr "���� ������������ %(item)s �� ������������������ ������������"
-
-#~ msgid "Timeout while running command '%(cmd)s' after %(seconds)s
seconds"
-#~ msgstr "���������� ��������-������ �������������������� �������������� %(cmd)s
(%(seconds)s ��)"
-
-#~ msgid "Help"
-#~ msgstr "������������"
-
-#~ msgid "About"
-#~ msgstr "�� ������������������"
-
-#~ msgid "Log out"
-#~ msgstr "����������"
-
-#~ msgid "Version:"
-#~ msgstr "������������:"
diff --git a/plugins/kimchi/po/zh_CN.po b/plugins/kimchi/po/zh_CN.po
deleted file mode 100644
index fc6dd84..0000000
--- a/plugins/kimchi/po/zh_CN.po
+++ /dev/null
@@ -1,2186 +0,0 @@
-# i18n portable object for kimchi.
-# Copyright (C) IBM, Corp. 2013-2014
-# ShaoHe Feng <shaohef(a)linux.vnet.ibm.com>, 2013-04-18.
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-#
-msgid ""
-msgstr ""
-"Project-Id-Version: kimchi 0.1\n"
-"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2015-07-01 16:11-0300\n"
-"PO-Revision-Date: 2013-06-27 10:48+0000\n"
-"Last-Translator: ShaoHe Feng <shaohef(a)linux.vnet.ibm.com>\n"
-"Language-Team: ShaoHe Feng <shaohef(a)linux.vnet.ibm.com>\n"
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
-"Content-Transfer-Encoding: 8bit\n"
-"Language: zh_CN\n"
-"Generated-By: pygettext.py 1.5\n"
-"X-Poedit-Country: CHINA\n"
-"X-Poedit-Language: Chinese\n"
-"X-Poedit-SourceCharset: utf-8\n"
-
-#, python-format
-msgid "Unknown parameter %(value)s"
-msgstr "������������ %(value)s"
-
-#, python-format
-msgid "Timeout of %(seconds)s seconds expired while running task
'%(task)s."
-msgstr "������'%(task)s������%(seconds)s������"
-
-#, python-format
-msgid "User %(user_id)s not found with given LDAP settings."
-msgstr "���������������LDAP���������������%(user_id)s������"
-
-msgid "Unknown \"_cap\" specified"
-msgstr "������������\"_cap\""
-
-msgid "\"_passthrough\" should be \"true\" or
\"false\""
-msgstr
"\"_passthrough\"���������\"true\"������\"false\""
-
-msgid "\"_passthrough_affected_by\" should be a device name string"
-msgstr
"\"_passthrough_affected_by\"���������������������������������"
-
-#, python-format
-msgid "Error while getting block devices. Details: %(err)s"
-msgstr "������������������������������������%(err)s"
-
-#, python-format
-msgid "Error while getting block device information for %(device)s."
-msgstr "��������������� %(device)s ������������������"
-
-#, python-format
-msgid "Unable to find distro file: %(filename)s"
-msgstr "���������������������������%(filename)s"
-
-#, python-format
-msgid ""
-"Unable to parse distro file: %(filename)s. Make sure, it is a JSON file."
-msgstr
"������������������������������%(filename)s������������������������JSON������������������"
-
-#, python-format
-msgid "Unable to login to iSCSI host target %(portal)s. Details: %(err)s"
-msgstr "������������ %(portal)s ������iSCSI���������������������������%(err)s"
-
-#, python-format
-msgid "Unable to login to iSCSI host %(host)s target %(target)s"
-msgstr "������������iSCSI������%(host)s������������%(target)s���"
-
-#, python-format
-msgid "Unable to find ISO file %(filename)s"
-msgstr "������������ISO������ %(filename)s"
-
-#, python-format
-msgid "The ISO file %(filename)s is not bootable"
-msgstr "ISO������%(filename)s���������������"
-
-#, python-format
-msgid "The ISO file %(filename)s does not have a valid El Torito boot record"
-msgstr "ISO������%(filename)s���������������El Torito���������������"
-
-#, python-format
-msgid "Invalid El Torito validation entry in ISO %(filename)s"
-msgstr "���ISO������%(filename)s������������������El Torito������������������"
-
-#, python-format
-msgid "Invalid El Torito boot indicator in ISO %(filename)s"
-msgstr "ISO������%(filename)s���El Torito������������������������"
-
-#, python-format
-msgid "Unexpected volume type for primary volume in ISO %(filename)s"
-msgstr "������������ISO������%(filename)s���������������"
-
-#, python-format
-msgid "Bad format while reading volume descriptor in ISO %(filename)s"
-msgstr "ISO������%(filename)s���������������������������"
-
-#, python-format
-msgid ""
-"The hypervisor doesn't have permission to use this ISO %(filename)s. "
-"Consider moving it under /var/lib/libvirt, or set the search permission to "
-"file access control lists for '%(user)s' user if possible, or add the
'%"
-"(user)s' to the ISO path group, or (not recommended) 'chmod -R o+x "
-"'path_to_iso'.Details: %(err)s"
-msgstr ""
-"hypervisor������������ISO������%(filename)s���������������������ISO������/var/lib/libvirt���"
-"���������������'%(user)s'���������������������������������'%(user)s'���������������ISO������������������"
-"������������������������������������������ 'chmod -R o+x
'���������������������������%(err)s"
-
-msgid "An error occurred when probing image OS information."
-msgstr "������������������������������������������������"
-
-msgid "No OS information found in given image."
-msgstr "���������������������������������������������������������"
-
-#, python-format
-msgid "Unable to read image file %(filename)s"
-msgstr "������������������������ %(filename)s"
-
-#, python-format
-msgid ""
-"Image file must be an existing file on system. %(filename)s is not a valid "
-"input."
-msgstr
"���������������������������������������%(filename)s���������������������"
-
-#, python-format
-msgid "Virtual machine %(name)s already exists"
-msgstr "���������%(name)s������������"
-
-#, python-format
-msgid "Virtual machine %(name)s does not exist"
-msgstr "���������%(name)s���������"
-
-#, python-format
-msgid ""
-"Unable to rename virtual machine %(name)s. The name %(new_name)s is already "
-"in use or the virtual machine is not powered off."
-msgstr ""
-"��������������������� %(name)s ������������������ %(new_name)s
������������������������������������"
-"������"
-
-#, python-format
-msgid "Unable to retrieve screenshot for stopped virtual machine %(name)s"
-msgstr "������������������������������������%(name)s���������"
-
-msgid "Remote ISO image is not supported by this server."
-msgstr "���������������������������ISO���������"
-
-#, python-format
-msgid "Screenshot is not supported on virtual machine %(name)s"
-msgstr "��������� %(name)s ���������������"
-
-#, python-format
-msgid "Unable to create virtual machine %(name)s. Details: %(err)s"
-msgstr "���������������������%(name)s������������%(err)s"
-
-#, python-format
-msgid "Unable to update virtual machine %(name)s. Details: %(err)s"
-msgstr "���������������������%(name)s������������%(err)s"
-
-#, python-format
-msgid "Unable to retrieve virtual machine %(name)s. Details: %(err)s"
-msgstr "���������������������%(name)s������������%(err)s"
-
-#, python-format
-msgid "Unable to connect to powered off virtual machine %(name)s."
-msgstr "���������%(name)s���������������������������"
-
-msgid "Virtual machine name must be a string without slashes (/)"
-msgstr ""
-
-#, python-format
-msgid "Invalid template URI %(value)s specified for virtual machine"
-msgstr "������������������������URI %(value)s"
-
-#, python-format
-msgid "Invalid storage pool URI %(value)s specified for virtual machine"
-msgstr "���������������������������URI %(value)s"
-
-msgid "Supported virtual machine graphics are Spice or VNC"
-msgstr "������������������������������Spice������VNC"
-
-msgid "Graphics address to listen on must be IPv4 or IPv6"
-msgstr "������������������������������������������IPv4���IPv6���������"
-
-msgid "Specify a template to create a virtual machine from"
-msgstr "������������������������������������"
-
-#, python-format
-msgid "Unable to start virtual machine %(name)s. Details: %(err)s"
-msgstr "��������������������� %(name)s. ���������%(err)s"
-
-#, python-format
-msgid "Unable to power off virtual machine %(name)s. Details: %(err)s"
-msgstr "���������������������%(name)s������������%(err)s"
-
-#, python-format
-msgid "Unable to delete virtual machine %(name)s. Details: %(err)s"
-msgstr "��������������������� %(name)s������������%(err)s"
-
-#, python-format
-msgid "Unable to reset virtual machine %(name)s. Details: %(err)s"
-msgstr "���������������������%(name)s������������%(err)s"
-
-msgid "User name list must be an array"
-msgstr "������������������������������������"
-
-msgid "User name must be a string"
-msgstr "���������������������������������"
-
-msgid "Group name list must be an array"
-msgstr "������������������������������������"
-
-msgid "Group name must be a string"
-msgstr "���������������������������������������"
-
-#, python-format
-msgid "User(s) '%(users)s' do not exist"
-msgstr "������'%(users)s'���������"
-
-#, python-format
-msgid "Group(s) '%(groups)s' do not exist"
-msgstr "���������'%(groups)s'���������"
-
-#, python-format
-msgid "Unable to shutdown virtual machine %(name)s. Details: %(err)s"
-msgstr "���������������������%(name)s������������%(err)s"
-
-#, python-format
-msgid ""
-"Unable to get access metadata of virtual machine %(name)s. Details: %(err)s"
-msgstr "��������������������� %(name)s������������������������%(err)s"
-
-msgid "The guest console password must be a string."
-msgstr "���������������������������������������������������"
-
-msgid "The life time for the guest console password must be a number."
-msgstr "������������������������������������������������������������"
-
-#, python-format
-msgid "Virtual machine '%(name)s' must be stopped before cloning it."
-msgstr "���������'%(name)s'���������������������������������"
-
-#, python-format
-msgid "Insufficient disk space to clone virtual machine '%(name)s'"
-msgstr "���������������'%(name)s'���������������������������������"
-
-#, python-format
-msgid "Unable to clone VM '%(name)s'. Details: %(err)s"
-msgstr
"���������������������������'%(name)s'������������������%(err)s"
-
-#, python-format
-msgid "Invalid operation for non-persistent virtual machine %(name)s"
-msgstr ""
-
-#, python-format
-msgid "Cannot suspend VM '%(name)s' because it is not running."
-msgstr ""
-
-#, python-format
-msgid "Unable to suspend VM '%(name)s'. Details: %(err)s"
-msgstr ""
-
-#, python-format
-msgid "Cannot resume VM '%(name)s' because it is not paused."
-msgstr ""
-
-#, python-format
-msgid "Unable to resume VM '%(name)s'. Details: %(err)s"
-msgstr ""
-
-msgid "Memory assigned is higher then the maximum allowed in the host."
-msgstr ""
-
-#, python-format
-msgid ""
-"VM '%(name)s' does not support live memory update. Update the memory with
"
-"the machine offline to enable this feature."
-msgstr ""
-
-msgid "Only increase memory is allowed in active VMs"
-msgstr ""
-
-msgid ""
-"For live memory update, new memory value must be equal old memory value plus
"
-"multiples of 1024 Mib"
-msgstr ""
-
-msgid "There are not enough free slots of 1024 Mib in the guest."
-msgstr ""
-
-msgid ""
-"Host's libvirt version does not support memory devices. Libvirt must be >=
"
-"1.2.14"
-msgstr ""
-
-#, python-format
-msgid "Error attaching memory device. Details: %(error)s"
-msgstr ""
-
-#, python-format
-msgid ""
-"VM %(vmid)s does not contain directly assigned host device %(dev_name)s."
-msgstr "���������%(vmid)s���������������������������������%(dev_name)s���"
-
-#, python-format
-msgid "The host device %(dev_name)s is not allowed to directly assign to VM."
-msgstr "������������%(dev_name)s������������������������������������"
-
-msgid ""
-"No IOMMU groups found. Host PCI pass through needs IOMMU group to function "
-"correctly. Please enable Intel VT-d or AMD IOMMU in your BIOS, then verify "
-"the Kernel is compiled with IOMMU support. For Intel CPU, add intel_iommu=on
"
-"to your Kernel parameter in /boot/grub2/grub.conf. For AMD CPU, add iommu=pt
"
-"iommu=1."
-msgstr ""
-"���������IOMMU groups���������PCI pass through������IOMMU
group������������������������������"
-"BIOS������������Intel VT-d ������ AMD IOMMU
���������������������������������������IOMMU���������"
-"Intel
CPU������������/boot/grub2/grub.conf���������������������intel_iommu=on���������AMD
"
-"CPU������������iommu=pt iommu=1���"
-
-msgid "\"name\" should be a device name string"
-msgstr "\"name\"���������������������������������������"
-
-#, python-format
-msgid ""
-"The device %(name)s is probably in use by the host. Unable to attach it to "
-"the guest."
-msgstr ""
-
-#, python-format
-msgid "Interface %(iface)s does not exist in virtual machine %(name)s"
-msgstr "��������� %(name)s ��������������� %(iface)s"
-
-#, python-format
-msgid ""
-"Network %(network)s specified for virtual machine %(name)s does not exist"
-msgstr "������������%(name)s���������������%(network)s���������"
-
-msgid "Supported virtual machine interfaces type is only network"
-msgstr "���������������������������������������"
-
-msgid "Network name for virtual machine interface must be a string"
-msgstr "������������������������������������������������"
-
-msgid "Invalid network model card specified for virtual machine interface"
-msgstr "���������������������������������������������"
-
-msgid "Specify type and network to add a new virtual machine interface"
-msgstr "���������������������������������������������"
-
-msgid "MAC Address must respect this format FF:FF:FF:FF:FF:FF"
-msgstr ""
-
-#, python-format
-msgid "MAC Address %(mac)s already exists in virtual machine %(name)s"
-msgstr ""
-
-msgid "Invalid MAC Address"
-msgstr ""
-
-msgid "Cannot change MAC address of a running virtual machine"
-msgstr ""
-
-#, python-format
-msgid "Template %(name)s already exists"
-msgstr "������ %(name)s ������������"
-
-#, python-format
-msgid ""
-"Network '%(network)s' specified for template %(template)s does not
exist"
-msgstr "��������� %(template)s ��������������� '%(network)s'
���������"
-
-#, python-format
-msgid ""
-"Storage pool %(pool)s specified for template %(template)s does not exist"
-msgstr "��������� %(template)s ������������������ '%(pool)s'
���������"
-
-#, python-format
-msgid "Storage pool %(pool)s specified for template %(template)s is not
active"
-msgstr "��������� %(template)s ������������������ '%(pool)s'
������������"
-
-#, python-format
-msgid "Invalid parameter '%(param)s' specified for CDROM."
-msgstr "���CDROM��������������� '%(param)s' ������"
-
-#, python-format
-msgid "Network %(network)s specified for template %(template)s is not active"
-msgstr "��������� %(template)s ��������������� '%(network)s'
������������"
-
-msgid "Template name must be a string"
-msgstr "���������������������������������������"
-
-msgid "Template icon must be a path to the image"
-msgstr "���������������������������������������������������"
-
-msgid "Template distribution must be a string"
-msgstr "������������������������������������������"
-
-msgid "Template distribution version must be a string"
-msgstr "���������������������������������������������������"
-
-msgid "The number of CPUs must be an integer greater than 0"
-msgstr "CPU���������������������������0���������"
-
-msgid "Amount of memory (MB) must be an integer greater than 512"
-msgstr "���������������MB���������������������������������512���������"
-
-msgid "Template CDROM must be a local or remote ISO file"
-msgstr "���������CDROM������������������������������������ISO������"
-
-#, python-format
-msgid "Invalid storage pool URI %(value)s specified for template"
-msgstr "������������������������������������URI %(value)s"
-
-msgid "Specify an ISO image as CDROM or a base image to create a template"
-msgstr "������������ISO���������������������������CDROM������������������"
-
-msgid "All networks for the template must be specified in a list."
-msgstr "������������������������������������������������"
-
-msgid "Specify a volume to a template when storage pool is iSCSI or SCSI"
-msgstr
"���������������������iSCSI������SCSI������������������������������������"
-
-#, python-format
-msgid "The volume %(volume)s is not in storage pool %(pool)s"
-msgstr "���%(volume)s���������������%(pool)s���"
-
-#, python-format
-msgid "Unable to create template due error: %(err)s"
-msgstr "������������������������������%(err)s"
-
-#, python-format
-msgid "Unable to delete template due error: %(err)s"
-msgstr "���������������%(err)s���������������������"
-
-msgid "Disk size must be an integer greater than 1GB."
-msgstr "������������������������1GB���"
-
-msgid "Template base image must be a valid local image file"
-msgstr "������������������������������������������������������������"
-
-#, python-format
-msgid "Cannot identify base image %(path)s format"
-msgstr "������������������������%(path)s������"
-
-msgid ""
-"When specifying CPU topology, VCPUs must be a product of sockets, cores, and
"
-"threads."
-msgstr "CPU������������VCPUs������������sockets, cores ������threads���"
-
-msgid ""
-"When specifying CPU topology, each element must be an integer greater than "
-"zero."
-msgstr "CPU���������������������������������������������������������"
-
-msgid ""
-"Invalid disk image format. Valid formats: bochs, cloop, cow, dmg, qcow, "
-"qcow2, qed, raw, vmdk, vpc."
-msgstr ""
-"���������������������������������������������������bochs, cloop, cow, dmg, qcow,
qcow2, qed, "
-"raw, vmdk, vpc���"
-
-#, python-format
-msgid "Storage pool %(name)s already exists"
-msgstr "���������%(name)s������������"
-
-#, python-format
-msgid "Storage pool %(name)s does not exist"
-msgstr "���������%(name)s���������"
-
-#, python-format
-msgid "Specify %(item)s in order to create the storage pool %(name)s"
-msgstr "���������������%(name)s������%(item)s"
-
-#, python-format
-msgid "Unable to delete active storage pool %(name)s"
-msgstr "������������������������������ %(name)s"
-
-#, python-format
-msgid "Unable to list storage pools. Details: %(err)s"
-msgstr "������������������������ ��������� %(err)s"
-
-#, python-format
-msgid "Unable to create storage pool %(name)s. Details: %(err)s"
-msgstr "��������������������� %(name)s������������ %(err)s"
-
-#, python-format
-msgid ""
-"Unable to get number of storage volumes in storage pool %(name)s. Details: %"
-"(err)s"
-msgstr "���������������������%(name)s��������������������������� %(err)s"
-
-#, python-format
-msgid "Unable to activate storage pool %(name)s. Details: %(err)s"
-msgstr "���������������������%(name)s������������ %(err)s"
-
-#, python-format
-msgid "Unable to deactivate storage pool %(name)s. Details: %(err)s"
-msgstr "���������������������%(name)s������������ %(err)s"
-
-#, python-format
-msgid "Unable to delete storage pool %(name)s. Details: %(err)s"
-msgstr "���������������������%(name)s������������ %(err)s"
-
-#, python-format
-msgid ""
-"Unable to create NFS Pool as export path %(path)s may block during mount"
-msgstr
"������������NFS������������������������������%(path)s������������������������"
-
-#, python-format
-msgid "Unable to create NFS Pool as export path %(path)s mount failed"
-msgstr "������������NFS������������������������������%(path)s������"
-
-#, python-format
-msgid "Unsupported storage pool type: %(type)s"
-msgstr "������������������������������%(type)s"
-
-#, python-format
-msgid "Error while retrieving storage pool XML to %(pool)s"
-msgstr "���������������XML���%(pool)s���������������"
-
-msgid "Storage pool name must be a string without slashes (/)"
-msgstr ""
-
-msgid ""
-"Supported storage pool types are dir, netfs, logical, iscsi, isci and
kimchi-"
-"iso"
-msgstr
"������������������������dir���netfs���logical���iscsi���isci������kimchi-iso"
-
-msgid "Storage pool path must be a string"
-msgstr "���������������������������������"
-
-msgid "Storage pool host must be a IP or hostname"
-msgstr "������������������������������IP���������������"
-
-msgid "Storage pool device must be the absolute path to the block device"
-msgstr "������������������������������������������������������"
-
-msgid "Storage pool devices parameter must be a list"
-msgstr "������������������������������������������"
-
-msgid "Target IQN of an iSCSI pool must be a string"
-msgstr "iSCSI������������������IQN������������������"
-
-msgid "Port of a remote storage server must be an integer between 1 and 65535"
-msgstr "���������������������������������������1���65535���������������"
-
-msgid "iSCSI target username must be a string"
-msgstr "iSCSI���������������������������������������"
-
-msgid "iSCSI target password must be a string"
-msgstr "iSCSI������������������������������������"
-
-msgid "Specify name and type to create a storage pool"
-msgstr "������������������������������������"
-
-#, python-format
-msgid ""
-"%(disk)s is not a valid disk/partition. Could not add it to the pool %(pool)"
-"s."
-msgstr "%(disk)s
���������������������/������������������������������������%(pool)s���"
-
-#, python-format
-msgid "Unable to extend logical pool %(pool)s. Details: %(err)s"
-msgstr "���������������������%(pool)s���������������������%(err)s"
-
-msgid "The parameter disks only can be updated for logical storage pool."
-msgstr "������������������������������������������������"
-
-msgid "The SCSI host adapter name must be a string."
-msgstr "SCSI���������������������������������������"
-
-msgid "The storage pool kimchi_isos is reserved for internal use"
-msgstr "���������kimchi_isos������������������"
-
-#, python-format
-msgid ""
-"Unable to activate NFS storage pool %(name)s. NFS server %(server)s is "
-"unreachable."
-msgstr
"������������NFS���������%(name)s���NFS���������%(server)s���������������"
-
-#, python-format
-msgid ""
-"Unable to deactivate NFS storage pool %(name)s. NFS server %(server)s is "
-"unreachable."
-msgstr
"������������NFS���������%(name)s���NFS���������%(server)s���������������"
-
-#, python-format
-msgid ""
-"Unable to deactivate pool %(name)s as it is associated with some templates"
-msgstr "���������������������%(name)s������������������������������������"
-
-#, python-format
-msgid "Unable to delete pool %(name)s as it is associated with some templates"
-msgstr "���������������������%(name)s������������������������������������"
-
-#, python-format
-msgid ""
-"A volume group named '%(name)s' already exists. Please, choose another name
"
-"to create the logical pool."
-msgstr
"������'%(name)s'������������������������������������������������������������������"
-
-#, python-format
-msgid "Unable to update database with deep scan information due error:
%(err)s"
-msgstr "������������������������������������������%(err)s���"
-
-#, python-format
-msgid "Storage volume %(name)s already exists"
-msgstr "���������%(name)s������������"
-
-#, python-format
-msgid "Storage volume %(name)s does not exist in storage pool %(pool)s"
-msgstr "���������%(pool)s������������������%(name)s"
-
-#, python-format
-msgid ""
-"Unable to create storage volume %(volume)s because storage pool %(pool)s is "
-"not active"
-msgstr "���������������������%(volume)s������������������%(pool)s
������������"
-
-#, python-format
-msgid "Specify %(item)s in order to create storage volume %(volume)s"
-msgstr "���������������%(volume)s������������%(item)s"
-
-#, python-format
-msgid ""
-"Unable to list storage volumes because storage pool %(pool)s is not active"
-msgstr "���������������������������������������%(pool)s������������"
-
-#, python-format
-msgid ""
-"Unable to create storage volume %(name)s in storage pool %(pool)s. Details:
%"
-"(err)s"
-msgstr
"������������������%(pool)s������������������%(name)s������������%(err)s"
-
-#, python-format
-msgid ""
-"Unable to list storage volumes in storage pool %(pool)s. Details: %(err)s"
-msgstr "������������������%(pool)s������������������������������%(err)s"
-
-#, python-format
-msgid "Unable to wipe storage volumes %(name)s. Details: %(err)s"
-msgstr "���������������������%(name)s������������%(err)s"
-
-#, python-format
-msgid "Unable to delete storage volume %(name)s. Details: %(err)s"
-msgstr "���������������������%(name)s������������%(err)s"
-
-#, python-format
-msgid "Unable to resize storage volume %(name)s. Details: %(err)s"
-msgstr "���������������������%(name)s���������������������%(err)s"
-
-#, python-format
-msgid "Storage type %(type)s does not support volume create and delete"
-msgstr "������������%(type)s������������������������������"
-
-msgid "Storage volume name must be a string"
-msgstr "������������������������������������"
-
-msgid "Storage volume allocation must be an integer number"
-msgstr "���������������������������������"
-
-msgid ""
-"Storage volume format not supported. Valid formats: bochs, cloop, cow, dmg, "
-"qcow, qcow2, qed, raw, vmdk, vpc."
-msgstr ""
-"������������������������������������������������bochs, cloop, cow, dmg, qcow,
qcow2, qed, "
-"raw, vmdk, vpc���"
-
-msgid "Storage volume requires a volume name"
-msgstr "���������������������"
-
-#, python-format
-msgid ""
-"Unable to update database with storage volume information due error: %(err)s"
-msgstr "���������������������������������������%(err)s"
-
-#, python-format
-msgid "Only one of parameter %(param)s can be specified"
-msgstr "���������������%(param)s������������������������"
-
-#, python-format
-msgid "Create volume from %(param)s is not supported"
-msgstr "������������%(param)s���������������"
-
-msgid "Storage volume capacity must be an integer number."
-msgstr "������������������������������������"
-
-msgid "Storage volume URL must be http://, https://, ftp:// or ftps://."
-msgstr "���������URL���������http://���https://���ftp://���ftps://"
-
-#, python-format
-msgid "Unable to access file %(url)s. Please, check it."
-msgstr "������������������%(url)s������������������������������������"
-
-#, python-format
-msgid ""
-"Unable to clone storage volume '%(name)s' in pool '%(pool)s'.
Details: %(err)"
-"s"
-msgstr
"������������������'%(pool)s'���������������'%(name)s'���������������������%(err)s"
-
-msgid "Specify chunk data and its size to upload a file."
-msgstr ""
-
-msgid "In order to upload a storage volume, specify the 'upload'
parameter."
-msgstr ""
-
-msgid ""
-"Unable to upload chunk data as it does not match with requested chunk size."
-msgstr ""
-
-#, python-format
-msgid "The storage volume %(vol)s is not under an upload process."
-msgstr ""
-
-msgid "The upload chunk data will exceed the storage volume size."
-msgstr ""
-
-#, python-format
-msgid "Unable to upload chunk data to storage volume. Details: %(err)s."
-msgstr ""
-
-#, python-format
-msgid "Interface %(name)s does not exist"
-msgstr "������%(name)s���������"
-
-#, python-format
-msgid "Network %(name)s already exists"
-msgstr "������%(name)s������������"
-
-#, python-format
-msgid "Network %(name)s does not exist"
-msgstr "������%(name)s���������"
-
-#, python-format
-msgid "Subnet %(subnet)s specified for network %(network)s is not valid."
-msgstr "���������%(network)s���������������%(subnet)s������"
-
-#, python-format
-msgid "Specify a network interface to create bridged network %(name)s"
-msgstr "������������������������������������������������������%(name)s"
-
-#, python-format
-msgid "Unable to delete active network %(name)s"
-msgstr "���������������������������%(name)s"
-
-#, python-format
-msgid "Interface %(iface)s specified for network %(network)s is already in
use"
-msgstr "���������%(network)s���������������%(iface)s������������"
-
-msgid "Interface should be bare NIC, bonding or bridge device."
-msgstr
"���������������������������������������������bonding���������������������"
-
-#, python-format
-msgid "Unable to create network %(name)s. Details: %(err)s"
-msgstr "������������������%(name)s������������%(err)s"
-
-#, python-format
-msgid "Unable to find a free IP address for network '%(name)s'"
-msgstr
"���������������'%(name)s'������������������������IP���������������"
-
-#, python-format
-msgid "The interface %(iface)s already exists."
-msgstr ""
-
-msgid "Network name must be a string without slashes (/) or quotes (\")"
-msgstr ""
-
-msgid "Supported network types are isolated, NAT and bridge"
-msgstr "���������������������������������NAT���������"
-
-msgid "Network subnet must be a string with IP address and prefix or netmask"
-msgstr
"���������������������������IP������������������������������������������������"
-
-msgid "Network interface must be a string"
-msgstr "������������������������������������"
-
-msgid "Network VLAN ID must be an integer between 1 and 4094"
-msgstr "������VLAN������������1���4094���������������"
-
-msgid "Specify name and type to create a Network"
-msgstr "���������������������������������"
-
-#, python-format
-msgid ""
-"Unable to delete network %(name)s. There are some virtual machines %(vms)s "
-"and/or templates linked to this network."
-msgstr ""
-
-#, python-format
-msgid ""
-"Unable to deactivate network %(name)s. There are some virtual machines
%(vms)"
-"s and/or templates linked to this network."
-msgstr ""
-
-#, python-format
-msgid "Bridge device %(name)s can not be the trunk device of a VLAN."
-msgstr "������������������%(name)s������VLAN���trunk���������"
-
-#, python-format
-msgid "Failed to activate interface %(iface)s: %(err)s."
-msgstr "������������������������ %(iface)s���%(err)s���"
-
-#, python-format
-msgid ""
-"Failed to activate interface %(iface)s. Please check the physical link "
-"status."
-msgstr "������������%(iface)s���������������������������������������������"
-
-#, python-format
-msgid "Failed to start network %(name)s. Details: %(err)s"
-msgstr "������������%(name)s������������������%(err)s"
-
-#, python-format
-msgid "Debug report %(name)s does not exist"
-msgstr "������������%(name)s���������"
-
-msgid "Debug report tool not found in system"
-msgstr "���������������������������������"
-
-#, python-format
-msgid "Unable to create debug report %(name)s. Details: %(err)s."
-msgstr "������������������������%(name)s������������%(err)s"
-
-#, python-format
-msgid "Can not find any debug report with the given name %(name)s"
-msgstr "������������������������%(name)s���������������"
-
-#, python-format
-msgid "Unable to generate debug report %(name)s. Details: %(err)s"
-msgstr "������������������������%(name)s������������%(err)s"
-
-msgid "You should give a name for the debug report file."
-msgstr "������������������������%(name)s������������%(err)s"
-
-msgid ""
-"Debug report name must be a string. Only letters, digits, underscore ('_')
"
-"and hyphen ('-') are allowed."
-msgstr ""
-"������������������������������������������������������������������������������������('_')���������������('-')"
-"������������������"
-
-#, python-format
-msgid ""
-"The debug report with specified name \"%(name)s\" already exists. Please
use "
-"another one."
-msgstr
"���������\"'%(name)s\"���������������������������������������������������������"
-
-#, python-format
-msgid "Storage server %(server)s was not used by Kimchi"
-msgstr "���������������%(server)s������Kimchi������"
-
-#, python-format
-msgid "Distro '%(name)s' does not exist"
-msgstr "������������'%(name)s'���������"
-
-#, python-format
-msgid "Partition %(name)s does not exist in the host"
-msgstr "������������������������%(name)s"
-
-msgid "Unable to shutdown host machine as there are running virtual machines"
-msgstr "������������������������������������������"
-
-msgid "Unable to reboot host machine as there are running virtual machines"
-msgstr "������������������������������������������"
-
-#, python-format
-msgid "Node device '%(name)s' not found"
-msgstr "������������������������'%(name)s'"
-
-msgid "Conflicting flag filters specified."
-msgstr "flag filters���������"
-
-msgid "No packages marked for update"
-msgstr "������������������������������"
-
-#, python-format
-msgid "Package %(name)s is not marked to be updated."
-msgstr "���������%(name)s������������������������"
-
-#, python-format
-msgid "Error while getting packages marked to be updated. Details: %(err)s"
-msgstr "���������������������������������������������������������%(err)s"
-
-msgid "There is no compatible package manager for this system."
-msgstr "������������������������������������������"
-
-#, python-format
-msgid "Invalid URI %(uri)s"
-msgstr "���������URI %(uri)s"
-
-msgid "Unable to choose a virtual machine name"
-msgstr "���������������������������������"
-
-msgid "Invalid storage type. Types supported: 'cdrom', 'disk'"
-msgstr
"������������������������������������������'cdrom'���'disk'"
-
-#, python-format
-msgid "The path '%(value)s' is not a valid local/remote path for the
device"
-msgstr "������'%(value)s'���������������������������/������������"
-
-msgid "Only CDROM path can be update."
-msgstr "���������CDROM���������������"
-
-#, python-format
-msgid ""
-"The storage device %(dev_name)s does not exist in the virtual machine %"
-"(vm_name)s"
-msgstr "������������%(dev_name)s������������%(vm_name)s������������"
-
-#, python-format
-msgid "Error while creating new storage device: %(error)s"
-msgstr "������������������������������������%(error)s"
-
-#, python-format
-msgid "Error while updating storage device: %(error)s"
-msgstr "������������������������������%(error)s"
-
-#, python-format
-msgid "Error while removing storage device: %(error)s"
-msgstr "������������������������������%(error)s"
-
-msgid "Do not support IDE device hot plug"
-msgstr "���������IDE������������������"
-
-msgid ""
-"Specify type and path or type and pool/volume to add a new virtual machine "
-"disk"
-msgstr
"���������������������������������������������������������������������������/���������"
-
-msgid "Specify path to update virtual machine disk"
-msgstr "������������������������������������"
-
-#, python-format
-msgid "Controller type %(type)s limitation of %(limit)s devices reached"
-msgstr "������������������%(type)s���������������������%(limit)s"
-
-#, python-format
-msgid "Cannot retrieve disk path information for given pool/volume: %(error)s"
-msgstr
"���������������������������/������������������������������������������%(error)s"
-
-msgid "Volume already in use by other virtual machine."
-msgstr "���������������������������������������"
-
-msgid ""
-"Only one of path or pool/volume can be specified to add a new virtual "
-"machine disk"
-msgstr
"���������������������������������������������������������/���������������������"
-
-#, python-format
-msgid ""
-"Volume chosen with format %(format)s does not fit in the storage type
%(type)"
-"s"
-msgstr "���������%(format)s���������������������������%(type)s"
-
-msgid "YUM Repository ID must be one word only string."
-msgstr "YUM������������ID������������������������������������������"
-
-msgid "Repository URL must be an http://, ftp:// or file:// URL."
-msgstr "������������URL���������http://��� ftp:// ��� file://"
-
-msgid ""
-"Repository configuration is a dictionary with specific values according to "
-"repository type."
-msgstr "������������������������������������������������������������������"
-
-msgid "Distribution to DEB repository must be a string"
-msgstr "DEB���������������������������������������������"
-
-msgid "Components to DEB repository must be listed in a array"
-msgstr "DEB������������������������������������������"
-
-msgid "Components to DEB repository must be a string"
-msgstr "DEB���������������������������������������"
-
-msgid "Mirror list to repository must be a string"
-msgstr ""
-
-msgid "YUM Repository name must be string."
-msgstr "YUM���������������������������������������"
-
-msgid "GPG check must be a boolean value."
-msgstr "GPG������������������������������"
-
-msgid "GPG key must be a URL pointing to the ASCII-armored file."
-msgstr "GPG������������������������ASCII���������������.asc������������URL"
-
-#, python-format
-msgid "Could not update repository %(repo_id)s."
-msgstr "������������������������%(repo_id)s"
-
-#, python-format
-msgid "Repository %(repo_id)s does not exist."
-msgstr "������������%(repo_id)s������������"
-
-msgid ""
-"Specify repository base URL, mirror list or metalink in order to create or "
-"update a YUM repository."
-msgstr ""
-
-msgid "Repository management tool was not recognized for your system."
-msgstr "������������������������������������������"
-
-#, python-format
-msgid "Repository %(repo_id)s is already enabled."
-msgstr "������������%(repo_id)s���������������"
-
-#, python-format
-msgid "Repository %(repo_id)s is already disabled."
-msgstr "������������%(repo_id)s���������������"
-
-#, python-format
-msgid "Could not remove repository %(repo_id)s."
-msgstr "������������������������%(repo_id)s"
-
-#, python-format
-msgid "Could not write repository configuration file %(repo_file)s"
-msgstr "������������������������������������%(repo_file)s"
-
-msgid "Specify repository distribution in order to create a DEB repository."
-msgstr "���������������������������������������������DEB���������"
-
-#, python-format
-msgid "Could not enable repository %(repo_id)s."
-msgstr "������������������������%(repo_id)s"
-
-#, python-format
-msgid "Could not disable repository %(repo_id)s."
-msgstr "������������������������%(repo_id)s"
-
-msgid "YUM Repository ID already exists"
-msgstr "YUM������ID������������"
-
-msgid "YUM Repository name must be a string"
-msgstr "YUM������������������������������������"
-
-#, python-format
-msgid "Unable to list repositories. Details: '%(err)s'"
-msgstr "������������������������������������'%(err)s'"
-
-#, python-format
-msgid "Unable to retrieve repository information. Details: '%(err)s'"
-msgstr "���������������������������������������������'%(err)s'"
-
-#, python-format
-msgid "Unable to add repository. Details: '%(err)s'"
-msgstr "������������������������������������'%(err)s'"
-
-#, python-format
-msgid "Unable to remove repository. Details: '%(err)s'"
-msgstr "������������������������������������'%(err)s'"
-
-#, python-format
-msgid ""
-"Configuration items: '%(items)s' are not supported by repository
manager"
-msgstr "���������������������������������: %(items)s"
-
-msgid "Repository metalink must be an http://, ftp:// or file:// URL."
-msgstr ""
-
-msgid "Cannot specify mirrorlist and metalink at the same time."
-msgstr ""
-
-#, python-format
-msgid ""
-"Virtual machine '%(vm)s' must be stopped before creating a snapshot of
it."
-msgstr "���������'%(vm)s'���������������������������������"
-
-#, python-format
-msgid ""
-"Unable to create snapshot '%(name)s' on virtual machine '%(vm)s'.
Details: %"
-"(err)s"
-msgstr
"������������������'%(vm)s'������������'%(name)s'������������%(err)s"
-
-#, python-format
-msgid "Snapshot '%(name)s' does not exist on virtual machine
'%(vm)s'."
-msgstr "������'%(name)s'������������������'%(vm)s'������"
-
-#, python-format
-msgid ""
-"Unable to retrieve snapshot '%(name)s' on virtual machine '%(vm)s'.
Details: "
-"%(err)s"
-msgstr
"������������������'%(vm)s'������������'%(name)s'������������%(err)s"
-
-#, python-format
-msgid "Unable to list snapshots on virtual machine '%(vm)s'. Details:
%(err)s"
-msgstr "���������������������'%(vm)s'���������������������%(err)s"
-
-#, python-format
-msgid ""
-"Unable to delete snapshot '%(name)s' on virtual machine '%(vm)s'.
Details: %"
-"(err)s"
-msgstr
"���������������������'%(vm)s'������'%(name)s'������������%(err)s"
-
-#, python-format
-msgid ""
-"Unable to retrieve current snapshot of virtual machine '%(vm)s'. Details:
%"
-"(err)s"
-msgstr "���������������������'%(vm)s'������������������������%(err)s"
-
-#, python-format
-msgid ""
-"Unable to revert virtual machine '%(vm)s' to snapshot '%(name)s'.
Details: %"
-"(err)s"
-msgstr
"���������������������'%(vm)s'���������'%(name)s'������������%(err)s"
-
-#, python-format
-msgid ""
-"Unable to create snapshot of virtual machine '%(vm)s' because it contains a
"
-"disk with format '%(format)s'; only 'qcow2' is supported."
-msgstr ""
-"������������������'%(vm)s'���������������������������������������'%(format)s'������������������������"
-"���'qcow2'���������"
-
-msgid "The number of vCPUs is too large for this system."
-msgstr "vCPUs������������������������������������"
-
-msgid "Invalid vCPU/topology combination."
-msgstr "���������vCPU/topology���������"
-
-msgid "This host (or current configuration) does not allow CPU topology."
-msgstr "������������������������������������������CPU���������"
-
-msgid "ERROR CODE"
-msgstr "���������"
-
-msgid "REASON"
-msgstr "������"
-
-msgid "STACK"
-msgstr "���������"
-
-msgid "Go to Homepage"
-msgstr "������������"
-
-msgid "Create a New Virtual Machine"
-msgstr "���������������������������"
-
-msgid "Virtual Machine Name"
-msgstr "���������������"
-
-msgid ""
-"The name used to identify the virtual machine. If omitted, a name will be "
-"chosen based on the template used."
-msgstr
"���������������������������������������������������������������������������������������������"
-
-msgid "Template"
-msgstr "������"
-
-msgid "Please create a template first."
-msgstr "������������������������"
-
-msgid "Create a Template"
-msgstr "������������������"
-
-msgid "Please choose a template."
-msgstr "������������������"
-
-msgid "OS"
-msgstr "������������"
-
-msgid "OS Version"
-msgstr "������������������"
-
-msgid "CPUS"
-msgstr "���������������"
-
-msgid "Memory"
-msgstr "������"
-
-msgid "Create"
-msgstr "������"
-
-msgid "Creating..."
-msgstr "������������..."
-
-msgid "Cancel"
-msgstr "������"
-
-msgid "Edit Guest"
-msgstr "���������������"
-
-msgid "General"
-msgstr "������"
-
-msgid "Storage"
-msgstr "������"
-
-msgid "Interface"
-msgstr "������������"
-
-msgid "Permission"
-msgstr "������"
-
-msgid "Host PCI Device"
-msgstr "������PCI������"
-
-msgid "Snapshot"
-msgstr "������"
-
-msgid "Name"
-msgstr "������"
-
-msgid "CPUs"
-msgstr "���������������"
-
-msgid "Memory (MB)"
-msgstr "������(MB)"
-
-msgid "Icon"
-msgstr "������"
-
-msgid "Device"
-msgstr "������������"
-
-msgid "Path"
-msgstr "������"
-
-msgid "Network"
-msgstr "������"
-
-msgid "Type"
-msgstr "������"
-
-msgid "MAC Address"
-msgstr ""
-
-msgid "Available system users and groups"
-msgstr "���������������������������������"
-
-msgid "Selected system users and groups"
-msgstr "���������������������������������"
-
-msgid "User"
-msgstr "������"
-
-msgid "All"
-msgstr "������"
-
-msgid "To Add"
-msgstr "���������"
-
-msgid "Added"
-msgstr "���������"
-
-msgid "filter"
-msgstr "���������"
-
-msgid "Product"
-msgstr "������"
-
-msgid "Vendor"
-msgstr "������"
-
-msgid "Created"
-msgstr "���������"
-
-msgid "Save"
-msgstr "������"
-
-msgid "Replace"
-msgstr "������"
-
-msgid "Detach"
-msgstr "������"
-
-msgid "revert"
-msgstr "������"
-
-msgid "Start"
-msgstr "������"
-
-msgid "Reset"
-msgstr "������"
-
-msgid "Pause"
-msgstr ""
-
-msgid "Resume"
-msgstr ""
-
-msgid "Power Off"
-msgstr "������������"
-
-msgid "Actions"
-msgstr "������"
-
-msgid "Connect"
-msgstr "���������"
-
-msgid "Clone"
-msgstr "������������"
-
-msgid "Edit"
-msgstr "������"
-
-msgid "Shut Down"
-msgstr "������"
-
-msgid "Delete"
-msgstr "������"
-
-msgid "CPU"
-msgstr "���������"
-
-msgid "Disk I/O"
-msgstr "������I/O"
-
-msgid "Network I/O"
-msgstr "������I/O"
-
-msgid "Livetile"
-msgstr "������"
-
-msgid "No guests found."
-msgstr "���������������������"
-
-msgid "Add a Storage Device to VM"
-msgstr "������������������������������������"
-
-msgid "Device Type"
-msgstr "������������"
-
-msgid "The device type. Currently, \"cdrom\" and \"disk\" are
supported."
-msgstr
"������������������������������������������\"cdrom\"���\"disk\"���
"
-
-msgid "Storage Pool"
-msgstr "���������"
-
-msgid "Storage pool which volume located in"
-msgstr "���������������������������"
-
-msgid "Storage Volume"
-msgstr "���������"
-
-msgid "Storage volume to be attached"
-msgstr "���������������������"
-
-msgid "File Path"
-msgstr "������������"
-
-msgid "The ISO file path in the server for CDROM."
-msgstr "������������CDROM������������ISO������������"
-
-msgid "Attach"
-msgstr "������"
-
-msgid "Shut down"
-msgstr "������"
-
-msgid "Restart"
-msgstr "������"
-
-msgid "Basic Information"
-msgstr "������������"
-
-msgid "OS Distro"
-msgstr "���������������������"
-
-msgid "OS Code Name"
-msgstr "������������������"
-
-msgid "Processor"
-msgstr "���������"
-
-msgid "CPU(s)"
-msgstr "CPU(s)"
-
-msgid "System Statistics"
-msgstr "������������������"
-
-msgid "Software Updates"
-msgstr "������������"
-
-msgid "Update Progress"
-msgstr "������������"
-
-msgid "Repositories"
-msgstr "������������"
-
-msgid "Debug Reports"
-msgstr "������������������"
-
-msgid "The username or password you entered is incorrect. Please try again."
-msgstr "���������������������������������������������"
-
-msgid "This field is required."
-msgstr "������������������"
-
-msgid "Log in"
-msgstr "������"
-
-msgid "Logging in..."
-msgstr "���������..."
-
-msgid "Host"
-msgstr "������"
-
-msgid "Guests"
-msgstr "���������"
-
-msgid "Templates"
-msgstr "������"
-
-msgid "Failed to get application configuration"
-msgstr "������������������������"
-
-msgid "This is not a valid Linux path"
-msgstr "������������������������Linux������"
-
-msgid "This is not a valid URL."
-msgstr "������������������������URL"
-
-msgid "No such data available."
-msgstr "���������������������"
-
-msgid ""
-"Can not contact the host system. Verify the host system is up and that you "
-"have network connectivity to it. HTTP request response %1. "
-msgstr ""
-"������������������������������������������������������������������������������������������HTTP���������������%1"
-
-msgid "Unable to read file."
-msgstr ""
-
-msgid "Error while uploading file."
-msgstr ""
-
-msgid "Delete Confirmation"
-msgstr "������������"
-
-msgid "OK"
-msgstr "������"
-
-msgid "Confirm"
-msgstr "������"
-
-msgid "Warning"
-msgstr "������"
-
-msgid "Cloning..."
-msgstr ""
-
-msgid "Loading..."
-msgstr "������������..."
-
-msgid "An error occurred while retrieving system information."
-msgstr ""
-
-msgid "Retry"
-msgstr "������"
-
-msgid "Detailed message:"
-msgstr "���������������"
-
-msgid "No ISO found"
-msgstr "������������ISO������"
-
-msgid "This is not a valid ISO file."
-msgstr "������������������������ISO������"
-
-msgid "This may take a long time. Do you want to continue?"
-msgstr "���������������������������������������"
-
-msgid "This will permanently delete the template. Would you like to continue?"
-msgstr "������������������������������������������"
-
-msgid "Unable to shut down system as there are some virtual machines running!"
-msgstr "���������������������������������������������"
-
-msgid "Max:"
-msgstr "���������"
-
-msgid "Utilization"
-msgstr "���������"
-
-msgid "Available"
-msgstr "������������"
-
-msgid "Read Rate"
-msgstr "���������"
-
-msgid "Write Rate"
-msgstr "���������"
-
-msgid "Received"
-msgstr "������"
-
-msgid "Sent"
-msgstr "������"
-
-msgid ""
-"Shutting down or restarting host will cause unsaved work lost. Continue to "
-"shut down/restarting?"
-msgstr
"���������������������������������������������������������������������������/���������"
-
-msgid ""
-"Repository will be removed permanently and can't be recovered. Do you want
"
-"to continue?"
-msgstr "���������������������������������������������������������������"
-
-msgid "ID"
-msgstr "���������"
-
-msgid "Base URL"
-msgstr "������URL"
-
-msgid "Is Mirror"
-msgstr "���������������"
-
-msgid "URL Args"
-msgstr "URL������"
-
-msgid "Enabled"
-msgstr "���������"
-
-msgid "GPG Check"
-msgstr "GPG������"
-
-msgid "GPG Key"
-msgstr "GPG���"
-
-msgid "Add"
-msgstr "������"
-
-msgid "Remove"
-msgstr "������"
-
-msgid "Enable"
-msgstr "������"
-
-msgid "Disable"
-msgstr "������"
-
-msgid "Package Name"
-msgstr "���������������"
-
-msgid "Version"
-msgstr "������"
-
-msgid "Architecture"
-msgstr "������������"
-
-msgid "Repository"
-msgstr "������������"
-
-msgid "Update All"
-msgstr "������������"
-
-msgid "Updating..."
-msgstr "������������..."
-
-msgid "Failed to retrieve packages update information."
-msgstr "������������������������������������"
-
-msgid "Failed to update package(s)."
-msgstr "���������������������"
-
-msgid ""
-"Debug report will be removed permanently and can't be recovered. Do you want
"
-"to continue?"
-msgstr "���������������������������������������������������������������������"
-
-msgid "Generated Time"
-msgstr "������������"
-
-msgid "Generate"
-msgstr "������"
-
-msgid "Generating..."
-msgstr "������������..."
-
-msgid "Rename"
-msgstr "���������"
-
-msgid "Download"
-msgstr "������"
-
-msgid ""
-"Report name should contain only letters, digits, underscore ('_') and/or
"
-"hyphen ('-')."
-msgstr
"������������������������������������������������������('_')������������('-')"
-
-msgid "Pending..."
-msgstr "������������..."
-
-msgid "Report name is the same as the original one."
-msgstr "������������������������������������"
-
-msgid ""
-"This will delete the virtual machine and its virtual disks. This operation "
-"cannot be undone. Would you like to continue?"
-msgstr
"���������������������������������������������������������������������������������"
-
-msgid "Power off Confirmation"
-msgstr "������������������"
-
-msgid ""
-"This action may produce undesirable results, for example unflushed disk "
-"cache in the guest. Would you like to continue?"
-msgstr
"������������������������������������������������������������������������������������������������"
-
-msgid "Reset Confirmation"
-msgstr "������������"
-
-msgid ""
-"There is a risk of data loss caused by reset without the guest OS shutdown. "
-"Would you like to continue?"
-msgstr
"������������������������������������������������������������������������������������������������������"
-
-msgid "Shut Down Confirmation"
-msgstr "������������"
-
-msgid "Note the guest OS may ignore this request. Would you like to continue?"
-msgstr
"���������������������������������������������������������������������������������"
-
-msgid "Virtual Machine delete Confirmation"
-msgstr "���������������������"
-
-msgid ""
-"This virtual machine is not persistent. Power Off will delete it. Continue?"
-msgstr
"������������������������������������������������������������������������������������"
-
-msgid ""
-"When the target guest has SCSI or iSCSI volumes, they will be cloned on "
-"default storage pool. The same will happen when the target pool does not "
-"have enough space to clone the volumes. Do you want to continue?"
-msgstr ""
-"������������������������SCSI������iSCSI���������������������������������������������������������������������"
-"������������������������������������������������������������������������������������������������������"
-
-msgid ""
-"This CDROM will be detached permanently and you can re-attach it. Continue "
-"to detach it?"
-msgstr "CDROM���������������������������������������������������������������"
-
-msgid "Attaching..."
-msgstr "������������"
-
-msgid "Replacing..."
-msgstr "������������..."
-
-msgid "Successfully attached!"
-msgstr "������������"
-
-msgid "Successfully replaced!"
-msgstr "������������"
-
-msgid "Successfully detached!"
-msgstr "������������"
-
-msgid ""
-"This disk will be detached permanently and you can re-attach it. Continue to
"
-"detach it?"
-msgstr
"���������������������������������������������������������������������������������������?"
-
-msgid "interface:"
-msgstr "���������"
-
-msgid "address:"
-msgstr "���������"
-
-msgid "link_type:"
-msgstr "���������������"
-
-msgid "block:"
-msgstr "������"
-
-msgid "drive_type:"
-msgstr "���������������"
-
-msgid "model:"
-msgstr "���������"
-
-msgid "Affected devices:"
-msgstr "���������������������"
-
-msgid "The VLAN id must be between 1 and 4094."
-msgstr "VLAN ������������������1���4094������"
-
-msgid "unavailable"
-msgstr "������������"
-
-msgid ""
-"This action will interrupt network connectivity for any virtual machine that
"
-"depend on this network."
-msgstr "������������������������������������������������������������������"
-
-msgid "Create a network"
-msgstr "������������������"
-
-msgid ""
-"This network is not persistent. Instead of stop, this action will "
-"permanently delete it. Would you like to continue?"
-msgstr ""
-"������������������������������������������������������������������������������������������������������������������"
-"���������"
-
-msgid ""
-"The bridged VLAN tag may not work well with NetworkManager enabled. You "
-"should consider disabling it."
-msgstr ""
-
-msgid ""
-"This will permanently delete the storage pool. Would you like to continue?"
-msgstr "���������������������������������������������"
-
-msgid "This storage pool is empty."
-msgstr "���������������������"
-
-msgid ""
-"It will format your disk and you will loose any data in there, are you sure "
-"to continue? "
-msgstr
"������������������������������������������������������������������������������������"
-
-msgid "SCSI Fibre Channel"
-msgstr "SCSI������������"
-
-msgid "No SCSI adapters found."
-msgstr "������������SCSI���������"
-
-msgid "Loading iSCSI targets..."
-msgstr "������iSCSI������..."
-
-msgid "No iSCSI found. Please input one."
-msgstr "������������iSCSI,������������������"
-
-msgid "Failed to load iSCSI targets."
-msgstr "������iSCSI���������������"
-
-msgid "The storage pool name can not be blank."
-msgstr "���������������������������������"
-
-msgid "The storage pool path can not be blank."
-msgstr "���������������������������������"
-
-msgid "NFS server mount path can not be blank."
-msgstr "NFS������������������������������������"
-
-msgid "Invalid NFS mount path."
-msgstr "���������NFS���������������"
-
-msgid "No logical device selected."
-msgstr "���������������������������"
-
-msgid "The iSCSI target can not be blank."
-msgstr "iSCSI���������������������"
-
-msgid "Server name can not be blank."
-msgstr "������������������������"
-
-msgid "This is not a valid Server Name or IP. Please, modify it."
-msgstr
"������������������������������������������IP���������������������������������"
-
-msgid "Looking for available partitions ..."
-msgstr "��������������������� ..."
-
-msgid "No available partitions found."
-msgstr "���������������������"
-
-msgid ""
-"This storage pool is not persistent. Instead of deactivate, this action will
"
-"permanently delete it. Would you like to continue?"
-msgstr
"���������������������������������������������������������������������������������������������������"
-
-msgid "Unable to retrieve partitions information."
-msgstr "���������������������������"
-
-msgid "In progress..."
-msgstr "������������..."
-
-msgid "Failed!"
-msgstr "���������"
-
-msgid "CDROM path needs to be a valid local/remote path and cannot be blank."
-msgstr "CDROM���������������������������������/������������������������������"
-
-msgid "Disk pool or volume cannot be blank."
-msgstr "���������������������������"
-
-#, fuzzy
-msgid "Filter"
-msgstr "���������"
-
-msgid "Network Name"
-msgstr "������������"
-
-msgid "State"
-msgstr "������"
-
-msgid "Network Type"
-msgstr "������������"
-
-msgid "Address Space"
-msgstr "������������"
-
-msgid "Name should not contain '/' and '\"'."
-msgstr "������������������������/������'\"'���"
-
-msgid "Isolated: no external network connection"
-msgstr "������: ������������������������"
-
-msgid "NAT: outbound physical network connection only"
-msgstr "NAT: ���������������������������������������"
-
-msgid "Bridged: Virtual machines are connected to physical network directly"
-msgstr "���������������������������������������������������������"
-
-msgid "(No interfaces found)"
-msgstr "(������������������������)"
-
-msgid "Destination"
-msgstr "������������"
-
-msgid "Enable VLAN"
-msgstr "������VLAN"
-
-msgid "VLAN ID"
-msgstr "VLAN���"
-
-msgid "Stop"
-msgstr "������"
-
-msgid "Generate a New Debug Report"
-msgstr "������������������������������"
-
-msgid "Report Name"
-msgstr "���������������"
-
-msgid ""
-"The name used to identify the report. If omitted, a name will be chosen "
-"based on current time. Name can contain: letters, digits, underscore
(\"_\") "
-"and hyphen (\"-\")."
-msgstr ""
-"������������������������������������������������������������������������������������������������������������������"
-"������������������������������ ('_') ���������������'-'���"
-
-msgid "Rename a Debug Report"
-msgstr "���������������������������"
-
-msgid ""
-"The name used to identify the report. Name can contain: letters, digits and "
-"hyphen (\"-\")."
-msgstr
"������������������������������������������������������������������������������������(\"-\")���"
-
-msgid "Submit"
-msgstr "������"
-
-msgid "Add a Repository"
-msgstr "������������������������"
-
-msgid "Identifier"
-msgstr "���������"
-
-msgid "Single word, unique identifier for the repository."
-msgstr "���������������������������������������"
-
-msgid "Textual name for the repository."
-msgstr "���������������������������"
-
-msgid "URL"
-msgstr "URL"
-
-msgid "Required Field"
-msgstr "���������������"
-
-msgid "URL to the repository. Supported protocols are http, ftp, and file."
-msgstr "���������������URL���������������������http���ftp������file"
-
-msgid "Repository is a mirror"
-msgstr "���������������������������"
-
-msgid "Distribution"
-msgstr "���������"
-
-msgid "Distribution of the DEB repository."
-msgstr "DEB������������������"
-
-msgid "Components"
-msgstr "������"
-
-msgid "List of components in DEB repository."
-msgstr "DEB������������������������"
-
-msgid "Edit Repository"
-msgstr "������������������"
-
-msgid "Mirror List URL"
-msgstr "������������URL"
-
-msgid "Yes"
-msgstr "���"
-
-msgid "No"
-msgstr "���"
-
-msgid "Capacity"
-msgstr "������"
-
-msgid "Allocated"
-msgstr "���������"
-
-msgid "Location"
-msgstr "������"
-
-msgid "Device path"
-msgstr "������������"
-
-msgid "active"
-msgstr "���������"
-
-msgid "inactive"
-msgstr "���������"
-
-msgid "Deactivate"
-msgstr "������"
-
-msgid "Activate"
-msgstr "������"
-
-msgid "Add Volume"
-msgstr "���������"
-
-msgid "Extend"
-msgstr "������"
-
-msgid "Undefine"
-msgstr "������������"
-
-msgid "Format"
-msgstr "������"
-
-msgid "Allocation"
-msgstr "������"
-
-msgid "Define a New Storage Pool"
-msgstr "���������������������������"
-
-msgid "Storage Pool Name"
-msgstr "���������������"
-
-msgid ""
-"The name used to identify the storage pools, and it should not be empty."
-msgstr "���������������������������������������������������������������"
-
-msgid "Storage Pool Type"
-msgstr "���������������"
-
-msgid "Storage Path"
-msgstr "������������"
-
-msgid ""
-"The path of the Storage Pool. Each Storage Pool must have a unique path."
-msgstr "������������������.���������������������������������������"
-
-msgid ""
-"Kimchi will try to create the directory when it does not already exist in "
-"your system."
-msgstr
"������������������������KIMCHI���������������������������������������������"
-
-msgid "NFS Server IP"
-msgstr "NFS���������IP"
-
-msgid "NFS server IP or hostname. It can be input or chosen from history."
-msgstr
"NFS���������IP���������������������������������������������������������������������"
-
-msgid "NFS Path"
-msgstr "NFS ������"
-
-msgid "The NFS exported path on NFS server."
-msgstr "NFS���������������������NFS������"
-
-msgid "iSCSI Server"
-msgstr "iSCSI���������"
-
-msgid "Server"
-msgstr "���������"
-
-msgid "Port"
-msgstr "������"
-
-msgid "iSCSI server IP or hostname. It should not be empty."
-msgstr "iSCSI���������IP������������������ ���������������"
-
-msgid "Target"
-msgstr "������"
-
-msgid "The iSCSI target on iSCSI server"
-msgstr "iSCSI������"
-
-msgid "Add iSCSI Authentication"
-msgstr "������ISCSI������"
-
-msgid "iSCSI Authentication"
-msgstr "iSCSI������"
-
-msgid "User Name"
-msgstr "���������"
-
-msgid "Password"
-msgstr "������"
-
-msgid "SCSI Adapter"
-msgstr "SCSI���������"
-
-msgid "Please, wait..."
-msgstr "���������..."
-
-msgid "Add a Volume to Storage Pool"
-msgstr "���������������������������"
-
-msgid "Fetch from remote URL"
-msgstr "���������URL������"
-
-msgid "Enter the remote URL here."
-msgstr "���������������������URL���"
-
-msgid "Upload a file"
-msgstr "������������������"
-
-msgid "Choose the file you want to upload."
-msgstr "������������������������������"
-
-msgid "Add Template"
-msgstr "������������"
-
-msgid "Where is the source media for this template? "
-msgstr "������������������������������"
-
-msgid "Local ISO Image"
-msgstr "������ISO������"
-
-msgid "Local Image File"
-msgstr "������������������"
-
-msgid "Remote ISO Image"
-msgstr "������ISO������"
-
-msgid "Search ISOs"
-msgstr "������ISO"
-
-msgid "The following ISOs are available:"
-msgstr "������ISO������������"
-
-msgid "OS: "
-msgstr "��������������� "
-
-msgid "Version: "
-msgstr "��������� "
-
-msgid "Size: "
-msgstr "���������"
-
-msgid "Search more ISOs"
-msgstr "������������ISO"
-
-msgid "Create Templates from Selected ISO"
-msgstr "������������ISO���������������"
-
-msgid "I want to use a specific ISO file"
-msgstr "������������ISO������"
-
-msgid "Loading default remote ISOs ..."
-msgstr "���������������������ISOs ..."
-
-msgid "Arch: "
-msgstr "���������������"
-
-msgid "I want to use a custom URL"
-msgstr "���������������������������URL"
-
-msgid "Edit Template"
-msgstr "������������"
-
-msgid "CDROM"
-msgstr "������"
-
-msgid "Image File"
-msgstr "������������"
-
-msgid "Graphics"
-msgstr "������"
-
-msgid "Disk(GB)"
-msgstr "������(GB)"
-
-msgid "Disk Format"
-msgstr ""
-
-msgid "CPU Number"
-msgstr "CPU������"
-
-msgid "Manually set CPU topology"
-msgstr "������������CPU������"
-
-msgid "Cores"
-msgstr "���������"
-
-msgid "Threads"
-msgstr "������"
-
-msgid "No templates found."
-msgstr "������������������"
-
-#~ msgid "Delete is not allowed for %(resource)s"
-#~ msgstr "���������������%(resource)s"
-
-#~ msgid "%(resource)s does not implement update method"
-#~ msgstr "���������������%(resource)s"
-
-#~ msgid "Create is not allowed for %(resource)s"
-#~ msgstr "���������������%(resource)s"
-
-#~ msgid "Unable to parse JSON request"
-#~ msgstr "������������JSON������"
-
-#~ msgid "This API only supports JSON"
-#~ msgstr "������API���������JSON"
-
-#~ msgid "Parameters does not match requirement in schema: %(err)s"
-#~ msgstr "���������������������������������%(err)s"
-
-#~ msgid "You don't have permission to perform this operation."
-#~ msgstr "������������������������������������"
-
-#~ msgid "Datastore is not initiated in the model object."
-#~ msgstr "���������model������������������������������"
-
-#~ msgid "Unable to start task due error: %(err)s"
-#~ msgstr "������������%(err)s������������������"
-
-#~ msgid ""
-#~ "Authentication failed for user '%(username)s'. [Error code:
%(code)s]"
-#~ msgstr
"������'%(username)s'������������������.[���������������%(code)s]"
-
-#~ msgid "You are not authorized to access Kimchi"
-#~ msgstr "������������������������Kimchi"
-
-#~ msgid "Specify %(item)s to login into Kimchi"
-#~ msgstr "������������Kimchi���%(item)s"
-
-#~ msgid "Invalid LDAP configuration: %(item)s : %(value)s"
-#~ msgstr "���������LDAP���������%(item)s : %(value)s"
-
-#~ msgid "Unable to find %(item)s in datastore"
-#~ msgstr "���������������������������%(item)s"
-
-#~ msgid "Timeout while running command '%(cmd)s' after %(seconds)s
seconds"
-#~ msgstr "������'%(cmd)s'������%(seconds)s���������������"
-
-#~ msgid "Peers"
-#~ msgstr "���������"
-
-#~ msgid "Searching"
-#~ msgstr "������������"
-
-#~ msgid "No peers found."
-#~ msgstr "������������������������"
-
-#~ msgid "Help"
-#~ msgstr "������"
-
-#~ msgid "About"
-#~ msgstr "������"
-
-#~ msgid "Log out"
-#~ msgstr "������"
-
-#~ msgid "Version:"
-#~ msgstr "���������"
-
-#~ msgid "Session timeout, please re-login."
-#~ msgstr "���������������������������������"
diff --git a/plugins/kimchi/po/zh_TW.po b/plugins/kimchi/po/zh_TW.po
deleted file mode 100644
index 90045b5..0000000
--- a/plugins/kimchi/po/zh_TW.po
+++ /dev/null
@@ -1,2138 +0,0 @@
-# English translations for kimchi package.
-# Copyright (C) 2013 ORGANIZATION
-#
-msgid ""
-msgstr ""
-"Project-Id-Version: kimchi 0.1\n"
-"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2015-07-01 16:11-0300\n"
-"PO-Revision-Date: 2013-07-11 17:32-0400\n"
-"Last-Translator: Cr��stian Viana <vianac(a)linux.vnet.ibm.com>\n"
-"Language-Team: English\n"
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
-"Content-Transfer-Encoding: 8bit\n"
-"Language: zh_TW\n"
-"Generated-By: pygettext.py 1.5\n"
-"Plural-Forms: nplurals=2; plural=(n != 1);\n"
-
-#, python-format
-msgid "Unknown parameter %(value)s"
-msgstr ""
-
-#, python-format
-msgid "Timeout of %(seconds)s seconds expired while running task
'%(task)s."
-msgstr ""
-
-#, python-format
-msgid "User %(user_id)s not found with given LDAP settings."
-msgstr ""
-
-msgid "Unknown \"_cap\" specified"
-msgstr ""
-
-msgid "\"_passthrough\" should be \"true\" or
\"false\""
-msgstr ""
-
-msgid "\"_passthrough_affected_by\" should be a device name string"
-msgstr ""
-
-#, python-format
-msgid "Error while getting block devices. Details: %(err)s"
-msgstr "���������������������������������������������������%(err)s"
-
-#, python-format
-msgid "Error while getting block device information for %(device)s."
-msgstr "������ %(device)s ���������������������������������������"
-
-#, python-format
-msgid "Unable to find distro file: %(filename)s"
-msgstr "��������� distro ���������%(filename)s"
-
-#, python-format
-msgid ""
-"Unable to parse distro file: %(filename)s. Make sure, it is a JSON file."
-msgstr "������������ distro ���������%(filename)s������������������ JSON
���������"
-
-#, python-format
-msgid "Unable to login to iSCSI host target %(portal)s. Details: %(err)s"
-msgstr "������������ iSCSI ������������ %(portal)s������������������%(err)s"
-
-#, python-format
-msgid "Unable to login to iSCSI host %(host)s target %(target)s"
-msgstr "������������ iSCSI ������ %(host)s ������ %(target)s"
-
-#, python-format
-msgid "Unable to find ISO file %(filename)s"
-msgstr ""
-
-#, python-format
-msgid "The ISO file %(filename)s is not bootable"
-msgstr "ISO ������ %(filename)s ������������"
-
-#, python-format
-msgid "The ISO file %(filename)s does not have a valid El Torito boot record"
-msgstr "ISO ������ %(filename)s ��������������� El Torito ������������"
-
-#, python-format
-msgid "Invalid El Torito validation entry in ISO %(filename)s"
-msgstr "ISO %(filename)s ��������������� El Torito ������������"
-
-#, python-format
-msgid "Invalid El Torito boot indicator in ISO %(filename)s"
-msgstr "ISO %(filename)s ��������������� El Torito ���������������"
-
-#, python-format
-msgid "Unexpected volume type for primary volume in ISO %(filename)s"
-msgstr "ISO %(filename)s ���������������������������������������������"
-
-#, python-format
-msgid "Bad format while reading volume descriptor in ISO %(filename)s"
-msgstr "������ ISO %(filename)s ���������������������������������������������"
-
-#, python-format
-msgid ""
-"The hypervisor doesn't have permission to use this ISO %(filename)s. "
-"Consider moving it under /var/lib/libvirt, or set the search permission to "
-"file access control lists for '%(user)s' user if possible, or add the
'%"
-"(user)s' to the ISO path group, or (not recommended) 'chmod -R o+x "
-"'path_to_iso'.Details: %(err)s"
-msgstr ""
-"Hypervisor ��������������� ISO %(filename)s ���������������������������������������
/var/lib/"
-"libvirt ������������������������������'%(user)s'
���������������������������������������������������������"
-"��� '%(user)s' ��������� ISO
������������������������������������������������������ 'chmod -R o+x "
-"'path_to_iso'������������������%(err)s"
-
-msgid "An error occurred when probing image OS information."
-msgstr ""
-
-msgid "No OS information found in given image."
-msgstr ""
-
-#, python-format
-msgid "Unable to read image file %(filename)s"
-msgstr ""
-
-#, python-format
-msgid ""
-"Image file must be an existing file on system. %(filename)s is not a valid "
-"input."
-msgstr ""
-
-#, python-format
-msgid "Virtual machine %(name)s already exists"
-msgstr "������������ %(name)s ���������"
-
-#, python-format
-msgid "Virtual machine %(name)s does not exist"
-msgstr "������������ %(name)s ���������"
-
-#, python-format
-msgid ""
-"Unable to rename virtual machine %(name)s. The name %(new_name)s is already "
-"in use or the virtual machine is not powered off."
-msgstr ""
-
-#, python-format
-msgid "Unable to retrieve screenshot for stopped virtual machine %(name)s"
-msgstr "��������������������������������� %(name)s ���������"
-
-msgid "Remote ISO image is not supported by this server."
-msgstr "��������������������������� ISO ������������"
-
-#, python-format
-msgid "Screenshot is not supported on virtual machine %(name)s"
-msgstr ""
-
-#, python-format
-msgid "Unable to create virtual machine %(name)s. Details: %(err)s"
-msgstr "������������������������ %(name)s������������������%(err)s"
-
-#, python-format
-msgid "Unable to update virtual machine %(name)s. Details: %(err)s"
-msgstr "������������������������ %(name)s������������������%(err)s"
-
-#, python-format
-msgid "Unable to retrieve virtual machine %(name)s. Details: %(err)s"
-msgstr "������������������������ %(name)s������������������%(err)s"
-
-#, python-format
-msgid "Unable to connect to powered off virtual machine %(name)s."
-msgstr ""
-
-msgid "Virtual machine name must be a string without slashes (/)"
-msgstr ""
-
-#, python-format
-msgid "Invalid template URI %(value)s specified for virtual machine"
-msgstr ""
-
-#, python-format
-msgid "Invalid storage pool URI %(value)s specified for virtual machine"
-msgstr ""
-
-msgid "Supported virtual machine graphics are Spice or VNC"
-msgstr ""
-
-msgid "Graphics address to listen on must be IPv4 or IPv6"
-msgstr "������������������������������������ IPv4 ��� IPv6"
-
-msgid "Specify a template to create a virtual machine from"
-msgstr "���������������������������������������"
-
-#, python-format
-msgid "Unable to start virtual machine %(name)s. Details: %(err)s"
-msgstr "������������������������ %(name)s������������������%(err)s"
-
-#, python-format
-msgid "Unable to power off virtual machine %(name)s. Details: %(err)s"
-msgstr "������������������������ %(name)s������������������%(err)s"
-
-#, python-format
-msgid "Unable to delete virtual machine %(name)s. Details: %(err)s"
-msgstr "������������������������ %(name)s������������������%(err)s"
-
-#, python-format
-msgid "Unable to reset virtual machine %(name)s. Details: %(err)s"
-msgstr "������������������������������ %(name)s������������������%(err)s"
-
-msgid "User name list must be an array"
-msgstr ""
-
-msgid "User name must be a string"
-msgstr "���������������������������"
-
-msgid "Group name list must be an array"
-msgstr ""
-
-msgid "Group name must be a string"
-msgstr "���������������������������"
-
-#, python-format
-msgid "User(s) '%(users)s' do not exist"
-msgstr "��������� '%(users)s' ������������"
-
-#, python-format
-msgid "Group(s) '%(groups)s' do not exist"
-msgstr "��������� '%(groups)s' ������������"
-
-#, python-format
-msgid "Unable to shutdown virtual machine %(name)s. Details: %(err)s"
-msgstr "������������������������ %(name)s������������������%(err)s"
-
-#, python-format
-msgid ""
-"Unable to get access metadata of virtual machine %(name)s. Details: %(err)s"
-msgstr "������������������������ %(name)s������������������%(err)s"
-
-msgid "The guest console password must be a string."
-msgstr ""
-
-msgid "The life time for the guest console password must be a number."
-msgstr ""
-
-#, python-format
-msgid "Virtual machine '%(name)s' must be stopped before cloning it."
-msgstr ""
-
-#, python-format
-msgid "Insufficient disk space to clone virtual machine '%(name)s'"
-msgstr ""
-
-#, python-format
-msgid "Unable to clone VM '%(name)s'. Details: %(err)s"
-msgstr ""
-
-#, python-format
-msgid "Invalid operation for non-persistent virtual machine %(name)s"
-msgstr ""
-
-#, python-format
-msgid "Cannot suspend VM '%(name)s' because it is not running."
-msgstr ""
-
-#, python-format
-msgid "Unable to suspend VM '%(name)s'. Details: %(err)s"
-msgstr ""
-
-#, python-format
-msgid "Cannot resume VM '%(name)s' because it is not paused."
-msgstr ""
-
-#, python-format
-msgid "Unable to resume VM '%(name)s'. Details: %(err)s"
-msgstr ""
-
-msgid "Memory assigned is higher then the maximum allowed in the host."
-msgstr ""
-
-#, python-format
-msgid ""
-"VM '%(name)s' does not support live memory update. Update the memory with
"
-"the machine offline to enable this feature."
-msgstr ""
-
-msgid "Only increase memory is allowed in active VMs"
-msgstr ""
-
-msgid ""
-"For live memory update, new memory value must be equal old memory value plus
"
-"multiples of 1024 Mib"
-msgstr ""
-
-msgid "There are not enough free slots of 1024 Mib in the guest."
-msgstr ""
-
-msgid ""
-"Host's libvirt version does not support memory devices. Libvirt must be >=
"
-"1.2.14"
-msgstr ""
-
-#, python-format
-msgid "Error attaching memory device. Details: %(error)s"
-msgstr ""
-
-#, python-format
-msgid ""
-"VM %(vmid)s does not contain directly assigned host device %(dev_name)s."
-msgstr ""
-
-#, python-format
-msgid "The host device %(dev_name)s is not allowed to directly assign to VM."
-msgstr ""
-
-msgid ""
-"No IOMMU groups found. Host PCI pass through needs IOMMU group to function "
-"correctly. Please enable Intel VT-d or AMD IOMMU in your BIOS, then verify "
-"the Kernel is compiled with IOMMU support. For Intel CPU, add intel_iommu=on
"
-"to your Kernel parameter in /boot/grub2/grub.conf. For AMD CPU, add iommu=pt
"
-"iommu=1."
-msgstr ""
-
-msgid "\"name\" should be a device name string"
-msgstr ""
-
-#, python-format
-msgid ""
-"The device %(name)s is probably in use by the host. Unable to attach it to "
-"the guest."
-msgstr ""
-
-#, python-format
-msgid "Interface %(iface)s does not exist in virtual machine %(name)s"
-msgstr "������ %(iface)s ������������������������ %(name)s ���"
-
-#, python-format
-msgid ""
-"Network %(network)s specified for virtual machine %(name)s does not exist"
-msgstr "��������������� %(name)s ��������������� %(network)s ���������"
-
-msgid "Supported virtual machine interfaces type is only network"
-msgstr "���������������������������������������������������"
-
-msgid "Network name for virtual machine interface must be a string"
-msgstr "������������������������������������������������"
-
-msgid "Invalid network model card specified for virtual machine interface"
-msgstr "���������������������������������������������������"
-
-msgid "Specify type and network to add a new virtual machine interface"
-msgstr "������������������������������������������������"
-
-msgid "MAC Address must respect this format FF:FF:FF:FF:FF:FF"
-msgstr ""
-
-#, python-format
-msgid "MAC Address %(mac)s already exists in virtual machine %(name)s"
-msgstr ""
-
-msgid "Invalid MAC Address"
-msgstr ""
-
-msgid "Cannot change MAC address of a running virtual machine"
-msgstr ""
-
-#, python-format
-msgid "Template %(name)s already exists"
-msgstr "������ %(name)s ���������"
-
-#, python-format
-msgid ""
-"Network '%(network)s' specified for template %(template)s does not
exist"
-msgstr "��������� %(template)s ��������������� '%(network)s'
���������"
-
-#, python-format
-msgid ""
-"Storage pool %(pool)s specified for template %(template)s does not exist"
-msgstr "��������� %(template)s ������������������ '%(pool)s'
���������"
-
-#, python-format
-msgid "Storage pool %(pool)s specified for template %(template)s is not
active"
-msgstr "��������� %(template)s ������������������ '%(pool)s'
������������������������"
-
-#, python-format
-msgid "Invalid parameter '%(param)s' specified for CDROM."
-msgstr "��� CDROM ��������������� '%(param)s' ���������"
-
-#, python-format
-msgid "Network %(network)s specified for template %(template)s is not active"
-msgstr "��������� %(template)s ��������������� %(network)s
������������������������"
-
-msgid "Template name must be a string"
-msgstr "���������������������������"
-
-msgid "Template icon must be a path to the image"
-msgstr "������������������������������������"
-
-msgid "Template distribution must be a string"
-msgstr "���������������������������������"
-
-msgid "Template distribution version must be a string"
-msgstr "���������������������������������"
-
-msgid "The number of CPUs must be an integer greater than 0"
-msgstr "CPU ���������������������"
-
-msgid "Amount of memory (MB) must be an integer greater than 512"
-msgstr "��������������� (MB) ��������������� 512 ���������"
-
-msgid "Template CDROM must be a local or remote ISO file"
-msgstr "������ CDROM ������������������������ ISO ������"
-
-#, python-format
-msgid "Invalid storage pool URI %(value)s specified for template"
-msgstr "��������������������������� URI %(value)s ������"
-
-msgid "Specify an ISO image as CDROM or a base image to create a template"
-msgstr "������ ISO ��������������� CDROM ���������������"
-
-msgid "All networks for the template must be specified in a list."
-msgstr "���������������������������������������������������"
-
-msgid "Specify a volume to a template when storage pool is iSCSI or SCSI"
-msgstr ""
-
-#, python-format
-msgid "The volume %(volume)s is not in storage pool %(pool)s"
-msgstr ""
-
-#, python-format
-msgid "Unable to create template due error: %(err)s"
-msgstr "������������������������������������������%(err)s"
-
-#, python-format
-msgid "Unable to delete template due error: %(err)s"
-msgstr "������������������������������������������%(err)s"
-
-msgid "Disk size must be an integer greater than 1GB."
-msgstr ""
-
-msgid "Template base image must be a valid local image file"
-msgstr "������ CDROM ������������������������ ISO ������"
-
-#, python-format
-msgid "Cannot identify base image %(path)s format"
-msgstr ""
-
-msgid ""
-"When specifying CPU topology, VCPUs must be a product of sockets, cores, and
"
-"threads."
-msgstr ""
-
-msgid ""
-"When specifying CPU topology, each element must be an integer greater than "
-"zero."
-msgstr ""
-
-msgid ""
-"Invalid disk image format. Valid formats: bochs, cloop, cow, dmg, qcow, "
-"qcow2, qed, raw, vmdk, vpc."
-msgstr ""
-
-#, python-format
-msgid "Storage pool %(name)s already exists"
-msgstr "��������� %(name)s ���������"
-
-#, python-format
-msgid "Storage pool %(name)s does not exist"
-msgstr "��������� %(name)s ���������"
-
-#, python-format
-msgid "Specify %(item)s in order to create the storage pool %(name)s"
-msgstr "������ %(item)s ������������������ %(name)s"
-
-#, python-format
-msgid "Unable to delete active storage pool %(name)s"
-msgstr "��������������������������������� %(name)s"
-
-#, python-format
-msgid "Unable to list storage pools. Details: %(err)s"
-msgstr "���������������������������������������%(err)s"
-
-#, python-format
-msgid "Unable to create storage pool %(name)s. Details: %(err)s"
-msgstr "��������������������� %(name)s������������������%(err)s"
-
-#, python-format
-msgid ""
-"Unable to get number of storage volumes in storage pool %(name)s. Details: %"
-"(err)s"
-msgstr "��������������������� %(name)s
������������������������������������������%(err)s"
-
-#, python-format
-msgid "Unable to activate storage pool %(name)s. Details: %(err)s"
-msgstr "��������������������� %(name)s������������������%(err)s"
-
-#, python-format
-msgid "Unable to deactivate storage pool %(name)s. Details: %(err)s"
-msgstr "��������������������������� %(name)s������������������%(err)s"
-
-#, python-format
-msgid "Unable to delete storage pool %(name)s. Details: %(err)s"
-msgstr "��������������������� %(name)s������������������%(err)s"
-
-#, python-format
-msgid ""
-"Unable to create NFS Pool as export path %(path)s may block during mount"
-msgstr "������������ NFS ������������������������������������������������ %(path)s
���������������"
-
-#, python-format
-msgid "Unable to create NFS Pool as export path %(path)s mount failed"
-msgstr "������������ NFS ������������������������������ %(path)s ������������"
-
-#, python-format
-msgid "Unsupported storage pool type: %(type)s"
-msgstr "���������������������������������%(type)s"
-
-#, python-format
-msgid "Error while retrieving storage pool XML to %(pool)s"
-msgstr ""
-
-msgid "Storage pool name must be a string without slashes (/)"
-msgstr ""
-
-msgid ""
-"Supported storage pool types are dir, netfs, logical, iscsi, isci and
kimchi-"
-"iso"
-msgstr ""
-
-msgid "Storage pool path must be a string"
-msgstr "������������������������������"
-
-msgid "Storage pool host must be a IP or hostname"
-msgstr "������������������������ IP ���������������"
-
-msgid "Storage pool device must be the absolute path to the block device"
-msgstr ""
-
-msgid "Storage pool devices parameter must be a list"
-msgstr "������������������������������������"
-
-msgid "Target IQN of an iSCSI pool must be a string"
-msgstr "iSCSI ������������������ IQN ���������������"
-
-msgid "Port of a remote storage server must be an integer between 1 and 65535"
-msgstr "��������������������������������������������� 1 ��� 65535
���������������"
-
-msgid "iSCSI target username must be a string"
-msgstr ""
-
-msgid "iSCSI target password must be a string"
-msgstr ""
-
-msgid "Specify name and type to create a storage pool"
-msgstr "���������������������������������������"
-
-#, python-format
-msgid ""
-"%(disk)s is not a valid disk/partition. Could not add it to the pool %(pool)"
-"s."
-msgstr "%(disk)s
���������������������/������������������������������������������%(pool)s���"
-
-#, python-format
-msgid "Unable to extend logical pool %(pool)s. Details: %(err)s"
-msgstr ""
-
-msgid "The parameter disks only can be updated for logical storage pool."
-msgstr "������������������������������������������������������������"
-
-msgid "The SCSI host adapter name must be a string."
-msgstr "SCSI ���������������������������������������"
-
-msgid "The storage pool kimchi_isos is reserved for internal use"
-msgstr "��������� kimchi_isos ���������������������"
-
-#, python-format
-msgid ""
-"Unable to activate NFS storage pool %(name)s. NFS server %(server)s is "
-"unreachable."
-msgstr "������������ NFS ��������� %(name)s���NFS ���������
%(server)s���������������"
-
-#, python-format
-msgid ""
-"Unable to deactivate NFS storage pool %(name)s. NFS server %(server)s is "
-"unreachable."
-msgstr "������������������ NFS ��������� %(name)s���NFS ���������
%(server)s���������������"
-
-#, python-format
-msgid ""
-"Unable to deactivate pool %(name)s as it is associated with some templates"
-msgstr "���������������������������
%(name)s������������������������������������"
-
-#, python-format
-msgid "Unable to delete pool %(name)s as it is associated with some templates"
-msgstr "��������������������� %(name)s������������������������������������"
-
-#, python-format
-msgid ""
-"A volume group named '%(name)s' already exists. Please, choose another name
"
-"to create the logical pool."
-msgstr "������ '%(name)s'
������������������������������������������������������������������������������"
-
-#, python-format
-msgid "Unable to update database with deep scan information due error:
%(err)s"
-msgstr
"������������������������������������������������������������������������%(err)s"
-
-#, python-format
-msgid "Storage volume %(name)s already exists"
-msgstr "������������ %(name)s ���������"
-
-#, python-format
-msgid "Storage volume %(name)s does not exist in storage pool %(pool)s"
-msgstr "������������ %(name)s ��������������������� %(pool)s ���"
-
-#, python-format
-msgid ""
-"Unable to create storage volume %(volume)s because storage pool %(pool)s is "
-"not active"
-msgstr ""
-
-#, python-format
-msgid "Specify %(item)s in order to create storage volume %(volume)s"
-msgstr "������ %(item)s ��������������������� %(volume)s"
-
-#, python-format
-msgid ""
-"Unable to list storage volumes because storage pool %(pool)s is not active"
-msgstr "������������������������������������������ %(pool)s
������������������������"
-
-#, python-format
-msgid ""
-"Unable to create storage volume %(name)s in storage pool %(pool)s. Details:
%"
-"(err)s"
-msgstr "������������������ %(pool)s ���������������������
%(name)s������������������%(err)s"
-
-#, python-format
-msgid ""
-"Unable to list storage volumes in storage pool %(pool)s. Details: %(err)s"
-msgstr "��������������������� %(pool)s
������������������������������������%(err)s"
-
-#, python-format
-msgid "Unable to wipe storage volumes %(name)s. Details: %(err)s"
-msgstr "������������������������ %(name)s������������������%(err)s"
-
-#, python-format
-msgid "Unable to delete storage volume %(name)s. Details: %(err)s"
-msgstr "������������������������ %(name)s������������������%(err)s"
-
-#, python-format
-msgid "Unable to resize storage volume %(name)s. Details: %(err)s"
-msgstr "������������������������ %(name)s ���������������������������%(err)s"
-
-#, python-format
-msgid "Storage type %(type)s does not support volume create and delete"
-msgstr "��������������� %(type)s ������������������������������"
-
-msgid "Storage volume name must be a string"
-msgstr "���������������������������������"
-
-msgid "Storage volume allocation must be an integer number"
-msgstr "���������������������������������"
-
-msgid ""
-"Storage volume format not supported. Valid formats: bochs, cloop, cow, dmg, "
-"qcow, qcow2, qed, raw, vmdk, vpc."
-msgstr ""
-
-msgid "Storage volume requires a volume name"
-msgstr "������������������������������"
-
-#, python-format
-msgid ""
-"Unable to update database with storage volume information due error: %(err)s"
-msgstr
"������������������������������������������������������������������������%(err)s"
-
-#, python-format
-msgid "Only one of parameter %(param)s can be specified"
-msgstr ""
-
-#, python-format
-msgid "Create volume from %(param)s is not supported"
-msgstr ""
-
-msgid "Storage volume capacity must be an integer number."
-msgstr ""
-
-msgid "Storage volume URL must be http://, https://, ftp:// or ftps://."
-msgstr ""
-
-#, python-format
-msgid "Unable to access file %(url)s. Please, check it."
-msgstr ""
-
-#, python-format
-msgid ""
-"Unable to clone storage volume '%(name)s' in pool '%(pool)s'.
Details: %(err)"
-"s"
-msgstr ""
-
-msgid "Specify chunk data and its size to upload a file."
-msgstr ""
-
-msgid "In order to upload a storage volume, specify the 'upload'
parameter."
-msgstr ""
-
-msgid ""
-"Unable to upload chunk data as it does not match with requested chunk size."
-msgstr ""
-
-#, python-format
-msgid "The storage volume %(vol)s is not under an upload process."
-msgstr ""
-
-msgid "The upload chunk data will exceed the storage volume size."
-msgstr ""
-
-#, python-format
-msgid "Unable to upload chunk data to storage volume. Details: %(err)s."
-msgstr ""
-
-#, python-format
-msgid "Interface %(name)s does not exist"
-msgstr "������ %(name)s ���������"
-
-#, python-format
-msgid "Network %(name)s already exists"
-msgstr "������ %(name)s ���������"
-
-#, python-format
-msgid "Network %(name)s does not exist"
-msgstr "������ %(name)s ���������"
-
-#, python-format
-msgid "Subnet %(subnet)s specified for network %(network)s is not valid."
-msgstr "��������� %(network)s ������������������ %(subnet)s ���������"
-
-#, python-format
-msgid "Specify a network interface to create bridged network %(name)s"
-msgstr "������������������������������������������ %(name)s"
-
-#, python-format
-msgid "Unable to delete active network %(name)s"
-msgstr "������������������������������ %(name)s"
-
-#, python-format
-msgid "Interface %(iface)s specified for network %(network)s is already in
use"
-msgstr "��������� %(network)s ��������������� %(iface)s ���������������"
-
-msgid "Interface should be bare NIC, bonding or bridge device."
-msgstr "��������������������� NIC������������������������������������"
-
-#, python-format
-msgid "Unable to create network %(name)s. Details: %(err)s"
-msgstr "������������������ %(name)s������������������%(err)s"
-
-#, python-format
-msgid "Unable to find a free IP address for network '%(name)s'"
-msgstr "��������������� '%(name)s' ��������� IP ������"
-
-#, python-format
-msgid "The interface %(iface)s already exists."
-msgstr ""
-
-msgid "Network name must be a string without slashes (/) or quotes (\")"
-msgstr ""
-
-msgid "Supported network types are isolated, NAT and bridge"
-msgstr "���������������������������������������NAT ������������"
-
-msgid "Network subnet must be a string with IP address and prefix or netmask"
-msgstr "��������������������������������� IP
���������������������������������������"
-
-msgid "Network interface must be a string"
-msgstr "���������������������������"
-
-msgid "Network VLAN ID must be an integer between 1 and 4094"
-msgstr "������ VLAN ID ��������������� 1 ��� 4094 ���������������"
-
-msgid "Specify name and type to create a Network"
-msgstr "������������������������������������"
-
-#, python-format
-msgid ""
-"Unable to delete network %(name)s. There are some virtual machines %(vms)s "
-"and/or templates linked to this network."
-msgstr ""
-
-#, python-format
-msgid ""
-"Unable to deactivate network %(name)s. There are some virtual machines
%(vms)"
-"s and/or templates linked to this network."
-msgstr ""
-
-#, python-format
-msgid "Bridge device %(name)s can not be the trunk device of a VLAN."
-msgstr "��������������� %(name)s ��������� VLAN ������������������"
-
-#, python-format
-msgid "Failed to activate interface %(iface)s: %(err)s."
-msgstr "������������������ %(iface)s���%(err)s���"
-
-#, python-format
-msgid ""
-"Failed to activate interface %(iface)s. Please check the physical link "
-"status."
-msgstr "������������������ %(iface)s���������������������������������"
-
-#, python-format
-msgid "Failed to start network %(name)s. Details: %(err)s"
-msgstr ""
-
-#, python-format
-msgid "Debug report %(name)s does not exist"
-msgstr "������������ %(name)s ���������"
-
-msgid "Debug report tool not found in system"
-msgstr "���������������������������������������"
-
-#, python-format
-msgid "Unable to create debug report %(name)s. Details: %(err)s."
-msgstr "������������������������ %(name)s������������������%(err)s���"
-
-#, python-format
-msgid "Can not find any debug report with the given name %(name)s"
-msgstr ""
-
-#, python-format
-msgid "Unable to generate debug report %(name)s. Details: %(err)s"
-msgstr "������������������������ %(name)s������������������%(err)s"
-
-msgid "You should give a name for the debug report file."
-msgstr ""
-
-msgid ""
-"Debug report name must be a string. Only letters, digits, underscore ('_')
"
-"and hyphen ('-') are allowed."
-msgstr ""
-
-#, python-format
-msgid ""
-"The debug report with specified name \"%(name)s\" already exists. Please
use "
-"another one."
-msgstr "������ '%(name)s'
������������������������������������������������������������������������������"
-
-#, python-format
-msgid "Storage server %(server)s was not used by Kimchi"
-msgstr "Kimchi ��������������������������� %(server)s"
-
-#, python-format
-msgid "Distro '%(name)s' does not exist"
-msgstr "Distro '%(name)s' ���������"
-
-#, python-format
-msgid "Partition %(name)s does not exist in the host"
-msgstr "��������� %(name)s ���������������������"
-
-msgid "Unable to shutdown host machine as there are running virtual machines"
-msgstr "���������������������������������������������������������������"
-
-msgid "Unable to reboot host machine as there are running virtual machines"
-msgstr
"������������������������������������������������������������������������"
-
-#, python-format
-msgid "Node device '%(name)s' not found"
-msgstr "��������������������� '%(name)s'"
-
-msgid "Conflicting flag filters specified."
-msgstr ""
-
-msgid "No packages marked for update"
-msgstr "������������������������������������"
-
-#, python-format
-msgid "Package %(name)s is not marked to be updated."
-msgstr "������ %(name)s ������������������������������"
-
-#, python-format
-msgid "Error while getting packages marked to be updated. Details: %(err)s"
-msgstr
"������������������������������������������������������������������������%(err)s"
-
-msgid "There is no compatible package manager for this system."
-msgstr "���������������������������������������������"
-
-#, python-format
-msgid "Invalid URI %(uri)s"
-msgstr "URI %(uri)s ������"
-
-msgid "Unable to choose a virtual machine name"
-msgstr ""
-
-msgid "Invalid storage type. Types supported: 'cdrom', 'disk'"
-msgstr "���������������������������������������������'cdrom'"
-
-#, python-format
-msgid "The path '%(value)s' is not a valid local/remote path for the
device"
-msgstr ""
-
-msgid "Only CDROM path can be update."
-msgstr ""
-
-#, python-format
-msgid ""
-"The storage device %(dev_name)s does not exist in the virtual machine %"
-"(vm_name)s"
-msgstr ""
-
-#, python-format
-msgid "Error while creating new storage device: %(error)s"
-msgstr "������������������������������������������%(error)s"
-
-#, python-format
-msgid "Error while updating storage device: %(error)s"
-msgstr "������������������������������������%(error)s"
-
-#, python-format
-msgid "Error while removing storage device: %(error)s"
-msgstr "������������������������������������%(error)s"
-
-msgid "Do not support IDE device hot plug"
-msgstr ""
-
-msgid ""
-"Specify type and path or type and pool/volume to add a new virtual machine "
-"disk"
-msgstr "������������������������������������������������"
-
-msgid "Specify path to update virtual machine disk"
-msgstr "���������������������������������������"
-
-#, python-format
-msgid "Controller type %(type)s limitation of %(limit)s devices reached"
-msgstr ""
-
-#, python-format
-msgid "Cannot retrieve disk path information for given pool/volume: %(error)s"
-msgstr ""
-
-msgid "Volume already in use by other virtual machine."
-msgstr ""
-
-msgid ""
-"Only one of path or pool/volume can be specified to add a new virtual "
-"machine disk"
-msgstr "������������������������������������������������"
-
-#, python-format
-msgid ""
-"Volume chosen with format %(format)s does not fit in the storage type
%(type)"
-"s"
-msgstr ""
-
-msgid "YUM Repository ID must be one word only string."
-msgstr "YUM ��������� ID ���������������������������������������"
-
-msgid "Repository URL must be an http://, ftp:// or file:// URL."
-msgstr "��������� URL ��������� http://���ftp:// ��� file:// URL���"
-
-msgid ""
-"Repository configuration is a dictionary with specific values according to "
-"repository type."
-msgstr
"������������������������������������������������������������������������������"
-
-msgid "Distribution to DEB repository must be a string"
-msgstr "DEB ���������������������������������������"
-
-msgid "Components to DEB repository must be listed in a array"
-msgstr "DEB ������������������������������������������������"
-
-msgid "Components to DEB repository must be a string"
-msgstr "DEB ���������������������������������"
-
-msgid "Mirror list to repository must be a string"
-msgstr ""
-
-msgid "YUM Repository name must be string."
-msgstr "YUM ���������������������������������"
-
-msgid "GPG check must be a boolean value."
-msgstr "GPG ���������������������������"
-
-msgid "GPG key must be a URL pointing to the ASCII-armored file."
-msgstr "GPG ��������������������� ASCII ��������������� URL���"
-
-#, python-format
-msgid "Could not update repository %(repo_id)s."
-msgstr "��������������������� %(repo_id)s���"
-
-#, python-format
-msgid "Repository %(repo_id)s does not exist."
-msgstr "��������� %(repo_id)s ������������"
-
-msgid ""
-"Specify repository base URL, mirror list or metalink in order to create or "
-"update a YUM repository."
-msgstr ""
-
-msgid "Repository management tool was not recognized for your system."
-msgstr "���������������������������������������������"
-
-#, python-format
-msgid "Repository %(repo_id)s is already enabled."
-msgstr "������������������ %(repo_id)s���"
-
-#, python-format
-msgid "Repository %(repo_id)s is already disabled."
-msgstr "������������������ %(repo_id)s���"
-
-#, python-format
-msgid "Could not remove repository %(repo_id)s."
-msgstr "��������������������� %(repo_id)s���"
-
-#, python-format
-msgid "Could not write repository configuration file %(repo_file)s"
-msgstr "������������������������������ %(repo_file)s"
-
-msgid "Specify repository distribution in order to create a DEB repository."
-msgstr "������������������������������������ DEB ������������"
-
-#, python-format
-msgid "Could not enable repository %(repo_id)s."
-msgstr "��������������������� %(repo_id)s���"
-
-#, python-format
-msgid "Could not disable repository %(repo_id)s."
-msgstr "��������������������� %(repo_id)s���"
-
-msgid "YUM Repository ID already exists"
-msgstr "YUM ��������� ID ���������"
-
-msgid "YUM Repository name must be a string"
-msgstr "YUM ������������������������������"
-
-#, python-format
-msgid "Unable to list repositories. Details: '%(err)s'"
-msgstr "���������������������������������������'%(err)s'"
-
-#, python-format
-msgid "Unable to retrieve repository information. Details: '%(err)s'"
-msgstr "���������������������������������������������'%(err)s'"
-
-#, python-format
-msgid "Unable to add repository. Details: '%(err)s'"
-msgstr "���������������������������������������'%(err)s'"
-
-#, python-format
-msgid "Unable to remove repository. Details: '%(err)s'"
-msgstr "���������������������������������������'%(err)s'"
-
-#, python-format
-msgid ""
-"Configuration items: '%(items)s' are not supported by repository
manager"
-msgstr ""
-
-msgid "Repository metalink must be an http://, ftp:// or file:// URL."
-msgstr ""
-
-msgid "Cannot specify mirrorlist and metalink at the same time."
-msgstr ""
-
-#, python-format
-msgid ""
-"Virtual machine '%(vm)s' must be stopped before creating a snapshot of
it."
-msgstr ""
-
-#, python-format
-msgid ""
-"Unable to create snapshot '%(name)s' on virtual machine '%(vm)s'.
Details: %"
-"(err)s"
-msgstr ""
-
-#, python-format
-msgid "Snapshot '%(name)s' does not exist on virtual machine
'%(vm)s'."
-msgstr ""
-
-#, python-format
-msgid ""
-"Unable to retrieve snapshot '%(name)s' on virtual machine '%(vm)s'.
Details: "
-"%(err)s"
-msgstr ""
-
-#, python-format
-msgid "Unable to list snapshots on virtual machine '%(vm)s'. Details:
%(err)s"
-msgstr ""
-
-#, python-format
-msgid ""
-"Unable to delete snapshot '%(name)s' on virtual machine '%(vm)s'.
Details: %"
-"(err)s"
-msgstr ""
-
-#, python-format
-msgid ""
-"Unable to retrieve current snapshot of virtual machine '%(vm)s'. Details:
%"
-"(err)s"
-msgstr ""
-
-#, python-format
-msgid ""
-"Unable to revert virtual machine '%(vm)s' to snapshot '%(name)s'.
Details: %"
-"(err)s"
-msgstr ""
-
-#, python-format
-msgid ""
-"Unable to create snapshot of virtual machine '%(vm)s' because it contains a
"
-"disk with format '%(format)s'; only 'qcow2' is supported."
-msgstr ""
-
-msgid "The number of vCPUs is too large for this system."
-msgstr ""
-
-msgid "Invalid vCPU/topology combination."
-msgstr ""
-
-msgid "This host (or current configuration) does not allow CPU topology."
-msgstr ""
-
-msgid "ERROR CODE"
-msgstr "���������"
-
-msgid "REASON"
-msgstr "������"
-
-msgid "STACK"
-msgstr "������"
-
-msgid "Go to Homepage"
-msgstr "������������"
-
-msgid "Create a New Virtual Machine"
-msgstr "������������������������"
-
-msgid "Virtual Machine Name"
-msgstr "������������������"
-
-msgid ""
-"The name used to identify the virtual machine. If omitted, a name will be "
-"chosen based on the template used."
-msgstr
"���������������������������������������������������������������������������������������������"
-
-msgid "Template"
-msgstr "������"
-
-msgid "Please create a template first."
-msgstr "���������������������"
-
-msgid "Create a Template"
-msgstr "������������"
-
-msgid "Please choose a template."
-msgstr "������������������"
-
-msgid "OS"
-msgstr "OS"
-
-msgid "OS Version"
-msgstr "OS ������"
-
-msgid "CPUS"
-msgstr "CPUS"
-
-msgid "Memory"
-msgstr "���������"
-
-msgid "Create"
-msgstr "������"
-
-msgid "Creating..."
-msgstr ""
-
-msgid "Cancel"
-msgstr "������ "
-
-msgid "Edit Guest"
-msgstr "������������"
-
-msgid "General"
-msgstr "������"
-
-msgid "Storage"
-msgstr "���������"
-
-msgid "Interface"
-msgstr "������"
-
-msgid "Permission"
-msgstr "������"
-
-msgid "Host PCI Device"
-msgstr ""
-
-msgid "Snapshot"
-msgstr ""
-
-msgid "Name"
-msgstr "������"
-
-msgid "CPUs"
-msgstr "CPU"
-
-msgid "Memory (MB)"
-msgstr "���������"
-
-msgid "Icon"
-msgstr "������"
-
-msgid "Device"
-msgstr "������������"
-
-msgid "Path"
-msgstr "NFS ������"
-
-msgid "Network"
-msgstr "������"
-
-msgid "Type"
-msgstr "������"
-
-msgid "MAC Address"
-msgstr ""
-
-msgid "Available system users and groups"
-msgstr ""
-
-msgid "Selected system users and groups"
-msgstr ""
-
-msgid "User"
-msgstr ""
-
-msgid "All"
-msgstr "������"
-
-msgid "To Add"
-msgstr ""
-
-msgid "Added"
-msgstr ""
-
-msgid "filter"
-msgstr ""
-
-msgid "Product"
-msgstr ""
-
-msgid "Vendor"
-msgstr "���������"
-
-msgid "Created"
-msgstr ""
-
-msgid "Save"
-msgstr "������"
-
-msgid "Replace"
-msgstr "������"
-
-msgid "Detach"
-msgstr "������"
-
-msgid "revert"
-msgstr ""
-
-msgid "Start"
-msgstr "������"
-
-msgid "Reset"
-msgstr "������"
-
-msgid "Pause"
-msgstr ""
-
-msgid "Resume"
-msgstr ""
-
-msgid "Power Off"
-msgstr ""
-
-msgid "Actions"
-msgstr "������"
-
-msgid "Connect"
-msgstr "������"
-
-msgid "Clone"
-msgstr ""
-
-msgid "Edit"
-msgstr "������"
-
-msgid "Shut Down"
-msgstr "������"
-
-msgid "Delete"
-msgstr "������"
-
-msgid "CPU"
-msgstr "CPU"
-
-msgid "Disk I/O"
-msgstr "������ I/O"
-
-msgid "Network I/O"
-msgstr "������ I/O"
-
-msgid "Livetile"
-msgstr "Livetile"
-
-msgid "No guests found."
-msgstr "������������������"
-
-msgid "Add a Storage Device to VM"
-msgstr "������������������������ VM"
-
-msgid "Device Type"
-msgstr "������������"
-
-msgid "The device type. Currently, \"cdrom\" and \"disk\" are
supported."
-msgstr "������������������������������ \"cdrom\"���"
-
-msgid "Storage Pool"
-msgstr "���������"
-
-msgid "Storage pool which volume located in"
-msgstr "������������������������������"
-
-msgid "Storage Volume"
-msgstr "���������������"
-
-msgid "Storage volume to be attached"
-msgstr "���������������������������������"
-
-msgid "File Path"
-msgstr "������������"
-
-msgid "The ISO file path in the server for CDROM."
-msgstr "CDROM ��� ISO ������������������������������"
-
-msgid "Attach"
-msgstr "������"
-
-msgid "Shut down"
-msgstr "������"
-
-msgid "Restart"
-msgstr "������������"
-
-msgid "Basic Information"
-msgstr "������������"
-
-msgid "OS Distro"
-msgstr "OS Distro"
-
-msgid "OS Code Name"
-msgstr "OS ���������������"
-
-msgid "Processor"
-msgstr "���������"
-
-msgid "CPU(s)"
-msgstr ""
-
-msgid "System Statistics"
-msgstr "������������������"
-
-msgid "Software Updates"
-msgstr "������������"
-
-msgid "Update Progress"
-msgstr "������������"
-
-msgid "Repositories"
-msgstr "���������"
-
-msgid "Debug Reports"
-msgstr "������������"
-
-msgid "The username or password you entered is incorrect. Please try again."
-msgstr "������������������������������������������������������������"
-
-msgid "This field is required."
-msgstr "������������������������"
-
-msgid "Log in"
-msgstr "������"
-
-msgid "Logging in..."
-msgstr "������������..."
-
-msgid "Host"
-msgstr "������"
-
-msgid "Guests"
-msgstr "������"
-
-msgid "Templates"
-msgstr "������"
-
-msgid "Failed to get application configuration"
-msgstr "������������������������������"
-
-msgid "This is not a valid Linux path"
-msgstr "��������������� Linux ������"
-
-msgid "This is not a valid URL."
-msgstr "��������������� URL���"
-
-msgid "No such data available."
-msgstr "���������������������������"
-
-msgid ""
-"Can not contact the host system. Verify the host system is up and that you "
-"have network connectivity to it. HTTP request response %1. "
-msgstr ""
-"������������������������������������������������������������������������������������������������������������HTTP
"
-"��������������� %1���"
-
-msgid "Unable to read file."
-msgstr ""
-
-msgid "Error while uploading file."
-msgstr ""
-
-msgid "Delete Confirmation"
-msgstr "������������"
-
-msgid "OK"
-msgstr "������"
-
-msgid "Confirm"
-msgstr "������"
-
-msgid "Warning"
-msgstr "������"
-
-msgid "Cloning..."
-msgstr ""
-
-msgid "Loading..."
-msgstr "������������..."
-
-msgid "An error occurred while retrieving system information."
-msgstr ""
-
-msgid "Retry"
-msgstr "������"
-
-msgid "Detailed message:"
-msgstr "������������������"
-
-msgid "No ISO found"
-msgstr ""
-
-msgid "This is not a valid ISO file."
-msgstr "��������������� ISO ���������"
-
-msgid "This may take a long time. Do you want to continue?"
-msgstr "������������������������������������������"
-
-msgid "This will permanently delete the template. Would you like to continue?"
-msgstr "���������������������������������������������������"
-
-msgid "Unable to shut down system as there are some virtual machines running!"
-msgstr "������������������������������������������������������������������"
-
-msgid "Max:"
-msgstr "���������"
-
-msgid "Utilization"
-msgstr "���������"
-
-msgid "Available"
-msgstr "������"
-
-msgid "Read Rate"
-msgstr "������������"
-
-msgid "Write Rate"
-msgstr "������������"
-
-msgid "Received"
-msgstr "���������"
-
-msgid "Sent"
-msgstr "���������"
-
-msgid ""
-"Shutting down or restarting host will cause unsaved work lost. Continue to "
-"shut down/restarting?"
-msgstr
"������������������������������������������������������������������������������/������������������"
-
-msgid ""
-"Repository will be removed permanently and can't be recovered. Do you want
"
-"to continue?"
-msgstr "������������������������������������������������������������������"
-
-msgid "ID"
-msgstr "ID"
-
-msgid "Base URL"
-msgstr "������ URL"
-
-msgid "Is Mirror"
-msgstr "���������"
-
-msgid "URL Args"
-msgstr "URL ������"
-
-msgid "Enabled"
-msgstr "���������"
-
-msgid "GPG Check"
-msgstr "GPG ������"
-
-msgid "GPG Key"
-msgstr "GPG ������"
-
-msgid "Add"
-msgstr "������"
-
-msgid "Remove"
-msgstr "������"
-
-msgid "Enable"
-msgstr "������"
-
-msgid "Disable"
-msgstr "������"
-
-msgid "Package Name"
-msgstr "������������"
-
-msgid "Version"
-msgstr "������"
-
-msgid "Architecture"
-msgstr "������"
-
-msgid "Repository"
-msgstr "���������"
-
-msgid "Update All"
-msgstr "������������"
-
-msgid "Updating..."
-msgstr "������������..."
-
-msgid "Failed to retrieve packages update information."
-msgstr ""
-
-msgid "Failed to update package(s)."
-msgstr "���������������������"
-
-msgid ""
-"Debug report will be removed permanently and can't be recovered. Do you want
"
-"to continue?"
-msgstr "���������������������������������������������������������������������"
-
-msgid "Generated Time"
-msgstr "������������"
-
-msgid "Generate"
-msgstr "������"
-
-msgid "Generating..."
-msgstr "������������..."
-
-msgid "Rename"
-msgstr "������������"
-
-msgid "Download"
-msgstr "������"
-
-msgid ""
-"Report name should contain only letters, digits, underscore ('_') and/or
"
-"hyphen ('-')."
-msgstr "���������������������������������������������/������������
('-')���"
-
-msgid "Pending..."
-msgstr "������������..."
-
-msgid "Report name is the same as the original one."
-msgstr ""
-
-msgid ""
-"This will delete the virtual machine and its virtual disks. This operation "
-"cannot be undone. Would you like to continue?"
-msgstr
"���������������������������������������������������������������������������������������������"
-
-msgid "Power off Confirmation"
-msgstr "������������"
-
-msgid ""
-"This action may produce undesirable results, for example unflushed disk "
-"cache in the guest. Would you like to continue?"
-msgstr ""
-
-msgid "Reset Confirmation"
-msgstr "������������"
-
-msgid ""
-"There is a risk of data loss caused by reset without the guest OS shutdown. "
-"Would you like to continue?"
-msgstr ""
-
-msgid "Shut Down Confirmation"
-msgstr "������������"
-
-msgid "Note the guest OS may ignore this request. Would you like to continue?"
-msgstr "���������������������������������������������������"
-
-msgid "Virtual Machine delete Confirmation"
-msgstr ""
-
-msgid ""
-"This virtual machine is not persistent. Power Off will delete it. Continue?"
-msgstr ""
-
-msgid ""
-"When the target guest has SCSI or iSCSI volumes, they will be cloned on "
-"default storage pool. The same will happen when the target pool does not "
-"have enough space to clone the volumes. Do you want to continue?"
-msgstr ""
-
-msgid ""
-"This CDROM will be detached permanently and you can re-attach it. Continue "
-"to detach it?"
-msgstr ""
-"������������������������
CDROM��������������������������������������������������������� CDROM ������"
-
-msgid "Attaching..."
-msgstr "������������..."
-
-msgid "Replacing..."
-msgstr "������������..."
-
-msgid "Successfully attached!"
-msgstr "������������������"
-
-msgid "Successfully replaced!"
-msgstr "������������������"
-
-msgid "Successfully detached!"
-msgstr "������������������"
-
-msgid ""
-"This disk will be detached permanently and you can re-attach it. Continue to
"
-"detach it?"
-msgstr ""
-
-msgid "interface:"
-msgstr ""
-
-msgid "address:"
-msgstr ""
-
-msgid "link_type:"
-msgstr ""
-
-msgid "block:"
-msgstr ""
-
-msgid "drive_type:"
-msgstr ""
-
-msgid "model:"
-msgstr ""
-
-msgid "Affected devices:"
-msgstr ""
-
-msgid "The VLAN id must be between 1 and 4094."
-msgstr "VLAN ID ������������ 1 ��� 4094 ���������"
-
-msgid "unavailable"
-msgstr "������������"
-
-msgid ""
-"This action will interrupt network connectivity for any virtual machine that
"
-"depend on this network."
-msgstr
"������������������������������������������������������������������������������������"
-
-msgid "Create a network"
-msgstr "������������"
-
-msgid ""
-"This network is not persistent. Instead of stop, this action will "
-"permanently delete it. Would you like to continue?"
-msgstr ""
-"������������������������������������������������������������������������������������������������������������������"
-"������"
-
-msgid ""
-"The bridged VLAN tag may not work well with NetworkManager enabled. You "
-"should consider disabling it."
-msgstr ""
-
-msgid ""
-"This will permanently delete the storage pool. Would you like to continue?"
-msgstr "������������������������������������������������������"
-
-msgid "This storage pool is empty."
-msgstr "������������������������"
-
-msgid ""
-"It will format your disk and you will loose any data in there, are you sure "
-"to continue? "
-msgstr
"������������������������������������������������������������������������������������������������������"
-
-msgid "SCSI Fibre Channel"
-msgstr "SCSI ������������"
-
-msgid "No SCSI adapters found."
-msgstr "��������� SCSI ������������"
-
-msgid "Loading iSCSI targets..."
-msgstr ""
-
-msgid "No iSCSI found. Please input one."
-msgstr ""
-
-msgid "Failed to load iSCSI targets."
-msgstr ""
-
-msgid "The storage pool name can not be blank."
-msgstr "������������������������������"
-
-msgid "The storage pool path can not be blank."
-msgstr "������������������������������"
-
-msgid "NFS server mount path can not be blank."
-msgstr "NFS ������������������������������������"
-
-msgid "Invalid NFS mount path."
-msgstr "NFS ���������������������"
-
-msgid "No logical device selected."
-msgstr "������������������������"
-
-msgid "The iSCSI target can not be blank."
-msgstr "iSCSI ���������������������"
-
-msgid "Server name can not be blank."
-msgstr "������������������������������"
-
-msgid "This is not a valid Server Name or IP. Please, modify it."
-msgstr ""
-
-msgid "Looking for available partitions ..."
-msgstr "������������������������������ ..."
-
-msgid "No available partitions found."
-msgstr "������������������������������"
-
-msgid ""
-"This storage pool is not persistent. Instead of deactivate, this action will
"
-"permanently delete it. Would you like to continue?"
-msgstr ""
-"������������������������������������������������������������������������������������������������������������������"
-"������"
-
-msgid "Unable to retrieve partitions information."
-msgstr "���������������������������������������������'%(err)s'"
-
-msgid "In progress..."
-msgstr ""
-
-msgid "Failed!"
-msgstr ""
-
-msgid "CDROM path needs to be a valid local/remote path and cannot be blank."
-msgstr ""
-
-msgid "Disk pool or volume cannot be blank."
-msgstr "������������������������������"
-
-msgid "Filter"
-msgstr ""
-
-msgid "Network Name"
-msgstr "������������"
-
-msgid "State"
-msgstr "������"
-
-msgid "Network Type"
-msgstr "������������"
-
-msgid "Address Space"
-msgstr "������������"
-
-msgid "Name should not contain '/' and '\"'."
-msgstr "������������������������������������������ '/'���"
-
-msgid "Isolated: no external network connection"
-msgstr "������������������������������������"
-
-msgid "NAT: outbound physical network connection only"
-msgstr "NAT���������������������������������"
-
-msgid "Bridged: Virtual machines are connected to physical network directly"
-msgstr "������������������������������������������������������"
-
-msgid "(No interfaces found)"
-msgstr ""
-
-msgid "Destination"
-msgstr "������������"
-
-msgid "Enable VLAN"
-msgstr "������ VLAN���"
-
-msgid "VLAN ID"
-msgstr "VLAN ID���"
-
-msgid "Stop"
-msgstr "������"
-
-msgid "Generate a New Debug Report"
-msgstr "������������������������"
-
-msgid "Report Name"
-msgstr "������������"
-
-msgid ""
-"The name used to identify the report. If omitted, a name will be chosen "
-"based on current time. Name can contain: letters, digits, underscore
(\"_\") "
-"and hyphen (\"-\")."
-msgstr ""
-"������������������������������������������������������������������������������������������������������������������"
-"������������������ (\"-\")���"
-
-msgid "Rename a Debug Report"
-msgstr "������������������������"
-
-msgid ""
-"The name used to identify the report. Name can contain: letters, digits and "
-"hyphen (\"-\")."
-msgstr ""
-"������������������������������������������������������������������������������������������������������������������"
-"������������������ (\"-\")���"
-
-msgid "Submit"
-msgstr ""
-
-msgid "Add a Repository"
-msgstr "���������������"
-
-msgid "Identifier"
-msgstr "ID"
-
-msgid "Single word, unique identifier for the repository."
-msgstr "��������������������������� ID���"
-
-msgid "Textual name for the repository."
-msgstr "���������������������������"
-
-msgid "URL"
-msgstr "URL"
-
-msgid "Required Field"
-msgstr "������������"
-
-msgid "URL to the repository. Supported protocols are http, ftp, and file."
-msgstr "������������ URL��������������������������������� http���ftp ���
file���"
-
-msgid "Repository is a mirror"
-msgstr "���������������������"
-
-msgid "Distribution"
-msgstr "������������"
-
-msgid "Distribution of the DEB repository."
-msgstr "DEB ���������������������������"
-
-msgid "Components"
-msgstr "������"
-
-msgid "List of components in DEB repository."
-msgstr "DEB ������������������������������"
-
-msgid "Edit Repository"
-msgstr "���������������"
-
-msgid "Mirror List URL"
-msgstr "������������ URL"
-
-msgid "Yes"
-msgstr "���"
-
-msgid "No"
-msgstr "���"
-
-msgid "Capacity"
-msgstr "������"
-
-msgid "Allocated"
-msgstr "���������"
-
-msgid "Location"
-msgstr "������"
-
-msgid "Device path"
-msgstr "������������"
-
-msgid "active"
-msgstr "���������"
-
-msgid "inactive"
-msgstr "������������"
-
-msgid "Deactivate"
-msgstr "������������"
-
-msgid "Activate"
-msgstr "������"
-
-msgid "Add Volume"
-msgstr ""
-
-msgid "Extend"
-msgstr ""
-
-msgid "Undefine"
-msgstr "������������"
-
-msgid "Format"
-msgstr "���������"
-
-msgid "Allocation"
-msgstr "���������"
-
-msgid "Define a New Storage Pool"
-msgstr "���������������������"
-
-msgid "Storage Pool Name"
-msgstr "���������������"
-
-msgid ""
-"The name used to identify the storage pools, and it should not be empty."
-msgstr "������������������������������������������������������"
-
-msgid "Storage Pool Type"
-msgstr "���������������"
-
-msgid "Storage Path"
-msgstr "���������������"
-
-msgid ""
-"The path of the Storage Pool. Each Storage Pool must have a unique path."
-msgstr
"���������������������������������������������������������������������������"
-
-msgid ""
-"Kimchi will try to create the directory when it does not already exist in "
-"your system."
-msgstr "Kimchi
������������������������������������������������������������������������"
-
-msgid "NFS Server IP"
-msgstr "NFS ��������� IP"
-
-msgid "NFS server IP or hostname. It can be input or chosen from history."
-msgstr "NFS ��������� IP
���������������������������������������������������������������������"
-
-msgid "NFS Path"
-msgstr "NFS ������"
-
-msgid "The NFS exported path on NFS server."
-msgstr "NFS ������������ NFS ������������������"
-
-msgid "iSCSI Server"
-msgstr "iSCSI ���������"
-
-msgid "Server"
-msgstr "���������"
-
-msgid "Port"
-msgstr "���"
-
-msgid "iSCSI server IP or hostname. It should not be empty."
-msgstr "iSCSI ��������� IP ������������������������������������������"
-
-msgid "Target"
-msgstr "������"
-
-msgid "The iSCSI target on iSCSI server"
-msgstr "iSCSI ��������������� iSCSI ������"
-
-msgid "Add iSCSI Authentication"
-msgstr "������ iSCSI ������"
-
-msgid "iSCSI Authentication"
-msgstr "iSCSI ������"
-
-msgid "User Name"
-msgstr "���������������"
-
-msgid "Password"
-msgstr "������"
-
-msgid "SCSI Adapter"
-msgstr "SCSI ���������"
-
-msgid "Please, wait..."
-msgstr "���������..."
-
-msgid "Add a Volume to Storage Pool"
-msgstr ""
-
-msgid "Fetch from remote URL"
-msgstr ""
-
-msgid "Enter the remote URL here."
-msgstr ""
-
-msgid "Upload a file"
-msgstr ""
-
-msgid "Choose the file you want to upload."
-msgstr ""
-
-msgid "Add Template"
-msgstr "������������"
-
-msgid "Where is the source media for this template? "
-msgstr "���������������������������������������"
-
-msgid "Local ISO Image"
-msgstr "������ ISO ���������"
-
-msgid "Local Image File"
-msgstr ""
-
-msgid "Remote ISO Image"
-msgstr "������ ISO ���������"
-
-msgid "Search ISOs"
-msgstr "������ ISO"
-
-msgid "The following ISOs are available:"
-msgstr "������ ISO ���������"
-
-msgid "OS: "
-msgstr "OS���"
-
-msgid "Version: "
-msgstr "���������"
-
-msgid "Size: "
-msgstr "���������"
-
-msgid "Search more ISOs"
-msgstr "������������ ISO"
-
-msgid "Create Templates from Selected ISO"
-msgstr "��������� ISO ������������"
-
-msgid "I want to use a specific ISO file"
-msgstr "��������������������� ISO ������"
-
-msgid "Loading default remote ISOs ..."
-msgstr "������������������������ ISO ..."
-
-msgid "Arch: "
-msgstr "���������"
-
-msgid "I want to use a custom URL"
-msgstr "������������������ URL"
-
-msgid "Edit Template"
-msgstr "������������"
-
-msgid "CDROM"
-msgstr "CDROM"
-
-msgid "Image File"
-msgstr ""
-
-msgid "Graphics"
-msgstr "���������"
-
-msgid "Disk(GB)"
-msgstr ""
-
-msgid "Disk Format"
-msgstr ""
-
-msgid "CPU Number"
-msgstr "CPU ������"
-
-msgid "Manually set CPU topology"
-msgstr ""
-
-msgid "Cores"
-msgstr ""
-
-msgid "Threads"
-msgstr ""
-
-msgid "No templates found."
-msgstr "������������������"
-
-#~ msgid "Delete is not allowed for %(resource)s"
-#~ msgstr "��������������� %(resource)s ������������"
-
-#~ msgid "%(resource)s does not implement update method"
-#~ msgstr "%(resource)s ���������������������"
-
-#~ msgid "Create is not allowed for %(resource)s"
-#~ msgstr "��������������� %(resource)s ������������"
-
-#~ msgid "Unable to parse JSON request"
-#~ msgstr "������������ JSON ������"
-
-#~ msgid "This API only supports JSON"
-#~ msgstr "��� API ��������� JSON"
-
-#~ msgid "Datastore is not initiated in the model object."
-#~ msgstr "���������������������������������������������"
-
-#~ msgid "Unable to start task due error: %(err)s"
-#~ msgstr "������������������������������������������%(err)s"
-
-#~ msgid ""
-#~ "Authentication failed for user '%(username)s'. [Error code:
%(code)s]"
-#~ msgstr "��������� '%(username)s'
������������������[������������%(code)s]"
-
-#~ msgid "You are not authorized to access Kimchi"
-#~ msgstr "������������������������ Kimchi"
-
-#~ msgid "Specify %(item)s to login into Kimchi"
-#~ msgstr "������ %(item)s ��������� Kimchi"
-
-#~ msgid "Unable to find %(item)s in datastore"
-#~ msgstr "������������������������������ %(item)s"
-
-#~ msgid "Timeout while running command '%(cmd)s' after %(seconds)s
seconds"
-#~ msgstr "������������ '%(cmd)s' %(seconds)s ���������������"
-
-#~ msgid "Help"
-#~ msgstr "������"
-
-#~ msgid "About"
-#~ msgstr "������"
-
-#~ msgid "Log out"
-#~ msgstr "������"
-
-#~ msgid "Version:"
-#~ msgstr "���������"
diff --git a/plugins/kimchi/repositories.py b/plugins/kimchi/repositories.py
deleted file mode 100644
index 9caabc4..0000000
--- a/plugins/kimchi/repositories.py
+++ /dev/null
@@ -1,529 +0,0 @@
-#
-# Project Kimchi
-#
-# Copyright IBM, Corp. 2014-2015
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-
-import copy
-import os
-import time
-import urlparse
-from ConfigParser import ConfigParser
-
-from wok.basemodel import Singleton
-from wok.exception import InvalidOperation, InvalidParameter
-from wok.exception import OperationFailed, NotFoundError, MissingParameter
-from wok.utils import validate_repo_url
-
-from config import kimchiLock
-from yumparser import get_yum_repositories, write_repo_to_file
-
-
-class Repositories(object):
- __metaclass__ = Singleton
-
- """
- Class to represent and operate with repositories information.
- """
- def __init__(self):
- try:
- __import__('yum')
- self._pkg_mnger = YumRepo()
- except ImportError:
- try:
- __import__('apt_pkg')
- self._pkg_mnger = AptRepo()
- except ImportError:
- raise InvalidOperation('KCHREPOS0014E')
-
- def addRepository(self, params):
- """
- Add and enable a new repository
- """
- config = params.get('config', {})
- extra_keys = list(
- set(config.keys()).difference(set(self._pkg_mnger.CONFIG_ENTRY)))
- if len(extra_keys) > 0:
- raise InvalidParameter("KCHREPOS0028E",
- {'items': ",".join(extra_keys)})
-
- return self._pkg_mnger.addRepo(params)
-
- def getRepositories(self):
- """
- Return a dictionary with all Kimchi's repositories. Each element uses
- the format {<repo_id>: {repo}}, where repo is a dictionary in the
- repositories.Repositories() format.
- """
- return self._pkg_mnger.getRepositoriesList()
-
- def getRepository(self, repo_id):
- """
- Return a dictionary with all info from a given repository ID.
- """
- info = self._pkg_mnger.getRepo(repo_id)
- info['repo_id'] = repo_id
- return info
-
- def enableRepository(self, repo_id):
- """
- Enable a repository.
- """
- return self._pkg_mnger.toggleRepo(repo_id, True)
-
- def disableRepository(self, repo_id):
- """
- Disable a given repository.
- """
- return self._pkg_mnger.toggleRepo(repo_id, False)
-
- def updateRepository(self, repo_id, params):
- """
- Update the information of a given repository.
- The input is the repo_id of the repository to be updated and a dict
- with the information to be updated.
- """
- return self._pkg_mnger.updateRepo(repo_id, params)
-
- def removeRepository(self, repo_id):
- """
- Remove a given repository
- """
- return self._pkg_mnger.removeRepo(repo_id)
-
-
-class YumRepo(object):
- """
- Class to represent and operate with YUM repositories.
- It's loaded only on those systems listed at YUM_DISTROS and loads necessary
- modules in runtime.
- """
- TYPE = 'yum'
- DEFAULT_CONF_DIR = "/etc/yum.repos.d"
- CONFIG_ENTRY = ('repo_name', 'mirrorlist', 'metalink')
-
- def __init__(self):
- self._confdir = self.DEFAULT_CONF_DIR
-
- def _get_repos(self, errcode):
- try:
- kimchiLock.acquire()
- repos = get_yum_repositories()
- except Exception, e:
- kimchiLock.release()
- raise OperationFailed(errcode, {'err': str(e)})
- finally:
- kimchiLock.release()
-
- return repos
-
- def getRepositoriesList(self):
- """
- Return a list of repositories IDs
- """
- repos = self._get_repos('KCHREPOS0024E')
- return repos.keys()
-
- def getRepo(self, repo_id):
- """
- Return a dictionary in the repositories.Repositories() of the given
- repository ID format with the information of a YumRepository object.
- """
- repos = self._get_repos('KCHREPOS0025E')
-
- if repo_id not in repos.keys():
- raise NotFoundError("KCHREPOS0012E", {'repo_id': repo_id})
-
- entry = repos.get(repo_id)
-
- info = {}
- info['enabled'] = entry.enabled
- info['baseurl'] = entry.baseurl or ''
- info['config'] = {}
- info['config']['repo_name'] = entry.name or ''
- info['config']['gpgcheck'] = entry.gpgcheck
- info['config']['gpgkey'] = entry.gpgkey or ''
- info['config']['mirrorlist'] = entry.mirrorlist or ''
- info['config']['metalink'] = entry.metalink or ''
- return info
-
- def addRepo(self, params):
- """
- Add a given repository to YumBase
- """
- # At least one base url, or one mirror, must be given.
- baseurl = params.get('baseurl', '')
-
- config = params.get('config', {})
- mirrorlist = config.get('mirrorlist', '')
- metalink = config.get('metalink', '')
- if not baseurl and not mirrorlist and not metalink:
- raise MissingParameter("KCHREPOS0013E")
-
- if baseurl:
- validate_repo_url(baseurl)
-
- if mirrorlist:
- validate_repo_url(mirrorlist)
-
- if metalink:
- validate_repo_url(metalink)
-
- if mirrorlist and metalink:
- raise InvalidOperation('KCHREPOS0030E')
-
- repo_id = params.get('repo_id', None)
- if repo_id is None:
- repo_id = "kimchi_repo_%s" % str(int(time.time() * 1000))
-
- repos = self._get_repos('KCHREPOS0026E')
- if repo_id in repos.keys():
- raise InvalidOperation("KCHREPOS0022E", {'repo_id':
repo_id})
-
- repo_name = config.get('repo_name', repo_id)
- repo = {'baseurl': baseurl, 'mirrorlist': mirrorlist,
- 'name': repo_name, 'gpgcheck': 1,
- 'gpgkey': [], 'enabled': 1, 'metalink':
metalink}
-
- # write a repo file in the system with repo{} information.
- parser = ConfigParser()
- parser.add_section(repo_id)
-
- for key, value in repo.iteritems():
- if value:
- parser.set(repo_id, key, value)
-
- repofile = os.path.join(self._confdir, repo_id + '.repo')
- try:
- with open(repofile, 'w') as fd:
- parser.write(fd)
- except:
- raise OperationFailed("KCHREPOS0018E",
- {'repo_file': repofile})
-
- return repo_id
-
- def toggleRepo(self, repo_id, enable):
- repos = self._get_repos('KCHREPOS0011E')
- if repo_id not in repos.keys():
- raise NotFoundError("KCHREPOS0012E", {'repo_id': repo_id})
-
- entry = repos.get(repo_id)
- if enable and entry.enabled:
- raise InvalidOperation("KCHREPOS0015E", {'repo_id':
repo_id})
-
- if not enable and not entry.enabled:
- raise InvalidOperation("KCHREPOS0016E", {'repo_id':
repo_id})
-
- kimchiLock.acquire()
- try:
- if enable:
- entry.enable()
- else:
- entry.disable()
-
- write_repo_to_file(entry)
- except:
- if enable:
- raise OperationFailed("KCHREPOS0020E", {'repo_id':
repo_id})
-
- raise OperationFailed("KCHREPOS0021E", {'repo_id':
repo_id})
- finally:
- kimchiLock.release()
-
- return repo_id
-
- def updateRepo(self, repo_id, params):
- """
- Update a given repository in repositories.Repositories() format
- """
- repos = self._get_repos('KCHREPOS0011E')
- if repo_id not in repos.keys():
- raise NotFoundError("KCHREPOS0012E", {'repo_id': repo_id})
-
- entry = repos.get(repo_id)
-
- baseurl = params.get('baseurl', None)
- config = params.get('config', {})
- mirrorlist = config.get('mirrorlist', None)
- metalink = config.get('metalink', None)
-
- if baseurl is not None and len(baseurl.strip()) == 0:
- baseurl = None
-
- if mirrorlist is not None and len(mirrorlist.strip()) == 0:
- mirrorlist = None
-
- if metalink is not None and len(metalink.strip()) == 0:
- metalink = None
-
- if baseurl is None and mirrorlist is None and metalink is None:
- raise MissingParameter("KCHREPOS0013E")
-
- if baseurl is not None:
- validate_repo_url(baseurl)
- entry.baseurl = baseurl
-
- if mirrorlist is not None:
- validate_repo_url(mirrorlist)
- entry.mirrorlist = mirrorlist
-
- if metalink is not None:
- validate_repo_url(metalink)
- entry.metalink = metalink
-
- if mirrorlist and metalink:
- raise InvalidOperation('KCHREPOS0030E')
-
- entry.id = params.get('repo_id', repo_id)
- entry.name = config.get('repo_name', entry.name)
- entry.gpgcheck = config.get('gpgcheck', entry.gpgcheck)
- entry.gpgkey = config.get('gpgkey', entry.gpgkey)
- kimchiLock.acquire()
- write_repo_to_file(entry)
- kimchiLock.release()
- return repo_id
-
- def removeRepo(self, repo_id):
- """
- Remove a given repository
- """
- repos = self._get_repos('KCHREPOS0027E')
- if repo_id not in repos.keys():
- raise NotFoundError("KCHREPOS0012E", {'repo_id': repo_id})
-
- entry = repos.get(repo_id)
- parser = ConfigParser()
- with open(entry.repofile) as fd:
- parser.readfp(fd)
-
- if len(parser.sections()) == 1:
- os.remove(entry.repofile)
- return
-
- parser.remove_section(repo_id)
- with open(entry.repofile, "w") as fd:
- parser.write(fd)
-
-
-class AptRepo(object):
- """
- Class to represent and operate with YUM repositories.
- It's loaded only on those systems listed at YUM_DISTROS and loads necessary
- modules in runtime.
- """
- TYPE = 'deb'
- KIMCHI_LIST = "kimchi-source.list"
- CONFIG_ENTRY = ('dist', 'comps')
-
- def __init__(self):
- getattr(__import__('apt_pkg'), 'init_config')()
- getattr(__import__('apt_pkg'), 'init_system')()
- config = getattr(__import__('apt_pkg'), 'config')
- self.pkg_lock = getattr(__import__('apt_pkg'), 'SystemLock')
- module = __import__('aptsources.sourceslist', globals(), locals(),
- ['SourcesList'], -1)
-
- self._sourceparts_path = '/%s%s' % (
- config.get('Dir::Etc'), config.get('Dir::Etc::sourceparts'))
- self._sourceslist = getattr(module, 'SourcesList')
- self.filename = os.path.join(self._sourceparts_path, self.KIMCHI_LIST)
- if not os.path.exists(self.filename):
- with open(self.filename, 'w') as fd:
- fd.write("# This file is managed by Kimchi and it must not "
- "be modified manually\n")
-
- def _get_repos(self):
- try:
- with self.pkg_lock():
- repos = self._sourceslist()
- repos.refresh()
- except Exception, e:
- kimchiLock.release()
- raise OperationFailed('KCHREPOS0025E', {'err': e.message})
-
- return repos
-
- def _get_repo_id(self, repo):
- data = urlparse.urlparse(repo.uri)
- name = data.hostname or data.path
- return '%s-%s-%s' % (name, repo.dist, "-".join(repo.comps))
-
- def _get_source_entry(self, repo_id):
- kimchiLock.acquire()
- repos = self._get_repos()
- kimchiLock.release()
-
- for r in repos:
- # Ignore deb-src repositories
- if r.type != 'deb':
- continue
-
- if self._get_repo_id(r) != repo_id:
- continue
-
- return r
-
- return None
-
- def getRepositoriesList(self):
- """
- Return a list of repositories IDs
-
- APT repositories there aren't the concept about repository ID, so for
- internal control, the repository ID will be built as described in
- _get_repo_id()
- """
- kimchiLock.acquire()
- repos = self._get_repos()
- kimchiLock.release()
-
- res = []
- for r in repos:
- # Ignore deb-src repositories
- if r.type != 'deb':
- continue
-
- res.append(self._get_repo_id(r))
-
- return res
-
- def getRepo(self, repo_id):
- """
- Return a dictionary in the repositories.Repositories() format of the
- given repository ID with the information of a SourceEntry object.
- """
- r = self._get_source_entry(repo_id)
- if r is None:
- raise NotFoundError("KCHREPOS0012E", {'repo_id': repo_id})
-
- info = {'enabled': not r.disabled,
- 'baseurl': r.uri,
- 'config': {'dist': r.dist,
- 'comps': r.comps}}
- return info
-
- def addRepo(self, params):
- """
- Add a new APT repository based on <params>
- """
- # To create a APT repository the dist is a required parameter
- # (in addition to baseurl, verified on controller through API.json)
- config = params.get('config', None)
- if config is None:
- raise MissingParameter("KCHREPOS0019E")
-
- if 'dist' not in config.keys():
- raise MissingParameter("KCHREPOS0019E")
-
- uri = params['baseurl']
- dist = config['dist']
- comps = config.get('comps', [])
-
- validate_repo_url(uri)
-
- kimchiLock.acquire()
- try:
- repos = self._get_repos()
- source_entry = repos.add('deb', uri, dist, comps,
- file=self.filename)
- with self.pkg_lock():
- repos.save()
- except Exception as e:
- kimchiLock.release()
- raise OperationFailed("KCHREPOS0026E", {'err': e.message})
- kimchiLock.release()
- return self._get_repo_id(source_entry)
-
- def toggleRepo(self, repo_id, enable):
- """
- Enable a given repository
- """
- r = self._get_source_entry(repo_id)
- if r is None:
- raise NotFoundError("KCHREPOS0012E", {'repo_id': repo_id})
-
- if enable and not r.disabled:
- raise InvalidOperation("KCHREPOS0015E", {'repo_id':
repo_id})
-
- if not enable and r.disabled:
- raise InvalidOperation("KCHREPOS0016E", {'repo_id':
repo_id})
-
- if enable:
- line = 'deb'
- else:
- line = '#deb'
-
- kimchiLock.acquire()
- try:
- repos = self._get_repos()
- with self.pkg_lock():
- repos.remove(r)
- repos.add(line, r.uri, r.dist, r.comps, file=self.filename)
- repos.save()
- except:
- kimchiLock.release()
- if enable:
- raise OperationFailed("KCHREPOS0020E", {'repo_id':
repo_id})
-
- raise OperationFailed("KCHREPOS0021E", {'repo_id':
repo_id})
- finally:
- kimchiLock.release()
-
- return repo_id
-
- def updateRepo(self, repo_id, params):
- """
- Update a given repository in repositories.Repositories() format
- """
- old_info = self.getRepo(repo_id)
- updated_info = copy.deepcopy(old_info)
- updated_info['baseurl'] = params.get(
- 'baseurl', updated_info['baseurl'])
-
- if 'config' in params.keys():
- config = params['config']
- updated_info['config']['dist'] = config.get(
- 'dist', old_info['config']['dist'])
- updated_info['config']['comps'] = config.get(
- 'comps', old_info['config']['comps'])
-
- self.removeRepo(repo_id)
- try:
- return self.addRepo(updated_info)
- except:
- self.addRepo(old_info)
- raise
-
- def removeRepo(self, repo_id):
- """
- Remove a given repository
- """
- r = self._get_source_entry(repo_id)
- if r is None:
- raise NotFoundError("KCHREPOS0012E", {'repo_id': repo_id})
-
- kimchiLock.acquire()
- try:
- repos = self._get_repos()
- with self.pkg_lock():
- repos.remove(r)
- repos.save()
- except:
- kimchiLock.release()
- raise OperationFailed("KCHREPOS0017E", {'repo_id':
repo_id})
- finally:
- kimchiLock.release()
diff --git a/plugins/kimchi/root.py b/plugins/kimchi/root.py
deleted file mode 100644
index 1e2bfc7..0000000
--- a/plugins/kimchi/root.py
+++ /dev/null
@@ -1,69 +0,0 @@
-#
-# Project Kimchi
-#
-# Copyright IBM, Corp. 2013-2015
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-
-import json
-import os
-import cherrypy
-
-from wok.i18n import messages
-from wok.root import WokRoot
-
-import config
-import mockmodel
-import vnc
-from control import sub_nodes
-from model import model as kimchiModel
-
-
-class KimchiRoot(WokRoot):
- def __init__(self, wok_options):
- if hasattr(wok_options, "model"):
- self.model = wok_options.model
- elif wok_options.test:
- self.model = mockmodel.MockModel()
- else:
- self.model = kimchiModel.Model()
-
- dev_env = wok_options.environment != 'production'
- super(KimchiRoot, self).__init__(self.model, dev_env)
-
- for ident, node in sub_nodes.items():
- setattr(self, ident, node(self.model))
-
- if isinstance(self.model, kimchiModel.Model):
- vnc_ws_proxy = vnc.new_ws_proxy()
- cherrypy.engine.subscribe('exit', vnc_ws_proxy.terminate)
-
- self.api_schema = json.load(open(os.path.join(os.path.dirname(
- os.path.abspath(__file__)), 'API.json')))
- self.paths = config.kimchiPaths
- self.domain = 'kimchi'
- self.messages = messages
-
- make_dirs = [
- os.path.abspath(config.get_distros_store()),
- os.path.abspath(config.get_debugreports_path()),
- os.path.abspath(config.get_screenshot_path())
- ]
- for directory in make_dirs:
- if not os.path.isdir(directory):
- os.makedirs(directory)
-
- def get_custom_conf(self):
- return config.KimchiConfig()
diff --git a/plugins/kimchi/scan.py b/plugins/kimchi/scan.py
deleted file mode 100644
index b475c46..0000000
--- a/plugins/kimchi/scan.py
+++ /dev/null
@@ -1,89 +0,0 @@
-#
-# Project Kimchi
-#
-# Copyright IBM, Corp. 2013-2014
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-#
-
-import glob
-import hashlib
-import os.path
-import shutil
-import tempfile
-import time
-
-from wok.utils import wok_log
-
-from isoinfo import IsoImage, probe_iso
-
-
-SCAN_IGNORE = ['/tmp/kimchi-scan-*']
-
-
-class Scanner(object):
- SCAN_TTL = 300
-
- def __init__(self, record_clean_cb):
- self.clean_cb = record_clean_cb
-
- def delete(self):
- self.clean_stale(-1)
-
- def clean_stale(self, window=SCAN_TTL):
- """
- Clear scan pools generated before time window,
- Clear all scan pools if window is -1.
- """
- try:
- now = time.time()
- clean_list = glob.glob("/tmp/kimchi-scan-*")
- for d in clean_list:
- transient_pool = \
- os.path.basename(d).replace('kimchi-scan-', '')[0:
-6]
- if now - os.path.getmtime(d) > window:
- shutil.rmtree(d)
- self.clean_cb(transient_pool)
- except OSError as e:
- msg = "Exception %s occured when cleaning stale pool, ignore"
- wok_log.debug(msg % e.message)
-
- def scan_dir_prepare(self, name):
- # clean stale scan storage pools
- self.clean_stale()
- return tempfile.mkdtemp(prefix='kimchi-scan-' + name,
dir='/tmp')
-
- def start_scan(self, cb, params):
- def updater(iso_info):
- iso_name = os.path.basename(iso_info['path'])[:-3]
-
- duplicates = "%s/%s*" % (params['pool_path'], iso_name)
- for f in glob.glob(duplicates):
- iso_img = IsoImage(f)
- if (iso_info['distro'], iso_info['version']) == \
- iso_img.probe():
- return
-
- iso_path = iso_name + hashlib.md5(iso_info['path']).hexdigest() + \
- '.iso'
- link_name = os.path.join(params['pool_path'],
- os.path.basename(iso_path))
- os.symlink(iso_info['path'], link_name)
-
- ignore_paths = params.get('ignore_list', [])
- scan_params = dict(path=params['scan_path'], updater=updater,
- ignore_list=ignore_paths + SCAN_IGNORE)
- probe_iso(None, scan_params)
- cb('', True)
diff --git a/plugins/kimchi/screenshot.py b/plugins/kimchi/screenshot.py
deleted file mode 100644
index ffe5a1a..0000000
--- a/plugins/kimchi/screenshot.py
+++ /dev/null
@@ -1,184 +0,0 @@
-#
-# Project Kimchi
-#
-# Copyright IBM, Corp. 2013-2014
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-#
-
-import glob
-import os
-import signal
-import tempfile
-import time
-import uuid
-
-try:
- from PIL import Image
-except ImportError:
- import Image
-
-
-from wok.utils import wok_log
-
-import config
-
-
-(fd, pipe) = tempfile.mkstemp()
-stream_test_result = None
-
-
-class VMScreenshot(object):
- OUTDATED_SECS = 5
- THUMBNAIL_SIZE = (256, 256)
- LIVE_WINDOW = 60
- MAX_STREAM_ATTEMPTS = 10
-
- def __init__(self, args):
- self.vm_uuid = args['uuid']
- args.setdefault('thumbnail',
- os.path.join(config.get_screenshot_path(),
- '%s-%s.png' %
- (self.vm_uuid, str(uuid.uuid4()))))
- self.info = args
-
- @staticmethod
- def get_stream_test_result():
- return stream_test_result
-
- def lookup(self):
- now = time.time()
- try:
- last_update = os.path.getmtime(self.info['thumbnail'])
- except OSError:
- last_update = 0
-
- if now - last_update > self.OUTDATED_SECS:
- self._clean_extra(self.LIVE_WINDOW)
- self._generate_thumbnail()
- return 'plugins/kimchi/data/screenshots/%s' %\
- os.path.basename(self.info['thumbnail'])
-
- def _clean_extra(self, window=-1):
- """
- Clear screenshots before time specified by window,
- Clear all screenshots if window is -1.
- """
- try:
- now = time.time()
- clear_list = glob.glob("%s/%s-*.png" %
- (config.get_screenshot_path(),
- self.vm_uuid))
- for f in clear_list:
- if now - os.path.getmtime(f) > window:
- os.unlink(f)
- except OSError:
- pass
-
- def delete(self):
- return self._clean_extra()
-
- def _generate_scratch(self, thumbnail):
- """
- Generate screenshot of given vm.
- Override me in child class.
- """
- pass
-
- def _create_black_image(self, thumbnail):
- image = Image.new("RGB", self.THUMBNAIL_SIZE, 'black')
- image.save(thumbnail)
-
- def _watch_stream_creation(self, thumbnail):
- """
- This is a verification test for libvirt stream functionality.
-
- It is necessary to avoid the server hangs while creating the screenshot
- image using libvirt stream API.
-
- This problem was found in libvirt 0.9.6 for SLES11 SP2.
-
- This test consists in running the screeshot creation with a timeout.
- If timeout occurs, the libvirt is taking too much time to create the
- screenshot image and the stream must be disabled it if happens
- successively (to avoid blocking server requests).
- """
- pid = os.fork()
- if pid == 0:
- try:
- self._generate_scratch(thumbnail)
- os._exit(0)
- except:
- os._exit(1)
- else:
- counter = 0
- ret = os.waitpid(pid, os.WNOHANG)
- while ret == (0, 0) and counter < 3:
- counter += 1
- time.sleep(1)
- ret = os.waitpid(pid, os.WNOHANG)
-
- fd = open(pipe, "a")
- if ret != (pid, 0):
- fd.write("-")
- if ret[0] != pid:
- os.kill(int(pid), signal.SIGKILL)
- os.waitpid(pid, 0)
- else:
- fd.write("+")
- fd.close()
-
- def _get_test_result(self):
- if not os.path.exists(pipe):
- return
-
- fd = open(pipe, "r")
- data = fd.read()
- fd.close()
-
- if len(data) >= self.MAX_STREAM_ATTEMPTS or bool('+' in data):
- global stream_test_result
- stream_test_result = bool('+' in data)
- os.remove(pipe)
-
- def _generate_thumbnail(self):
- thumbnail = os.path.join(config.get_screenshot_path(), '%s-%s.png' %
- (self.vm_uuid, str(uuid.uuid4())))
-
- self._get_test_result()
- if stream_test_result is None:
- self._watch_stream_creation(thumbnail)
- elif stream_test_result:
- try:
- self._generate_scratch(thumbnail)
- except:
- wok_log.error("screenshot_creation: Unable to create "
- "screenshot image %s." % thumbnail)
- else:
- self._create_black_image(thumbnail)
-
- if os.path.getsize(thumbnail) == 0:
- self._create_black_image(thumbnail)
- else:
- im = Image.open(thumbnail)
- try:
- # Prevent Image lib from lazy load,
- # work around pic truncate validation in thumbnail generation
- im.thumbnail(self.THUMBNAIL_SIZE)
- except Exception as e:
- wok_log.warning("Image load with warning: %s." % e)
- im.save(thumbnail, "PNG")
-
- self.info['thumbnail'] = thumbnail
diff --git a/plugins/kimchi/swupdate.py b/plugins/kimchi/swupdate.py
deleted file mode 100644
index 84b927f..0000000
--- a/plugins/kimchi/swupdate.py
+++ /dev/null
@@ -1,263 +0,0 @@
-#
-# Project Kimchi
-#
-# Copyright IBM, Corp. 2014-2015
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-
-import subprocess
-import time
-
-from wok.basemodel import Singleton
-from wok.exception import NotFoundError, OperationFailed
-from wok.utils import run_command, wok_log
-
-from config import kimchiLock
-from yumparser import get_yum_packages_list_update
-
-
-class SoftwareUpdate(object):
- __metaclass__ = Singleton
-
- """
- Class to represent and operate with OS software update.
- """
- def __init__(self):
- # This stores all packages to be updated for Kimchi perspective. It's a
- # dictionary of dictionaries, in the format {'package_name': package},
- # where:
- # package = {'package_name': <string>, 'version':
<string>,
- # 'arch': <string>, 'repository': <string>
- # }
- self._packages = {}
-
- # This stores the number of packages to update
- self._num2update = 0
-
- # Get the distro of host machine and creates an object related to
- # correct package management system
- try:
- __import__('yum')
- wok_log.info("Loading YumUpdate features.")
- self._pkg_mnger = YumUpdate()
- except ImportError:
- try:
- __import__('apt')
- wok_log.info("Loading AptUpdate features.")
- self._pkg_mnger = AptUpdate()
- except ImportError:
- zypper_help = ["zypper", "--help"]
- (stdout, stderr, returncode) = run_command(zypper_help)
- if returncode == 0:
- wok_log.info("Loading ZypperUpdate features.")
- self._pkg_mnger = ZypperUpdate()
- else:
- raise Exception("There is no compatible package manager "
- "for this system.")
-
- def _scanUpdates(self):
- """
- Update self._packages with packages to be updated.
- """
- self._packages = {}
- self._num2update = 0
-
- # Call system pkg_mnger to get the packages as list of dictionaries.
- for pkg in self._pkg_mnger.getPackagesList():
-
- # Check if already exist a package in self._packages
- pkg_id = pkg.get('package_name')
- if pkg_id in self._packages.keys():
- # package already listed to update. do nothing
- continue
-
- # Update the self._packages and self._num2update
- self._packages[pkg_id] = pkg
- self._num2update = self._num2update + 1
-
- def getUpdates(self):
- """
- Return the self._packages.
- """
- self._scanUpdates()
- return self._packages
-
- def getUpdate(self, name):
- """
- Return a dictionary with all info from a given package name.
- """
- if name not in self._packages.keys():
- raise NotFoundError('KCHPKGUPD0002E', {'name': name})
-
- return self._packages[name]
-
- def getNumOfUpdates(self):
- """
- Return the number of packages to be updated.
- """
- self._scanUpdates()
- return self._num2update
-
- def doUpdate(self, cb, params):
- """
- Execute the update
- """
- # reset messages
- cb('')
-
- cmd = self._pkg_mnger.update_cmd
- proc = subprocess.Popen(cmd, stdout=subprocess.PIPE,
- stderr=subprocess.PIPE)
- msgs = []
- while proc.poll() is None:
- msgs.append(proc.stdout.readline())
- cb(''.join(msgs))
- time.sleep(0.5)
-
- # read the final output lines
- msgs.extend(proc.stdout.readlines())
-
- retcode = proc.poll()
- if retcode == 0:
- return cb(''.join(msgs), True)
-
- msgs.extend(proc.stderr.readlines())
- return cb(''.join(msgs), False)
-
-
-class YumUpdate(object):
- """
- Class to represent and operate with YUM software update system.
- It's loaded only on those systems listed at YUM_DISTROS and loads necessary
- modules in runtime.
- """
- def __init__(self):
- self._pkgs = {}
- self.update_cmd = ["yum", "-y", "update"]
-
- def _refreshUpdateList(self):
- """
- Update the list of packages to be updated in the system.
- """
- try:
- kimchiLock.acquire()
- self._pkgs = get_yum_packages_list_update()
- except Exception, e:
- raise OperationFailed('KCHPKGUPD0003E', {'err': str(e)})
- finally:
- kimchiLock.release()
-
- def getPackagesList(self):
- """
- Return a list of package's dictionaries. Each dictionary contains the
- information about a package, in the format:
- package = {'package_name': <string>, 'version':
<string>,
- 'arch': <string>, 'repository': <string>}
- """
- self._refreshUpdateList()
- pkg_list = []
- for pkg in self._pkgs:
- package = {'package_name': pkg.name, 'version': pkg.version,
- 'arch': pkg.arch, 'repository': pkg.ui_from_repo}
- pkg_list.append(package)
- return pkg_list
-
-
-class AptUpdate(object):
- """
- Class to represent and operate with APT software update system.
- It's loaded only on those systems listed at APT_DISTROS and loads necessary
- modules in runtime.
- """
- def __init__(self):
- self._pkgs = {}
- self.pkg_lock = getattr(__import__('apt_pkg'), 'SystemLock')
- self.update_cmd = ['apt-get', 'upgrade', '-y']
-
- def _refreshUpdateList(self):
- """
- Update the list of packages to be updated in the system.
- """
- apt_cache = getattr(__import__('apt'), 'Cache')()
- try:
- with self.pkg_lock():
- apt_cache.update()
- apt_cache.upgrade()
- self._pkgs = apt_cache.get_changes()
- except Exception, e:
- kimchiLock.release()
- raise OperationFailed('KCHPKGUPD0003E', {'err': e.message})
-
- def getPackagesList(self):
- """
- Return a list of package's dictionaries. Each dictionary contains the
- information about a package, in the format
- package = {'package_name': <string>, 'version':
<string>,
- 'arch': <string>, 'repository': <string>}
- """
- kimchiLock.acquire()
- self._refreshUpdateList()
- kimchiLock.release()
- pkg_list = []
- for pkg in self._pkgs:
- package = {'package_name': pkg.shortname,
- 'version': pkg.candidate.version,
- 'arch': pkg._pkg.architecture,
- 'repository': pkg.candidate.origins[0].label}
- pkg_list.append(package)
-
- return pkg_list
-
-
-class ZypperUpdate(object):
- """
- Class to represent and operate with Zypper software update system.
- It's loaded only on those systems listed at ZYPPER_DISTROS and loads
- necessary modules in runtime.
- """
- def __init__(self):
- self._pkgs = {}
- self.update_cmd = ["zypper", "--non-interactive",
"update",
- "--auto-agree-with-licenses"]
-
- def _refreshUpdateList(self):
- """
- Update the list of packages to be updated in the system.
- """
- self._pkgs = []
- cmd = ["zypper", "list-updates"]
- (stdout, stderr, returncode) = run_command(cmd)
-
- if len(stderr) > 0:
- raise OperationFailed('KCHPKGUPD0003E', {'err': stderr})
-
- for line in stdout.split('\n'):
- if line.find('v |') >= 0:
- info = line.split(' | ')
- package = {'package_name': info[2], 'version': info[4],
- 'arch': info[5], 'repository': info[1]}
- self._pkgs.append(package)
-
- def getPackagesList(self):
- """
- Return a list of package's dictionaries. Each dictionary contains the
- information about a package, in the format
- package = {'package_name': <string>, 'version':
<string>,
- 'arch': <string>, 'repository': <string>}
- """
- kimchiLock.acquire()
- self._refreshUpdateList()
- kimchiLock.release()
- return self._pkgs
diff --git a/plugins/kimchi/template.conf b/plugins/kimchi/template.conf
deleted file mode 100644
index f3615e6..0000000
--- a/plugins/kimchi/template.conf
+++ /dev/null
@@ -1,47 +0,0 @@
-#
-# Configuration file for Kimchi Templates
-#
-
-[main]
-# Memory in MB
-#memory = 1024
-
-# List of networks separated by comma
-# Represents the virtual network interfaces to be assigned to guest
-#networks = default,
-
-[storage]
-# Storage pool used to handle the guest disk
-#pool = default
-
-# Specify multiple [[disk.X]] sub-sections to add multiples disks to guest
-# All the disk files will be created in the same storage pool as set above
-[[disk.0]]
-# Disk size in GB
-#size = 10
-
-# Disk format
-#format = qcow2
-
-[graphics]
-# Graphics type
-# Valid options: vnc | spice
-#type = vnc
-
-# The network which the vnc/spice server listens on
-#listen = 127.0.0.1
-
-[processor]
-# Number of vcpus
-# When specifying CPU topology, make sure cpus value is equal to the product
-# of sockets, cores, and threads.
-#cpus = 1
-
-# Number of sockets (not set by default)
-#sockets =
-
-# Number of cores per socket (not set by default)
-#cores =
-
-# Number of threads per core (not set by default)
-#threads =
diff --git a/plugins/kimchi/tests/Makefile.am b/plugins/kimchi/tests/Makefile.am
deleted file mode 100644
index c1f6784..0000000
--- a/plugins/kimchi/tests/Makefile.am
+++ /dev/null
@@ -1,50 +0,0 @@
-#
-# Kimchi
-#
-# Copyright IBM Corp, 2013
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-
-EXTRA_DIST = \
- Makefile.am \
- run_tests.sh.in \
- test_config.py.in \
- $(filter-out test_config.py, $(wildcard *.py)) \
- $(NULL)
-
-noinst_SCRIPTS = run_tests.sh
-
-do_substitution = \
- sed -e 's,[@]HAVE_PYMOD_UNITTEST[@],$(HAVE_PYMOD_UNITTEST),g' \
- -e 's,[@]prefix[@],$(prefix),g' \
- -e 's,[@]datadir[@],$(datadir),g' \
- -e 's,[@]PYTHON_VERSION[@],$(PYTHON_VERSION),g' \
- -e 's,[@]wokdir[@],$(pythondir)/wok,g' \
- -e 's,[@]pkgdatadir[@],$(pkgdatadir),g'
-
-
-run_tests.sh: run_tests.sh.in Makefile
- $(do_substitution) < $(srcdir)/run_tests.sh.in > run_tests.sh
- chmod +x run_tests.sh
-
-test_config.py: test_config.py.in Makefile
- $(do_substitution) < $(srcdir)/test_config.py.in > test_config.py
-
-check-local:
- $(MKDIR_P) $(top_srcdir)/data/screenshots
- ./run_tests.sh
-
-BUILT_SOURCES = test_config.py
-CLEANFILES = run_tests.sh test_config.py
diff --git a/plugins/kimchi/tests/iso_gen.py b/plugins/kimchi/tests/iso_gen.py
deleted file mode 100644
index 736c660..0000000
--- a/plugins/kimchi/tests/iso_gen.py
+++ /dev/null
@@ -1,212 +0,0 @@
-#
-# Project Kimchi
-#
-# Copyright IBM, Corp. 2013-2015
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-
-import platform
-import struct
-
-from wok.plugins.kimchi.isoinfo import IsoImage
-
-
-iso_des = [
- ('openbsd', lambda v: True,
- lambda v: 'OpenBSD/i386 %s Install CD' % v),
- ('centos', lambda v: True, lambda v: 'CentOS_%s_Final' % v),
- ('windows', '2000', 'W2AFPP'),
- ('windows', 'xp', 'WXPFPP'),
- ('windows', '2003', 'ARMECHK'),
- ('windows', '2003r2', 'CRMEFPP'),
- ('windows', '2008', 'KRTMSVOL'),
- ('windows', '2008r2', 'GRMSXVOL'),
- ('windows', 'vista', 'FB1EVOL'),
- ('windows', '7', 'GRMCULFRER'),
- ('windows', '8', 'HB1_CCPA_X86FRE'),
- ('sles', '10', 'SLES10'),
- ('sles', '11', 'SUSE_SLES-11-0-0'),
- ('opensuse', '11.1', 'SU1110.001'),
- ('opensuse', '11.3', 'openSUSE-DVD-x86_64.0702..001'),
- ('opensuse', '11.4', 'openSUSE-DVD-x86_640024'),
- ('opensuse', '12.1', 'openSUSE-DVD-x86_640039'),
- ('opensuse', '12.2', 'openSUSE-DVD-x86_640167'),
- ('opensuse', lambda v: True, lambda v: 'openSUSE-%s' % v),
- ('rhel', '4.8', 'RHEL/4-U8'),
- ('rhel', lambda v: v.startswith('6.'), lambda v: 'RHEL_%s' %
v),
- ('debian', lambda v: True, lambda v: 'Debian %s' % v),
- ('ubuntu',
- lambda v: v in ('7.10', '8.04', '8.10', '9.04',
'9.10', '10.04', '10.10',
- '11.04', '11.10', '12.04', '12.10',
'13.04', '13.10',
- '14.04'),
- lambda v: 'Ubuntu %s' % v),
- ('fedora',
- lambda v: v in ('16', '17', '18', '19'),
- lambda v: 'Fedora %s' % v)
-]
-
-
-class FakeIsoImage(object):
- def _build_iso(self, fd, iso_volid, bootable):
- if platform.machine().startswith('ppc'):
- self._build_powerpc_bootable_iso(fd, iso_volid)
- return
- self._build_intel_iso(fd, iso_volid, bootable)
-
- def _build_powerpc_bootable_iso(self, fd, iso_volid):
- self._build_prim_vol(fd, iso_volid)
- self._build_bootable_ppc_path_table(fd)
-
- def _build_intel_iso(self, fd, iso_volid, bootable):
- # Do not change the order of the method calls
- self._build_el_boot(fd, bootable)
- self._build_prim_vol(fd, iso_volid)
- self._build_el_torito(fd)
-
- def _build_prim_vol(self, fd, iso_volid):
- fd.seek(16 * IsoImage.SECTOR_SIZE)
- fmt = IsoImage.VOL_DESC
- vd_type = 1
- vd_ident = 'CD001'
- vd_ver = 1
- pad0 = 1
- sys_id = 'fake os'
- vol_id = iso_volid
- data = (vd_type, vd_ident, vd_ver, pad0, sys_id, vol_id)
- s = fmt.pack(*data)
- fd.write(s)
- self._add_sector_padding(fd, s)
-
- def _add_sector_padding(self, fd, s):
- padding_len = IsoImage.SECTOR_SIZE - len(s)
- fmt = struct.Struct('=%ss' % padding_len)
- s = fmt.pack('a' * padding_len)
- fd.write(s)
-
- def _build_el_torito(self, fd):
- fmt = IsoImage.EL_TORITO_BOOT_RECORD
- vd_type = 0
- vd_ident = 'CD001'
- vd_ver = 1
- et_ident = "EL TORITO SPECIFICATION:"
- pad0 = 'a' * 32
- boot_cat = 0
- data = (vd_type, vd_ident, vd_ver, et_ident, pad0, boot_cat)
- s = fmt.pack(*data)
- fd.write(s)
- self._add_sector_padding(fd, s)
-
- def _build_el_boot(self, fd, bootable):
- fmt = IsoImage.EL_TORITO_VALIDATION_ENTRY
- hdr_id = 0
- platform_id = 0
- pad0 = 1
- ident = 'c' * 24
- csum = 1
- key55 = 0x55
- keyAA = 0xaa
- data = (hdr_id, platform_id, pad0, ident, csum, key55, keyAA)
- s = fmt.pack(*data)
- fd.write(s)
-
- fmt = IsoImage.EL_TORITO_BOOT_ENTRY
- if bootable:
- boot = 0x88
- else:
- boot = 0
- media_type = 1
- load_seg = 1
- sys_type = 1
- pad0 = 1
- sectors = 1
- load_rba = 1
- data = (boot, media_type, load_seg, sys_type, pad0, sectors, load_rba)
- s = fmt.pack(*data)
- fd.write(s)
-
- s = 'a' * IsoImage.SECTOR_SIZE
- fd.write(s)
-
- def _build_bootable_ppc_path_table(self, fd):
- # write path table locator
- PATH_TABLE_LOC_OFFSET = 16 * IsoImage.SECTOR_SIZE + 132
- PATH_TABLE_SIZE_LOC = struct.Struct("<I 4s I")
- path_table_size = 64
- path_table_loc = 18
- fd.seek(PATH_TABLE_LOC_OFFSET)
- fmt = PATH_TABLE_SIZE_LOC
- data = (path_table_size, 4*'0', path_table_loc)
- s = fmt.pack(*data)
- fd.write(s)
- # write path table entry
- fd.seek(path_table_loc * IsoImage.SECTOR_SIZE)
- DIR_NAMELEN_LOCATION_PARENT = struct.Struct("<B B I H 3s")
- dir_namelen = 3
- dir_loc = 19
- dir_parent = 1
- dir_name = 'ppc'
- data = (dir_namelen, 0, dir_loc, dir_parent, dir_name)
- fmt = DIR_NAMELEN_LOCATION_PARENT
- s = fmt.pack(*data)
- fd.write(s)
- # write 'ppc' dir record
- ppc_dir_offset = dir_loc * IsoImage.SECTOR_SIZE
- fd.seek(ppc_dir_offset)
- STATIC_DIR_RECORD_FMT = struct.Struct("<B 9s I 11s B 6s B 12s")
- dir_rec_len = 1
- unused1 = 9 * '0'
- dir_size = 100
- unused2 = 11 * '0'
- file_flags = 0
- unused3 = 6 * '0'
- file_name_len = 12
- boot_file_name = "bootinfo.txt"
- data = (dir_rec_len, unused1, dir_size, unused2, file_flags,
- unused3, file_name_len, boot_file_name)
- fmt = STATIC_DIR_RECORD_FMT
- s = fmt.pack(*data)
- fd.write(s)
-
-
-def construct_fake_iso(path, bootable, version, distro):
- iso = FakeIsoImage()
-
- for d, v, gen_id in iso_des:
- if d != distro:
- continue
- if hasattr(v, '__call__'):
- supported = v(version)
- else:
- supported = version == v
-
- if not supported:
- continue
-
- if hasattr(gen_id, '__call__'):
- vol_id = gen_id(version)
- else:
- vol_id = gen_id
- with open(path, 'w') as fd:
- return iso._build_iso(fd, vol_id, bootable)
-
- raise Exception("%s: %s not supported generation" % (distro, version))
-
-
-if __name__ == '__main__':
- construct_fake_iso('centos.iso', True, '6.1', 'centos')
- construct_fake_iso('ubuntu12.04.iso', True, '12.04',
'ubuntu')
- construct_fake_iso('fedora17.iso', True, '17', 'fedora')
- construct_fake_iso('sles10.iso', True, '10', 'sles')
- construct_fake_iso('openbsd.iso', True, '5.0', 'openbsd')
diff --git a/plugins/kimchi/tests/run_tests.sh.in b/plugins/kimchi/tests/run_tests.sh.in
deleted file mode 100644
index beef75e..0000000
--- a/plugins/kimchi/tests/run_tests.sh.in
+++ /dev/null
@@ -1,55 +0,0 @@
-#!/bin/bash
-#
-# Project Kimchi
-#
-# Copyright IBM, Corp. 2013-2015
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-
-HAVE_UNITTEST=@HAVE_PYMOD_UNITTEST@
-PYTHON_VER=@PYTHON_VERSION@
-
-if [ "$1" = "-v" ]; then
- OPTS="-v"
- shift
-else
- OPTS=""
-fi
-
-if [ $# -ne 0 ]; then
- ARGS="$@"
-else
- ARGS=`find -name "test_*.py" | xargs -I @ basename @ .py`
-fi
-
-if [ "$HAVE_UNITTEST" != "yes" -o "$PYTHON_VER" ==
"2.6" ]; then
- CMD="unit2"
-else
- CMD="python -m unittest"
-fi
-
-LIST=($ARGS)
-MODEL_LIST=()
-MOCK_LIST=()
-for ((i=0;i<${#LIST[@]};i++)); do
-
- if [[ ${LIST[$i]} == test_model* ]]; then
- MODEL_LIST+=(${LIST[$i]})
- else
- MOCK_LIST+=(${LIST[$i]})
- fi
-done
-
-PYTHONPATH=../plugins:../src:../ $CMD $OPTS ${MODEL_LIST[@]} ${MOCK_LIST[@]}
diff --git a/plugins/kimchi/tests/test_authorization.py
b/plugins/kimchi/tests/test_authorization.py
deleted file mode 100644
index 87d68ab..0000000
--- a/plugins/kimchi/tests/test_authorization.py
+++ /dev/null
@@ -1,178 +0,0 @@
-#
-# Project Kimchi
-#
-# Copyright IBM, Corp. 2014-2015
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-
-import json
-import os
-import unittest
-from functools import partial
-
-from wok.plugins.kimchi import mockmodel
-
-from iso_gen import construct_fake_iso
-from utils import get_free_port, patch_auth, request
-from utils import run_server, wait_task
-
-
-test_server = None
-model = None
-host = None
-port = None
-ssl_port = None
-fake_iso = '/tmp/fake.iso'
-
-
-def setUpModule():
- global test_server, model, host, port, ssl_port
-
- patch_auth(sudo=False)
- model = mockmodel.MockModel('/tmp/obj-store-test')
- host = '127.0.0.1'
- port = get_free_port('http')
- ssl_port = get_free_port('https')
- test_server = run_server(host, port, ssl_port, test_mode=True, model=model)
-
- # Create fake ISO to do the tests
- construct_fake_iso(fake_iso, True, '12.04', 'ubuntu')
-
-
-def tearDownModule():
- test_server.stop()
- os.unlink('/tmp/obj-store-test')
- os.unlink(fake_iso)
-
-
-class AuthorizationTests(unittest.TestCase):
- def setUp(self):
- self.request = partial(request, host, ssl_port)
- model.reset()
-
- def test_nonroot_access(self):
- # Non-root users can access static host information
- resp = self.request('/plugins/kimchi/host', '{}', 'GET')
- self.assertEquals(403, resp.status)
-
- # Non-root users can access host stats
- resp = self.request('/plugins/kimchi/host/stats', '{}',
'GET')
- self.assertEquals(403, resp.status)
-
- # Non-root users can not reboot/shutdown host system
- resp = self.request('/plugins/kimchi/host/reboot', '{}',
'POST')
- self.assertEquals(403, resp.status)
- resp = self.request('/plugins/kimchi/host/shutdown', '{}',
'POST')
- self.assertEquals(403, resp.status)
-
- # Non-root users can not get or debug reports
- resp = self.request('/plugins/kimchi/debugreports', '{}',
'GET')
- self.assertEquals(403, resp.status)
- resp = self.request('/plugins/kimchi/debugreports', '{}',
'POST')
- self.assertEquals(403, resp.status)
-
- # Non-root users can not create or delete network (only get)
- resp = self.request('/plugins/kimchi/networks', '{}',
'GET')
- self.assertEquals(200, resp.status)
- resp = self.request('/plugins/kimchi/networks', '{}',
'POST')
- self.assertEquals(403, resp.status)
- resp = self.request('/plugins/kimchi/networks/default/activate',
'{}',
- 'POST')
- self.assertEquals(403, resp.status)
- resp = self.request('/plugins/kimchi/networks/default', '{}',
'DELETE')
- self.assertEquals(403, resp.status)
-
- # Non-root users can not create or delete storage pool (only get)
- resp = self.request('/plugins/kimchi/storagepools', '{}',
'GET')
- self.assertEquals(200, resp.status)
- resp = self.request('/plugins/kimchi/storagepools', '{}',
'POST')
- self.assertEquals(403, resp.status)
- resp = self.request('/plugins/kimchi/storagepools/default/activate',
- '{}', 'POST')
- self.assertEquals(403, resp.status)
- resp = self.request('/plugins/kimchi/storagepools/default',
'{}',
- 'DELETE')
- self.assertEquals(403, resp.status)
-
- # Non-root users can not update or delete a template
- # but he can get and create a new one
- resp = self.request('/plugins/kimchi/templates', '{}',
'GET')
- self.assertEquals(403, resp.status)
- req = json.dumps({'name': 'test', 'cdrom': fake_iso})
- resp = self.request('/plugins/kimchi/templates', req, 'POST')
- self.assertEquals(403, resp.status)
- resp = self.request('/plugins/kimchi/templates/test', '{}',
'PUT')
- self.assertEquals(403, resp.status)
- resp = self.request('/plugins/kimchi/templates/test', '{}',
'DELETE')
- self.assertEquals(403, resp.status)
-
- # Non-root users can only get vms authorized to them
- model.templates_create({'name': u'test', 'cdrom':
fake_iso})
-
- task_info = model.vms_create({
- 'name': u'test-me',
- 'template': '/plugins/kimchi/templates/test'
- })
- wait_task(model.task_lookup, task_info['id'])
-
- model.vm_update(u'test-me',
- {'users': [mockmodel.fake_user.keys()[0]],
- 'groups': []})
-
- task_info = model.vms_create({
- 'name': u'test-usera',
- 'template': '/plugins/kimchi/templates/test'
- })
- wait_task(model.task_lookup, task_info['id'])
-
- non_root = list(set(model.users_get_list()) - set(['root']))[0]
- model.vm_update(u'test-usera', {'users': [non_root],
'groups': []})
-
- task_info = model.vms_create({
- 'name': u'test-groupa',
- 'template': '/plugins/kimchi/templates/test'
- })
- wait_task(model.task_lookup, task_info['id'])
- a_group = model.groups_get_list()[0]
- model.vm_update(u'test-groupa', {'groups': [a_group]})
-
- resp = self.request('/plugins/kimchi/vms', '{}', 'GET')
- self.assertEquals(200, resp.status)
- vms_data = json.loads(resp.read())
- self.assertEquals([u'test-groupa', u'test-me'],
- sorted([v['name'] for v in vms_data]))
- resp = self.request('/plugins/kimchi/vms', req, 'POST')
- self.assertEquals(403, resp.status)
-
- # Create a vm using mockmodel directly to test Resource access
- task_info = model.vms_create({
- 'name': 'kimchi-test',
- 'template': '/plugins/kimchi/templates/test'
- })
- wait_task(model.task_lookup, task_info['id'])
- resp = self.request('/plugins/kimchi/vms/kimchi-test', '{}',
'PUT')
- self.assertEquals(403, resp.status)
- resp = self.request('/plugins/kimchi/vms/kimchi-test', '{}',
'DELETE')
- self.assertEquals(403, resp.status)
-
- # Non-root users can only update VMs authorized by them
- resp = self.request('/plugins/kimchi/vms/test-me/start', '{}',
'POST')
- self.assertEquals(200, resp.status)
- resp = self.request('/plugins/kimchi/vms/test-usera/start',
'{}',
- 'POST')
- self.assertEquals(403, resp.status)
-
- model.template_delete('test')
- model.vm_delete('test-me')
diff --git a/plugins/kimchi/tests/test_config.py.in
b/plugins/kimchi/tests/test_config.py.in
deleted file mode 100644
index 4604eb1..0000000
--- a/plugins/kimchi/tests/test_config.py.in
+++ /dev/null
@@ -1,267 +0,0 @@
-#
-# Project Kimchi
-#
-# Copyright IBM, Corp. 2014-2015
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-
-import unittest
-from cherrypy.lib.reprconf import Parser
-
-from wok.config import Paths, PluginPaths, WokConfig
-
-from wok.plugins.kimchi.config import get_debugreports_path
-from wok.plugins.kimchi.config import get_screenshot_path
-from wok.plugins.kimchi.config import KimchiConfig, KimchiPaths
-
-
-get_prefix = None
-
-
-def setUpModule():
- global get_prefix
- get_prefix = Paths.get_prefix
-
-
-def tearDownModule():
- Paths.get_prefix = KimchiPaths.get_prefix = get_prefix
-
-
-class ConfigTests(unittest.TestCase):
- def assertInstalledPath(self, actual, expected):
- if '@pkgdatadir@' != '/usr/share/kimchi':
- usr_local = '/usr/local'
- if not expected.startswith('/usr'):
- expected = usr_local + expected
- self.assertEquals(actual, expected)
-
- def test_installed_paths(self):
- Paths.get_prefix = lambda self: '@datadir@/wok'
- paths = Paths()
- self.assertInstalledPath(paths.state_dir, '/var/lib/wok')
- self.assertInstalledPath(paths.log_dir, '/var/log/wok')
- self.assertInstalledPath(paths.conf_dir, '/etc/wok')
- self.assertInstalledPath(paths.src_dir, '@wokdir@')
- self.assertInstalledPath(paths.plugins_dir, '@wokdir@/plugins')
- self.assertInstalledPath(paths.ui_dir, '@datadir@/wok/ui')
- self.assertInstalledPath(paths.mo_dir, '@prefix@/share/locale')
-
- def test_uninstalled_paths(self):
- Paths.get_prefix = lambda self: '/home/user/wok'
- paths = Paths()
- self.assertEquals(paths.state_dir, '/home/user/wok/data')
- self.assertEquals(paths.log_dir, '/home/user/wok/log')
- self.assertEquals(paths.conf_dir, '/home/user/wok/src')
- self.assertEquals(paths.src_dir, '/home/user/wok/src/wok')
- self.assertEquals(paths.plugins_dir, '/home/user/wok/plugins')
- self.assertEquals(paths.ui_dir, '/home/user/wok/ui')
- self.assertEquals(paths.mo_dir, '/home/user/wok/mo')
-
- def test_installed_plugin_paths(self):
- KimchiPaths.get_prefix = lambda self: '@datadir@/wok'
- paths = KimchiPaths()
- self.assertInstalledPath(paths.conf_dir, '/etc/wok/plugins.d')
- self.assertInstalledPath(paths.conf_file,
- '/etc/wok/plugins.d/kimchi.conf')
- self.assertInstalledPath(paths.src_dir, '@wokdir@/plugins/kimchi')
- self.assertInstalledPath(paths.ui_dir,
- '@datadir@/wok/plugins/kimchi/ui')
- self.assertInstalledPath(paths.mo_dir, '@prefix@/share/locale')
-
- def test_uninstalled_plugin_paths(self):
- KimchiPaths.get_prefix = lambda self: '/home/user/wok'
- paths = KimchiPaths()
- self.assertEquals(paths.conf_dir, '/home/user/wok/plugins/kimchi')
- self.assertEquals(
- paths.conf_file, '/home/user/wok/plugins/kimchi/kimchi.conf')
- self.assertEquals(paths.src_dir, '/home/user/wok/plugins/kimchi')
- self.assertEquals(paths.ui_dir, '/home/user/wok/plugins/kimchi/ui')
- self.assertEquals(paths.mo_dir, '/home/user/wok/plugins/kimchi/mo')
-
- def test_wok_config(self):
- Paths.get_prefix = PluginPaths.get_prefix = get_prefix
- paths = Paths()
- CACHEEXPIRES = 31536000
- SESSIONSTIMEOUT = 10
- configObj = {
- '/': {
- 'tools.trailing_slash.on': False,
- 'request.methods_with_bodies': ('POST', 'PUT'),
- 'tools.nocache.on': True,
- 'tools.proxy.on': True,
- 'tools.sessions.on': True,
- 'tools.sessions.name': 'wok',
- 'tools.sessions.secure': True,
- 'tools.sessions.httponly': True,
- 'tools.sessions.locking': 'explicit',
- 'tools.sessions.storage_type': 'ram',
- 'tools.sessions.timeout': SESSIONSTIMEOUT,
- 'tools.wokauth.on': False
- },
- '/wok-ui.html': {
- 'tools.wokauth.on': True
- },
- '/css': {
- 'tools.staticdir.on': True,
- 'tools.staticdir.dir': '%s/ui/css' % paths.prefix,
- 'tools.expires.on': True,
- 'tools.expires.secs': CACHEEXPIRES,
- 'tools.nocache.on': False,
- 'tools.wokauth.on': False
- },
- '/js': {
- 'tools.staticdir.on': True,
- 'tools.staticdir.dir': '%s/ui/js' % paths.prefix,
- 'tools.expires.on': True,
- 'tools.expires.secs': CACHEEXPIRES,
- 'tools.nocache.on': False,
- 'tools.wokauth.on': False
- },
- '/libs': {
- 'tools.staticdir.on': True,
- 'tools.staticdir.dir': '%s/ui/libs' % paths.prefix,
- 'tools.expires.on': True,
- 'tools.expires.secs': CACHEEXPIRES,
- 'tools.nocache.on': False,
- 'tools.wokauth.on': False
- },
- '/images': {
- 'tools.staticdir.on': True,
- 'tools.staticdir.dir': '%s/ui/images' % paths.prefix,
- 'tools.nocache.on': False,
- 'tools.wokauth.on': False
- },
- '/favicon.ico': {
- 'tools.staticfile.on': True,
- 'tools.staticfile.filename':
- '%s/images/logo.ico' % paths.ui_dir
- },
- '/robots.txt': {
- 'tools.staticfile.on': True,
- 'tools.staticfile.filename': '%s/robots.txt' %
paths.ui_dir
- },
- }
-
- wok_config = WokConfig()
- self.assertEquals(wok_config, configObj)
-
-
- def test_kimchi_config(self):
- KimchiPaths.get_prefix = PluginPaths.get_prefix = get_prefix
- paths = KimchiPaths()
- pluginPrefix = paths.add_prefix(paths.plugin_dir)
- CACHEEXPIRES = 31536000
- SESSIONSTIMEOUT = 10
- configObj = {
- 'wok': {
- 'enable': True,
- 'plugin_class': "KimchiRoot",
- 'uri': '/%s' % paths.plugin_dir,
- 'extra_auth_api_class': "control.sub_nodes"
- },
- '/': {
- 'tools.trailing_slash.on': False,
- 'request.methods_with_bodies': ('POST', 'PUT'),
- 'tools.nocache.on': True,
- 'tools.proxy.on': True,
- 'tools.sessions.on': True,
- 'tools.sessions.name': 'wok',
- 'tools.sessions.secure': True,
- 'tools.sessions.httponly': True,
- 'tools.sessions.locking': 'explicit',
- 'tools.sessions.storage_type': 'ram',
- 'tools.sessions.timeout': SESSIONSTIMEOUT,
- 'tools.wokauth.on': True
- },
- '/novnc': {
- 'tools.staticdir.on': True,
- 'tools.staticdir.dir': paths.novnc_dir,
- 'tools.nocache.on': True,
- 'tools.wokauth.on': True
- },
- '/spice_auto.html': {
- 'tools.staticfile.on': True,
- 'tools.staticfile.filename': paths.spice_file,
- 'tools.nocache.on': True,
- 'tools.wokauth.on': True
- },
- '/spice-html5': {
- 'tools.staticdir.on': True,
- 'tools.staticdir.dir': paths.spice_dir,
- 'tools.nocache.on': True
- },
- '/spice-html5/spice.css': {
- 'tools.staticfile.on': True,
- 'tools.staticfile.filename': paths.spice_css_file,
- 'tools.nocache.on': True,
- },
- '/ui/config/tab-ext.xml': {
- 'tools.staticfile.on': True,
- 'tools.staticfile.filename': '%s/ui/config/tab-ext.xml'
%
- pluginPrefix,
- 'tools.nocache.on': True
- },
- '/css': {
- 'tools.staticdir.on': True,
- 'tools.staticdir.dir': '%s/ui/css' % pluginPrefix,
- 'tools.expires.on': True,
- 'tools.expires.secs': CACHEEXPIRES,
- 'tools.nocache.on': False,
- 'tools.wokauth.on': False
- },
- '/js': {
- 'tools.staticdir.on': True,
- 'tools.staticdir.dir': '%s/ui/js' % pluginPrefix,
- 'tools.expires.on': True,
- 'tools.expires.secs': CACHEEXPIRES,
- 'tools.nocache.on': False,
- 'tools.wokauth.on': False
- },
- '/libs': {
- 'tools.staticdir.on': True,
- 'tools.staticdir.dir': '%s/ui/libs' % pluginPrefix,
- 'tools.expires.on': True,
- 'tools.expires.secs': CACHEEXPIRES,
- 'tools.nocache.on': False,
- 'tools.wokauth.on': False,
- },
- '/images': {
- 'tools.staticdir.on': True,
- 'tools.staticdir.dir': '%s/ui/images' % pluginPrefix,
- 'tools.nocache.on': False,
- 'tools.wokauth.on': False
- },
- '/data/screenshots': {
- 'tools.staticdir.on': True,
- 'tools.staticdir.dir': get_screenshot_path(),
- 'tools.nocache.on': False
- },
- '/data/debugreports': {
- 'tools.staticdir.on': True,
- 'tools.staticdir.dir': get_debugreports_path(),
- 'tools.nocache.on': False,
- 'tools.wokauth.on': True,
- 'tools.staticdir.content_types': {'xz':
'application/x-xz'}
- },
- '/help': {
- 'tools.staticdir.on': True,
- 'tools.staticdir.dir': '%s/ui/pages/help' %
pluginPrefix,
- 'tools.nocache.on': True
- }
- }
-
- kimchi_config = Parser().dict_from_file(KimchiPaths().conf_file)
- kimchi_config.update(KimchiConfig())
- self.assertEquals(kimchi_config, configObj)
diff --git a/plugins/kimchi/tests/test_exception.py
b/plugins/kimchi/tests/test_exception.py
deleted file mode 100644
index 4459aa6..0000000
--- a/plugins/kimchi/tests/test_exception.py
+++ /dev/null
@@ -1,123 +0,0 @@
-#
-# Kimchi
-#
-# Copyright IBM, Corp. 2013-2014
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-
-import json
-import os
-import unittest
-
-from wok.plugins.kimchi import mockmodel
-
-from utils import get_free_port, patch_auth, request, run_server
-
-
-test_server = None
-model = None
-host = None
-port = None
-ssl_port = None
-
-
-def setup_server(environment='development'):
- global test_server, model, host, port, ssl_port
-
- patch_auth()
- model = mockmodel.MockModel('/tmp/obj-store-test')
- host = '127.0.0.1'
- port = get_free_port('http')
- ssl_port = get_free_port('https')
- test_server = run_server(host, port, ssl_port, test_mode=True, model=model,
- environment=environment)
-
-
-class ExceptionTests(unittest.TestCase):
- def tearDown(self):
- test_server.stop()
- os.unlink('/tmp/obj-store-test')
-
- def test_production_env(self):
- """
- Test reasons sanitized in production env
- """
- setup_server('production')
- # test 404
- resp = json.loads(
- request(host, ssl_port, '/plugins/kimchi/vms/blah').read()
- )
- self.assertEquals('404 Not Found', resp.get('code'))
-
- # test 405 wrong method
- resp = json.loads(request(host, ssl_port, '/', None,
'DELETE').read())
- msg = u'WOKAPI0002E: Delete is not allowed for wokroot'
- self.assertEquals('405 Method Not Allowed', resp.get('code'))
- self.assertEquals(msg, resp.get('reason'))
-
- # test 400 parse error
- resp = json.loads(
- request(host, ssl_port, '/plugins/kimchi/vms', '{',
'POST').read()
- )
- msg = u'WOKAPI0006E: Unable to parse JSON request'
- self.assertEquals('400 Bad Request', resp.get('code'))
- self.assertEquals(msg, resp.get('reason'))
- self.assertNotIn('call_stack', resp)
-
- # test 400 missing required parameter
- req = json.dumps({})
- resp = json.loads(
- request(host, ssl_port, '/plugins/kimchi/vms', req,
'POST').read()
- )
- self.assertEquals('400 Bad Request', resp.get('code'))
- m = u"KCHVM0016E: Specify a template to create a virtual machine from"
- self.assertEquals(m, resp.get('reason'))
- self.assertNotIn('call_stack', resp)
-
- def test_development_env(self):
- """
- Test traceback thrown in development env
- """
- setup_server()
- # test 404
- resp = json.loads(
- request(host, ssl_port, '/plugins/kimchi/vms/blah').read()
- )
- self.assertEquals('404 Not Found', resp.get('code'))
-
- # test 405 wrong method
- resp = json.loads(request(host, ssl_port, '/', None,
'DELETE').read())
- msg = u'WOKAPI0002E: Delete is not allowed for wokroot'
- self.assertEquals('405 Method Not Allowed', resp.get('code'))
- self.assertEquals(msg, resp.get('reason'))
-
- # test 400 parse error
- resp = json.loads(
- request(host, ssl_port, '/plugins/kimchi/vms', '{',
'POST').read()
- )
- msg = u'WOKAPI0006E: Unable to parse JSON request'
- self.assertEquals('400 Bad Request', resp.get('code'))
- self.assertEquals(msg, resp.get('reason'))
- self.assertIn('call_stack', resp)
-
- # test 400 missing required parameter
- req = json.dumps({})
- resp = json.loads(
- request(host, ssl_port, '/plugins/kimchi/vms', req,
'POST').read()
- )
- m = u"KCHVM0016E: Specify a template to create a virtual machine from"
- self.assertEquals('400 Bad Request', resp.get('code'))
- self.assertEquals(m, resp.get('reason'))
- self.assertIn('call_stack', resp)
diff --git a/plugins/kimchi/tests/test_host.py b/plugins/kimchi/tests/test_host.py
deleted file mode 100644
index 6cd0833..0000000
--- a/plugins/kimchi/tests/test_host.py
+++ /dev/null
@@ -1,206 +0,0 @@
-# -*- coding: utf-8 -*-
-#
-# Project Kimchi
-#
-# Copyright IBM, Corp. 2015
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-
-import json
-import os
-import platform
-import psutil
-import tempfile
-import time
-import unittest
-from functools import partial
-
-from wok.plugins.kimchi.mockmodel import MockModel
-
-from utils import get_free_port, patch_auth, request, run_server, wait_task
-
-
-test_server = None
-model = None
-host = None
-ssl_port = None
-tmpfile = None
-
-
-def setUpModule():
- global test_server, model, host, ssl_port, tmpfile
-
- patch_auth()
- tmpfile = tempfile.mktemp()
- model = MockModel(tmpfile)
- host = '127.0.0.1'
- port = get_free_port('http')
- ssl_port = get_free_port('https')
- cherrypy_port = get_free_port('cherrypy_port')
- test_server = run_server(host, port, ssl_port, test_mode=True,
- cherrypy_port=cherrypy_port, model=model)
-
-
-def tearDownModule():
- test_server.stop()
- os.unlink(tmpfile)
-
-
-class HostTests(unittest.TestCase):
- def setUp(self):
- self.request = partial(request, host, ssl_port)
-
- def test_hostinfo(self):
- resp = self.request('/plugins/kimchi/host').read()
- info = json.loads(resp)
- keys = ['os_distro', 'os_version', 'os_codename',
'cpu_model',
- 'memory', 'cpus']
- self.assertEquals(sorted(keys), sorted(info.keys()))
-
- distro, version, codename = platform.linux_distribution()
- self.assertEquals(distro, info['os_distro'])
- self.assertEquals(version, info['os_version'])
- self.assertEquals(unicode(codename, "utf-8"),
info['os_codename'])
- self.assertEquals(psutil.TOTAL_PHYMEM, info['memory'])
-
- def test_hoststats(self):
- time.sleep(1)
- stats_keys = ['cpu_utilization', 'memory',
'disk_read_rate',
- 'disk_write_rate', 'net_recv_rate',
'net_sent_rate']
- resp = self.request('/plugins/kimchi/host/stats').read()
- stats = json.loads(resp)
- self.assertEquals(sorted(stats_keys), sorted(stats.keys()))
-
- cpu_utilization = stats['cpu_utilization']
- self.assertIsInstance(cpu_utilization, float)
- self.assertGreaterEqual(cpu_utilization, 0.0)
- self.assertTrue(cpu_utilization <= 100.0)
-
- memory_stats = stats['memory']
- self.assertIn('total', memory_stats)
- self.assertIn('free', memory_stats)
- self.assertIn('cached', memory_stats)
- self.assertIn('buffers', memory_stats)
- self.assertIn('avail', memory_stats)
-
- resp = self.request('/plugins/kimchi/host/stats/history').read()
- history = json.loads(resp)
- self.assertEquals(sorted(stats_keys), sorted(history.keys()))
-
- def test_host_actions(self):
- def _task_lookup(taskid):
- return json.loads(
- self.request('/plugins/kimchi/tasks/%s' % taskid).read()
- )
-
- resp = self.request('/plugins/kimchi/host/shutdown', '{}',
'POST')
- self.assertEquals(200, resp.status)
- resp = self.request('/plugins/kimchi/host/reboot', '{}',
'POST')
- self.assertEquals(200, resp.status)
-
- # Test system update
- resp = self.request('/plugins/kimchi/host/packagesupdate', None,
'GET')
- pkgs = json.loads(resp.read())
- self.assertEquals(3, len(pkgs))
-
- pkg_keys = ['package_name', 'repository', 'arch',
'version']
- for p in pkgs:
- name = p['package_name']
- resp = self.request('/plugins/kimchi/host/packagesupdate/' + name,
- None, 'GET')
- info = json.loads(resp.read())
- self.assertEquals(sorted(pkg_keys), sorted(info.keys()))
-
- resp = self.request('/plugins/kimchi/host/swupdate', '{}',
'POST')
- task = json.loads(resp.read())
- task_params = [u'id', u'message', u'status',
u'target_uri']
- self.assertEquals(sorted(task_params), sorted(task.keys()))
-
- resp = self.request('/tasks/' + task[u'id'], None,
- 'GET')
- task_info = json.loads(resp.read())
- self.assertEquals(task_info['status'], 'running')
- wait_task(_task_lookup, task_info['id'])
- resp = self.request('/tasks/' + task[u'id'], None,
- 'GET')
- task_info = json.loads(resp.read())
- self.assertEquals(task_info['status'], 'finished')
- self.assertIn(u'All packages updated', task_info['message'])
- pkgs = model.packagesupdate_get_list()
- self.assertEquals(0, len(pkgs))
-
- def test_host_partitions(self):
- resp = self.request('/plugins/kimchi/host/partitions')
- self.assertEquals(200, resp.status)
- partitions = json.loads(resp.read())
-
- keys = ['name', 'path', 'type', 'fstype',
'size', 'mountpoint',
- 'available']
- for item in partitions:
- resp = self.request('/plugins/kimchi/host/partitions/%s' %
- item['name'])
- info = json.loads(resp.read())
- self.assertEquals(sorted(info.keys()), sorted(keys))
-
- def test_host_devices(self):
- def asset_devices_type(devices, dev_type):
- for dev in devices:
- self.assertEquals(dev['device_type'], dev_type)
-
- resp = self.request('/plugins/kimchi/host/devices?_cap=scsi_host')
- nodedevs = json.loads(resp.read())
- # Mockmodel brings 3 preconfigured scsi fc_host
- self.assertEquals(3, len(nodedevs))
-
- nodedev = json.loads(
- self.request('/plugins/kimchi/host/devices/scsi_host2').read()
- )
- # Mockmodel generates random wwpn and wwnn
- self.assertEquals('scsi_host2', nodedev['name'])
- self.assertEquals('fc_host', nodedev['adapter']['type'])
- self.assertEquals(16, len(nodedev['adapter']['wwpn']))
- self.assertEquals(16, len(nodedev['adapter']['wwnn']))
-
- devs = json.loads(self.request('/plugins/kimchi/host/devices').read())
- dev_names = [dev['name'] for dev in devs]
- for dev_type in ('pci', 'usb_device', 'scsi'):
- resp = self.request('/plugins/kimchi/host/devices?_cap=%s' %
- dev_type)
- devsByType = json.loads(resp.read())
- names = [dev['name'] for dev in devsByType]
- self.assertTrue(set(names) <= set(dev_names))
- asset_devices_type(devsByType, dev_type)
-
- resp = self.request('/plugins/kimchi/host/devices?_passthrough=true')
- passthru_devs = [dev['name'] for dev in json.loads(resp.read())]
- self.assertTrue(set(passthru_devs) <= set(dev_names))
-
- for dev_type in ('pci', 'usb_device', 'scsi'):
- resp = self.request(
- '/plugins/kimchi/host/devices?_cap=%s&_passthrough=true' %
- dev_type
- )
- filteredDevs = json.loads(resp.read())
- filteredNames = [dev['name'] for dev in filteredDevs]
- self.assertTrue(set(filteredNames) <= set(dev_names))
- asset_devices_type(filteredDevs, dev_type)
-
- for dev in passthru_devs:
- resp = self.request(
- '/plugins/kimchi/host/devices?_passthrough_affected_by=%s' %
- dev
- )
- affected_devs = [dev['name'] for dev in json.loads(resp.read())]
- self.assertTrue(set(affected_devs) <= set(dev_names))
diff --git a/plugins/kimchi/tests/test_mock_network.py
b/plugins/kimchi/tests/test_mock_network.py
deleted file mode 100644
index 4e2a939..0000000
--- a/plugins/kimchi/tests/test_mock_network.py
+++ /dev/null
@@ -1,73 +0,0 @@
-# -*- coding: utf-8 -*-
-#
-# Project Kimchi
-#
-# Copyright IBM, Corp. 2015
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-
-import json
-import os
-import unittest
-from functools import partial
-
-from wok.plugins.kimchi.mockmodel import MockModel
-
-from test_model_network import _do_network_test
-from utils import get_free_port, patch_auth, request, run_server
-
-
-model = None
-test_server = None
-host = None
-port = None
-ssl_port = None
-cherrypy_port = None
-
-
-def setUpModule():
- global test_server, model, host, port, ssl_port, cherrypy_port
-
- patch_auth()
- model = MockModel('/tmp/obj-store-test')
- host = '127.0.0.1'
- port = get_free_port('http')
- ssl_port = get_free_port('https')
- cherrypy_port = get_free_port('cherrypy_port')
- test_server = run_server(host, port, ssl_port, test_mode=True,
- cherrypy_port=cherrypy_port, model=model)
-
-
-def tearDownModule():
- test_server.stop()
- os.unlink('/tmp/obj-store-test')
-
-
-class MockNetworkTests(unittest.TestCase):
- def setUp(self):
- self.request = partial(request, host, ssl_port)
- model.reset()
-
- def test_vlan_tag_bridge(self):
- # Verify the current system has at least one interface to create a
- # bridged network
- interfaces = json.loads(
- self.request('/plugins/kimchi/interfaces?type=nic').read()
- )
- if len(interfaces) > 0:
- iface = interfaces[0]['name']
- _do_network_test(self, model, {'name': u'bridge-network',
- 'connection': 'bridge',
- 'interface': iface, 'vlan_id':
987})
diff --git a/plugins/kimchi/tests/test_mock_storagepool.py
b/plugins/kimchi/tests/test_mock_storagepool.py
deleted file mode 100644
index 5cf5b3e..0000000
--- a/plugins/kimchi/tests/test_mock_storagepool.py
+++ /dev/null
@@ -1,147 +0,0 @@
-# -*- coding: utf-8 -*-
-#
-# Project Kimchi
-#
-# Copyright IBM, Corp. 2015
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-
-import json
-import os
-import unittest
-from functools import partial
-
-from wok.plugins.kimchi.mockmodel import MockModel
-
-from utils import get_free_port, patch_auth, request, run_server
-
-
-model = None
-test_server = None
-host = None
-port = None
-ssl_port = None
-cherrypy_port = None
-
-
-def setUpModule():
- global test_server, model, host, port, ssl_port, cherrypy_port
-
- patch_auth()
- model = MockModel('/tmp/obj-store-test')
- host = '127.0.0.1'
- port = get_free_port('http')
- ssl_port = get_free_port('https')
- cherrypy_port = get_free_port('cherrypy_port')
- test_server = run_server(host, port, ssl_port, test_mode=True,
- cherrypy_port=cherrypy_port, model=model)
-
-
-def tearDownModule():
- test_server.stop()
- os.unlink('/tmp/obj-store-test')
-
-
-class MockStoragepoolTests(unittest.TestCase):
- def setUp(self):
- self.request = partial(request, host, ssl_port)
- model.reset()
-
- def _task_lookup(self, taskid):
- return json.loads(
- self.request('/tasks/%s' % taskid).read()
- )
-
- def test_storagepool(self):
- # MockModel always returns 2 partitions (vdx, vdz)
- partitions = json.loads(
- self.request('/plugins/kimchi/host/partitions').read()
- )
- devs = [dev['path'] for dev in partitions]
-
- # MockModel always returns 3 FC devices
- fc_devs = json.loads(
- self.request('/plugins/kimchi/host/devices?_cap=fc_host').read()
- )
- fc_devs = [dev['name'] for dev in fc_devs]
-
- poolDefs = [
- {'type': 'dir', 'name':
u'k������h��UnitTestDirPool',
- 'path': '/tmp/kimchi-images'},
- {'type': 'netfs', 'name':
u'k������h��UnitTestNSFPool',
- 'source': {'host': 'localhost',
- 'path': '/var/lib/kimchi/nfs-pool'}},
- {'type': 'scsi', 'name':
u'k������h��UnitTestSCSIFCPool',
- 'source': {'adapter_name': fc_devs[0]}},
- {'type': 'iscsi', 'name':
u'k������h��UnitTestISCSIPool',
- 'source': {'host': '127.0.0.1',
- 'target':
'iqn.2015-01.localhost.kimchiUnitTest'}},
- {'type': 'logical', 'name':
u'k������h��UnitTestLogicalPool',
- 'source': {'devices': [devs[0]]}}]
-
- def _do_test(params):
- name = params['name']
- uri = '/plugins/kimchi/storagepools/%s' %
name.encode('utf-8')
-
- req = json.dumps(params)
- resp = self.request('/plugins/kimchi/storagepools', req,
'POST')
- self.assertEquals(201, resp.status)
-
- # activate the storage pool
- resp = self.request(uri + '/activate', '{}', 'POST')
- storagepool = json.loads(self.request(uri).read())
- self.assertEquals('active', storagepool['state'])
-
- # Set autostart flag of an active storage pool
- for autostart in [True, False]:
- t = {'autostart': autostart}
- req = json.dumps(t)
- resp = self.request(uri, req, 'PUT')
- storagepool = json.loads(self.request(uri).read())
- self.assertEquals(autostart, storagepool['autostart'])
-
- # Extend an active logical pool
- if params['type'] == 'logical':
- t = {'disks': [devs[1]]}
- req = json.dumps(t)
- resp = self.request(uri, req, 'PUT')
- self.assertEquals(200, resp.status)
-
- # Deactivate the storage pool
- resp = self.request(uri + '/deactivate', '{}',
'POST')
- storagepool = json.loads(self.request(uri).read())
- self.assertEquals('inactive', storagepool['state'])
-
- # Set autostart flag of an inactive storage pool
- for autostart in [True, False]:
- t = {'autostart': autostart}
- req = json.dumps(t)
- resp = self.request(uri, req, 'PUT')
- storagepool = json.loads(self.request(uri).read())
- self.assertEquals(autostart, storagepool['autostart'])
-
- # Extend an inactive logical pool
- if params['type'] == 'logical':
- t = {'disks': [devs[1]]}
- req = json.dumps(t)
- resp = self.request(uri, req, 'PUT')
- self.assertEquals(200, resp.status)
-
- # Delete the storage pool
- resp = self.request(uri, '{}', 'DELETE')
- self.assertEquals(204, resp.status)
-
- for pool in poolDefs:
- _do_test(pool)
diff --git a/plugins/kimchi/tests/test_mock_storagevolume.py
b/plugins/kimchi/tests/test_mock_storagevolume.py
deleted file mode 100644
index 9d0a5ad..0000000
--- a/plugins/kimchi/tests/test_mock_storagevolume.py
+++ /dev/null
@@ -1,98 +0,0 @@
-# -*- coding: utf-8 -*-
-#
-# Project Kimchi
-#
-# Copyright IBM, Corp. 2015
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-
-import json
-import os
-import unittest
-from functools import partial
-
-from wok.plugins.kimchi.mockmodel import MockModel
-
-from test_model_storagevolume import _do_volume_test
-from utils import get_free_port, patch_auth, request, run_server
-
-
-model = None
-test_server = None
-host = None
-port = None
-ssl_port = None
-cherrypy_port = None
-
-
-def setUpModule():
- global test_server, model, host, port, ssl_port, cherrypy_port
-
- patch_auth()
- model = MockModel('/tmp/obj-store-test')
- host = '127.0.0.1'
- port = get_free_port('http')
- ssl_port = get_free_port('https')
- cherrypy_port = get_free_port('cherrypy_port')
- test_server = run_server(host, port, ssl_port, test_mode=True,
- cherrypy_port=cherrypy_port, model=model)
-
-
-def tearDownModule():
- test_server.stop()
- os.unlink('/tmp/obj-store-test')
-
-
-class MockStorageVolumeTests(unittest.TestCase):
- def setUp(self):
- self.request = partial(request, host, ssl_port)
-
- def test_storagevolume(self):
- # MockModel always returns 2 partitions (vdx, vdz)
- partitions = json.loads(
- self.request('/plugins/kimchi/host/partitions').read()
- )
- devs = [dev['path'] for dev in partitions]
-
- # MockModel always returns 3 FC devices
- fc_devs = json.loads(
- self.request('/plugins/kimchi/host/devices?_cap=fc_host').read()
- )
- fc_devs = [dev['name'] for dev in fc_devs]
-
- poolDefs = [
- {'type': 'dir', 'name':
u'k������h��UnitTestDirPool',
- 'path': '/tmp/kimchi-images'},
- {'type': 'netfs', 'name':
u'k������h��UnitTestNSFPool',
- 'source': {'host': 'localhost',
- 'path': '/var/lib/kimchi/nfs-pool'}},
- {'type': 'scsi', 'name':
u'k������h��UnitTestSCSIFCPool',
- 'source': {'adapter_name': fc_devs[0]}},
- {'type': 'iscsi', 'name':
u'k������h��UnitTestISCSIPool',
- 'source': {'host': '127.0.0.1',
- 'target':
'iqn.2015-01.localhost.kimchiUnitTest'}},
- {'type': 'logical', 'name':
u'k������h��UnitTestLogicalPool',
- 'source': {'devices': [devs[0]]}}]
-
- for pool in poolDefs:
- pool_name = pool['name']
- uri = '/plugins/kimchi/storagepools/%s' %
pool_name.encode('utf-8')
- req = json.dumps(pool)
- resp = self.request('/plugins/kimchi/storagepools', req,
'POST')
- self.assertEquals(201, resp.status)
- # activate the storage pool
- resp = self.request(uri + '/activate', '{}', 'POST')
- self.assertEquals(200, resp.status)
- _do_volume_test(self, model, host, ssl_port, pool_name)
diff --git a/plugins/kimchi/tests/test_mockmodel.py
b/plugins/kimchi/tests/test_mockmodel.py
deleted file mode 100644
index ffbf8d5..0000000
--- a/plugins/kimchi/tests/test_mockmodel.py
+++ /dev/null
@@ -1,141 +0,0 @@
-#
-# Project Kimchi
-#
-# Copyright IBM, Corp. 2013-2015
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-
-import cherrypy
-import json
-import os
-import time
-import unittest
-
-from wok.plugins.kimchi import mockmodel
-from wok.plugins.kimchi.osinfo import get_template_default
-
-from utils import get_free_port, patch_auth, request, run_server, wait_task
-
-
-test_server = None
-model = None
-host = None
-port = None
-ssl_port = None
-fake_iso = None
-
-
-def setUpModule():
- global host, port, ssl_port, model, test_server, fake_iso
- cherrypy.request.headers = {'Accept': 'application/json'}
- model = mockmodel.MockModel('/tmp/obj-store-test')
- patch_auth()
- port = get_free_port('http')
- ssl_port = get_free_port('https')
- host = '127.0.0.1'
- test_server = run_server(host, port, ssl_port, test_mode=True,
- model=model)
- fake_iso = '/tmp/fake.iso'
- open(fake_iso, 'w').close()
-
-
-def tearDown():
- test_server.stop()
- os.unlink('/tmp/obj-store-test')
- os.unlink(fake_iso)
-
-
-class MockModelTests(unittest.TestCase):
- def setUp(self):
- model.reset()
-
- def test_screenshot_refresh(self):
- # Create a VM
- req = json.dumps({'name': 'test', 'cdrom': fake_iso})
- request(host, ssl_port, '/plugins/kimchi/templates', req,
'POST')
- req = json.dumps({'name': 'test-vm', 'template':
'/templates/test'})
- resp = request(host, ssl_port, '/plugins/kimchi/vms', req,
'POST')
- task = json.loads(resp.read())
- wait_task(model.task_lookup, task['id'])
-
- # Test screenshot refresh for running vm
- request(host, ssl_port, '/plugins/kimchi/vms/test-vm/start',
'{}',
- 'POST')
- resp = request(host, ssl_port,
- '/plugins/kimchi/vms/test-vm/screenshot')
- self.assertEquals(200, resp.status)
- self.assertEquals('image/png', resp.getheader('content-type'))
- resp1 = request(host, ssl_port, '/plugins/kimchi/vms/test-vm')
- rspBody = resp1.read()
- testvm_Data = json.loads(rspBody)
- screenshotURL = testvm_Data['screenshot']
- time.sleep(5)
- resp2 = request(host, ssl_port, screenshotURL)
- self.assertEquals(200, resp2.status)
- self.assertEquals(resp2.getheader('content-type'),
- resp.getheader('content-type'))
- self.assertEquals(resp2.getheader('content-length'),
- resp.getheader('content-length'))
- self.assertEquals(resp2.getheader('last-modified'),
- resp.getheader('last-modified'))
-
- def test_vm_list_sorted(self):
- req = json.dumps({'name': 'test', 'cdrom': fake_iso})
- request(host, ssl_port, '/plugins/kimchi/templates', req,
'POST')
-
- def add_vm(name):
- # Create a VM
- req = json.dumps({'name': name,
- 'template':
'/plugins/kimchi/templates/test'})
- task = json.loads(request(host, ssl_port, '/plugins/kimchi/vms',
- req, 'POST').read())
- wait_task(model.task_lookup, task['id'])
-
- vms = [u'abc', u'bca', u'cab', u'xba']
- for vm in vms:
- add_vm(vm)
-
- vms.append(u'test')
- self.assertEqual(model.vms_get_list(), sorted(vms))
-
- def test_vm_info(self):
- model.templates_create({'name': u'test',
- 'cdrom': fake_iso})
- task = model.vms_create({'name': u'test-vm',
- 'template':
'/plugins/kimchi/templates/test'})
- wait_task(model.task_lookup, task['id'])
- vms = model.vms_get_list()
- self.assertEquals(2, len(vms))
- self.assertIn(u'test-vm', vms)
-
- keys = set(('name', 'state', 'stats', 'uuid',
'memory', 'cpus',
- 'screenshot', 'icon', 'graphics',
'users', 'groups',
- 'access', 'persistent'))
-
- stats_keys = set(('cpu_utilization',
- 'net_throughput', 'net_throughput_peak',
- 'io_throughput', 'io_throughput_peak'))
-
- info = model.vm_lookup(u'test-vm')
- self.assertEquals(keys, set(info.keys()))
- self.assertEquals('shutoff', info['state'])
- self.assertEquals('test-vm', info['name'])
- self.assertEquals(get_template_default('old', 'memory'),
- info['memory'])
- self.assertEquals(1, info['cpus'])
- self.assertEquals('images/icon-vm.png', info['icon'])
- self.assertEquals(stats_keys, set(info['stats'].keys()))
- self.assertEquals('vnc', info['graphics']['type'])
- self.assertEquals('127.0.0.1',
info['graphics']['listen'])
diff --git a/plugins/kimchi/tests/test_model.py b/plugins/kimchi/tests/test_model.py
deleted file mode 100644
index 7c89048..0000000
--- a/plugins/kimchi/tests/test_model.py
+++ /dev/null
@@ -1,1248 +0,0 @@
-# -*- coding: utf-8 -*-
-#
-# Project Kimchi
-#
-# Copyright IBM, Corp. 2013-2015
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-
-import grp
-import os
-import pwd
-import re
-import shutil
-import time
-import unittest
-import uuid
-
-import wok.objectstore
-from wok.basemodel import Singleton
-from wok.config import config
-from wok.exception import InvalidOperation
-from wok.exception import InvalidParameter, NotFoundError, OperationFailed
-from wok.rollbackcontext import RollbackContext
-from wok.utils import add_task
-
-from wok.plugins.kimchi import netinfo
-from wok.plugins.kimchi.osinfo import get_template_default
-from wok.plugins.kimchi.model import model
-from wok.plugins.kimchi.model.libvirtconnection import LibvirtConnection
-
-import iso_gen
-import utils
-
-
-invalid_repository_urls = ['www.fedora.org', # missing protocol
- '://www.fedora.org', # missing protocol
- 'http://www.fedora', # invalid domain name
- 'file:///home/foobar'] # invalid path
-
-TMP_DIR = '/var/lib/kimchi/tests/'
-UBUNTU_ISO = TMP_DIR + 'ubuntu14.04.iso'
-
-
-def setUpModule():
- if not os.path.exists(TMP_DIR):
- os.makedirs(TMP_DIR)
-
- iso_gen.construct_fake_iso(UBUNTU_ISO, True, '14.04', 'ubuntu')
-
- # Some FeatureTests functions depend on server to validate their result.
- # As CapabilitiesModel is a Singleton class it will get the first result
- # from FeatureTests which may be wrong when using the Model instance
- # directly - the case of this test_model.py
- # So clean Singleton instances to make sure to get the right result when
- # running the following tests.
- Singleton._instances = {}
-
-
-def tearDownModule():
- shutil.rmtree(TMP_DIR)
-
-
-class ModelTests(unittest.TestCase):
- def setUp(self):
- self.tmp_store = '/tmp/kimchi-store-test'
-
- def tearDown(self):
- # FIXME: Tests using 'test:///default' URI should be moved to
- # test_rest or test_mockmodel to avoid overriding problems
- LibvirtConnection._connections['test:///default'] = {}
-
- os.unlink(self.tmp_store)
-
- def test_vm_info(self):
- inst = model.Model('test:///default', self.tmp_store)
- vms = inst.vms_get_list()
- self.assertEquals(1, len(vms))
- self.assertEquals('test', vms[0])
-
- keys = set(('name', 'state', 'stats', 'uuid',
'memory', 'cpus',
- 'screenshot', 'icon', 'graphics',
'users', 'groups',
- 'access', 'persistent'))
-
- stats_keys = set(('cpu_utilization',
- 'net_throughput', 'net_throughput_peak',
- 'io_throughput', 'io_throughput_peak'))
- info = inst.vm_lookup('test')
- self.assertEquals(keys, set(info.keys()))
- self.assertEquals('running', info['state'])
- self.assertEquals('test', info['name'])
- self.assertEquals(2048, info['memory'])
- self.assertEquals(2, info['cpus'])
- self.assertEquals(None, info['icon'])
- self.assertEquals(stats_keys, set(info['stats'].keys()))
- self.assertRaises(NotFoundError, inst.vm_lookup, 'nosuchvm')
- self.assertEquals([], info['users'])
- self.assertEquals([], info['groups'])
- self.assertTrue(info['persistent'])
-
- @unittest.skipUnless(utils.running_as_root(), 'Must be run as root')
- def test_vm_lifecycle(self):
- inst = model.Model(objstore_loc=self.tmp_store)
-
- with RollbackContext() as rollback:
- vol_params = {'name': u'test-vol', 'capacity': 1024}
- task = inst.storagevolumes_create(u'default', vol_params)
- rollback.prependDefer(inst.storagevolume_delete, u'default',
- vol_params['name'])
- inst.task_wait(task['id'])
- task = inst.task_lookup(task['id'])
- self.assertEquals('finished', task['status'])
- vol = inst.storagevolume_lookup(u'default',
vol_params['name'])
-
- params = {'name': 'test', 'disks': [{'base':
vol['path'],
- 'size': 1}],
- 'cdrom': UBUNTU_ISO}
- inst.templates_create(params)
- rollback.prependDefer(inst.template_delete, 'test')
-
- params = {'name': 'kimchi-vm',
- 'template': '/plugins/kimchi/templates/test'}
- task = inst.vms_create(params)
- rollback.prependDefer(inst.vm_delete, 'kimchi-vm')
- inst.task_wait(task['id'], 10)
- task = inst.task_lookup(task['id'])
- self.assertEquals('finished', task['status'])
-
- vms = inst.vms_get_list()
- self.assertTrue('kimchi-vm' in vms)
-
- inst.vm_start('kimchi-vm')
-
- info = inst.vm_lookup('kimchi-vm')
- self.assertEquals('running', info['state'])
-
- self.assertRaises(InvalidOperation, inst.vmsnapshots_create,
- u'kimchi-vm')
-
- inst.vm_poweroff(u'kimchi-vm')
- vm = inst.vm_lookup(u'kimchi-vm')
-
- empty_snap = inst.currentvmsnapshot_lookup(u'kimchi-vm')
- self.assertEquals({}, empty_snap)
-
- # this snapshot should be deleted when its VM is deleted
- params = {'name': u'mysnap'}
- task = inst.vmsnapshots_create(u'kimchi-vm', params)
- inst.task_wait(task['id'])
- task = inst.task_lookup(task['id'])
- self.assertEquals('finished', task['status'])
-
- self.assertRaises(NotFoundError, inst.vmsnapshot_lookup,
- u'kimchi-vm', u'foobar')
-
- snap = inst.vmsnapshot_lookup(u'kimchi-vm', params['name'])
- self.assertTrue(int(time.time()) >= int(snap['created']))
- self.assertEquals(vm['state'], snap['state'])
- self.assertEquals(params['name'], snap['name'])
- self.assertEquals(u'', snap['parent'])
-
- snaps = inst.vmsnapshots_get_list(u'kimchi-vm')
- self.assertEquals([params['name']], snaps)
-
- current_snap = inst.currentvmsnapshot_lookup(u'kimchi-vm')
- self.assertEquals(snap, current_snap)
-
- task = inst.vmsnapshots_create(u'kimchi-vm')
- snap_name = task['target_uri'].split('/')[-1]
- rollback.prependDefer(inst.vmsnapshot_delete,
- u'kimchi-vm', snap_name)
- inst.task_wait(task['id'])
- task = inst.task_lookup(task['id'])
- self.assertEquals('finished', task['status'])
-
- snaps = inst.vmsnapshots_get_list(u'kimchi-vm')
- self.assertEquals(sorted([params['name'], snap_name],
- key=unicode.lower), snaps)
-
- snap = inst.vmsnapshot_lookup(u'kimchi-vm', snap_name)
- current_snap = inst.currentvmsnapshot_lookup(u'kimchi-vm')
- self.assertEquals(snap, current_snap)
-
- # update vm name
- inst.vm_update('kimchi-vm', {'name':
u'kimchi-vm-new'})
-
- # Look up the first created snapshot from the renamed vm
- snap = inst.vmsnapshot_lookup(u'kimchi-vm-new',
params['name'])
-
- # snapshot revert to the first created vm
- result = inst.vmsnapshot_revert(u'kimchi-vm-new',
params['name'])
- self.assertEquals(result, [u'kimchi-vm', snap['name']])
-
- vm = inst.vm_lookup(u'kimchi-vm')
- self.assertEquals(vm['state'], snap['state'])
-
- current_snap = inst.currentvmsnapshot_lookup(u'kimchi-vm')
- self.assertEquals(params['name'], current_snap['name'])
-
- self.assertRaises(NotFoundError, inst.vmsnapshot_delete,
- u'kimchi-vm', u'foobar')
-
- # suspend and resume the VM
- info = inst.vm_lookup(u'kimchi-vm')
- self.assertEquals(info['state'], 'shutoff')
- self.assertRaises(InvalidOperation, inst.vm_suspend, u'kimchi-vm')
- inst.vm_start(u'kimchi-vm')
- info = inst.vm_lookup(u'kimchi-vm')
- self.assertEquals(info['state'], 'running')
- inst.vm_suspend(u'kimchi-vm')
- info = inst.vm_lookup(u'kimchi-vm')
- self.assertEquals(info['state'], 'paused')
- self.assertRaises(InvalidParameter, inst.vm_update, u'kimchi-vm',
- {'name': 'foo'})
- inst.vm_resume(u'kimchi-vm')
- info = inst.vm_lookup(u'kimchi-vm')
- self.assertEquals(info['state'], 'running')
- self.assertRaises(InvalidOperation, inst.vm_resume, u'kimchi-vm')
- # leave the VM suspended to make sure a paused VM can be
- # deleted correctly
- inst.vm_suspend(u'kimchi-vm')
-
- vms = inst.vms_get_list()
- self.assertFalse('kimchi-vm' in vms)
-
- @unittest.skipUnless(utils.running_as_root(), 'Must be run as root')
- def test_image_based_template(self):
- inst = model.Model(objstore_loc=self.tmp_store)
-
- with RollbackContext() as rollback:
- vol = 'base-vol.img'
- params = {'name': vol,
- 'capacity': 1073741824, # 1 GiB
- 'allocation': 1048576, # 1 MiB
- 'format': 'qcow2'}
- task_id = inst.storagevolumes_create('default',
params)['id']
- rollback.prependDefer(inst.storagevolume_delete, 'default', vol)
- inst.task_wait(task_id)
- self.assertEquals('finished',
inst.task_lookup(task_id)['status'])
- vol_path = inst.storagevolume_lookup('default', vol)['path']
-
- params = {'name': 'test', 'disks': [{'base':
vol_path}]}
- self.assertRaises(OperationFailed, inst.templates_create, params)
-
- # Hack the model objstore to add a new template
- # It is needed as the image file must be a bootable image when
- # using model
- # As it is difficult to create one on test runtime, inject a
- # template with an empty image file to the objstore to test the
- # feature
- tmpl_name = "img-tmpl"
- tmpl_info = {"cpus": 1, "cdrom": "",
- "graphics": {"type": "vnc",
"listen": "127.0.0.1"},
- "networks": ["default"], "memory":
1024, "folder": [],
- "icon": "images/icon-vm.png",
- "os_distro": "unknown",
"os_version": "unknown",
- "disks": [{"base": vol_path,
"size": 10}],
- "storagepool":
"/plugins/kimchi/storagepools/default"}
-
- with inst.objstore as session:
- session.store('template', tmpl_name, tmpl_info)
-
- params = {'name': 'kimchi-vm',
- 'template': '/plugins/kimchi/templates/img-tmpl'}
- task = inst.vms_create(params)
- inst.task_wait(task['id'])
- rollback.prependDefer(inst.vm_delete, 'kimchi-vm')
-
- vms = inst.vms_get_list()
- self.assertTrue('kimchi-vm' in vms)
-
- inst.vm_start('kimchi-vm')
- rollback.prependDefer(inst.vm_poweroff, 'kimchi-vm')
-
- info = inst.vm_lookup('kimchi-vm')
- self.assertEquals('running', info['state'])
-
- @unittest.skipUnless(utils.running_as_root(), 'Must be run as root')
- def test_vm_graphics(self):
- inst = model.Model(objstore_loc=self.tmp_store)
- params = {'name': 'test', 'disks': [], 'cdrom':
UBUNTU_ISO}
- inst.templates_create(params)
- with RollbackContext() as rollback:
- params = {'name': 'kimchi-vnc',
- 'template': '/plugins/kimchi/templates/test'}
- task1 = inst.vms_create(params)
- inst.task_wait(task1['id'])
- rollback.prependDefer(inst.vm_delete, 'kimchi-vnc')
-
- info = inst.vm_lookup('kimchi-vnc')
- self.assertEquals('vnc', info['graphics']['type'])
- self.assertEquals('127.0.0.1',
info['graphics']['listen'])
-
- graphics = {'type': 'spice', 'listen':
'127.0.0.1'}
- params = {'name': 'kimchi-spice',
- 'template': '/plugins/kimchi/templates/test',
- 'graphics': graphics}
- task2 = inst.vms_create(params)
- inst.task_wait(task2['id'])
- rollback.prependDefer(inst.vm_delete, 'kimchi-spice')
-
- info = inst.vm_lookup('kimchi-spice')
- self.assertEquals('spice', info['graphics']['type'])
- self.assertEquals('127.0.0.1',
info['graphics']['listen'])
-
- inst.template_delete('test')
-
- @unittest.skipUnless(utils.running_as_root(), 'Must be run as root')
- def test_vm_ifaces(self):
- inst = model.Model(objstore_loc=self.tmp_store)
- with RollbackContext() as rollback:
- params = {'name': 'test', 'disks': [],
'cdrom': UBUNTU_ISO}
- inst.templates_create(params)
- rollback.prependDefer(inst.template_delete, 'test')
-
- # Create a network
- net_name = 'test-network'
- net_args = {'name': net_name,
- 'connection': 'nat',
- 'subnet': '127.0.100.0/24'}
- inst.networks_create(net_args)
- rollback.prependDefer(inst.network_delete, net_name)
- inst.network_activate(net_name)
- rollback.prependDefer(inst.network_deactivate, net_name)
-
- for vm_name in ['kimchi-ifaces', 'kimchi-ifaces-running']:
- params = {'name': vm_name,
- 'template': '/plugins/kimchi/templates/test'}
- task = inst.vms_create(params)
- inst.task_wait(task['id'])
- rollback.prependDefer(inst.vm_delete, vm_name)
-
- ifaces = inst.vmifaces_get_list(vm_name)
- self.assertEquals(1, len(ifaces))
-
- iface = inst.vmiface_lookup(vm_name, ifaces[0])
- self.assertEquals(17, len(iface['mac']))
- self.assertEquals("default", iface['network'])
- self.assertIn("model", iface)
-
- # attach network interface to vm
- iface_args = {"type": "network",
- "network": "test-network",
- "model": "virtio"}
- mac = inst.vmifaces_create(vm_name, iface_args)
- # detach network interface from vm
- rollback.prependDefer(inst.vmiface_delete, vm_name, mac)
- self.assertEquals(17, len(mac))
-
- iface = inst.vmiface_lookup(vm_name, mac)
- self.assertEquals("network", iface["type"])
- self.assertEquals("test-network", iface['network'])
- self.assertEquals("virtio", iface["model"])
-
- # attach network interface to vm without providing model
- iface_args = {"type": "network",
- "network": "test-network"}
- mac = inst.vmifaces_create(vm_name, iface_args)
- rollback.prependDefer(inst.vmiface_delete, vm_name, mac)
-
- iface = inst.vmiface_lookup(vm_name, mac)
- self.assertEquals("network", iface["type"])
- self.assertEquals("test-network", iface['network'])
-
- # update vm interface
- newMacAddr = '54:50:e3:44:8a:af'
- iface_args = {"mac": newMacAddr}
- inst.vmiface_update(vm_name, mac, iface_args)
- iface = inst.vmiface_lookup(vm_name, newMacAddr)
- self.assertEquals(newMacAddr, iface['mac'])
-
- # undo mac address change
- iface_args = {"mac": mac}
- inst.vmiface_update(vm_name, newMacAddr, iface_args)
- iface = inst.vmiface_lookup(vm_name, mac)
- self.assertEquals(mac, iface['mac'])
-
- @unittest.skipUnless(utils.running_as_root(), 'Must be run as root')
- def test_vm_disk(self):
- disk_path = os.path.join(TMP_DIR, 'existent2.iso')
- open(disk_path, 'w').close()
- modern_disk_bus = get_template_default('modern', 'disk_bus')
-
- def _attach_disk(expect_bus=modern_disk_bus):
- disk_args = {"type": "disk",
- "pool": pool,
- "vol": vol}
- disk = inst.vmstorages_create(vm_name, disk_args)
- storage_list = inst.vmstorages_get_list(vm_name)
- self.assertEquals(prev_count + 1, len(storage_list))
-
- # Check the bus type to be 'virtio'
- disk_info = inst.vmstorage_lookup(vm_name, disk)
- self.assertEquals(u'disk', disk_info['type'])
- self.assertEquals(vol_path, disk_info['path'])
- self.assertEquals(expect_bus, disk_info['bus'])
- return disk
-
- inst = model.Model(objstore_loc=self.tmp_store)
- with RollbackContext() as rollback:
- path = os.path.join(TMP_DIR, 'kimchi-images')
- pool = 'test-pool'
- vol = 'test-volume.img'
- vol_path = "%s/%s" % (path, vol)
- if not os.path.exists(path):
- os.mkdir(path)
- rollback.prependDefer(shutil.rmtree, path)
-
- args = {'name': pool,
- 'path': path,
- 'type': 'dir'}
- inst.storagepools_create(args)
- rollback.prependDefer(inst.storagepool_delete, pool)
-
- # Activate the pool before adding any volume
- inst.storagepool_activate(pool)
- rollback.prependDefer(inst.storagepool_deactivate, pool)
-
- params = {'name': vol,
- 'capacity': 1073741824, # 1 GiB
- 'allocation': 536870912, # 512 MiB
- 'format': 'qcow2'}
- task_id = inst.storagevolumes_create(pool, params)['id']
- rollback.prependDefer(inst.storagevolume_delete, pool, vol)
- inst.task_wait(task_id)
-
- vm_name = 'kimchi-cdrom'
- params = {'name': 'test', 'disks': [],
'cdrom': UBUNTU_ISO}
- inst.templates_create(params)
- rollback.prependDefer(inst.template_delete, 'test')
- params = {'name': vm_name,
- 'template': '/plugins/kimchi/templates/test'}
- task1 = inst.vms_create(params)
- inst.task_wait(task1['id'])
- rollback.prependDefer(inst.vm_delete, vm_name)
-
- prev_count = len(inst.vmstorages_get_list(vm_name))
- self.assertEquals(1, prev_count)
-
- # Volume format with mismatched type raise error
- cdrom_args = {"type": "cdrom", "pool": pool,
"vol": vol}
- self.assertRaises(InvalidParameter, inst.vmstorages_create,
- vm_name, cdrom_args)
-
- # Cold plug and unplug a disk
- disk = _attach_disk()
- inst.vmstorage_delete(vm_name, disk)
-
- # Hot plug a disk
- inst.vm_start(vm_name)
- disk = _attach_disk()
-
- # VM disk still there after powered off
- inst.vm_poweroff(vm_name)
- disk_info = inst.vmstorage_lookup(vm_name, disk)
- self.assertEquals(u'disk', disk_info['type'])
- inst.vmstorage_delete(vm_name, disk)
-
- # Specifying pool and path at same time will fail
- disk_args = {"type": "disk",
- "pool": pool,
- "vol": vol,
- "path": disk_path}
- self.assertRaises(
- InvalidParameter, inst.vmstorages_create, vm_name, disk_args)
-
- old_distro_iso = TMP_DIR + 'rhel4_8.iso'
- iso_gen.construct_fake_iso(old_distro_iso, True, '4.8',
'rhel')
-
- vm_name = 'kimchi-ide-bus-vm'
- params = {'name': 'old_distro_template', 'disks':
[],
- 'cdrom': old_distro_iso}
- inst.templates_create(params)
- rollback.prependDefer(inst.template_delete, 'old_distro_template')
- params = {
- 'name': vm_name,
- 'template':
'/plugins/kimchi/templates/old_distro_template'
- }
- task2 = inst.vms_create(params)
- inst.task_wait(task2['id'])
- rollback.prependDefer(inst.vm_delete, vm_name)
-
- # Need to check the right disk_bus for old distro
- disk = _attach_disk(get_template_default('old', 'disk_bus'))
- inst.vmstorage_delete('kimchi-ide-bus-vm', disk)
-
- # Hot plug IDE bus disk does not work
- inst.vm_start(vm_name)
- self.assertRaises(InvalidOperation, _attach_disk)
- inst.vm_poweroff(vm_name)
-
- @unittest.skipUnless(utils.running_as_root(), 'Must be run as root')
- def test_vm_cdrom(self):
- inst = model.Model(objstore_loc=self.tmp_store)
- with RollbackContext() as rollback:
- vm_name = 'kimchi-cdrom'
- params = {'name': 'test', 'disks': [],
'cdrom': UBUNTU_ISO}
- inst.templates_create(params)
- rollback.prependDefer(inst.template_delete, 'test')
- params = {'name': vm_name,
- 'template': '/plugins/kimchi/templates/test'}
- task = inst.vms_create(params)
- inst.task_wait(task['id'])
- rollback.prependDefer(inst.vm_delete, vm_name)
-
- prev_count = len(inst.vmstorages_get_list(vm_name))
- self.assertEquals(1, prev_count)
-
- # dummy .iso files
- iso_path = os.path.join(TMP_DIR, 'existent.iso')
- iso_path2 = os.path.join(TMP_DIR, 'existent2.iso')
- open(iso_path, 'w').close()
- rollback.prependDefer(os.remove, iso_path)
- open(iso_path2, 'w').close()
- rollback.prependDefer(os.remove, iso_path2)
- wrong_iso_path = '/nonexistent.iso'
-
- # Create a cdrom
- cdrom_args = {"type": "cdrom",
- "path": iso_path}
- cdrom_dev = inst.vmstorages_create(vm_name, cdrom_args)
- storage_list = inst.vmstorages_get_list(vm_name)
- self.assertEquals(prev_count + 1, len(storage_list))
-
- # Get cdrom info
- cd_info = inst.vmstorage_lookup(vm_name, cdrom_dev)
- self.assertEquals(u'cdrom', cd_info['type'])
- self.assertEquals(iso_path, cd_info['path'])
-
- # update path of existing cd with
- # non existent iso
- self.assertRaises(InvalidParameter, inst.vmstorage_update,
- vm_name, cdrom_dev, {'path': wrong_iso_path})
-
- # Make sure CD ROM still exists after failure
- cd_info = inst.vmstorage_lookup(vm_name, cdrom_dev)
- self.assertEquals(u'cdrom', cd_info['type'])
- self.assertEquals(iso_path, cd_info['path'])
-
- # update path of existing cd with existent iso of shutoff vm
- inst.vmstorage_update(vm_name, cdrom_dev, {'path': iso_path2})
- cdrom_info = inst.vmstorage_lookup(vm_name, cdrom_dev)
- self.assertEquals(iso_path2, cdrom_info['path'])
-
- # update path of existing cd with existent iso of running vm
- inst.vm_start(vm_name)
- inst.vmstorage_update(vm_name, cdrom_dev, {'path': iso_path})
- cdrom_info = inst.vmstorage_lookup(vm_name, cdrom_dev)
- self.assertEquals(iso_path, cdrom_info['path'])
-
- # eject cdrom
- cdrom_dev = inst.vmstorage_update(vm_name, cdrom_dev, {'path':
''})
- cdrom_info = inst.vmstorage_lookup(vm_name, cdrom_dev)
- self.assertEquals('', cdrom_info['path'])
- inst.vm_poweroff(vm_name)
-
- # removing non existent cdrom
- self.assertRaises(NotFoundError, inst.vmstorage_delete, vm_name,
- "fakedev")
-
- # removing valid cdrom
- inst.vmstorage_delete(vm_name, cdrom_dev)
- storage_list = inst.vmstorages_get_list(vm_name)
- self.assertEquals(prev_count, len(storage_list))
-
- # Create a new cdrom using a remote iso
- valid_remote_iso_path = utils.get_remote_iso_path()
- cdrom_args = {"type": "cdrom",
- "path": valid_remote_iso_path}
- cdrom_dev = inst.vmstorages_create(vm_name, cdrom_args)
- storage_list = inst.vmstorages_get_list(vm_name)
- self.assertEquals(prev_count + 1, len(storage_list))
-
- # Update remote-backed cdrom with the same ISO
- inst.vmstorage_update(vm_name, cdrom_dev,
- {'path': valid_remote_iso_path})
- cdrom_info = inst.vmstorage_lookup(vm_name, cdrom_dev)
- cur_cdrom_path = re.sub(":80/", '/',
cdrom_info['path'])
- self.assertEquals(valid_remote_iso_path, cur_cdrom_path)
-
- @unittest.skipUnless(utils.running_as_root(), 'Must be run as root')
- def test_vm_storage_provisioning(self):
- inst = model.Model(objstore_loc=self.tmp_store)
-
- with RollbackContext() as rollback:
- params = {'name': 'test', 'disks': [{'size':
1}],
- 'cdrom': UBUNTU_ISO}
- inst.templates_create(params)
- rollback.prependDefer(inst.template_delete, 'test')
-
- params = {'name': 'test-vm-1',
- 'template': '/plugins/kimchi/templates/test'}
- task = inst.vms_create(params)
- inst.task_wait(task['id'])
- rollback.prependDefer(inst.vm_delete, 'test-vm-1')
-
- vm_info = inst.vm_lookup(params['name'])
- disk_path = '%s/%s-0.img' % (
- inst.storagepool_lookup('default')['path'],
vm_info['uuid'])
- self.assertTrue(os.access(disk_path, os.F_OK))
- self.assertFalse(os.access(disk_path, os.F_OK))
-
- def test_vm_memory_hotplug(self):
- config.set("authentication", "method", "pam")
- inst = model.Model(None, objstore_loc=self.tmp_store)
- orig_params = {'name': 'test', 'memory': 1024,
'cdrom': UBUNTU_ISO}
- inst.templates_create(orig_params)
-
- with RollbackContext() as rollback:
- params = {'name': 'kimchi-vm1',
- 'template': '/plugins/kimchi/templates/test'}
- task1 = inst.vms_create(params)
- inst.task_wait(task1['id'])
- rollback.prependDefer(utils.rollback_wrapper, inst.vm_delete,
- 'kimchi-vm1')
- # Start vm
- inst.vm_start('kimchi-vm1')
- rollback.prependDefer(utils.rollback_wrapper, inst.vm_poweroff,
- 'kimchi-vm1')
-
- # Hotplug memory, only available in Libvirt >= 1.2.14
- params = {'memory': 2048}
- if inst.capabilities_lookup()['mem_hotplug_support']:
- inst.vm_update('kimchi-vm1', params)
- rollback.prependDefer(utils.rollback_wrapper, inst.vm_delete,
- 'kimchi-vm1')
- self.assertEquals(params['memory'],
-
inst.vm_lookup('kimchi-vm1')['memory'])
- else:
- self.assertRaises(InvalidOperation, inst.vm_update,
- 'kimchi-vm1', params)
-
- def test_vm_edit(self):
- config.set("authentication", "method", "pam")
- inst = model.Model(None,
- objstore_loc=self.tmp_store)
-
- orig_params = {'name': 'test', 'memory': 1024,
'cpus': 1,
- 'cdrom': UBUNTU_ISO}
- inst.templates_create(orig_params)
-
- with RollbackContext() as rollback:
- params_1 = {'name': 'kimchi-vm1',
- 'template': '/plugins/kimchi/templates/test'}
- params_2 = {'name': 'kimchi-vm2',
- 'template': '/plugins/kimchi/templates/test'}
- task1 = inst.vms_create(params_1)
- inst.task_wait(task1['id'])
- rollback.prependDefer(utils.rollback_wrapper, inst.vm_delete,
- 'kimchi-vm1')
- task2 = inst.vms_create(params_2)
- inst.task_wait(task2['id'])
- rollback.prependDefer(utils.rollback_wrapper, inst.vm_delete,
- 'kimchi-vm2')
-
- vms = inst.vms_get_list()
- self.assertTrue('kimchi-vm1' in vms)
-
- # make sure "vm_update" works when the domain has a snapshot
- inst.vmsnapshots_create(u'kimchi-vm1')
-
- # update vm graphics when vm is not running
- inst.vm_update(u'kimchi-vm1',
- {"graphics": {"passwd":
"123456"}})
-
- inst.vm_start('kimchi-vm1')
- rollback.prependDefer(utils.rollback_wrapper, inst.vm_poweroff,
- 'kimchi-vm1')
-
- vm_info = inst.vm_lookup(u'kimchi-vm1')
- self.assertEquals('123456',
vm_info['graphics']["passwd"])
- self.assertEquals(None,
vm_info['graphics']["passwdValidTo"])
-
- # update vm graphics when vm is running
- inst.vm_update(u'kimchi-vm1',
- {"graphics": {"passwd":
"abcdef",
- "passwdValidTo": 20}})
- vm_info = inst.vm_lookup(u'kimchi-vm1')
- self.assertEquals('abcdef',
vm_info['graphics']["passwd"])
- self.assertGreaterEqual(20,
vm_info['graphics']['passwdValidTo'])
-
- info = inst.vm_lookup('kimchi-vm1')
- self.assertEquals('running', info['state'])
-
- params = {'name': 'new-vm'}
- self.assertRaises(InvalidParameter, inst.vm_update,
- 'kimchi-vm1', params)
-
- # change VM users and groups, when wm is running.
- inst.vm_update(u'kimchi-vm1',
- {'users': ['root'], 'groups':
['root']})
- vm_info = inst.vm_lookup(u'kimchi-vm1')
- self.assertEquals(['root'], vm_info['users'])
- self.assertEquals(['root'], vm_info['groups'])
- # change VM users and groups by removing all elements,
- # when wm is running.
- inst.vm_update(u'kimchi-vm1', {'users': [], 'groups':
[]})
- vm_info = inst.vm_lookup(u'kimchi-vm1')
- self.assertEquals([], vm_info['users'])
- self.assertEquals([], vm_info['groups'])
-
- inst.vm_poweroff('kimchi-vm1')
- self.assertRaises(OperationFailed, inst.vm_update,
- 'kimchi-vm1', {'name':
'kimchi-vm2'})
-
- params = {'name': u'��e��-�����', 'cpus': 4,
'memory': 2048}
- inst.vm_update('kimchi-vm1', params)
- rollback.prependDefer(utils.rollback_wrapper, inst.vm_delete,
- u'��e��-�����')
- self.assertEquals(info['uuid'],
inst.vm_lookup(u'��e��-�����')['uuid'])
- info = inst.vm_lookup(u'��e��-�����')
- for key in params.keys():
- self.assertEquals(params[key], info[key])
-
- # change only VM users - groups are not changed (default is empty)
- users = inst.users_get_list()[:3]
- inst.vm_update(u'��e��-�����', {'users': users})
- self.assertEquals(users,
inst.vm_lookup(u'��e��-�����')['users'])
- self.assertEquals([],
inst.vm_lookup(u'��e��-�����')['groups'])
-
- # change only VM groups - users are not changed (default is empty)
- groups = inst.groups_get_list()[:2]
- inst.vm_update(u'��e��-�����', {'groups': groups})
- self.assertEquals(users,
inst.vm_lookup(u'��e��-�����')['users'])
- self.assertEquals(groups,
inst.vm_lookup(u'��e��-�����')['groups'])
-
- # change VM users and groups by adding a new element to each one
- users.append(pwd.getpwuid(os.getuid()).pw_name)
- groups.append(grp.getgrgid(os.getgid()).gr_name)
- inst.vm_update(u'��e��-�����', {'users': users,
'groups': groups})
- self.assertEquals(users,
inst.vm_lookup(u'��e��-�����')['users'])
- self.assertEquals(groups,
inst.vm_lookup(u'��e��-�����')['groups'])
-
- # change VM users (wrong value) and groups
- # when an error occurs, everything fails and nothing is changed
- self.assertRaises(InvalidParameter, inst.vm_update, u'��e��-�����',
- {'users': ['userdoesnotexist'],
'groups': []})
- self.assertEquals(users,
inst.vm_lookup(u'��e��-�����')['users'])
- self.assertEquals(groups,
inst.vm_lookup(u'��e��-�����')['groups'])
-
- # change VM users and groups (wrong value)
- # when an error occurs, everything fails and nothing is changed
- self.assertRaises(InvalidParameter, inst.vm_update, u'��e��-�����',
- {'users': [], 'groups':
['groupdoesnotexist']})
- self.assertEquals(users,
inst.vm_lookup(u'��e��-�����')['users'])
- self.assertEquals(groups,
inst.vm_lookup(u'��e��-�����')['groups'])
-
- # change VM users and groups by removing all elements
- inst.vm_update(u'��e��-�����', {'users': [],
'groups': []})
- self.assertEquals([],
inst.vm_lookup(u'��e��-�����')['users'])
- self.assertEquals([],
inst.vm_lookup(u'��e��-�����')['groups'])
-
- def test_get_interfaces(self):
- inst = model.Model('test:///default',
- objstore_loc=self.tmp_store)
- expected_ifaces = netinfo.all_favored_interfaces()
- ifaces = inst.interfaces_get_list()
- self.assertEquals(len(expected_ifaces), len(ifaces))
- for name in expected_ifaces:
- iface = inst.interface_lookup(name)
- self.assertEquals(iface['name'], name)
- self.assertIn('type', iface)
- self.assertIn('status', iface)
- self.assertIn('ipaddr', iface)
- self.assertIn('netmask', iface)
-
- def test_async_tasks(self):
- class task_except(Exception):
- pass
-
- def quick_op(cb, message):
- cb(message, True)
-
- def long_op(cb, params):
- time.sleep(params.get('delay', 3))
- cb(params.get('message', ''), params.get('result',
False))
-
- def abnormal_op(cb, params):
- try:
- raise task_except
- except:
- cb("Exception raised", False)
-
- def continuous_ops(cb, params):
- cb("step 1 OK")
- time.sleep(2)
- cb("step 2 OK")
- time.sleep(2)
- cb("step 3 OK", params.get('result', True))
-
- inst = model.Model('test:///default',
- objstore_loc=self.tmp_store)
- taskid = add_task('', quick_op, inst.objstore, 'Hello')
- inst.task_wait(taskid)
- self.assertEquals(1, taskid)
- self.assertEquals('finished',
inst.task_lookup(taskid)['status'])
- self.assertEquals('Hello', inst.task_lookup(taskid)['message'])
-
- taskid = add_task('', long_op, inst.objstore,
- {'delay': 3, 'result': False,
- 'message': 'It was not meant to be'})
- self.assertEquals(2, taskid)
- self.assertEquals('running', inst.task_lookup(taskid)['status'])
- self.assertEquals('OK', inst.task_lookup(taskid)['message'])
- inst.task_wait(taskid)
- self.assertEquals('failed', inst.task_lookup(taskid)['status'])
- self.assertEquals('It was not meant to be',
- inst.task_lookup(taskid)['message'])
- taskid = add_task('', abnormal_op, inst.objstore, {})
- inst.task_wait(taskid)
- self.assertEquals('Exception raised',
- inst.task_lookup(taskid)['message'])
- self.assertEquals('failed', inst.task_lookup(taskid)['status'])
-
- taskid = add_task('', continuous_ops, inst.objstore,
- {'result': True})
- self.assertEquals('running', inst.task_lookup(taskid)['status'])
- inst.task_wait(taskid, timeout=10)
- self.assertEquals('finished',
inst.task_lookup(taskid)['status'])
-
- @unittest.skipUnless(utils.running_as_root(), 'Must be run as root')
- def test_delete_running_vm(self):
- inst = model.Model(objstore_loc=self.tmp_store)
-
- with RollbackContext() as rollback:
- params = {'name': u'test', 'disks': [],
'cdrom': UBUNTU_ISO}
- inst.templates_create(params)
- rollback.prependDefer(inst.template_delete, 'test')
-
- params = {'name': u'k������h��-�����',
- 'template': u'/plugins/kimchi/templates/test'}
- task = inst.vms_create(params)
- inst.task_wait(task['id'])
- rollback.prependDefer(utils.rollback_wrapper, inst.vm_delete,
- u'k������h��-�����')
-
- inst.vm_start(u'k������h��-�����')
-
self.assertEquals(inst.vm_lookup(u'k������h��-�����')['state'],
'running')
- rollback.prependDefer(utils.rollback_wrapper, inst.vm_poweroff,
- u'k������h��-�����')
-
- inst.vm_delete(u'k������h��-�����')
-
- vms = inst.vms_get_list()
- self.assertFalse(u'k������h��-�����' in vms)
-
- @unittest.skipUnless(utils.running_as_root(), 'Must be run as root')
- def test_vm_list_sorted(self):
- inst = model.Model(objstore_loc=self.tmp_store)
-
- with RollbackContext() as rollback:
- params = {'name': 'test', 'disks': [],
'cdrom': UBUNTU_ISO}
- inst.templates_create(params)
- rollback.prependDefer(inst.template_delete, 'test')
-
- params = {'name': 'kimchi-vm',
- 'template': '/plugins/kimchi/templates/test'}
- task = inst.vms_create(params)
- inst.task_wait(task['id'])
- rollback.prependDefer(inst.vm_delete, 'kimchi-vm')
-
- vms = inst.vms_get_list()
-
- self.assertEquals(vms, sorted(vms, key=unicode.lower))
-
- def test_vm_clone(self):
- inst = model.Model('test:///default', objstore_loc=self.tmp_store)
-
- all_vm_names = inst.vms_get_list()
- name = all_vm_names[0]
-
- original_vm = inst.vm_lookup(name)
- if original_vm['state'] == u'shutoff':
- inst.vm_start(name)
-
- # the VM 'test' should be running by now, so we can't clone it yet
- self.assertRaises(InvalidParameter, inst.vm_clone, name)
-
- with RollbackContext() as rollback:
- inst.vm_poweroff(name)
- rollback.prependDefer(inst.vm_start, name)
-
- # create two simultaneous clones of the same VM
- # and make sure both of them complete successfully
- task1 = inst.vm_clone(name)
- task2 = inst.vm_clone(name)
- clone1_name = task1['target_uri'].split('/')[-2]
- rollback.prependDefer(inst.vm_delete, clone1_name)
- clone2_name = task2['target_uri'].split('/')[-2]
- rollback.prependDefer(inst.vm_delete, clone2_name)
- inst.task_wait(task1['id'])
- task1 = inst.task_lookup(task1['id'])
- self.assertEquals('finished', task1['status'])
- inst.task_wait(task2['id'])
- task2 = inst.task_lookup(task2['id'])
- self.assertEquals('finished', task2['status'])
-
- # update the original VM info because its state has changed
- original_vm = inst.vm_lookup(name)
- clone_vm = inst.vm_lookup(clone1_name)
-
- self.assertNotEqual(original_vm['name'], clone_vm['name'])
- self.assertTrue(re.match(u'%s-clone-\d+' %
original_vm['name'],
- clone_vm['name']))
- del original_vm['name']
- del clone_vm['name']
-
- self.assertNotEqual(original_vm['uuid'], clone_vm['uuid'])
- del original_vm['uuid']
- del clone_vm['uuid']
-
- # compare all VM settings except the ones already compared
- # (and removed) above (i.e. 'name' and 'uuid')
- self.assertEquals(original_vm, clone_vm)
-
- def test_use_test_host(self):
- inst = model.Model('test:///default',
- objstore_loc=self.tmp_store)
-
- with RollbackContext() as rollback:
- params = {
- 'name': 'test',
- 'disks': [],
- 'cdrom': UBUNTU_ISO,
- 'storagepool':
'/plugins/kimchi/storagepools/default-pool',
- 'domain': 'test',
- 'arch': 'i686'
- }
-
- inst.templates_create(params)
- rollback.prependDefer(inst.template_delete, 'test')
-
- params = {'name': 'kimchi-vm',
- 'template': '/plugins/kimchi/templates/test'}
- task = inst.vms_create(params)
- inst.task_wait(task['id'])
- rollback.prependDefer(inst.vm_delete, 'kimchi-vm')
-
- vms = inst.vms_get_list()
-
- self.assertTrue('kimchi-vm' in vms)
-
- @unittest.skipUnless(utils.running_as_root(), 'Must be run as root')
- def test_debug_reports(self):
- inst = model.Model('test:///default',
- objstore_loc=self.tmp_store)
-
- if not inst.capabilities_lookup()['system_report_tool']:
- raise unittest.SkipTest("Without debug report tool")
-
- try:
- timeout = int(os.environ['TEST_REPORT_TIMEOUT'])
- except (ValueError, KeyError):
- timeout = 120
-
- namePrefix = 'unitTestReport'
- # sosreport always deletes unsual letters like '-' and '_' in
the
- # generated report file name.
- uuidstr = str(uuid.uuid4()).translate(None, "-_")
- reportName = namePrefix + uuidstr
- try:
- inst.debugreport_delete(namePrefix + '*')
- except NotFoundError:
- pass
- with RollbackContext() as rollback:
- report_list = inst.debugreports_get_list()
- self.assertFalse(reportName in report_list)
- try:
- tmp_name = reportName + "_1"
- task = inst.debugreports_create({'name': reportName})
- rollback.prependDefer(inst.debugreport_delete, tmp_name)
- taskid = task['id']
- inst.task_wait(taskid, timeout)
- self.assertEquals('finished',
- inst.task_lookup(taskid)['status'],
- "It is not necessary an error. "
- "You may need to increase the "
- "timeout number by "
- "TEST_REPORT_TIMEOUT=200 "
- "./run_tests.sh test_model")
- report_list = inst.debugreports_get_list()
- self.assertTrue(reportName in report_list)
- name = inst.debugreport_update(reportName, {'name': tmp_name})
- self.assertEquals(name, tmp_name)
- report_list = inst.debugreports_get_list()
- self.assertTrue(tmp_name in report_list)
- except OperationFailed, e:
- if 'debugreport tool not found' not in e.message:
- raise e
-
- def test_get_distros(self):
- inst = model.Model('test:///default',
- objstore_loc=self.tmp_store)
- distros = inst.distros_get_list()
- for d in distros:
- distro = inst.distro_lookup(d)
- self.assertIn('name', distro)
- self.assertIn('os_distro', distro)
- self.assertIn('os_version', distro)
- self.assertIn('os_arch', distro)
- self.assertIn('path', distro)
-
- @unittest.skipUnless(utils.running_as_root(), 'Must be run as root')
- def test_deep_scan(self):
- inst = model.Model(None,
- objstore_loc=self.tmp_store)
- with RollbackContext() as rollback:
- deep_path = os.path.join(TMP_DIR, 'deep-scan')
- subdir_path = os.path.join(deep_path, 'isos')
- if not os.path.exists(subdir_path):
- os.makedirs(subdir_path)
- ubuntu_iso = os.path.join(deep_path, 'ubuntu12.04.iso')
- sles_iso = os.path.join(subdir_path, 'sles10.iso')
- iso_gen.construct_fake_iso(ubuntu_iso, True, '12.04',
'ubuntu')
- iso_gen.construct_fake_iso(sles_iso, True, '10', 'sles')
-
- args = {'name': 'kimchi-scanning-pool',
- 'path': deep_path,
- 'type': 'kimchi-iso'}
- inst.storagepools_create(args)
- rollback.prependDefer(shutil.rmtree, deep_path)
- rollback.prependDefer(shutil.rmtree, args['path'])
- rollback.prependDefer(inst.storagepool_deactivate, args['name'])
-
- time.sleep(1)
- volumes = inst.storagevolumes_get_list(args['name'])
- self.assertEquals(len(volumes), 2)
-
- def test_repository_create(self):
- inst = model.Model('test:///default',
- objstore_loc=self.tmp_store)
-
- yum_repos = [{'repo_id': 'fedora-fake',
- 'baseurl': 'http://www.fedora.org'},
- {'repo_id': 'fedora-updates-fake',
- 'config':
- {'mirrorlist': 'http://www.fedoraproject.org'}}]
-
- deb_repos = [{'baseurl': 'http://archive.ubuntu.com/ubuntu/',
- 'config': {'dist': 'quantal'}},
- {'baseurl': 'http://archive.ubuntu.com/ubuntu/',
- 'config': {'dist': 'quantal',
'comps': ['main']}}]
-
- yum_invalid_repos = []
- deb_invalid_repos = []
-
- for url in invalid_repository_urls:
- wrong_baseurl = {'repo_id': 'wrong-id', 'baseurl':
url}
- wrong_mirrorlist = {'repo_id': 'wrong-id',
- 'baseurl': 'www.example.com',
- 'config': {'mirrorlist': url}}
- wrong_config_item = {
- 'repo_id': 'wrong-id',
- 'baseurl': 'www.example.com',
- 'config': {
- 'gpgkey': 'file:///tmp/KEY-fedora-updates-fake-19'}}
-
- yum_invalid_repos.append(wrong_baseurl)
- yum_invalid_repos.append(wrong_mirrorlist)
- yum_invalid_repos.append(wrong_config_item)
-
- wrong_baseurl['config'] = {'dist': 'tasty'}
- wrong_config = {'baseurl': deb_repos[0]['baseurl'],
- 'config': {
- 'unsupported_item':
"a_unsupported_item"}}
- deb_invalid_repos.append(wrong_baseurl)
- deb_invalid_repos.append(wrong_config)
-
- repo_type = inst.capabilities_lookup()['repo_mngt_tool']
- if repo_type == 'yum':
- test_repos = yum_repos
- invalid_repos = yum_invalid_repos
- elif repo_type == 'deb':
- test_repos = deb_repos
- invalid_repos = deb_invalid_repos
- else:
- # repository management tool was not recognized by Kimchi
- # skip test case
- return
-
- # create repositories with invalid data
- for repo in invalid_repos:
- self.assertRaises(InvalidParameter, inst.repositories_create, repo)
-
- for repo in test_repos:
- system_host_repos = len(inst.repositories_get_list())
- repo_id = inst.repositories_create(repo)
- host_repos = inst.repositories_get_list()
- self.assertEquals(system_host_repos + 1, len(host_repos))
-
- repo_info = inst.repository_lookup(repo_id)
- self.assertEquals(repo_id, repo_info['repo_id'])
- self.assertEquals(True, repo_info.get('enabled'))
- self.assertEquals(repo.get('baseurl', ''),
- repo_info.get('baseurl'))
-
- original_config = repo.get('config', {})
- config_info = repo_info.get('config', {})
-
- if repo_type == 'yum':
- self.assertEquals(original_config.get('mirrorlist', ''),
- config_info.get('mirrorlist', ''))
- self.assertEquals(True, config_info['gpgcheck'])
- else:
- self.assertEquals(original_config['dist'],
config_info['dist'])
- self.assertEquals(original_config.get('comps', []),
- config_info.get('comps', []))
-
- inst.repository_delete(repo_id)
- self.assertRaises(NotFoundError, inst.repository_lookup, repo_id)
-
- self.assertRaises(NotFoundError, inst.repository_lookup, 'google')
-
- def test_repository_update(self):
- inst = model.Model('test:///default',
- objstore_loc=self.tmp_store)
-
- yum_repo = {'repo_id': 'fedora-fake',
- 'baseurl': 'http://www.fedora.org'}
- yum_new_repo = {'baseurl': 'http://www.fedoraproject.org'}
-
- deb_repo = {'baseurl': 'http://archive.ubuntu.com/ubuntu/',
- 'config': {'dist': 'quantal'}}
- deb_new_repo = {'baseurl':
'http://br.archive.canonical.com/ubuntu/',
- 'config': {'dist': 'utopic'}}
-
- yum_invalid_repos = []
- deb_invalid_repos = []
-
- for url in invalid_repository_urls:
- wrong_baseurl = {'baseurl': url}
- wrong_mirrorlist = {'baseurl': 'www.example.com',
- 'config': {'mirrorlist': url}}
-
- yum_invalid_repos.append(wrong_baseurl)
- yum_invalid_repos.append(wrong_mirrorlist)
-
- wrong_baseurl['config'] = {'dist': 'tasty'}
- deb_invalid_repos.append(wrong_baseurl)
-
- repo_type = inst.capabilities_lookup()['repo_mngt_tool']
- if repo_type == 'yum':
- repo = yum_repo
- new_repo = yum_new_repo
- invalid_repos = yum_invalid_repos
- elif repo_type == 'deb':
- repo = deb_repo
- new_repo = deb_new_repo
- invalid_repos = deb_invalid_repos
- else:
- # repository management tool was not recognized by Kimchi
- # skip test case
- return
-
- system_host_repos = len(inst.repositories_get_list())
-
- with RollbackContext() as rollback:
- repo_id = inst.repositories_create(repo)
- rollback.prependDefer(inst.repository_delete, repo_id)
-
- host_repos = inst.repositories_get_list()
- self.assertEquals(system_host_repos + 1, len(host_repos))
-
- # update repositories with invalid data
- for tmp_repo in invalid_repos:
- self.assertRaises(InvalidParameter, inst.repository_update,
- repo_id, tmp_repo)
-
- new_repo_id = inst.repository_update(repo_id, new_repo)
- repo_info = inst.repository_lookup(new_repo_id)
-
- self.assertEquals(new_repo_id, repo_info['repo_id'])
- self.assertEquals(new_repo['baseurl'], repo_info['baseurl'])
- self.assertEquals(True, repo_info['enabled'])
- inst.repository_update(new_repo_id, repo)
-
- def test_repository_disable_enable(self):
- inst = model.Model('test:///default',
- objstore_loc=self.tmp_store)
-
- yum_repo = {'repo_id': 'fedora-fake',
- 'baseurl': 'http://www.fedora.org'}
- deb_repo = {'baseurl': 'http://archive.ubuntu.com/ubuntu/',
- 'config': {'dist': 'quantal'}}
-
- repo_type = inst.capabilities_lookup()['repo_mngt_tool']
- if repo_type == 'yum':
- repo = yum_repo
- elif repo_type == 'deb':
- repo = deb_repo
- else:
- # repository management tool was not recognized by Kimchi
- # skip test case
- return
-
- system_host_repos = len(inst.repositories_get_list())
-
- repo_id = inst.repositories_create(repo)
-
- host_repos = inst.repositories_get_list()
- self.assertEquals(system_host_repos + 1, len(host_repos))
-
- repo_info = inst.repository_lookup(repo_id)
- self.assertEquals(True, repo_info['enabled'])
-
- inst.repository_disable(repo_id)
- repo_info = inst.repository_lookup(repo_id)
- self.assertEquals(False, repo_info['enabled'])
-
- inst.repository_enable(repo_id)
- repo_info = inst.repository_lookup(repo_id)
- self.assertEquals(True, repo_info['enabled'])
-
- # remove files creates
- inst.repository_delete(repo_id)
-
-
-class BaseModelTests(unittest.TestCase):
- class FoosModel(object):
- def __init__(self):
- self.data = {}
-
- def create(self, params):
- self.data.update(params)
-
- def get_list(self):
- return list(self.data)
-
- class TestModel(wok.basemodel.BaseModel):
- def __init__(self):
- foo = BaseModelTests.FoosModel()
- super(BaseModelTests.TestModel, self).__init__([foo])
-
- def test_root_model(self):
- t = BaseModelTests.TestModel()
- t.foos_create({'item1': 10})
- self.assertEquals(t.foos_get_list(), ['item1'])
diff --git a/plugins/kimchi/tests/test_model_network.py
b/plugins/kimchi/tests/test_model_network.py
deleted file mode 100644
index e4cf5ef..0000000
--- a/plugins/kimchi/tests/test_model_network.py
+++ /dev/null
@@ -1,149 +0,0 @@
-# -*- coding: utf-8 -*-
-#
-# Project Kimchi
-#
-# Copyright IBM, Corp. 2015
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-
-import json
-import os
-import unittest
-from functools import partial
-
-from wok.rollbackcontext import RollbackContext
-
-from wok.plugins.kimchi.model.model import Model
-
-from utils import get_free_port, patch_auth, request, rollback_wrapper
-from utils import run_server
-
-
-model = None
-test_server = None
-host = None
-port = None
-ssl_port = None
-cherrypy_port = None
-
-
-def setUpModule():
- global test_server, model, host, port, ssl_port, cherrypy_port
-
- patch_auth()
- model = Model(None, '/tmp/obj-store-test')
- host = '127.0.0.1'
- port = get_free_port('http')
- ssl_port = get_free_port('https')
- cherrypy_port = get_free_port('cherrypy_port')
- test_server = run_server(host, port, ssl_port, test_mode=True,
- cherrypy_port=cherrypy_port, model=model)
-
-
-def tearDownModule():
- test_server.stop()
- os.unlink('/tmp/obj-store-test')
-
-
-def _do_network_test(self, model, params):
- with RollbackContext() as rollback:
- net_name = params['name']
- uri = '/plugins/kimchi/networks/%s' % net_name.encode('utf-8')
-
- # Create a network
- req = json.dumps(params)
- resp = self.request('/plugins/kimchi/networks', req, 'POST')
- rollback.prependDefer(rollback_wrapper, model.network_delete,
- net_name)
- self.assertEquals(201, resp.status)
-
- # Verify the network
- resp = self.request(uri)
- network = json.loads(resp.read())
- self.assertEquals('inactive', network['state'])
- self.assertTrue(network['persistent'])
-
- # activate the network
- resp = self.request(uri + '/activate', '{}', 'POST')
- rollback.prependDefer(rollback_wrapper,
- model.network_deactivate, net_name)
- self.assertEquals(200, resp.status)
- resp = self.request(uri)
- network = json.loads(resp.read())
- self.assertEquals('active', network['state'])
-
- # Deactivate the network
- resp = self.request(uri + '/deactivate', '{}', 'POST')
- self.assertEquals(200, resp.status)
- resp = self.request(uri)
- network = json.loads(resp.read())
- self.assertEquals('inactive', network['state'])
-
- # Delete the network
- resp = self.request(uri, '{}', 'DELETE')
- self.assertEquals(204, resp.status)
-
-
-class NetworkTests(unittest.TestCase):
- def setUp(self):
- self.request = partial(request, host, ssl_port)
-
- def test_get_networks(self):
- networks = json.loads(self.request('/plugins/kimchi/networks').read())
- self.assertIn('default', [net['name'] for net in networks])
-
- with RollbackContext() as rollback:
- # Now add a couple of Networks to the mock model
- for i in xrange(5):
- name = 'network-%i' % i
- req = json.dumps({'name': name,
- 'connection': 'nat',
- 'subnet': '127.0.10%i.0/24' % i})
-
- resp = self.request('/plugins/kimchi/networks', req,
'POST')
- rollback.prependDefer(model.network_delete, name)
- self.assertEquals(201, resp.status)
- network = json.loads(resp.read())
- self.assertEquals([], network["vms"])
-
- nets = json.loads(self.request('/plugins/kimchi/networks').read())
- self.assertEquals(len(networks) + 5, len(nets))
-
- network = json.loads(
- self.request('/plugins/kimchi/networks/network-1').read()
- )
- keys = [u'name', u'connection', u'interface',
u'subnet', u'dhcp',
- u'vms', u'in_use', u'autostart',
u'state', u'persistent']
- self.assertEquals(sorted(keys), sorted(network.keys()))
-
- def test_network_lifecycle(self):
- # Verify all the supported network type
- networks = [{'name': u'k������h��-��et', 'connection':
'isolated'},
- {'name': u'nat-network', 'connection':
'nat'},
- {'name': u'subnet-network', 'connection':
'nat',
- 'subnet': '127.0.100.0/24'}]
-
- # Verify the current system has at least one interface to create a
- # bridged network
- interfaces = json.loads(
- self.request('/plugins/kimchi/interfaces?type=nic').read()
- )
- if len(interfaces) > 0:
- iface = interfaces[0]['name']
- networks.append({'name': u'bridge-network',
'connection': 'bridge',
- 'interface': iface})
-
- for net in networks:
- _do_network_test(self, model, net)
diff --git a/plugins/kimchi/tests/test_model_storagepool.py
b/plugins/kimchi/tests/test_model_storagepool.py
deleted file mode 100644
index 5f9b966..0000000
--- a/plugins/kimchi/tests/test_model_storagepool.py
+++ /dev/null
@@ -1,123 +0,0 @@
-# -*- coding: utf-8 -*-
-#
-# Project Kimchi
-#
-# Copyright IBM, Corp. 2015
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-
-import json
-import os
-import tempfile
-import unittest
-from functools import partial
-
-from wok.rollbackcontext import RollbackContext
-
-from wok.plugins.kimchi.model.model import Model
-
-from utils import get_free_port, patch_auth, request
-from utils import run_server
-
-
-model = None
-test_server = None
-host = None
-port = None
-ssl_port = None
-cherrypy_port = None
-
-
-def setUpModule():
- global test_server, model, host, port, ssl_port, cherrypy_port
-
- patch_auth()
- model = Model(None, '/tmp/obj-store-test')
- host = '127.0.0.1'
- port = get_free_port('http')
- ssl_port = get_free_port('https')
- cherrypy_port = get_free_port('cherrypy_port')
- test_server = run_server(host, port, ssl_port, test_mode=True,
- cherrypy_port=cherrypy_port, model=model)
-
-
-def tearDownModule():
- test_server.stop()
- os.unlink('/tmp/obj-store-test')
-
-
-class StoragepoolTests(unittest.TestCase):
- def setUp(self):
- self.request = partial(request, host, ssl_port)
-
- def test_get_storagepools(self):
- storagepools = json.loads(
- self.request('/plugins/kimchi/storagepools').read()
- )
- self.assertIn('default', [pool['name'] for pool in
storagepools])
-
- with RollbackContext() as rollback:
- # Now add a couple of storage pools
- for i in xrange(3):
- name = u'k������h��-storagepool-%i' % i
- req = json.dumps({'name': name, 'type': 'dir',
- 'path': '/var/lib/libvirt/images/%i' %
i})
- resp = self.request('/plugins/kimchi/storagepools', req,
- 'POST')
- rollback.prependDefer(model.storagepool_delete, name)
-
- self.assertEquals(201, resp.status)
-
- # Pool name must be unique
- req = json.dumps({'name': name, 'type': 'dir',
- 'path': '/var/lib/libvirt/images/%i' %
i})
- resp = self.request('/plugins/kimchi/storagepools', req,
- 'POST')
- self.assertEquals(400, resp.status)
-
- # Verify pool information
- resp = self.request('/plugins/kimchi/storagepools/%s' %
- name.encode("utf-8"))
- p = json.loads(resp.read())
- keys = [u'name', u'state', u'capacity',
u'allocated',
- u'available', u'path', u'source',
u'type',
- u'nr_volumes', u'autostart',
u'persistent']
- self.assertEquals(sorted(keys), sorted(p.keys()))
- self.assertEquals(name, p['name'])
- self.assertEquals('inactive', p['state'])
- self.assertEquals(True, p['persistent'])
- self.assertEquals(True, p['autostart'])
- self.assertEquals(0, p['nr_volumes'])
-
- pools = json.loads(
- self.request('/plugins/kimchi/storagepools').read()
- )
- self.assertEquals(len(storagepools) + 3, len(pools))
-
- # Create a pool with an existing path
- tmp_path = tempfile.mkdtemp(dir='/var/lib/kimchi')
- rollback.prependDefer(os.rmdir, tmp_path)
- req = json.dumps({'name': 'existing_path', 'type':
'dir',
- 'path': tmp_path})
- resp = self.request('/plugins/kimchi/storagepools', req,
'POST')
- rollback.prependDefer(model.storagepool_delete, 'existing_path')
- self.assertEquals(201, resp.status)
-
- # Reserved pool return 400
- req = json.dumps({'name': 'kimchi_isos', 'type':
'dir',
- 'path': '/var/lib/libvirt/images/%i' % i})
- resp = request(host, ssl_port, '/plugins/kimchi/storagepools', req,
- 'POST')
- self.assertEquals(400, resp.status)
diff --git a/plugins/kimchi/tests/test_model_storagevolume.py
b/plugins/kimchi/tests/test_model_storagevolume.py
deleted file mode 100644
index 46c07bd..0000000
--- a/plugins/kimchi/tests/test_model_storagevolume.py
+++ /dev/null
@@ -1,280 +0,0 @@
-# -*- coding: utf-8 -*-
-#
-# Project Kimchi
-#
-# Copyright IBM, Corp. 2015
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-
-import json
-import os
-import requests
-import unittest
-from functools import partial
-
-from wok.config import paths
-from wok.rollbackcontext import RollbackContext
-
-from wok.plugins.kimchi.config import READONLY_POOL_TYPE
-from wok.plugins.kimchi.mockmodel import MockModel
-from wok.plugins.kimchi.model.model import Model
-
-from utils import fake_auth_header, get_free_port, patch_auth, request
-from utils import rollback_wrapper, run_server, wait_task
-
-
-model = None
-test_server = None
-host = None
-port = None
-ssl_port = None
-cherrypy_port = None
-
-
-def setUpModule():
- global test_server, model, host, port, ssl_port, cherrypy_port
-
- patch_auth()
- model = Model(None, '/tmp/obj-store-test')
- host = '127.0.0.1'
- port = get_free_port('http')
- ssl_port = get_free_port('https')
- cherrypy_port = get_free_port('cherrypy_port')
- test_server = run_server(host, port, ssl_port, test_mode=True,
- cherrypy_port=cherrypy_port, model=model)
-
-
-def tearDownModule():
- test_server.stop()
- os.unlink('/tmp/obj-store-test')
-
-
-def _do_volume_test(self, model, host, ssl_port, pool_name):
- def _task_lookup(taskid):
- return json.loads(
- self.request('/tasks/%s' % taskid).read()
- )
-
- uri = '/plugins/kimchi/storagepools/%s/storagevolumes' \
- % pool_name.encode('utf-8')
- resp = self.request(uri)
- self.assertEquals(200, resp.status)
-
- resp = self.request('/plugins/kimchi/storagepools/%s' %
- pool_name.encode('utf-8'))
- pool_info = json.loads(resp.read())
- with RollbackContext() as rollback:
- # Create storage volume with 'capacity'
- vol = 'test-volume'
- vol_uri = uri + '/' + vol
- req = json.dumps({'name': vol, 'format': 'raw',
- 'capacity': 1073741824}) # 1 GiB
- resp = self.request(uri, req, 'POST')
- if pool_info['type'] in READONLY_POOL_TYPE:
- self.assertEquals(400, resp.status)
- else:
- rollback.prependDefer(rollback_wrapper, model.storagevolume_delete,
- pool_name, vol)
- self.assertEquals(202, resp.status)
- task_id = json.loads(resp.read())['id']
- wait_task(_task_lookup, task_id)
- status = json.loads(
- self.request('/tasks/%s' % task_id).read()
- )
- self.assertEquals('finished', status['status'])
- vol_info = json.loads(self.request(vol_uri).read())
- vol_info['name'] = vol
- vol_info['format'] = 'raw'
- vol_info['capacity'] = 1073741824
-
- # Resize the storage volume: increase its capacity to 2 GiB
- req = json.dumps({'size': 2147483648}) # 2 GiB
- resp = self.request(vol_uri + '/resize', req, 'POST')
- self.assertEquals(200, resp.status)
- storagevolume = json.loads(self.request(vol_uri).read())
- self.assertEquals(2147483648, storagevolume['capacity'])
-
- # Resize the storage volume: decrease its capacity to 512 MiB
- # FIXME: Due a libvirt bug it is not possible to decrease the
- # volume capacity
- # For reference:
- # -
https://bugzilla.redhat.com/show_bug.cgi?id=1021802
- req = json.dumps({'size': 536870912}) # 512 MiB
- resp = self.request(vol_uri + '/resize', req, 'POST')
- # It is only possible when using MockModel
- if isinstance(model, MockModel):
- self.assertEquals(200, resp.status)
- storagevolume = json.loads(self.request(vol_uri).read())
- self.assertEquals(536870912, storagevolume['capacity'])
- else:
- self.assertEquals(500, resp.status)
-
- # Wipe the storage volume
- resp = self.request(vol_uri + '/wipe', '{}', 'POST')
- self.assertEquals(200, resp.status)
- storagevolume = json.loads(self.request(vol_uri).read())
- self.assertEquals(0, storagevolume['allocation'])
-
- # Clone the storage volume
- vol_info = json.loads(self.request(vol_uri).read())
- resp = self.request(vol_uri + '/clone', '{}',
'POST')
- self.assertEquals(202, resp.status)
- task = json.loads(resp.read())
- cloned_vol_name = task['target_uri'].split('/')[-1]
- rollback.prependDefer(model.storagevolume_delete, pool_name,
- cloned_vol_name)
- wait_task(_task_lookup, task['id'])
- task = json.loads(
- self.request('/tasks/%s' % task['id']).read()
- )
- self.assertEquals('finished', task['status'])
- resp = self.request(uri + '/' +
cloned_vol_name.encode('utf-8'))
-
- self.assertEquals(200, resp.status)
- cloned_vol = json.loads(resp.read())
-
- self.assertNotEquals(vol_info['name'], cloned_vol['name'])
- self.assertNotEquals(vol_info['path'], cloned_vol['path'])
- for key in ['name', 'path', 'allocation']:
- del vol_info[key]
- del cloned_vol[key]
-
- self.assertEquals(vol_info, cloned_vol)
-
- # Delete the storage volume
- resp = self.request(vol_uri, '{}', 'DELETE')
- self.assertEquals(204, resp.status)
- resp = self.request(vol_uri)
- self.assertEquals(404, resp.status)
-
- # Storage volume upload
- # It is done through a sequence of POST and several PUT requests
- filename = 'COPYING.LGPL'
- filepath = os.path.join(paths.get_prefix(), filename)
- filesize = os.stat(filepath).st_size
-
- # Create storage volume for upload
- req = json.dumps({'name': filename, 'format': 'raw',
- 'capacity': filesize, 'upload': True})
- resp = self.request(uri, req, 'POST')
- if pool_info['type'] in READONLY_POOL_TYPE:
- self.assertEquals(400, resp.status)
- else:
- rollback.prependDefer(rollback_wrapper, model.storagevolume_delete,
- pool_name, filename)
- self.assertEquals(202, resp.status)
- task_id = json.loads(resp.read())['id']
- wait_task(_task_lookup, task_id)
- status = json.loads(self.request('/tasks/%s' %
- task_id).read())
- self.assertEquals('ready for upload', status['message'])
-
- # Upload volume content
- url = 'https://%s:%s' % (host, ssl_port) + uri + '/' +
filename
-
- # Create a file with 5M to upload
- # Max body size is set to 4M so the upload will fail with 413
- newfile = '/tmp/5m-file'
- with open(newfile, 'wb') as fd:
- fd.seek(5*1024*1024-1)
- fd.write("\0")
- rollback.prependDefer(os.remove, newfile)
-
- with open(newfile, 'rb') as fd:
- with open(newfile + '.tmp', 'wb') as tmp_fd:
- data = fd.read()
- tmp_fd.write(data)
-
- with open(newfile + '.tmp', 'rb') as tmp_fd:
- r = requests.put(url, data={'chunk_size': len(data)},
- files={'chunk': tmp_fd},
- verify=False,
- headers=fake_auth_header())
- self.assertEquals(r.status_code, 413)
-
- # Do upload
- index = 0
- chunk_size = 2 * 1024
- content = ''
-
- with open(filepath, 'rb') as fd:
- while True:
- with open(filepath + '.tmp', 'wb') as tmp_fd:
- fd.seek(index*chunk_size)
- data = fd.read(chunk_size)
- tmp_fd.write(data)
-
- with open(filepath + '.tmp', 'rb') as tmp_fd:
- r = requests.put(url, data={'chunk_size': len(data)},
- files={'chunk': tmp_fd},
- verify=False,
- headers=fake_auth_header())
- self.assertEquals(r.status_code, 200)
- content += data
- index = index + 1
-
- if len(data) < chunk_size:
- break
-
- rollback.prependDefer(os.remove, filepath + '.tmp')
- resp = self.request(uri + '/' + filename)
- self.assertEquals(200, resp.status)
- uploaded_path = json.loads(resp.read())['path']
- with open(uploaded_path) as fd:
- uploaded_content = fd.read()
-
- self.assertEquals(content, uploaded_content)
-
- # Create storage volume with 'url'
- url = 'https://github.com/kimchi-project/kimchi/raw/master/COPYING'
- req = json.dumps({'url': url})
- resp = self.request(uri, req, 'POST')
-
- if pool_info['type'] in READONLY_POOL_TYPE:
- self.assertEquals(400, resp.status)
- else:
- rollback.prependDefer(model.storagevolume_delete, pool_name,
- 'COPYING')
- self.assertEquals(202, resp.status)
- task = json.loads(resp.read())
- wait_task(_task_lookup, task['id'])
- resp = self.request(uri + '/COPYING')
- self.assertEquals(200, resp.status)
-
-
-class StorageVolumeTests(unittest.TestCase):
- def setUp(self):
- self.request = partial(request, host, ssl_port)
-
- def test_get_storagevolume(self):
- uri = '/plugins/kimchi/storagepools/default/storagevolumes'
- resp = self.request(uri)
- self.assertEquals(200, resp.status)
-
- keys = [u'name', u'type', u'capacity',
u'allocation', u'path',
- u'used_by', u'format']
- for vol in json.loads(resp.read()):
- resp = self.request(uri + '/' + vol['name'])
- self.assertEquals(200, resp.status)
-
- all_keys = keys[:]
- vol_info = json.loads(resp.read())
- if vol_info['format'] == 'iso':
- all_keys.extend([u'os_distro', u'os_version',
u'bootable'])
-
- self.assertEquals(sorted(all_keys), sorted(vol_info.keys()))
-
- def test_storagevolume_action(self):
- _do_volume_test(self, model, host, ssl_port, 'default')
diff --git a/plugins/kimchi/tests/test_networkxml.py
b/plugins/kimchi/tests/test_networkxml.py
deleted file mode 100644
index a64b6c2..0000000
--- a/plugins/kimchi/tests/test_networkxml.py
+++ /dev/null
@@ -1,172 +0,0 @@
-#
-# Kimchi
-#
-# Copyright IBM, Corp. 2013-2014
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-
-import ipaddr
-import lxml.etree as ET
-import unittest
-
-from wok.xmlutils.utils import xpath_get_text
-
-from wok.plugins.kimchi.xmlutils import network as nxml
-
-import utils
-
-
-class NetworkXmlTests(unittest.TestCase):
- def test_dhcp_xml(self):
- """
- Test network dhcp xml
- """
- dhcp_range = {"start": "192.168.122.100", "end":
"192.168.122.254"}
- host1 = {"mac": "00:16:3e:77:e2:ed",
- "name": "foo.example.com",
- "ip": "192.168.122.10"}
- host2 = {"mac": "00:16:3e:3e:a9:1a",
- "name": "bar.example.com",
- "ip": "192.168.122.11"}
- params = {}
-
- dhcp = nxml._get_dhcp_elem(**params)
- self.assertEquals(None, dhcp)
-
- params["range"] = dhcp_range
- xml = ET.tostring(nxml._get_dhcp_elem(**params))
- start = xpath_get_text(xml, "/dhcp/range/@start")
- end = xpath_get_text(xml, "/dhcp/range/@end")
- self.assertEquals(dhcp_range['start'], start[0])
- self.assertEquals(dhcp_range['end'], end[0])
-
- params["hosts"] = [host1, host2]
- xml = ET.tostring(nxml._get_dhcp_elem(**params))
- ip = xpath_get_text(xml, "/dhcp/host/@ip")
- self.assertEquals(ip, [host1['ip'], host2['ip']])
-
- def test_ip_xml(self):
- """
- Test network ip xml
- """
- dhcp_range = {"start": "192.168.122.100", "end":
"192.168.122.254"}
- params = {}
-
- dhcp = nxml._get_dhcp_elem(**params)
- self.assertEquals(None, dhcp)
-
- params["net"] = "192.168.122.0/255.255.255.0"
- params["dhcp"] = {'range': dhcp_range}
- xml = ET.tostring(nxml._get_ip_elem(**params))
- start = xpath_get_text(xml, "/ip/dhcp/range/@start")[0]
- end = xpath_get_text(xml, "/ip/dhcp/range/@end")[0]
- self.assertEquals(dhcp_range['start'], start)
- self.assertEquals(dhcp_range['end'], end)
-
- address = xpath_get_text(xml, "/ip/@address")[0]
- netmask = xpath_get_text(xml, "/ip/@netmask")[0]
- self.assertEquals(address, params["net"].split("/")[0])
- self.assertEquals(netmask, params["net"].split("/")[1])
-
- # test _get_ip_xml can accepts strings: '192.168.122.0/24',
- # which is same as "192.168.122.0/255.255.255.0"
- params["net"] = "192.168.122.0/24"
- xml = ET.tostring(nxml._get_ip_elem(**params))
- netmask = xpath_get_text(xml, "/ip/@netmask")[0]
- self.assertEquals(netmask,
- str(ipaddr.IPNetwork(params["net"]).netmask))
-
- def test_forward_xml(self):
- """
- Test network forward xml
- """
- params = {"mode": None}
-
- forward = nxml._get_forward_elem(**params)
- self.assertEquals(None, forward)
-
- params["mode"] = 'nat'
- params["dev"] = 'eth0'
- xml = ET.tostring(nxml._get_forward_elem(**params))
- mode = xpath_get_text(xml, "/forward/@mode")[0]
- dev = xpath_get_text(xml, "/forward/@dev")[0]
- self.assertEquals(params['mode'], mode)
- self.assertEquals(params['dev'], dev)
-
- def test_network_xml(self):
- """
- Test network xml
- """
- params = {"name": "test",
- "forward": {"mode": "nat",
"dev": ""},
- "net": "192.168.0.0/255.255.255.0"}
- xml = nxml.to_network_xml(**params)
- name = xpath_get_text(xml, "/network/name")[0]
- self.assertEquals(name, params['name'])
-
- forward_mode = xpath_get_text(xml, "/network/forward/@mode")[0]
- self.assertEquals(forward_mode, params['forward']['mode'])
- forward_dev = xpath_get_text(xml, "/network/forward/@dev")[0]
- self.assertEquals(forward_dev, '')
-
- address = xpath_get_text(xml, "/network/ip/@address")[0]
- self.assertEquals(address, params["net"].split("/")[0])
- netmask = xpath_get_text(xml, "/network/ip/@netmask")[0]
- self.assertEquals(netmask, params["net"].split("/")[1])
-
- dhcp_start = xpath_get_text(xml, "/network/ip/dhcp/range/@start")
- self.assertEquals(dhcp_start, [])
- dhcp_end = xpath_get_text(xml, "/network/ip/dhcp/range/@end")
- self.assertEquals(dhcp_end, [])
-
- # test optional params
- params['forward']['dev'] = "eth0"
- params['dhcp'] = {"range": {'start':
'192.168.0.1',
- 'end': '192.168.0.254'}}
- xml = nxml.to_network_xml(**params)
- forward_dev = xpath_get_text(xml, "/network/forward/@dev")[0]
- self.assertEquals(forward_dev, params['forward']['dev'])
-
- dhcp_start = xpath_get_text(xml, "/network/ip/dhcp/range/@start")[0]
- self.assertEquals(dhcp_start,
params['dhcp']['range']['start'])
- dhcp_end = xpath_get_text(xml, "/network/ip/dhcp/range/@end")[0]
- self.assertEquals(dhcp_end,
params['dhcp']['range']['end'])
-
- # test _get_ip_xml can accepts strings: '192.168.122.0/24',
- # which is same as "192.168.122.0/255.255.255.0"
- params["net"] = "192.168.0.0/24"
- xml = nxml.to_network_xml(**params)
- netmask = xpath_get_text(xml, "/network/ip/@netmask")[0]
- self.assertEquals(netmask,
- str(ipaddr.IPNetwork(params["net"]).netmask))
-
-
-class InterfaceXmlTests(unittest.TestCase):
-
- def test_vlan_tagged_bridge_no_ip(self):
- expected_xml = """
- <interface type='bridge' name='br10'>
- <start mode='onboot'/>
- <bridge>
- <interface type='vlan' name='em1.10'>
- <vlan tag='10'>
- <interface name='em1'/>
- </vlan>
- </interface>
- </bridge>
- </interface>
- """
- actual_xml = nxml.create_vlan_tagged_bridge_xml('br10', 'em1',
'10')
- self.assertEquals(actual_xml, utils.normalize_xml(expected_xml))
diff --git a/plugins/kimchi/tests/test_objectstore.py
b/plugins/kimchi/tests/test_objectstore.py
deleted file mode 100644
index 632786f..0000000
--- a/plugins/kimchi/tests/test_objectstore.py
+++ /dev/null
@@ -1,97 +0,0 @@
-# -*- coding: utf-8 -*-
-#
-# Project Kimchi
-#
-# Copyright IBM, Corp. 2015
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-
-import os
-import tempfile
-import threading
-import unittest
-
-from wok import objectstore
-from wok.exception import NotFoundError
-
-
-tmpfile = None
-
-
-def setUpModule():
- global tmpfile
- tmpfile = tempfile.mktemp()
-
-
-def tearDownModule():
- os.unlink(tmpfile)
-
-
-class ObjectStoreTests(unittest.TestCase):
- def test_objectstore(self):
- store = objectstore.ObjectStore(tmpfile)
-
- with store as session:
- # Test create
- session.store('f����', 't��st1', {'��': 1})
- session.store('f����', 't��st2', {'��': 2})
-
- # Test list
- items = session.get_list('f����')
- self.assertTrue(u't��st1' in items)
- self.assertTrue(u't��st2' in items)
-
- # Test get
- item = session.get('f����', 't��st1')
- self.assertEquals(1, item[u'��'])
-
- # Test delete
- session.delete('f����', 't��st2')
- self.assertEquals(1, len(session.get_list('f����')))
-
- # Test get non-existent item
-
- self.assertRaises(NotFoundError, session.get,
- '��', '��')
-
- # Test delete non-existent item
- self.assertRaises(NotFoundError, session.delete,
- 'f����', 't��st2')
-
- # Test refresh existing item
- session.store('f����', 't��st1', {'��': 2})
- item = session.get('f����', 't��st1')
- self.assertEquals(2, item[u'��'])
-
- def test_object_store_threaded(self):
- def worker(ident):
- with store as session:
- session.store('foo', ident, {})
-
- store = objectstore.ObjectStore(tmpfile)
-
- threads = []
- for i in xrange(50):
- t = threading.Thread(target=worker, args=(i,))
- t.setDaemon(True)
- t.start()
- threads.append(t)
-
- for t in threads:
- t.join()
-
- with store as session:
- self.assertEquals(50, len(session.get_list('foo')))
- self.assertEquals(10, len(store._connections.keys()))
diff --git a/plugins/kimchi/tests/test_osinfo.py b/plugins/kimchi/tests/test_osinfo.py
deleted file mode 100644
index bd2af58..0000000
--- a/plugins/kimchi/tests/test_osinfo.py
+++ /dev/null
@@ -1,69 +0,0 @@
-#
-# Project Kimchi
-#
-# Copyright IBM, Corp. 2013-2015
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-
-import unittest
-
-from wok.plugins.kimchi.osinfo import _get_arch, get_template_default, lookup
-from wok.plugins.kimchi.osinfo import modern_version_bases
-
-
-class OSInfoTests(unittest.TestCase):
- def test_default_lookup(self):
- entry = lookup(None, None)
- self.assertEquals('unknown', entry['os_distro'])
- self.assertEquals('unknown', entry['os_version'])
- self.assertEquals(['default'], entry['networks'])
-
- def test_old_distros(self):
- old_versions = {'debian': '5.0', 'ubuntu':
'7.04', 'opensuse': '10.1',
- 'centos': '5.1', 'rhel': '5.1',
'fedora': '15'}
- for distro, version in old_versions.iteritems():
- entry = lookup(distro, version)
- self.assertEquals(entry['disk_bus'],
- get_template_default('old', 'disk_bus'))
- self.assertEquals(entry['nic_model'],
- get_template_default('old', 'nic_model'))
-
- def test_modern_bases(self):
- for distro, version in modern_version_bases[_get_arch()].iteritems():
- entry = lookup(distro, version)
- self.assertEquals(entry['disk_bus'],
- get_template_default('modern',
'disk_bus'))
- self.assertEquals(entry['nic_model'],
- get_template_default('modern',
'nic_model'))
-
- def test_modern_distros(self):
- # versions based on ppc64 modern distros
- modern_versions = {'ubuntu': '14.04', 'opensuse':
'13.1',
- 'rhel': '6.5', 'fedora': '19',
'sles': '11sp3'}
- for distro, version in modern_versions.iteritems():
- entry = lookup(distro, version)
- self.assertEquals(entry['disk_bus'],
- get_template_default('modern',
'disk_bus'))
- self.assertEquals(entry['nic_model'],
- get_template_default('modern',
'nic_model'))
-
- def test_lookup_unknown_distro_version_returns_old_distro(self):
- distro = 'unknown_distro'
- version = 'unknown_version'
- entry = lookup(distro, version)
- self.assertEquals(entry['disk_bus'],
- get_template_default('old', 'disk_bus'))
- self.assertEquals(entry['nic_model'],
- get_template_default('old', 'nic_model'))
diff --git a/plugins/kimchi/tests/test_plugin.py b/plugins/kimchi/tests/test_plugin.py
deleted file mode 100644
index fc8e277..0000000
--- a/plugins/kimchi/tests/test_plugin.py
+++ /dev/null
@@ -1,126 +0,0 @@
-#
-# Project Kimchi
-#
-# Copyright IBM, Corp. 2013-2014
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-
-import json
-import os
-import unittest
-from functools import partial
-
-from wok.utils import get_enabled_plugins
-
-from wok.plugins.kimchi import mockmodel
-
-import utils
-
-
-test_server = None
-model = None
-host = None
-port = None
-ssl_port = None
-
-
-def setUpModule():
- global test_server, model, host, port, ssl_port
-
- utils.patch_auth()
- model = mockmodel.MockModel('/tmp/obj-store-test')
- host = '127.0.0.1'
- port = utils.get_free_port('http')
- ssl_port = utils.get_free_port('https')
- test_server = utils.run_server(host, port, ssl_port, test_mode=True,
- model=model)
-
-
-def tearDownModule():
- test_server.stop()
- os.unlink('/tmp/obj-store-test')
-
-
-(a)unittest.skipUnless(
- 'sample' in [plugin for plugin, _config in get_enabled_plugins()],
- 'sample plugin is not enabled, skip this test!')
-class PluginTests(unittest.TestCase):
-
- def setUp(self):
- self.request = partial(utils.request, host, ssl_port)
-
- def _create_rectangle(self, name, length, width):
- req = json.dumps({'name': name, 'length': length,
'width': width})
- resp = self.request('/plugins/sample/rectangles', req, 'POST')
- return resp
-
- def _get_rectangle(self, name):
- resp = self.request('/plugins/sample/rectangles/%s' % name)
- return json.loads(resp.read())
-
- def _create_rectangle_and_assert(self, name, length, width):
- resp = self._create_rectangle(name, length, width)
- self.assertEquals(201, resp.status)
-
- rectangle = self._get_rectangle(name)
- self.assertEquals(rectangle['name'], name)
- self.assertEquals(rectangle['length'], length)
- self.assertEquals(rectangle['width'], width)
-
- def _get_rectangles_list(self):
- resp = self.request('/plugins/sample/rectangles')
- rectangles = json.loads(resp.read())
- name_list = [rectangle['name'] for rectangle in rectangles]
- return name_list
-
- def test_rectangles(self):
- # Create two new rectangles
- self._create_rectangle_and_assert('small', 10, 8)
- self._create_rectangle_and_assert('big', 20, 16)
-
- # Verify they're in the list
- name_list = self._get_rectangles_list()
- self.assertIn('small', name_list)
- self.assertIn('big', name_list)
-
- # Update the big rectangle.
- req = json.dumps({'length': 40, 'width': 30})
- resp = self.request('/plugins/sample/rectangles/big', req,
'PUT')
- self.assertEquals(200, resp.status)
- big = self._get_rectangle('big')
- self.assertEquals(big['length'], 40)
- self.assertEquals(big['width'], 30)
-
- # Delete two rectangles
- resp = self.request('/plugins/sample/rectangles/big', '{}',
'DELETE')
- self.assertEquals(204, resp.status)
- resp = self.request('/plugins/sample/rectangles/small', '{}',
'DELETE')
- self.assertEquals(204, resp.status)
- name_list = self._get_rectangles_list()
- self.assertEquals([], name_list)
-
- def test_bad_params(self):
- # Bad name
- resp = self._create_rectangle(1.0, 30, 40)
- self.assertEquals(400, resp.status)
-
- # Bad length value
- resp = self._create_rectangle('test', -10.0, 40)
- self.assertEquals(400, resp.status)
-
- # Missing param for width
- req = json.dumps({'name': 'nowidth', 'length': 40})
- resp = self.request('/plugins/sample/rectangles', req, 'POST')
- self.assertEquals(400, resp.status)
diff --git a/plugins/kimchi/tests/test_rest.py b/plugins/kimchi/tests/test_rest.py
deleted file mode 100644
index 243074e..0000000
--- a/plugins/kimchi/tests/test_rest.py
+++ /dev/null
@@ -1,1327 +0,0 @@
-# -*- coding: utf-8 -*-
-#
-# Project Kimchi
-#
-# Copyright IBM, Corp. 2013-2015
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-
-import json
-import os
-import re
-import time
-import unittest
-import urllib2
-import urlparse
-from functools import partial
-
-from wok.rollbackcontext import RollbackContext
-from wok.utils import add_task
-
-from wok.plugins.kimchi import mockmodel
-from wok.plugins.kimchi.osinfo import get_template_default
-
-import iso_gen
-from utils import get_free_port, patch_auth, request
-from utils import run_server, wait_task
-
-
-test_server = None
-model = None
-host = None
-port = None
-ssl_port = None
-cherrypy_port = None
-fake_iso = '/tmp/fake.iso'
-
-
-def setUpModule():
- global test_server, model, host, port, ssl_port, cherrypy_port
-
- patch_auth()
- model = mockmodel.MockModel('/tmp/obj-store-test')
- host = '127.0.0.1'
- port = get_free_port('http')
- ssl_port = get_free_port('https')
- cherrypy_port = get_free_port('cherrypy_port')
- test_server = run_server(host, port, ssl_port, test_mode=True,
- cherrypy_port=cherrypy_port, model=model)
-
- # Create fake ISO to do the tests
- iso_gen.construct_fake_iso(fake_iso, True, '12.04', 'ubuntu')
- iso_gen.construct_fake_iso("/var/lib/libvirt/images/fedora.iso", True,
- "17", "fedora")
-
-
-def tearDownModule():
- test_server.stop()
- os.unlink('/tmp/obj-store-test')
- os.unlink(fake_iso)
- os.unlink("/var/lib/libvirt/images/fedora.iso")
-
-
-class RestTests(unittest.TestCase):
- def _async_op(self, cb, opaque):
- time.sleep(1)
- cb('success', True)
-
- def _except_op(self, cb, opaque):
- time.sleep(1)
- raise Exception("Oops, this is an exception handle test."
- " You can ignore it safely")
- cb('success', True)
-
- def _intermid_op(self, cb, opaque):
- time.sleep(1)
- cb('in progress')
-
- def setUp(self):
- self.request = partial(request, host, ssl_port)
- model.reset()
-
- def assertHTTPStatus(self, code, *args):
- resp = self.request(*args)
- self.assertEquals(code, resp.status)
-
- def test_get_vms(self):
- vms = json.loads(self.request('/plugins/kimchi/vms').read())
- # test_rest.py uses MockModel() which connects to libvirt URI
- # test:///default. By default this driver already has one VM created
- self.assertEquals(1, len(vms))
-
- # Create a template as a base for our VMs
- req = json.dumps({'name': 'test', 'cdrom': fake_iso})
- resp = self.request('/plugins/kimchi/templates', req, 'POST')
- self.assertEquals(201, resp.status)
-
- test_users = ['root']
- test_groups = ['wheel']
- # Now add a couple of VMs to the mock model
- for i in xrange(10):
- name = 'vm-%i' % i
- req = json.dumps({'name': name,
- 'template':
'/plugins/kimchi/templates/test',
- 'users': test_users, 'groups':
test_groups})
- resp = self.request('/plugins/kimchi/vms', req, 'POST')
- self.assertEquals(202, resp.status)
- task = json.loads(resp.read())
- wait_task(self._task_lookup, task['id'])
-
- vms = json.loads(self.request('/plugins/kimchi/vms').read())
- self.assertEquals(11, len(vms))
-
- vm = json.loads(self.request('/plugins/kimchi/vms/vm-1').read())
- self.assertEquals('vm-1', vm['name'])
- self.assertEquals('shutoff', vm['state'])
- self.assertEquals([], vm['users'])
- self.assertEquals([], vm['groups'])
-
- def test_edit_vm(self):
- req = json.dumps({'name': 'test', 'cdrom': fake_iso})
- resp = self.request('/plugins/kimchi/templates', req, 'POST')
- self.assertEquals(201, resp.status)
-
- req = json.dumps({'name': 'vm-1',
- 'template': '/plugins/kimchi/templates/test'})
- resp = self.request('/plugins/kimchi/vms', req, 'POST')
- self.assertEquals(202, resp.status)
- task = json.loads(resp.read())
- wait_task(self._task_lookup, task['id'])
-
- vm = json.loads(self.request('/plugins/kimchi/vms/vm-1').read())
- self.assertEquals('vm-1', vm['name'])
-
- resp = self.request('/plugins/kimchi/vms/vm-1/start', '{}',
'POST')
- self.assertEquals(200, resp.status)
-
- req = json.dumps({'unsupported-attr': 'attr'})
- resp = self.request('/plugins/kimchi/vms/vm-1', req, 'PUT')
- self.assertEquals(400, resp.status)
-
- req = json.dumps({'name': 'new-vm'})
- resp = self.request('/plugins/kimchi/vms/vm-1', req, 'PUT')
- self.assertEquals(400, resp.status)
-
- req = json.dumps({'cpus': 3})
- resp = self.request('/plugins/kimchi/vms/vm-1', req, 'PUT')
- self.assertEquals(200, resp.status)
-
- # Check if there is support to memory hotplug, once vm is running
- resp = self.request('/plugins/kimchi/config/capabilities').read()
- conf = json.loads(resp)
- req = json.dumps({'memory': 2048})
- resp = self.request('/plugins/kimchi/vms/vm-1', req, 'PUT')
- if conf['mem_hotplug_support']:
- self.assertEquals(200, resp.status)
- else:
- self.assertEquals(400, resp.status)
-
- req = json.dumps({"graphics": {'passwd': "abcdef"}})
- resp = self.request('/plugins/kimchi/vms/vm-1', req, 'PUT')
- info = json.loads(resp.read())
- self.assertEquals('abcdef',
info["graphics"]["passwd"])
- self.assertEquals(None, info["graphics"]["passwdValidTo"])
-
- resp = self.request('/plugins/kimchi/vms/vm-1/poweroff', '{}',
'POST')
- self.assertEquals(200, resp.status)
-
- req = json.dumps({"graphics": {'passwd': "123456",
- 'passwdValidTo': 20}})
- resp = self.request('/plugins/kimchi/vms/vm-1', req, 'PUT')
- info = json.loads(resp.read())
- self.assertEquals('123456',
info["graphics"]["passwd"])
- self.assertGreaterEqual(20,
info["graphics"]["passwdValidTo"])
-
- req = json.dumps({'name': 12})
- resp = self.request('/plugins/kimchi/vms/vm-1', req, 'PUT')
- self.assertEquals(400, resp.status)
-
- req = json.dumps({'name': ''})
- resp = self.request('/plugins/kimchi/vms/vm-1', req, 'PUT')
- self.assertEquals(400, resp.status)
-
- req = json.dumps({'cpus': -2})
- resp = self.request('/plugins/kimchi/vms/vm-1', req, 'PUT')
- self.assertEquals(400, resp.status)
-
- req = json.dumps({'cpus': 'four'})
- resp = self.request('/plugins/kimchi/vms/vm-1', req, 'PUT')
- self.assertEquals(400, resp.status)
-
- req = json.dumps({'memory': 100})
- resp = self.request('/plugins/kimchi/vms/vm-1', req, 'PUT')
- self.assertEquals(400, resp.status)
-
- req = json.dumps({'memory': 'ten gigas'})
- resp = self.request('/plugins/kimchi/vms/vm-1', req, 'PUT')
- self.assertEquals(400, resp.status)
-
- req = json.dumps({'name': 'new-name', 'cpus': 5,
'UUID': 'notallowed'})
- resp = self.request('/plugins/kimchi/vms/vm-1', req, 'PUT')
- self.assertEquals(400, resp.status)
-
- params = {'name': u'�����-����d��t��d', 'cpus': 5,
'memory': 3072}
- req = json.dumps(params)
- resp = self.request('/plugins/kimchi/vms/vm-1', req, 'PUT')
- self.assertEquals(303, resp.status)
- vm = json.loads(
- self.request('/plugins/kimchi/vms/�����-����d��t��d', req).read()
- )
- for key in params.keys():
- self.assertEquals(params[key], vm[key])
-
- # change only VM users - groups are not changed (default is empty)
- resp = self.request('/plugins/kimchi/users', '{}',
'GET')
- users = json.loads(resp.read())
- req = json.dumps({'users': users})
- resp = self.request('/plugins/kimchi/vms/�����-����d��t��d', req,
'PUT')
- self.assertEquals(200, resp.status)
- info = json.loads(
- self.request('/plugins/kimchi/vms/�����-����d��t��d',
'{}').read()
- )
- self.assertEquals(users, info['users'])
-
- # change only VM groups - users are not changed (default is empty)
- resp = self.request('/plugins/kimchi/groups', '{}',
'GET')
- groups = json.loads(resp.read())
- req = json.dumps({'groups': groups})
- resp = self.request('/plugins/kimchi/vms/�����-����d��t��d', req,
'PUT')
- self.assertEquals(200, resp.status)
- info = json.loads(
- self.request('/plugins/kimchi/vms/�����-����d��t��d',
'{}').read()
- )
- self.assertEquals(groups, info['groups'])
-
- # change VM users (wrong value) and groups
- # when an error occurs, everything fails and nothing is changed
- req = json.dumps({'users': ['userdoesnotexist'],
'groups': []})
- resp = self.request('/plugins/kimchi/vms/�����-����d��t��d', req,
'PUT')
- self.assertEquals(400, resp.status)
-
- # change VM users and groups (wrong value)
- # when an error occurs, everything fails and nothing is changed
- req = json.dumps({'users': [], 'groups':
['groupdoesnotexist']})
- resp = self.request('/plugins/kimchi/vms/�����-����d��t��d', req,
'PUT')
- self.assertEquals(400, resp.status)
-
- def test_vm_lifecycle(self):
- # Create a Template
- req = json.dumps({'name': 'test', 'disks':
[{'size': 1}],
- 'icon': 'images/icon-debian.png',
- 'cdrom': fake_iso})
- resp = self.request('/plugins/kimchi/templates', req, 'POST')
- self.assertEquals(201, resp.status)
-
- # Create a VM
- req = json.dumps({'name': 'test-vm',
- 'template': '/plugins/kimchi/templates/test'})
- resp = self.request('/plugins/kimchi/vms', req, 'POST')
- task = json.loads(resp.read())
- wait_task(self._task_lookup, task['id'])
- self.assertEquals(202, resp.status)
-
- # Verify the VM
- vm = json.loads(self.request('/plugins/kimchi/vms/test-vm').read())
- self.assertEquals('shutoff', vm['state'])
- self.assertEquals('images/icon-debian.png', vm['icon'])
-
- # Verify the volume was created
- vol_uri = '/plugins/kimchi/storagepools/default-pool/storagevolumes/' \
- + '%s-0.img'
- resp = self.request(vol_uri % vm['uuid'])
- vol = json.loads(resp.read())
- self.assertEquals(1 << 30, vol['capacity'])
- self.assertEquals(['test-vm'], vol['used_by'])
-
- # Start the VM
- resp = self.request('/plugins/kimchi/vms/test-vm/start', '{}',
'POST')
- vm = json.loads(self.request('/plugins/kimchi/vms/test-vm').read())
- self.assertEquals('running', vm['state'])
-
- # Test screenshot
- resp = self.request(vm['screenshot'], method='HEAD')
- self.assertEquals(200, resp.status)
-
self.assertTrue(resp.getheader('Content-type').startswith('image'))
-
- # Clone a running VM
- resp = self.request('/plugins/kimchi/vms/test-vm/clone', '{}',
'POST')
- self.assertEquals(400, resp.status)
-
- # Force poweroff the VM
- resp = self.request('/plugins/kimchi/vms/test-vm/poweroff',
'{}',
- 'POST')
- vm = json.loads(self.request('/plugins/kimchi/vms/test-vm').read())
- self.assertEquals('shutoff', vm['state'])
-
- # Test create VM with same name fails with 400
- req = json.dumps({'name': 'test-vm',
- 'template': '/plugins/kimchi/templates/test'})
- resp = self.request('/plugins/kimchi/vms', req, 'POST')
- self.assertEquals(400, resp.status)
-
- # Clone a VM
- resp = self.request('/plugins/kimchi/vms/test-vm/clone', '{}',
'POST')
- self.assertEquals(202, resp.status)
- task = json.loads(resp.read())
- wait_task(self._task_lookup, task['id'])
- task = json.loads(
- self.request('/tasks/%s' % task['id'], '{}').read()
- )
- self.assertEquals('finished', task['status'])
- clone_vm_name = task['target_uri'].split('/')[-2]
- self.assertTrue(re.match(u'test-vm-clone-\d+', clone_vm_name))
-
- resp = self.request('/plugins/kimchi/vms/test-vm', '{}')
- original_vm_info = json.loads(resp.read())
- resp = self.request('/plugins/kimchi/vms/%s' % clone_vm_name,
'{}')
- self.assertEquals(200, resp.status)
- clone_vm_info = json.loads(resp.read())
-
- self.assertNotEqual(original_vm_info['name'],
clone_vm_info['name'])
- del original_vm_info['name']
- del clone_vm_info['name']
-
- self.assertNotEqual(original_vm_info['uuid'],
clone_vm_info['uuid'])
- del original_vm_info['uuid']
- del clone_vm_info['uuid']
-
- self.assertEquals(original_vm_info, clone_vm_info)
-
- # Create a snapshot on a stopped VM
- params = {'name': 'test-snap'}
- resp = self.request('/plugins/kimchi/vms/test-vm/snapshots',
- json.dumps(params),
- 'POST')
- self.assertEquals(202, resp.status)
- task = json.loads(resp.read())
- wait_task(self._task_lookup, task['id'])
- task = json.loads(
- self.request('/tasks/%s' % task['id']).read()
- )
- self.assertEquals('finished', task['status'])
-
- # Look up a non-existing snapshot
- resp = self.request('/plugins/kimchi/vms/test-vm/snapshots/snap404',
- '{}', 'GET')
- self.assertEquals(404, resp.status)
-
- # Look up a snapshot
- resp = self.request('/plugins/kimchi/vms/test-vm/snapshots/%s' %
- params['name'], '{}', 'GET')
- self.assertEquals(200, resp.status)
- snap = json.loads(resp.read())
- self.assertTrue(int(time.time()) >= int(snap['created']))
- self.assertEquals(params['name'], snap['name'])
- self.assertEquals(u'', snap['parent'])
- self.assertEquals(u'shutoff', snap['state'])
-
- resp = self.request('/plugins/kimchi/vms/test-vm/snapshots',
'{}',
- 'GET')
- self.assertEquals(200, resp.status)
- snaps = json.loads(resp.read())
- self.assertEquals(1, len(snaps))
-
- # Look up current snapshot (the one created above)
- resp = self.request('/plugins/kimchi/vms/test-vm/snapshots/current',
- '{}', 'GET')
- self.assertEquals(200, resp.status)
- snap = json.loads(resp.read())
- self.assertEquals(params['name'], snap['name'])
-
- resp = self.request('/plugins/kimchi/vms/test-vm/snapshots',
'{}',
- 'POST')
- self.assertEquals(202, resp.status)
- task = json.loads(resp.read())
- snap_name = task['target_uri'].split('/')[-1]
- wait_task(self._task_lookup, task['id'])
- resp = self.request('/tasks/%s' % task['id'], '{}',
- 'GET')
- task = json.loads(resp.read())
- self.assertEquals('finished', task['status'])
-
- resp = self.request('/plugins/kimchi/vms/test-vm/snapshots',
'{}',
- 'GET')
- self.assertEquals(200, resp.status)
- snaps = json.loads(resp.read())
- self.assertEquals(2, len(snaps))
-
- # Look up current snapshot (the one created above)
- resp = self.request('/plugins/kimchi/vms/test-vm/snapshots/current',
- '{}', 'GET')
- self.assertEquals(200, resp.status)
- snap = json.loads(resp.read())
- self.assertEquals(snap_name, snap['name'])
-
- # Revert to snapshot
- resp = self.request('/plugins/kimchi/vms/test-vm/snapshots/%s/revert' %
- params['name'], '{}', 'POST')
- self.assertEquals(200, resp.status)
- snap = json.loads(resp.read())
- resp = self.request('/plugins/kimchi/vms/test-vm', '{}',
'GET')
- self.assertEquals(200, resp.status)
- vm = json.loads(resp.read())
- self.assertEquals(vm['state'], snap['state'])
- resp = self.request('/plugins/kimchi/vms/test-vm/snapshots/current',
- '{}', 'GET')
- self.assertEquals(200, resp.status)
- current_snap = json.loads(resp.read())
- self.assertEquals(snap, current_snap)
-
- # Delete a snapshot
- resp = self.request('/plugins/kimchi/vms/test-vm/snapshots/%s' %
- params['name'], '{}', 'DELETE')
- self.assertEquals(204, resp.status)
-
- # Suspend the VM
- resp = self.request('/plugins/kimchi/vms/test-vm', '{}',
'GET')
- self.assertEquals(200, resp.status)
- vm = json.loads(resp.read())
- self.assertEquals(vm['state'], 'shutoff')
- resp = self.request('/plugins/kimchi/vms/test-vm/suspend', '{}',
- 'POST')
- self.assertEquals(400, resp.status)
- resp = self.request('/plugins/kimchi/vms/test-vm/start', '{}',
'POST')
- self.assertEquals(200, resp.status)
- resp = self.request('/plugins/kimchi/vms/test-vm', '{}',
'GET')
- self.assertEquals(200, resp.status)
- vm = json.loads(resp.read())
- self.assertEquals(vm['state'], 'running')
- resp = self.request('/plugins/kimchi/vms/test-vm/suspend', '{}',
- 'POST')
- self.assertEquals(200, resp.status)
- resp = self.request('/plugins/kimchi/vms/test-vm', '{}',
'GET')
- self.assertEquals(200, resp.status)
- vm = json.loads(resp.read())
- self.assertEquals(vm['state'], 'paused')
-
- # Resume the VM
- resp = self.request('/plugins/kimchi/vms/test-vm/resume', '{}',
'POST')
- self.assertEquals(200, resp.status)
- resp = self.request('/plugins/kimchi/vms/test-vm', '{}',
'GET')
- self.assertEquals(200, resp.status)
- vm = json.loads(resp.read())
- self.assertEquals(vm['state'], 'running')
-
- # Delete the VM
- resp = self.request('/plugins/kimchi/vms/test-vm', '{}',
'DELETE')
- self.assertEquals(204, resp.status)
-
- # Delete the Template
- resp = self.request('/plugins/kimchi/templates/test', '{}',
'DELETE')
- self.assertEquals(204, resp.status)
-
- # Verify the volume was deleted
- self.assertHTTPStatus(404, vol_uri % vm['uuid'])
-
- def test_vm_graphics(self):
- # Create a Template
- req = json.dumps({'name': 'test', 'cdrom': fake_iso})
- resp = self.request('/plugins/kimchi/templates', req, 'POST')
- self.assertEquals(201, resp.status)
-
- # Create a VM with default args
- req = json.dumps({'name': 'test-vm',
- 'template': '/plugins/kimchi/templates/test'})
- resp = self.request('/plugins/kimchi/vms', req, 'POST')
- self.assertEquals(202, resp.status)
- task = json.loads(resp.read())
- wait_task(self._task_lookup, task['id'])
- # Verify the VM
- vm = json.loads(self.request('/plugins/kimchi/vms/test-vm').read())
- self.assertEquals('127.0.0.1', vm['graphics']['listen'])
- self.assertEquals('vnc', vm['graphics']['type'])
- # Delete the VM
- resp = self.request('/plugins/kimchi/vms/test-vm', '{}',
'DELETE')
- self.assertEquals(204, resp.status)
-
- # Create a VM with specified graphics type and listen
- graphics = {'type': 'vnc', 'listen':
'127.0.0.1'}
- req = json.dumps({'name': 'test-vm',
- 'template': '/plugins/kimchi/templates/test',
- 'graphics': graphics})
- resp = self.request('/plugins/kimchi/vms', req, 'POST')
- self.assertEquals(202, resp.status)
- task = json.loads(resp.read())
- wait_task(self._task_lookup, task['id'])
- # Verify the VM
- vm = json.loads(self.request('/plugins/kimchi/vms/test-vm').read())
- self.assertEquals('127.0.0.1', vm['graphics']['listen'])
- self.assertEquals('vnc', vm['graphics']['type'])
- # Delete the VM
- resp = self.request('/plugins/kimchi/vms/test-vm', '{}',
'DELETE')
- self.assertEquals(204, resp.status)
-
- # Create a VM with listen as ipv6 address
- graphics = {'type': 'spice', 'listen':
'fe00::0'}
- req = json.dumps({'name': 'test-vm',
- 'template': '/plugins/kimchi/templates/test',
- 'graphics': graphics})
- resp = self.request('/plugins/kimchi/vms', req, 'POST')
- self.assertEquals(202, resp.status)
- task = json.loads(resp.read())
- wait_task(self._task_lookup, task['id'])
- # Verify the VM
- vm = json.loads(self.request('/plugins/kimchi/vms/test-vm').read())
- self.assertEquals('fe00::0', vm['graphics']['listen'])
- self.assertEquals('spice', vm['graphics']['type'])
- # Delete the VM
- resp = self.request('/plugins/kimchi/vms/test-vm', '{}',
'DELETE')
- self.assertEquals(204, resp.status)
-
- # Create a VM with specified graphics type and default listen
- graphics = {'type': 'spice'}
- req = json.dumps({'name': 'test-vm',
- 'template': '/plugins/kimchi/templates/test',
- 'graphics': graphics})
- resp = self.request('/plugins/kimchi/vms', req, 'POST')
- self.assertEquals(202, resp.status)
- task = json.loads(resp.read())
- wait_task(self._task_lookup, task['id'])
- # Verify the VM
- vm = json.loads(self.request('/plugins/kimchi/vms/test-vm').read())
- self.assertEquals('127.0.0.1', vm['graphics']['listen'])
- self.assertEquals('spice', vm['graphics']['type'])
- # Delete the VM
- resp = self.request('/plugins/kimchi/vms/test-vm', '{}',
'DELETE')
- self.assertEquals(204, resp.status)
-
- # Try to create a VM with invalid graphics type
- graphics = {'type': 'invalid'}
- req = json.dumps({'name': 'test-vm',
- 'template': '/plugins/kimchi/templates/test',
- 'graphics': graphics})
- resp = self.request('/plugins/kimchi/vms', req, 'POST')
- self.assertEquals(400, resp.status)
-
- # Try to create a VM with invalid graphics listen
- graphics = {'type': 'spice', 'listen':
'invalid'}
- req = json.dumps({'name': 'test-vm',
- 'template': '/plugins/kimchi/templates/test',
- 'graphics': graphics})
- resp = self.request('/plugins/kimchi/vms', req, 'POST')
- self.assertEquals(400, resp.status)
-
- # Delete the Template
- resp = self.request('/plugins/kimchi/templates/test', '{}',
'DELETE')
- self.assertEquals(204, resp.status)
-
- def test_vm_storage_devices(self):
-
- with RollbackContext() as rollback:
- # Create a template as a base for our VMs
- req = json.dumps({'name': 'test', 'cdrom':
fake_iso})
- resp = self.request('/plugins/kimchi/templates', req,
'POST')
- self.assertEquals(201, resp.status)
- # Delete the template
- rollback.prependDefer(self.request,
- '/plugins/kimchi/templates/test',
'{}',
- 'DELETE')
-
- # Create a VM with default args
- req = json.dumps({'name': 'test-vm',
- 'template':
'/plugins/kimchi/templates/test'})
- resp = self.request('/plugins/kimchi/vms', req, 'POST')
- self.assertEquals(202, resp.status)
- task = json.loads(resp.read())
- wait_task(self._task_lookup, task['id'])
- # Delete the VM
- rollback.prependDefer(self.request, '/plugins/kimchi/vms/test-vm',
- '{}', 'DELETE')
-
- # Check storage devices
- resp = self.request('/plugins/kimchi/vms/test-vm/storages',
'{}',
- 'GET')
- devices = json.loads(resp.read())
- self.assertEquals(2, len(devices))
- dev_types = []
- for d in devices:
- self.assertIn(u'type', d.keys())
- self.assertIn(u'dev', d.keys())
- self.assertIn(u'path', d.keys())
- dev_types.append(d['type'])
-
- self.assertEquals(['cdrom', 'disk'], sorted(dev_types))
-
- # Attach cdrom with nonexistent iso
- req = json.dumps({'dev': 'hdx',
- 'type': 'cdrom',
- 'path': '/tmp/nonexistent.iso'})
- resp = self.request('/plugins/kimchi/vms/test-vm/storages', req,
- 'POST')
- self.assertEquals(400, resp.status)
-
- # Create temp storage pool
- req = json.dumps({'name': 'tmp',
- 'capacity': 1024,
- 'allocated': 512,
- 'path': '/tmp',
- 'type': 'dir'})
- resp = self.request('/plugins/kimchi/storagepools', req,
'POST')
- self.assertEquals(201, resp.status)
- resp = self.request('/plugins/kimchi/storagepools/tmp/activate',
- req, 'POST')
- self.assertEquals(200, resp.status)
-
- # 'name' is required for this type of volume
- req = json.dumps({'capacity': 1024,
- 'allocation': 512,
- 'type': 'disk',
- 'format': 'raw'})
- resp = self.request(
- '/plugins/kimchi/storagepools/tmp/storagevolumes', req,
'POST'
- )
- self.assertEquals(400, resp.status)
- req = json.dumps({'name': "attach-volume",
- 'capacity': 1024,
- 'allocation': 512,
- 'type': 'disk',
- 'format': 'raw'})
- resp = self.request(
- '/plugins/kimchi/storagepools/tmp/storagevolumes', req,
'POST'
- )
- self.assertEquals(202, resp.status)
- time.sleep(1)
-
- # Attach cdrom with both path and volume specified
- open('/tmp/existent.iso', 'w').close()
- req = json.dumps({'dev': 'hdx',
- 'type': 'cdrom',
- 'pool': 'tmp',
- 'vol': 'attach-volume',
- 'path': '/tmp/existent.iso'})
- resp = self.request(
- '/plugins/kimchi/vms/test-vm/storages', req, 'POST'
- )
- self.assertEquals(400, resp.status)
-
- # Attach disk with both path and volume specified
- req = json.dumps({'dev': 'hdx',
- 'type': 'disk',
- 'pool': 'tmp',
- 'vol': 'attach-volume',
- 'path': '/tmp/existent.iso'})
- resp = self.request(
- '/plugins/kimchi/vms/test-vm/storages', req, 'POST'
- )
- self.assertEquals(400, resp.status)
-
- # Attach disk with only pool specified
- req = json.dumps({'dev': 'hdx',
- 'type': 'cdrom',
- 'pool': 'tmp'})
- resp = self.request(
- '/plugins/kimchi/vms/test-vm/storages', req, 'POST'
- )
- self.assertEquals(400, resp.status)
-
- # Attach disk with pool and vol specified
- req = json.dumps({'type': 'disk',
- 'pool': 'tmp',
- 'vol': 'attach-volume'})
- resp = self.request(
- '/plugins/kimchi/vms/test-vm/storages', req, 'POST'
- )
- self.assertEquals(201, resp.status)
- cd_info = json.loads(resp.read())
- self.assertEquals('disk', cd_info['type'])
-
- # Attach a cdrom with existent dev name
- req = json.dumps({'type': 'cdrom',
- 'path': '/tmp/existent.iso'})
- resp = self.request(
- '/plugins/kimchi/vms/test-vm/storages', req, 'POST'
- )
- self.assertEquals(201, resp.status)
- cd_info = json.loads(resp.read())
- cd_dev = cd_info['dev']
- self.assertEquals('cdrom', cd_info['type'])
- self.assertEquals('/tmp/existent.iso', cd_info['path'])
- # Delete the file and cdrom
- rollback.prependDefer(self.request,
- '/plugins/kimchi/vms/test-vm/storages/hdx',
- '{}', 'DELETE')
- os.remove('/tmp/existent.iso')
-
- # Change path of storage cdrom
- cdrom =
u'http://fedora.mirrors.tds.net/pub/fedora/releases/20/'\
- 'Live/x86_64/Fedora-Live-Desktop-x86_64-20-1.iso'
- req = json.dumps({'path': cdrom})
- resp = self.request('/plugins/kimchi/vms/test-vm/storages/' +
- cd_dev, req, 'PUT')
- self.assertEquals(200, resp.status)
- cd_info = json.loads(resp.read())
- self.assertEquals(urlparse.urlparse(cdrom).path,
- urlparse.urlparse(cd_info['path']).path)
-
- # Test GET
- devs = json.loads(
- self.request('/plugins/kimchi/vms/test-vm/storages').read()
- )
- self.assertEquals(4, len(devs))
-
- # Detach storage cdrom
- resp = self.request('/plugins/kimchi/vms/test-vm/storages/' +
- cd_dev, '{}', 'DELETE')
- self.assertEquals(204, resp.status)
-
- # Test GET
- devs = json.loads(
- self.request('/plugins/kimchi/vms/test-vm/storages').read()
- )
- self.assertEquals(3, len(devs))
- resp = self.request('/plugins/kimchi/storagepools/tmp/deactivate',
- {}, 'POST')
- self.assertEquals(200, resp.status)
- resp = self.request('/plugins/kimchi/storagepools/tmp', {},
- 'DELETE')
- self.assertEquals(204, resp.status)
-
- def test_vm_iface(self):
-
- with RollbackContext() as rollback:
- # Create a template as a base for our VMs
- req = json.dumps({'name': 'test', 'cdrom':
fake_iso})
- resp = self.request('/plugins/kimchi/templates', req,
'POST')
- self.assertEquals(201, resp.status)
- # Delete the template
- rollback.prependDefer(self.request,
- '/plugins/kimchi/templates/test',
'{}',
- 'DELETE')
-
- # Create a VM with default args
- req = json.dumps({'name': 'test-vm',
- 'template':
'/plugins/kimchi/templates/test'})
- resp = self.request('/plugins/kimchi/vms', req, 'POST')
- self.assertEquals(202, resp.status)
- task = json.loads(resp.read())
- wait_task(self._task_lookup, task['id'])
- # Delete the VM
- rollback.prependDefer(self.request,
- '/plugins/kimchi/vms/test-vm', '{}',
- 'DELETE')
-
- # Create a network
- req = json.dumps({'name': 'test-network',
- 'connection': 'nat',
- 'net': '127.0.1.0/24'})
- resp = self.request('/plugins/kimchi/networks', req, 'POST')
- self.assertEquals(201, resp.status)
- # Delete the network
- rollback.prependDefer(self.request,
- '/plugins/kimchi/networks/test-network',
- '{}', 'DELETE')
-
- ifaces = json.loads(
- self.request('/plugins/kimchi/vms/test-vm/ifaces').read()
- )
- self.assertEquals(1, len(ifaces))
-
- for iface in ifaces:
- res = json.loads(
- self.request('/plugins/kimchi/vms/test-vm/ifaces/%s' %
- iface['mac']).read()
- )
- self.assertEquals('default', res['network'])
- self.assertEquals(17, len(res['mac']))
- self.assertEquals(get_template_default('old',
'nic_model'),
- res['model'])
-
- # try to attach an interface without specifying 'model'
- req = json.dumps({'type': 'network'})
- resp = self.request('/plugins/kimchi/vms/test-vm/ifaces', req,
- 'POST')
- self.assertEquals(400, resp.status)
-
- # attach network interface to vm
- req = json.dumps({"type": "network",
- "network": "test-network",
- "model": "virtio"})
- resp = self.request('/plugins/kimchi/vms/test-vm/ifaces', req,
- 'POST')
- self.assertEquals(201, resp.status)
- iface = json.loads(resp.read())
-
- self.assertEquals('test-network', iface['network'])
- self.assertEquals(17, len(iface['mac']))
- self.assertEquals('virtio', iface['model'])
- self.assertEquals('network', iface['type'])
-
- # update vm interface
- newMacAddr = '54:50:e3:44:8a:af'
- req = json.dumps({"network": "default",
"model": "virtio",
- "type": "network", "mac":
newMacAddr})
- resp = self.request('/plugins/kimchi/vms/test-vm/ifaces/%s' %
- iface['mac'], req, 'PUT')
- self.assertEquals(303, resp.status)
- iface = json.loads(
- self.request('/plugins/kimchi/vms/test-vm/ifaces/%s' %
- newMacAddr).read()
- )
- self.assertEquals(newMacAddr, iface['mac'])
-
- # detach network interface from vm
- resp = self.request('/plugins/kimchi/vms/test-vm/ifaces/%s' %
- iface['mac'], '{}', 'DELETE')
- self.assertEquals(204, resp.status)
-
- def test_vm_customise_storage(self):
- # Create a Template
- req = json.dumps({'name': 'test', 'cdrom': fake_iso,
- 'disks': [{'size': 1}]})
- resp = self.request('/plugins/kimchi/templates', req, 'POST')
- self.assertEquals(201, resp.status)
-
- # Create alternate storage
- req = json.dumps({'name': 'alt',
- 'capacity': 1024,
- 'allocated': 512,
- 'path': '/tmp',
- 'type': 'dir'})
- resp = self.request('/plugins/kimchi/storagepools', req, 'POST')
- self.assertEquals(201, resp.status)
- resp = self.request('/plugins/kimchi/storagepools/alt/activate', req,
- 'POST')
- self.assertEquals(200, resp.status)
-
- # Create a VM
- req = json.dumps({'name': 'test-vm',
- 'template': '/plugins/kimchi/templates/test',
- 'storagepool':
'/plugins/kimchi/storagepools/alt'})
- resp = self.request('/plugins/kimchi/vms', req, 'POST')
- self.assertEquals(202, resp.status)
- task = json.loads(resp.read())
- wait_task(self._task_lookup, task['id'])
- resp = self.request('/plugins/kimchi/vms/test-vm', {}, 'GET')
- vm_info = json.loads(resp.read())
-
- # Test template not changed after vm customise its pool
- t = json.loads(self.request('/plugins/kimchi/templates/test').read())
- self.assertEquals(t['storagepool'],
- '/plugins/kimchi/storagepools/default-pool')
-
- # Verify the volume was created
- vol_uri = '/plugins/kimchi/storagepools/alt/storagevolumes/%s-0.img' \
- % vm_info['uuid']
- resp = self.request(vol_uri)
- vol = json.loads(resp.read())
- self.assertEquals(1 << 30, vol['capacity'])
-
- # Delete the VM
- resp = self.request('/plugins/kimchi/vms/test-vm', '{}',
'DELETE')
- self.assertEquals(204, resp.status)
-
- # Verify the volume was deleted
- self.assertHTTPStatus(404, vol_uri)
-
- def test_scsi_fc_storage(self):
- # Create scsi fc pool
- req = json.dumps({'name': 'scsi_fc_pool',
- 'type': 'scsi',
- 'source': {'adapter_name':
'scsi_host2'}})
- resp = self.request('/plugins/kimchi/storagepools', req, 'POST')
- self.assertEquals(201, resp.status)
-
- # Test create vms using lun of this pool
- # activate the storage pool
- resp = self.request(
- '/plugins/kimchi/storagepools/scsi_fc_pool/activate', '{}',
'POST'
- )
-
- # Create template fails because SCSI volume is missing
- tmpl_params = {
- 'name': 'test_fc_pool', 'cdrom': fake_iso,
- 'storagepool': '/plugins/kimchi/storagepools/scsi_fc_pool'
- }
- req = json.dumps(tmpl_params)
- resp = self.request('/plugins/kimchi/templates', req, 'POST')
- self.assertEquals(400, resp.status)
-
- # Choose SCSI volume to create template
- resp = self.request(
- '/plugins/kimchi/storagepools/scsi_fc_pool/storagevolumes'
- )
- lun_name = json.loads(resp.read())[0]['name']
-
- tmpl_params['disks'] = [{'index': 0, 'volume':
lun_name}]
- req = json.dumps(tmpl_params)
- resp = self.request('/plugins/kimchi/templates', req, 'POST')
- self.assertEquals(201, resp.status)
-
- # Create vm in scsi pool
- req = json.dumps({'name': 'test-vm',
- 'template':
'/plugins/kimchi/templates/test_fc_pool'})
- resp = self.request('/plugins/kimchi/vms', req, 'POST')
- self.assertEquals(202, resp.status)
- task = json.loads(resp.read())
- wait_task(self._task_lookup, task['id'])
-
- # Start the VM
- resp = self.request('/plugins/kimchi/vms/test-vm/start', '{}',
'POST')
- vm = json.loads(self.request('/plugins/kimchi/vms/test-vm').read())
- self.assertEquals('running', vm['state'])
-
- # Force poweroff the VM
- resp = self.request('/plugins/kimchi/vms/test-vm/poweroff',
'{}',
- 'POST')
- vm = json.loads(self.request('/plugins/kimchi/vms/test-vm').read())
- self.assertEquals('shutoff', vm['state'])
-
- # Delete the VM
- resp = self.request('/plugins/kimchi/vms/test-vm', '{}',
'DELETE')
- self.assertEquals(204, resp.status)
-
- def test_unnamed_vms(self):
- # Create a Template
- req = json.dumps({'name': 'test', 'cdrom': fake_iso})
- resp = self.request('/plugins/kimchi/templates', req, 'POST')
- self.assertEquals(201, resp.status)
-
- # Create 5 unnamed vms from this template
- for i in xrange(1, 6):
- req = json.dumps({'template':
'/plugins/kimchi/templates/test'})
- task = json.loads(self.request('/plugins/kimchi/vms',
- req, 'POST').read())
- wait_task(self._task_lookup, task['id'])
- resp = self.request('/plugins/kimchi/vms/test-vm-%i' % i, {},
- 'GET')
- self.assertEquals(resp.status, 200)
- count = len(json.loads(self.request('/plugins/kimchi/vms').read()))
- self.assertEquals(6, count)
-
- def test_create_vm_without_template(self):
- req = json.dumps({'name': 'vm-without-template'})
- resp = self.request('/plugins/kimchi/vms', req, 'POST')
- self.assertEquals(400, resp.status)
- resp = json.loads(resp.read())
- self.assertIn(u"KCHVM0016E:", resp['reason'])
-
- def test_create_vm_with_bad_template_uri(self):
- req = json.dumps({'name': 'vm-bad-template',
- 'template': '/mytemplate'})
- resp = self.request('/plugins/kimchi/vms', req, 'POST')
- self.assertEquals(400, resp.status)
- resp = json.loads(resp.read())
- self.assertIn(u"KCHVM0012E", resp['reason'])
-
- def test_create_vm_with_img_based_template(self):
- resp = json.loads(
- self.request(
- '/plugins/kimchi/storagepools/default-pool/storagevolumes'
- ).read()
- )
- self.assertEquals(0, len(resp))
-
- # Create a Template
- mock_base = '/tmp/mock.img'
- open(mock_base, 'w').close()
- req = json.dumps({'name': 'test', 'disks':
[{'base': mock_base}]})
- resp = self.request('/plugins/kimchi/templates', req, 'POST')
- self.assertEquals(201, resp.status)
-
- req = json.dumps({'template': '/plugins/kimchi/templates/test'})
- resp = self.request('/plugins/kimchi/vms', req, 'POST')
- self.assertEquals(202, resp.status)
- task = json.loads(resp.read())
- wait_task(self._task_lookup, task['id'])
-
- # Test storage volume created with backing store of base file
- resp = json.loads(
- self.request(
- '/plugins/kimchi/storagepools/default-pool/storagevolumes'
- ).read()
- )
- self.assertEquals(1, len(resp))
-
- def _create_pool(self, name):
- req = json.dumps({'name': name,
- 'capacity': 10240,
- 'allocated': 5120,
- 'path': '/var/lib/libvirt/images/',
- 'type': 'dir'})
- resp = self.request('/plugins/kimchi/storagepools', req, 'POST')
- self.assertEquals(201, resp.status)
-
- # Verify the storage pool
- storagepool = json.loads(self.request('/plugins/kimchi/storagepools/%s'
- % name).read())
- self.assertEquals('inactive', storagepool['state'])
- return name
-
- def _delete_pool(self, name):
- # Delete the storage pool
- resp = self.request('/plugins/kimchi/storagepools/%s' % name,
'{}',
- 'DELETE')
- self.assertEquals(204, resp.status)
-
- def test_iso_scan_shallow(self):
- # fake environment preparation
- self._create_pool('pool-3')
- self.request('/plugins/kimchi/storagepools/pool-3/activate',
'{}',
- 'POST')
- params = {'name': 'fedora.iso',
- 'capacity': 1073741824, # 1 GiB
- 'type': 'file',
- 'format': 'iso'}
- task_info = model.storagevolumes_create('pool-3', params)
- wait_task(self._task_lookup, task_info['id'])
-
- storagevolume = json.loads(
- self.request(
- '/plugins/kimchi/storagepools/kimchi_isos/storagevolumes/'
- ).read()
- )[0]
- self.assertEquals('fedora.iso', storagevolume['name'])
- self.assertEquals('iso', storagevolume['format'])
- self.assertEquals('/var/lib/libvirt/images/fedora.iso',
- storagevolume['path'])
- self.assertEquals(1073741824, storagevolume['capacity']) # 1 GiB
- self.assertEquals(0, storagevolume['allocation'])
- self.assertEquals('17', storagevolume['os_version'])
- self.assertEquals('fedora', storagevolume['os_distro'])
- self.assertEquals(True, storagevolume['bootable'])
-
- # Create a template
- # In real model os distro/version can be omitted
- # as we will scan the iso
- req = json.dumps({'name': 'test',
- 'cdrom': storagevolume['path'],
- 'os_distro': storagevolume['os_distro'],
- 'os_version': storagevolume['os_version']})
- resp = self.request('/plugins/kimchi/templates', req, 'POST')
- self.assertEquals(201, resp.status)
-
- # Verify the template
- t = json.loads(self.request('/plugins/kimchi/templates/test').read())
- self.assertEquals('test', t['name'])
- self.assertEquals('fedora', t['os_distro'])
- self.assertEquals('17', t['os_version'])
- self.assertEquals(get_template_default('old', 'memory'),
t['memory'])
-
- # Deactivate or destroy scan pool return 405
- resp = self.request(
- '/plugins/kimchi/storagepools/kimchi_isos/storagevolumes'
- '/deactivate', '{}', 'POST'
- )
- self.assertEquals(405, resp.status)
-
- resp = self.request(
- '/plugins/kimchi/storagepools/kimchi_isos/storagevolumes',
- '{}', 'DELETE'
- )
- self.assertEquals(405, resp.status)
-
- # Delete the template
- resp = self.request('/plugins/kimchi/templates/%s' % t['name'],
'{}',
- 'DELETE')
- self.assertEquals(204, resp.status)
-
- resp = self.request('/plugins/kimchi/storagepools/pool-3/deactivate',
- '{}', 'POST')
- self.assertEquals(200, resp.status)
- self._delete_pool('pool-3')
-
- def test_screenshot_refresh(self):
- # Create a VM
- req = json.dumps({'name': 'test', 'cdrom': fake_iso})
- resp = self.request('/plugins/kimchi/templates', req, 'POST')
- req = json.dumps({'name': 'test-vm',
- 'template': '/plugins/kimchi/templates/test'})
- resp = self.request('/plugins/kimchi/vms', req, 'POST')
- task = json.loads(resp.read())
- wait_task(self._task_lookup, task['id'])
-
- # Test screenshot for shut-off state vm
- resp = self.request('/plugins/kimchi/vms/test-vm/screenshot')
- self.assertEquals(404, resp.status)
-
- # Test screenshot for running vm
- resp = self.request('/plugins/kimchi/vms/test-vm/start', '{}',
'POST')
- vm = json.loads(self.request('/plugins/kimchi/vms/test-vm').read())
-
- resp = self.request(vm['screenshot'], method='HEAD')
- self.assertEquals(200, resp.status)
-
self.assertTrue(resp.getheader('Content-type').startswith('image'))
-
- # Test screenshot sub-resource redirect
- resp = self.request('/plugins/kimchi/vms/test-vm/screenshot')
- self.assertEquals(200, resp.status)
- self.assertEquals('image/png', resp.getheader('content-type'))
- lastMod1 = resp.getheader('last-modified')
-
- # Take another screenshot instantly and compare the last Modified date
- resp = self.request('/plugins/kimchi/vms/test-vm/screenshot')
- lastMod2 = resp.getheader('last-modified')
- self.assertEquals(lastMod2, lastMod1)
-
- resp = self.request('/plugins/kimchi/vms/test-vm/screenshot',
'{}',
- 'DELETE')
- self.assertEquals(405, resp.status)
-
- # No screenshot after stopped the VM
- self.request('/plugins/kimchi/vms/test-vm/poweroff', '{}',
'POST')
- resp = self.request('/plugins/kimchi/vms/test-vm/screenshot')
- self.assertEquals(404, resp.status)
-
- # Picture link not available after VM deleted
- self.request('/plugins/kimchi/vms/test-vm/start', '{}',
'POST')
- vm = json.loads(self.request('/plugins/kimchi/vms/test-vm').read())
- img_lnk = vm['screenshot']
- self.request('/plugins/kimchi/vms/test-vm', '{}',
'DELETE')
- resp = self.request(img_lnk)
- self.assertEquals(404, resp.status)
-
- def test_interfaces(self):
- resp = self.request('/plugins/kimchi/interfaces').read()
- self.assertIn('name', resp)
- interfaces = json.loads(resp)
- keys = ['name', 'type', 'ipaddr', 'netmask',
'status']
- for interface in interfaces:
- self.assertEquals(sorted(keys), sorted(interface.keys()))
-
- def _task_lookup(self, taskid):
- return json.loads(
- self.request('/tasks/%s' % taskid).read()
- )
-
- def test_tasks(self):
- id1 = add_task('/tasks/1', self._async_op,
- model.objstore)
- id2 = add_task('/tasks/2', self._except_op,
- model.objstore)
- id3 = add_task('/tasks/3', self._intermid_op,
- model.objstore)
-
- target_uri = urllib2.quote('^/tasks/*', safe="")
- filter_data = 'status=running&target_uri=%s' % target_uri
- tasks = json.loads(
- self.request('/tasks?%s' % filter_data).read()
- )
- self.assertEquals(3, len(tasks))
-
- tasks = json.loads(self.request('/tasks').read())
- tasks_ids = [int(t['id']) for t in tasks]
- self.assertEquals(set([id1, id2, id3]) - set(tasks_ids), set([]))
- wait_task(self._task_lookup, id2)
- foo2 = json.loads(
- self.request('/tasks/%s' % id2).read()
- )
- keys = ['id', 'status', 'message', 'target_uri']
- self.assertEquals(sorted(keys), sorted(foo2.keys()))
- self.assertEquals('failed', foo2['status'])
- wait_task(self._task_lookup, id3)
- foo3 = json.loads(
- self.request('/tasks/%s' % id3).read()
- )
- self.assertEquals('in progress', foo3['message'])
- self.assertEquals('running', foo3['status'])
-
- def test_config(self):
- resp = self.request('/plugins/kimchi/config').read()
- conf = json.loads(resp)
- keys = ["display_proxy_port", "version"]
- self.assertEquals(keys, sorted(conf.keys()))
-
- def test_capabilities(self):
- resp = self.request('/plugins/kimchi/config/capabilities').read()
- conf = json.loads(resp)
-
- keys = [u'libvirt_stream_protocols', u'qemu_stream',
u'qemu_spice',
- u'screenshot', u'system_report_tool',
u'update_tool',
- u'repo_mngt_tool', u'federation', u'kernel_vfio',
u'auth',
- u'nm_running', u'mem_hotplug_support']
- self.assertEquals(sorted(keys), sorted(conf.keys()))
-
- def test_peers(self):
- resp = self.request('/plugins/kimchi/peers').read()
- self.assertEquals([], json.loads(resp))
-
- def test_distros(self):
- resp = self.request('/plugins/kimchi/config/distros').read()
- distros = json.loads(resp)
- for distro in distros:
- self.assertIn('name', distro)
- self.assertIn('os_distro', distro)
- self.assertIn('os_version', distro)
- self.assertIn('path', distro)
-
- # Test in X86
- ident = "Fedora 20"
- resp = self.request('/plugins/kimchi/config/distros/%s' %
- urllib2.quote(ident)).read()
- distro = json.loads(resp)
- if os.uname()[4] in ['x86_64', 'amd64']:
- self.assertEquals(distro['name'], ident)
- self.assertEquals(distro['os_distro'], "fedora")
- self.assertEquals(distro['os_version'], "20")
- self.assertEquals(distro['os_arch'], "x86_64")
- self.assertIn('path', distro)
- else:
- # Distro not found error
- self.assertIn('KCHDISTRO0001E', distro.get('reason'))
-
- # Test in PPC
- ident = "Fedora 20 (PPC64)"
- resp = self.request('/plugins/kimchi/config/distros/%s' %
- urllib2.quote(ident)).read()
- distro = json.loads(resp)
- if os.uname()[4] == 'ppc64':
- self.assertEquals(distro['name'], ident)
- self.assertEquals(distro['os_distro'], "fedora")
- self.assertEquals(distro['os_version'], "20")
- self.assertEquals(distro['os_arch'], "ppc64")
- self.assertIn('path', distro)
- else:
- # Distro not found error
- self.assertIn('KCHDISTRO0001E', distro.get('reason'))
-
- def test_debugreports(self):
- resp = request(host, ssl_port, '/plugins/kimchi/debugreports')
- self.assertEquals(200, resp.status)
-
- def _report_delete(self, name):
- request(host, ssl_port, '/plugins/kimchi/debugreports/%s' % name,
'{}',
- 'DELETE')
-
- def test_create_debugreport(self):
- req = json.dumps({'name': 'report1'})
- with RollbackContext() as rollback:
- resp = request(host, ssl_port, '/plugins/kimchi/debugreports', req,
- 'POST')
- self.assertEquals(202, resp.status)
- task = json.loads(resp.read())
- # make sure the debugreport doesn't exist until the
- # the task is finished
- wait_task(self._task_lookup, task['id'])
- rollback.prependDefer(self._report_delete, 'report2')
- resp = request(host, ssl_port,
- '/plugins/kimchi/debugreports/report1')
- debugreport = json.loads(resp.read())
- self.assertEquals("report1", debugreport['name'])
- self.assertEquals(200, resp.status)
- req = json.dumps({'name': 'report2'})
- resp = request(host, ssl_port,
- '/plugins/kimchi/debugreports/report1', req,
'PUT')
- self.assertEquals(303, resp.status)
-
- def test_debugreport_download(self):
- req = json.dumps({'name': 'report1'})
- with RollbackContext() as rollback:
- resp = request(host, ssl_port, '/plugins/kimchi/debugreports', req,
- 'POST')
- self.assertEquals(202, resp.status)
- task = json.loads(resp.read())
- # make sure the debugreport doesn't exist until the
- # the task is finished
- wait_task(self._task_lookup, task['id'], 20)
- rollback.prependDefer(self._report_delete, 'report1')
- resp = request(host, ssl_port,
- '/plugins/kimchi/debugreports/report1')
- debugreport = json.loads(resp.read())
- self.assertEquals("report1", debugreport['name'])
- self.assertEquals(200, resp.status)
- resp = request(host, ssl_port,
- '/plugins/kimchi/debugreports/report1/content')
- self.assertEquals(200, resp.status)
- resp = request(host, ssl_port,
- '/plugins/kimchi/debugreports/report1')
- debugre = json.loads(resp.read())
- resp = request(host, ssl_port, debugre['uri'])
- self.assertEquals(200, resp.status)
-
- def test_repositories(self):
- def verify_repo(t, res):
- for field in ('repo_id', 'enabled', 'baseurl',
'config'):
- if field in t.keys():
- self.assertEquals(t[field], res[field])
-
- base_uri = '/plugins/kimchi/host/repositories'
- resp = self.request(base_uri)
- self.assertEquals(200, resp.status)
- # Already have one repo in Kimchi's system
- self.assertEquals(1, len(json.loads(resp.read())))
-
- # Create a repository
- repo = {'repo_id': 'fedora-fake',
- 'baseurl': 'http://www.fedora.org'}
- req = json.dumps(repo)
- resp = self.request(base_uri, req, 'POST')
- self.assertEquals(201, resp.status)
-
- # Verify the repository
- res = json.loads(self.request('%s/fedora-fake' % base_uri).read())
- verify_repo(repo, res)
-
- # Update the repository
- params = {}
- params['baseurl'] = repo['baseurl'] =
'http://www.fedoraproject.org'
- resp = self.request('%s/fedora-fake' % base_uri, json.dumps(params),
- 'PUT')
-
- # Verify the repository
- res = json.loads(self.request('%s/fedora-fake' % base_uri).read())
- verify_repo(repo, res)
-
- # Delete the repository
- resp = self.request('%s/fedora-fake' % base_uri, '{}',
'DELETE')
- self.assertEquals(204, resp.status)
-
-
-class HttpsRestTests(RestTests):
- """
- Run all of the same tests as above, but use https instead
- """
- def setUp(self):
- self.request = partial(request, host, ssl_port)
- model.reset()
diff --git a/plugins/kimchi/tests/test_rollbackcontext.py
b/plugins/kimchi/tests/test_rollbackcontext.py
deleted file mode 100644
index 6eac6d0..0000000
--- a/plugins/kimchi/tests/test_rollbackcontext.py
+++ /dev/null
@@ -1,99 +0,0 @@
-#
-# Project Kimchi
-#
-# Copyright IBM, Corp. 2014
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-
-import unittest
-
-from wok.rollbackcontext import RollbackContext
-
-
-class FirstError(Exception):
- '''A hypothetical exception to be raise in the test
firstly.'''
- pass
-
-
-class SecondError(Exception):
- '''A hypothetical exception to be raise in the test
secondly.'''
- pass
-
-
-class RollbackContextTests(unittest.TestCase):
-
- def setUp(self):
- self._counter = 0
-
- def _inc_counter(self):
- self._counter += 1
-
- def _raise(self, exception=FirstError):
- raise exception()
-
- def test_rollback(self):
- with RollbackContext() as rollback:
- rollback.prependDefer(self._inc_counter)
- rollback.prependDefer(self._inc_counter)
- self.assertEquals(self._counter, 2)
-
- def test_raise(self):
- try:
- with RollbackContext() as rollback:
- rollback.prependDefer(self._inc_counter)
- rollback.prependDefer(self._inc_counter)
- raise FirstError()
- rollback.prependDefer(self._inc_counter)
- except FirstError:
- # All undo before the FirstError should be run
- self.assertEquals(self._counter, 2)
- else:
- self.fail('Should have raised FirstError')
-
- def test_raise_undo(self):
- try:
- with RollbackContext() as rollback:
- rollback.prependDefer(self._inc_counter)
- rollback.prependDefer(self._raise)
- rollback.prependDefer(self._inc_counter)
- except FirstError:
- # All undo should be run
- self.assertEquals(self._counter, 2)
- else:
- self.fail('Should have raised FirstError')
-
- def test_raise_prefer_original(self):
- try:
- with RollbackContext() as rollback:
- rollback.prependDefer(self._raise, SecondError)
- raise FirstError()
- except FirstError:
- pass
- except SecondError:
- self.fail('Should have preferred FirstError to SecondError')
- else:
- self.fail('Should have raised FirstError')
-
- def test_raise_prefer_first_undo(self):
- try:
- with RollbackContext() as rollback:
- rollback.prependDefer(self._raise, SecondError)
- rollback.prependDefer(self._raise, FirstError)
- except FirstError:
- pass
- except SecondError:
- self.fail('Should have preferred FirstError to SecondError')
- else:
- self.fail('Should have raised FirstError')
diff --git a/plugins/kimchi/tests/test_server.py b/plugins/kimchi/tests/test_server.py
deleted file mode 100644
index d5ef565..0000000
--- a/plugins/kimchi/tests/test_server.py
+++ /dev/null
@@ -1,289 +0,0 @@
-#
-# Project Kimchi
-#
-# Copyright IBM, Corp. 2013-2015
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-
-import base64
-import cherrypy
-import json
-import os
-import tempfile
-import threading
-import unittest
-from functools import partial
-
-from wok.control.base import Collection, Resource
-
-from wok.plugins.kimchi import mockmodel
-
-import utils
-
-
-test_server = None
-model = None
-host = None
-port = None
-ssl_port = None
-cherrypy_port = None
-tmpfile = None
-
-
-def setUpModule():
- global test_server, model, host, port, ssl_port, cherrypy_port, tmpfile
-
- utils.patch_auth()
- tmpfile = tempfile.mktemp()
- model = mockmodel.MockModel(tmpfile)
- host = '127.0.0.1'
- port = utils.get_free_port('http')
- ssl_port = utils.get_free_port('https')
- cherrypy_port = utils.get_free_port('cherrypy_port')
- test_server = utils.run_server(host, port, ssl_port, test_mode=True,
- cherrypy_port=cherrypy_port, model=model)
-
-
-def tearDownModule():
- test_server.stop()
- os.unlink(tmpfile)
-
-
-class ServerTests(unittest.TestCase):
- def setUp(self):
- self.request = partial(utils.request, host, ssl_port)
- model.reset()
-
- def assertValidJSON(self, txt):
- try:
- json.loads(txt)
- except ValueError:
- self.fail("Invalid JSON: %s" % txt)
-
- def test_server_start(self):
- """
- Test that we can start a server and receive HTTP:200.
- """
- resp = self.request('/')
- self.assertEquals(200, resp.status)
-
- def test_multithreaded_connection(self):
- def worker():
- for i in xrange(100):
- ret = model.vms_get_list()
- self.assertEquals('test', ret[0])
-
- threads = []
- for i in xrange(100):
- t = threading.Thread(target=worker)
- t.setDaemon(True)
- t.start()
- threads.append(t)
- for t in threads:
- t.join()
-
- def test_collection(self):
- c = Collection(model)
-
- # The base Collection is always empty
- cherrypy.request.method = 'GET'
- cherrypy.request.headers['Accept'] = 'application/json'
- self.assertEquals('[]', c.index())
-
- # POST and DELETE raise HTTP:405 by default
- for method in ('POST', 'DELETE'):
- cherrypy.request.method = method
- try:
- c.index()
- except cherrypy.HTTPError, e:
- self.assertEquals(405, e.code)
- else:
- self.fail("Expected exception not raised")
-
- def test_resource(self):
- r = Resource(model)
-
- # Test the base Resource representation
- cherrypy.request.method = 'GET'
- cherrypy.request.headers['Accept'] = 'application/json'
- self.assertEquals('{}', r.index())
-
- # POST and DELETE raise HTTP:405 by default
- for method in ('POST', 'DELETE'):
- cherrypy.request.method = method
- try:
- r.index()
- except cherrypy.HTTPError, e:
- self.assertEquals(405, e.code)
- else:
- self.fail("Expected exception not raised")
-
- def test_404(self):
- """
- A non-existent path should return HTTP:404
- """
- url_list = ['/plugins/kimchi/doesnotexist',
'/plugins/kimchi/vms/blah']
- for url in url_list:
- resp = self.request(url)
- self.assertEquals(404, resp.status)
-
- # Verify it works for DELETE too
- resp = self.request('/plugins/kimchi/templates/blah', '',
'DELETE')
- self.assertEquals(404, resp.status)
-
- def test_accepts(self):
- """
- Verify the following expectations regarding the client Accept header:
- If omitted, default to html
- If 'application/json', serve the rest api
- If 'text/html', serve the UI
- If both of the above (in any order), serve the rest api
- If neither of the above, HTTP:406
- """
- resp = self.request("/", headers={})
- location = resp.getheader('location')
- self.assertTrue(location.endswith("login.html"))
- resp = self.request("/login.html", headers={})
- self.assertTrue('<!doctype html>' in resp.read().lower())
-
- resp = self.request("/", headers={'Accept':
'application/json'})
- self.assertValidJSON(resp.read())
-
- resp = self.request("/", headers={'Accept':
'text/html'})
- location = resp.getheader('location')
- self.assertTrue(location.endswith("login.html"))
-
- resp = self.request("/", headers={'Accept':
- 'application/json, text/html'})
- self.assertValidJSON(resp.read())
-
- resp = self.request("/", headers={'Accept':
- 'text/html, application/json'})
- self.assertValidJSON(resp.read())
-
- h = {'Accept': 'text/plain'}
- resp = self.request('/', None, 'GET', h)
- self.assertEquals(406, resp.status)
-
- def test_auth_unprotected(self):
- hdrs = {'AUTHORIZATION': ''}
- uris = ['/plugins/kimchi/js/kimchi.min.js',
- '/plugins/kimchi/css/theme-default.min.css',
- '/plugins/kimchi/images/icon-vm.png',
- '/libs/jquery-1.10.0.min.js',
- '/login.html',
- '/logout']
-
- for uri in uris:
- resp = self.request(uri, None, 'HEAD', hdrs)
- self.assertEquals(200, resp.status)
-
- def test_auth_protected(self):
- hdrs = {'AUTHORIZATION': ''}
- uris = ['/plugins/kimchi/vms',
- '/plugins/kimchi/vms/doesnotexist',
- '/tasks']
-
- for uri in uris:
- resp = self.request(uri, None, 'GET', hdrs)
- self.assertEquals(401, resp.status)
-
- def test_auth_bad_creds(self):
- # Test HTTPBA
- hdrs = {'AUTHORIZATION': "Basic " +
base64.b64encode("nouser:badpass")}
- resp = self.request('/plugins/kimchi/vms', None, 'GET', hdrs)
- self.assertEquals(401, resp.status)
-
- # Test REST API
- hdrs = {'AUTHORIZATION': ''}
- req = json.dumps({'username': 'nouser', 'password':
'badpass'})
- resp = self.request('/login', req, 'POST', hdrs)
- self.assertEquals(401, resp.status)
-
- def test_auth_browser_no_httpba(self):
- # Kimchi detects REST requests from the browser by looking for a
- # specific header
- hdrs = {"X-Requested-With": "XMLHttpRequest"}
-
- # Try our request (Note that request() will add a valid HTTPBA header)
- resp = self.request('/plugins/kimchi/vms', None, 'GET', hdrs)
- self.assertEquals(401, resp.status)
- self.assertEquals(None, resp.getheader('WWW-Authenticate'))
-
- def test_auth_session(self):
- hdrs = {'AUTHORIZATION': '',
- 'Content-Type': 'application/json',
- 'Accept': 'application/json'}
-
- # Test we are logged out
- resp = self.request('/tasks', None, 'GET', hdrs)
- self.assertEquals(401, resp.status)
-
- # Execute a login call
- user, pw = mockmodel.fake_user.items()[0]
- req = json.dumps({'username': user, 'password': pw})
- resp = self.request('/login', req, 'POST', hdrs)
- self.assertEquals(200, resp.status)
-
- user_info = json.loads(resp.read())
- self.assertEquals(sorted(user_info.keys()),
- ['groups', 'roles', 'username'])
- roles = user_info['roles']
- for tab, role in roles.iteritems():
- self.assertEquals(role, u'admin')
-
- cookie = resp.getheader('set-cookie')
- hdrs['Cookie'] = cookie
-
- # Test we are logged in with the cookie
- resp = self.request('/tasks', None, 'GET', hdrs)
- self.assertEquals(200, resp.status)
-
- # Execute a logout call
- resp = self.request('/logout', '{}', 'POST', hdrs)
- self.assertEquals(200, resp.status)
- del hdrs['Cookie']
-
- # Test we are logged out
- resp = self.request('/tasks', None, 'GET', hdrs)
- self.assertEquals(401, resp.status)
-
- def test_get_param(self):
- # Create a mock ISO file
- mockiso = '/tmp/mock.iso'
- open('/tmp/mock.iso', 'w').close()
-
- # Create 2 different templates
- req = json.dumps({'name': 'test-tmpl1', 'cdrom':
mockiso})
- self.request('/plugins/kimchi/templates', req, 'POST')
-
- req = json.dumps({'name': 'test-tmpl2', 'cdrom':
mockiso})
- self.request('/plugins/kimchi/templates', req, 'POST')
-
- # Remove mock iso
- os.unlink(mockiso)
-
- # Get the templates
- resp = self.request('/plugins/kimchi/templates')
- self.assertEquals(200, resp.status)
- res = json.loads(resp.read())
- self.assertEquals(2, len(res))
-
- # Get a specific template
- resp = self.request('/plugins/kimchi/templates?name=test-tmpl1')
- self.assertEquals(200, resp.status)
- res = json.loads(resp.read())
- self.assertEquals(1, len(res))
- self.assertEquals('test-tmpl1', res[0]['name'])
diff --git a/plugins/kimchi/tests/test_storagepoolxml.py
b/plugins/kimchi/tests/test_storagepoolxml.py
deleted file mode 100644
index 7e45cca..0000000
--- a/plugins/kimchi/tests/test_storagepoolxml.py
+++ /dev/null
@@ -1,171 +0,0 @@
-#
-# Project Kimchi
-#
-# Copyright IBM, Corp. 2015
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-
-import lxml.etree as ET
-import unittest
-
-from wok.plugins.kimchi.model.libvirtstoragepool import StoragePoolDef
-
-
-class StoragepoolXMLTests(unittest.TestCase):
- def test_get_storagepool_xml(self):
- poolDefs = [
- {'def':
- {'type': 'dir',
- 'name': 'unitTestDirPool',
- 'path': '/var/temp/images'},
- 'xml':
- """
- <pool type='dir'>
- <name>unitTestDirPool</name>
- <target>
- <path>/var/temp/images</path>
- </target>
- </pool>
- """},
- {'def':
- {'type': 'netfs',
- 'name': 'unitTestNFSPool',
- 'source': {'host': '127.0.0.1',
- 'path': '/var/export'}},
- 'xml':
- """
- <pool type='netfs'>
- <name>unitTestNFSPool</name>
- <source>
- <host name='127.0.0.1'/>
- <dir path='/var/export'/>
- </source>
- <target>
- <path>/var/lib/kimchi/nfs_mount/unitTestNFSPool</path>
- </target>
- </pool>
- """},
- {'def':
- {'type': 'logical',
- 'name': 'unitTestLogicalPool',
- 'source': {'devices': ['/dev/hda',
'/dev/hdb']}},
- 'xml':
- """
- <pool type='logical'>
- <name>unitTestLogicalPool</name>
- <source>
- <device path="/dev/hda" />
- <device path="/dev/hdb" />
- </source>
- <target>
- <path>/dev/unitTestLogicalPool</path>
- </target>
- </pool>
- """},
- {'def':
- {'type': 'iscsi',
- 'name': 'unitTestISCSIPool',
- 'source': {
- 'host': '127.0.0.1',
- 'target':
'iqn.2003-01.org.linux-iscsi.localhost'}},
- 'xml':
- """
- <pool type='iscsi'>
- <name>unitTestISCSIPool</name>
- <source>
- <host name='127.0.0.1' />
- <device path='iqn.2003-01.org.linux-iscsi.localhost'/>
- </source>
- <target>
- <path>/dev/disk/by-id</path>
- </target>
- </pool>
- """},
- {'def':
- {'type': 'iscsi',
- 'name': 'unitTestISCSIPoolPort',
- 'source': {
- 'host': '127.0.0.1',
- 'port': 3266,
- 'target':
'iqn.2003-01.org.linux-iscsi.localhost'}},
- 'xml':
- """
- <pool type='iscsi'>
- <name>unitTestISCSIPoolPort</name>
- <source>
- <host name='127.0.0.1' port='3266' />
- <device path='iqn.2003-01.org.linux-iscsi.localhost'/>
- </source>
- <target>
- <path>/dev/disk/by-id</path>
- </target>
- </pool>
- """},
- {'def':
- {'type': 'iscsi',
- 'name': 'unitTestISCSIPoolAuth',
- 'source': {
- 'host': '127.0.0.1',
- 'target': 'iqn.2003-01.org.linux-iscsi.localhost',
- 'auth': {'username': 'testUser',
- 'password': 'ActuallyNotUsedInPoolXML'}}},
- 'xml':
- """
- <pool type='iscsi'>
- <name>unitTestISCSIPoolAuth</name>
- <source>
- <host name='127.0.0.1' />
- <device path='iqn.2003-01.org.linux-iscsi.localhost'/>
- <auth type='chap' username='testUser'>
- <secret type='iscsi'
usage='unitTestISCSIPoolAuth'/>
- </auth>
- </source>
- <target>
- <path>/dev/disk/by-id</path>
- </target>
- </pool>
- """},
- {'def':
- {'type': 'scsi',
- 'name': 'unitTestSCSIFCPool',
- 'path': '/dev/disk/by-path',
- 'source': {
- 'name': 'scsi_host3',
- 'adapter': {
- 'type': 'fc_host',
- 'wwpn': '0123456789abcdef',
- 'wwnn': 'abcdef0123456789'}}},
- 'xml':
- """
- <pool type='scsi'>
- <name>unitTestSCSIFCPool</name>
- <source>
- <adapter type='fc_host' name='scsi_host3'
- wwnn='abcdef0123456789'
wwpn='0123456789abcdef'></adapter>
- </source>
- <target>
- <path>/dev/disk/by-path</path>
- </target>
- </pool>
- """}]
-
- for poolDef in poolDefs:
- defObj = StoragePoolDef.create(poolDef['def'])
- xmlStr = defObj.xml
-
- parser = ET.XMLParser(remove_blank_text=True)
- t1 = ET.fromstring(xmlStr, parser)
- t2 = ET.fromstring(poolDef['xml'], parser)
- self.assertEquals(ET.tostring(t1), ET.tostring(t2))
diff --git a/plugins/kimchi/tests/test_template.py
b/plugins/kimchi/tests/test_template.py
deleted file mode 100644
index c7de182..0000000
--- a/plugins/kimchi/tests/test_template.py
+++ /dev/null
@@ -1,387 +0,0 @@
-# -*- coding: utf-8 -*-
-#
-# Project Kimchi
-#
-# Copyright IBM, Corp. 2015
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-
-import json
-import os
-import unittest
-from functools import partial
-
-from wok.plugins.kimchi.config import READONLY_POOL_TYPE
-from wok.plugins.kimchi.mockmodel import MockModel
-
-from utils import get_free_port, patch_auth, request, run_server
-
-
-model = None
-test_server = None
-host = None
-port = None
-ssl_port = None
-cherrypy_port = None
-
-
-def setUpModule():
- global test_server, model, host, port, ssl_port, cherrypy_port
-
- patch_auth()
- model = MockModel('/tmp/obj-store-test')
- host = '127.0.0.1'
- port = get_free_port('http')
- ssl_port = get_free_port('https')
- cherrypy_port = get_free_port('cherrypy_port')
- test_server = run_server(host, port, ssl_port, test_mode=True,
- cherrypy_port=cherrypy_port, model=model)
-
-
-def tearDownModule():
- test_server.stop()
- os.unlink('/tmp/obj-store-test')
-
-
-class TemplateTests(unittest.TestCase):
- def setUp(self):
- self.request = partial(request, host, ssl_port)
- model.reset()
-
- def test_tmpl_lifecycle(self):
- resp = self.request('/plugins/kimchi/templates')
- self.assertEquals(200, resp.status)
- self.assertEquals(0, len(json.loads(resp.read())))
-
- # Create a template without cdrom and disk specified fails with 400
- t = {'name': 'test', 'os_distro': 'ImagineOS',
- 'os_version': '1.0', 'memory': 1024, 'cpus':
1,
- 'storagepool': '/plugins/kimchi/storagepools/alt'}
- req = json.dumps(t)
- resp = self.request('/plugins/kimchi/templates', req, 'POST')
- self.assertEquals(400, resp.status)
-
- # Create a template
- t = {'name': 'test', 'cdrom': '/tmp/mock.iso'}
- req = json.dumps(t)
- resp = self.request('/plugins/kimchi/templates', req, 'POST')
- self.assertEquals(201, resp.status)
-
- # Verify the template
- keys = ['name', 'icon', 'invalid', 'os_distro',
'os_version', 'cpus',
- 'memory', 'cdrom', 'disks',
'storagepool', 'networks',
- 'folder', 'graphics', 'cpu_info']
- tmpl = json.loads(
- self.request('/plugins/kimchi/templates/test').read()
- )
- self.assertEquals(sorted(tmpl.keys()), sorted(keys))
-
- # Verify if default disk format was configured
- self.assertEquals(tmpl['disks'][0]['format'], 'qcow2')
-
- # Clone a template
- resp = self.request('/plugins/kimchi/templates/test/clone',
'{}',
- 'POST')
- self.assertEquals(303, resp.status)
-
- # Verify the cloned template
- tmpl_cloned = json.loads(
- self.request('/plugins/kimchi/templates/test-clone1').read()
- )
- del tmpl['name']
- del tmpl_cloned['name']
- self.assertEquals(tmpl, tmpl_cloned)
-
- # Delete the cloned template
- resp = self.request('/plugins/kimchi/templates/test-clone1',
'{}',
- 'DELETE')
- self.assertEquals(204, resp.status)
-
- # Create a template with same name fails with 400
- req = json.dumps({'name': 'test', 'cdrom':
'/tmp/mock.iso'})
- resp = self.request('/plugins/kimchi/templates', req, 'POST')
- self.assertEquals(400, resp.status)
-
- # Create an image based template
- open('/tmp/mock.img', 'w').close()
- t = {'name': 'test_img_template',
- 'disks': [{'base': '/tmp/mock.img'}]}
- req = json.dumps(t)
- resp = self.request('/plugins/kimchi/templates', req, 'POST')
- self.assertEquals(201, resp.status)
- os.remove('/tmp/mock.img')
-
- # Test disk format
- t = {'name': 'test-format', 'cdrom':
'/tmp/mock.iso',
- 'disks': [{'index': 0, 'size': 10, 'format':
'vmdk'}]}
- req = json.dumps(t)
- resp = self.request('/plugins/kimchi/templates', req, 'POST')
- self.assertEquals(201, resp.status)
- tmpl = json.loads(
- self.request('/plugins/kimchi/templates/test-format').read()
- )
- self.assertEquals(tmpl['disks'][0]['format'], 'vmdk')
-
- def test_customized_tmpl(self):
- # Create a template
- t = {'name': 'test', 'cdrom': '/tmp/mock.iso'}
- req = json.dumps(t)
- resp = self.request('/plugins/kimchi/templates', req, 'POST')
- self.assertEquals(201, resp.status)
- tmpl = json.loads(
- self.request('/plugins/kimchi/templates/test').read()
- )
-
- # Update name
- new_name = u'k������h��Tmpl'
- new_tmpl_uri = '/plugins/kimchi/templates/%s' \
- % new_name.encode('utf-8')
- req = json.dumps({'name': new_name})
- resp = self.request('/plugins/kimchi/templates/test', req,
'PUT')
- self.assertEquals(303, resp.status)
- resp = self.request(new_tmpl_uri)
- update_tmpl = json.loads(resp.read())
- self.assertEquals(new_name, update_tmpl['name'])
- del tmpl['name']
- del update_tmpl['name']
- self.assertEquals(tmpl, update_tmpl)
-
- # Update icon
- req = json.dumps({'icon': 'kimchi/images/icon-fedora.png'})
- resp = self.request(new_tmpl_uri, req, 'PUT')
- self.assertEquals(200, resp.status)
- update_tmpl = json.loads(resp.read())
- self.assertEquals('kimchi/images/icon-fedora.png',
update_tmpl['icon'])
-
- # Update os_distro and os_version
- req = json.dumps({'os_distro': 'fedora', 'os_version':
'21'})
- resp = self.request(new_tmpl_uri, req, 'PUT')
- self.assertEquals(200, resp.status)
- update_tmpl = json.loads(resp.read())
- self.assertEquals('fedora', update_tmpl['os_distro'])
- self.assertEquals('21', update_tmpl['os_version'])
-
- # Update cpus
- req = json.dumps({'cpus': 2})
- resp = self.request(new_tmpl_uri, req, 'PUT')
- self.assertEquals(200, resp.status)
- update_tmpl = json.loads(resp.read())
- self.assertEquals(2, update_tmpl['cpus'])
-
- # Update memory
- req = json.dumps({'memory': 2048})
- resp = self.request(new_tmpl_uri, req, 'PUT')
- self.assertEquals(200, resp.status)
- update_tmpl = json.loads(resp.read())
- self.assertEquals(2048, update_tmpl['memory'])
-
- # Update cpu_info
- resp = self.request(new_tmpl_uri)
- cpu_info = json.loads(resp.read())['cpu_info']
- self.assertEquals(cpu_info, {})
- self.assertEquals(cpu_info.get('topology'), None)
-
- cpu_info_data = {'cpu_info': {'topology': {'sockets': 1,
- 'cores': 2,
- 'threads': 1}}}
- resp = self.request(new_tmpl_uri, json.dumps(cpu_info_data), 'PUT')
- self.assertEquals(200, resp.status)
- update_tmpl = json.loads(resp.read())
- self.assertEquals(update_tmpl['cpu_info'],
cpu_info_data['cpu_info'])
-
- # Update cdrom
- cdrom_data = {'cdrom': '/tmp/mock2.iso'}
- resp = self.request(new_tmpl_uri, json.dumps(cdrom_data), 'PUT')
- self.assertEquals(200, resp.status)
- update_tmpl = json.loads(resp.read())
- self.assertEquals(update_tmpl['cdrom'], cdrom_data['cdrom'])
-
- # Update disks
- disk_data = {'disks': [{'index': 0, 'size': 10},
- {'index': 1, 'size': 20}]}
- resp = self.request(new_tmpl_uri, json.dumps(disk_data), 'PUT')
- self.assertEquals(200, resp.status)
- resp = self.request(new_tmpl_uri)
- self.assertEquals(200, resp.status)
- updated_tmpl = json.loads(resp.read())
- self.assertEquals(updated_tmpl['disks'], disk_data['disks'])
-
- # For all supported types, edit the template and check if
- # the change was made.
- disk_types = ['bochs', 'cloop', 'cow', 'dmg',
'qcow', 'qcow2',
- 'qed', 'raw', 'vmdk', 'vpc']
- for disk_type in disk_types:
- disk_data = {'disks': [{'index': 0, 'format':
disk_type,
- 'size': 10}]}
- resp = self.request(new_tmpl_uri, json.dumps(disk_data), 'PUT')
- self.assertEquals(200, resp.status)
-
- resp = self.request(new_tmpl_uri)
- self.assertEquals(200, resp.status)
- updated_tmpl = json.loads(resp.read())
- self.assertEquals(updated_tmpl['disks'], disk_data['disks'])
-
- # Update folder
- folder_data = {'folder': ['mock', 'isos']}
- resp = self.request(new_tmpl_uri, json.dumps(folder_data), 'PUT')
- self.assertEquals(200, resp.status)
- update_tmpl = json.loads(resp.read())
- self.assertEquals(update_tmpl['folder'], folder_data['folder'])
-
- # Update graphics
- req = json.dumps({'graphics': {'type': 'spice'}})
- resp = self.request(new_tmpl_uri, req, 'PUT')
- self.assertEquals(200, resp.status)
- update_tmpl = json.loads(resp.read())
- self.assertEquals('spice',
update_tmpl['graphics']['type'])
-
- req = json.dumps({'graphics': {'type': 'vnc',
'listen': 'fe00::0'}})
- resp = self.request(new_tmpl_uri, req, 'PUT')
- self.assertEquals(200, resp.status)
- update_tmpl = json.loads(resp.read())
- self.assertEquals('vnc',
update_tmpl['graphics']['type'])
- self.assertEquals('fe00::0',
update_tmpl['graphics']['listen'])
-
- def test_customized_network(self):
- # Create a template
- t = {'name': 'test', 'cdrom': '/tmp/mock.iso'}
- req = json.dumps(t)
- resp = self.request('/plugins/kimchi/templates', req, 'POST')
- self.assertEquals(201, resp.status)
-
- # Create networks to be used for testing
- networks = [{'name': u'k������h��-��et', 'connection':
'isolated'},
- {'name': u'nat-network', 'connection':
'nat'},
- {'name': u'subnet-network', 'connection':
'nat',
- 'subnet': '127.0.100.0/24'}]
-
- # Verify the current system has at least one interface to create a
- # bridged network
- interfaces = json.loads(
- self.request('/plugins/kimchi/interfaces?type=nic').read()
- )
- if len(interfaces) > 0:
- iface = interfaces[0]['name']
- networks.append({'name': u'bridge-network',
'connection': 'bridge',
- 'interface': iface})
- networks.append({'name': u'bridge-network',
'connection': 'bridge',
- 'interface': iface, 'vlan_id': 987})
-
- tmpl_nets = []
- for net in networks:
- self.request('/plugins/kimchi/networks', json.dumps(net),
'POST')
- tmpl_nets.append(net['name'])
- req = json.dumps({'networks': tmpl_nets})
- resp = self.request('/plugins/kimchi/templates/test', req,
'PUT')
- self.assertEquals(200, resp.status)
-
- def test_customized_storagepool(self):
- # Create a template
- t = {'name': 'test', 'cdrom': '/tmp/mock.iso'}
- req = json.dumps(t)
- resp = self.request('/plugins/kimchi/templates', req, 'POST')
- self.assertEquals(201, resp.status)
-
- # MockModel always returns 2 partitions (vdx, vdz)
- partitions = json.loads(
- self.request('/plugins/kimchi/host/partitions').read()
- )
- devs = [dev['path'] for dev in partitions]
-
- # MockModel always returns 3 FC devices
- fc_devs = json.loads(
- self.request('/plugins/kimchi/host/devices?_cap=fc_host').read()
- )
- fc_devs = [dev['name'] for dev in fc_devs]
-
- poolDefs = [
- {'type': 'dir', 'name':
u'k������h��UnitTestDirPool',
- 'path': '/tmp/kimchi-images'},
- {'type': 'netfs', 'name':
u'k������h��UnitTestNSFPool',
- 'source': {'host': 'localhost',
- 'path': '/var/lib/kimchi/nfs-pool'}},
- {'type': 'scsi', 'name':
u'k������h��UnitTestSCSIFCPool',
- 'source': {'adapter_name': fc_devs[0]}},
- {'type': 'iscsi', 'name':
u'k������h��UnitTestISCSIPool',
- 'source': {'host': '127.0.0.1',
- 'target':
'iqn.2015-01.localhost.kimchiUnitTest'}},
- {'type': 'logical', 'name':
u'k������h��UnitTestLogicalPool',
- 'source': {'devices': [devs[0]]}}]
-
- for pool in poolDefs:
- self.request('/plugins/kimchi/storagepools', json.dumps(pool),
- 'POST')
- pool_uri = '/plugins/kimchi/storagepools/%s' \
- % pool['name'].encode('utf-8')
- self.request(pool_uri + '/activate', '{}', 'POST')
-
- req = None
- if pool['type'] in READONLY_POOL_TYPE:
- resp = self.request(pool_uri + '/storagevolumes')
- vols = json.loads(resp.read())
- if len(vols) > 0:
- vol = vols[0]['name']
- req = json.dumps({'storagepool': pool_uri,
- 'disks': [{'volume': vol}]})
- else:
- req = json.dumps({'storagepool': pool_uri})
-
- if req is not None:
- resp = self.request('/plugins/kimchi/templates/test', req,
- 'PUT')
- self.assertEquals(200, resp.status)
-
- def test_tmpl_integrity(self):
- # Create a network and a pool for testing template integrity
- net = {'name': u'nat-network', 'connection':
'nat'}
- self.request('/plugins/kimchi/networks', json.dumps(net),
'POST')
-
- pool = {'type': 'dir', 'name': 'dir-pool',
'path': '/tmp/dir-pool'}
- self.request('/plugins/kimchi/storagepools', json.dumps(pool),
'POST')
- pool_uri = '/plugins/kimchi/storagepools/%s' \
- % pool['name'].encode('utf-8')
- self.request(pool_uri + '/activate', '{}', 'POST')
-
- # Create a template using the custom network and pool
- t = {'name': 'test', 'cdrom': '/tmp/mock.iso',
- 'networks': ['nat-network'],
- 'storagepool': '/plugins/kimchi/storagepools/dir-pool'}
- req = json.dumps(t)
- resp = self.request('/plugins/kimchi/templates', req, 'POST')
- self.assertEquals(201, resp.status)
-
- # Try to delete network
- # It should fail as it is associated to a template
- resp = self.request('/plugins/kimchi/networks/nat-network',
'{}',
- 'DELETE')
- self.assertIn("KCHNET0017E",
json.loads(resp.read())["reason"])
-
- # Update template to release network and then delete it
- params = {'networks': []}
- req = json.dumps(params)
- self.request('/plugins/kimchi/templates/test', req, 'PUT')
- resp = self.request('/plugins/kimchi/networks/nat-network',
'{}',
- 'DELETE')
- self.assertEquals(204, resp.status)
-
- # Try to delete the storagepool
- # It should fail as it is associated to a template
- resp = self.request('/plugins/kimchi/storagepools/dir-pool',
'{}',
- 'DELETE')
- self.assertEquals(400, resp.status)
-
- # Verify the template
- res = json.loads(self.request('/plugins/kimchi/templates/test').read())
- self.assertEquals(res['invalid']['cdrom'],
['/tmp/mock.iso'])
diff --git a/plugins/kimchi/tests/test_utils.py b/plugins/kimchi/tests/test_utils.py
deleted file mode 100644
index bcb14e2..0000000
--- a/plugins/kimchi/tests/test_utils.py
+++ /dev/null
@@ -1,69 +0,0 @@
-#
-# Project Kimchi
-#
-# Copyright IBM, Corp. 2015
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-
-import unittest
-
-from wok.exception import InvalidParameter
-from wok.utils import convert_data_size
-
-
-class UtilsTests(unittest.TestCase):
- def test_convert_data_size(self):
- failure_data = [{'val': None, 'from': 'MiB'},
- {'val': self, 'from': 'MiB'},
- {'val': 1, 'from': None},
- {'val': 1, 'from': ''},
- {'val': 1, 'from': 'foo'},
- {'val': 1, 'from': 'kib'},
- {'val': 1, 'from': 'MiB',
'to': None},
- {'val': 1, 'from': 'MiB',
'to': ''},
- {'val': 1, 'from': 'MiB',
'to': 'foo'},
- {'val': 1, 'from': 'MiB',
'to': 'kib'}]
-
- for d in failure_data:
- if 'to' in d:
- self.assertRaises(InvalidParameter, convert_data_size,
- d['val'], d['from'], d['to'])
- else:
- self.assertRaises(InvalidParameter, convert_data_size,
- d['val'], d['from'])
-
- success_data = [{'got': convert_data_size(5, 'MiB',
'MiB'),
- 'want': 5},
- {'got': convert_data_size(5, 'MiB',
'KiB'),
- 'want': 5120},
- {'got': convert_data_size(5, 'MiB',
'M'),
- 'want': 5.24288},
- {'got': convert_data_size(5, 'MiB',
'GiB'),
- 'want': 0.0048828125},
- {'got': convert_data_size(5, 'MiB',
'Tb'),
- 'want': 4.194304e-05},
- {'got': convert_data_size(5, 'KiB',
'MiB'),
- 'want': 0.0048828125},
- {'got': convert_data_size(5, 'M',
'MiB'),
- 'want': 4.76837158203125},
- {'got': convert_data_size(5, 'GiB',
'MiB'),
- 'want': 5120},
- {'got': convert_data_size(5, 'Tb',
'MiB'),
- 'want': 596046.4477539062},
- {'got': convert_data_size(5, 'MiB'),
- 'want': convert_data_size(5, 'MiB',
'B')}]
-
- for d in success_data:
- self.assertEquals(d['got'], d['want'])
diff --git a/plugins/kimchi/tests/test_vmtemplate.py
b/plugins/kimchi/tests/test_vmtemplate.py
deleted file mode 100644
index 0bca215..0000000
--- a/plugins/kimchi/tests/test_vmtemplate.py
+++ /dev/null
@@ -1,116 +0,0 @@
-#
-# Project Kimchi
-#
-# Copyright IBM, Corp. 2013-2015
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-
-import os
-import unittest
-import uuid
-
-from wok.xmlutils.utils import xpath_get_text
-
-from wok.plugins.kimchi.osinfo import get_template_default
-from wok.plugins.kimchi.vmtemplate import VMTemplate
-
-
-class VMTemplateTests(unittest.TestCase):
- def setUp(self):
- self.iso = '/tmp/mock.iso'
- open(self.iso, 'w').close()
-
- def tearDown(self):
- os.unlink(self.iso)
-
- def test_minimal_construct(self):
- disk_bus = get_template_default('old', 'disk_bus')
- memory = get_template_default('old', 'memory')
- nic_model = get_template_default('old', 'nic_model')
- fields = (('name', 'test'), ('os_distro',
'unknown'),
- ('os_version', 'unknown'), ('cpus', 1),
- ('memory', memory), ('networks', ['default']),
- ('disk_bus', disk_bus), ('nic_model', nic_model),
- ('graphics', {'type': 'vnc', 'listen':
'127.0.0.1'}),
- ('cdrom', self.iso))
-
- args = {'name': 'test', 'cdrom': self.iso}
- t = VMTemplate(args)
- for name, val in fields:
- self.assertEquals(val, t.info.get(name))
-
- def test_construct_overrides(self):
- graphics = {'type': 'spice', 'listen':
'127.0.0.1'}
- args = {'name': 'test', 'disks': [{'size': 10},
{'size': 20}],
- 'graphics': graphics, "cdrom": self.iso}
- t = VMTemplate(args)
- self.assertEquals(2, len(t.info['disks']))
- self.assertEquals(graphics, t.info['graphics'])
-
- def test_specified_graphics(self):
- # Test specified listen
- graphics = {'type': 'vnc', 'listen':
'127.0.0.1'}
- args = {'name': 'test', 'disks': [{'size': 10},
{'size': 20}],
- 'graphics': graphics, 'cdrom': self.iso}
- t = VMTemplate(args)
- self.assertEquals(graphics, t.info['graphics'])
-
- # Test specified type
- graphics = {'type': 'spice', 'listen':
'127.0.0.1'}
- args['graphics'] = graphics
- t = VMTemplate(args)
- self.assertEquals(graphics, t.info['graphics'])
-
- # If no listen specified, test the default listen
- graphics = {'type': 'vnc'}
- args['graphics'] = graphics
- t = VMTemplate(args)
- self.assertEquals(graphics['type'],
t.info['graphics']['type'])
- self.assertEquals('127.0.0.1',
t.info['graphics']['listen'])
-
- def test_to_xml(self):
- graphics = {'type': 'spice', 'listen':
'127.0.0.1'}
- vm_uuid = str(uuid.uuid4()).replace('-', '')
- if os.uname()[4] in ['ppc', 'ppc64', 'ppc64le']:
- maxmem = 3328
- else:
- maxmem = 3072
- t = VMTemplate({'name': 'test-template', 'cdrom':
self.iso,
- 'max_memory': maxmem << 10})
- xml = t.to_vm_xml('test-vm', vm_uuid, graphics=graphics)
- self.assertEquals(vm_uuid, xpath_get_text(xml, "/domain/uuid")[0])
- self.assertEquals('test-vm', xpath_get_text(xml,
"/domain/name")[0])
- expr = "/domain/devices/graphics/@type"
- self.assertEquals(graphics['type'], xpath_get_text(xml, expr)[0])
- expr = "/domain/devices/graphics/@listen"
- self.assertEquals(graphics['listen'], xpath_get_text(xml, expr)[0])
- expr = "/domain/maxMemory/@slots"
- self.assertEquals('2', xpath_get_text(xml, expr)[0])
-
- def test_arg_merging(self):
- """
- Make sure that default parameters from osinfo do not override user-
- provided parameters.
- """
- graphics = {'type': 'vnc', 'listen':
'127.0.0.1'}
- args = {'name': 'test', 'os_distro': 'opensuse',
'os_version': '12.3',
- 'cpus': 2, 'memory': 2048, 'networks':
['foo'],
- 'cdrom': self.iso, 'graphics': graphics}
- t = VMTemplate(args)
- self.assertEquals(2, t.info.get('cpus'))
- self.assertEquals(2048, t.info.get('memory'))
- self.assertEquals(['foo'], t.info.get('networks'))
- self.assertEquals(self.iso, t.info.get('cdrom'))
- self.assertEquals(graphics, t.info.get('graphics'))
diff --git a/plugins/kimchi/tests/test_yumparser.py
b/plugins/kimchi/tests/test_yumparser.py
deleted file mode 100644
index be5e95c..0000000
--- a/plugins/kimchi/tests/test_yumparser.py
+++ /dev/null
@@ -1,162 +0,0 @@
-#
-# Project Kimchi
-#
-# Copyright IBM, Corp. 2015
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-
-import os
-import tempfile
-import unittest
-
-from wok.rollbackcontext import RollbackContext
-
-from wok.plugins.kimchi.model import model
-from wok.plugins.kimchi.yumparser import delete_repo_from_file, get_repo_files
-from wok.plugins.kimchi.yumparser import get_yum_packages_list_update
-from wok.plugins.kimchi.yumparser import get_yum_repositories
-from wok.plugins.kimchi.yumparser import write_repo_to_file, YumRepoObject
-
-
-TEMP_REPO_FILE = ''
-
-
-def _is_yum_distro():
- inst = model.Model('test:///default')
- repo_type = inst.capabilities_lookup()['repo_mngt_tool']
- return repo_type == 'yum'
-
-
-def _create_fake_repos(repo_file_name):
- repo1 = YumRepoObject('fake-repo-1', repo_file_name)
- repo2 = YumRepoObject('fake-repo-2', repo_file_name)
- repo3 = YumRepoObject('fake-repo-3', repo_file_name)
- repo4 = YumRepoObject('fake-repo-4', repo_file_name)
- repos = [repo1, repo2, repo3, repo4]
- return repos
-
-
-def _create_empty_repo_file():
- data = """
-#
-# This is a repository file with no repositories at all
-# No repositories must be added after reading this file.
-#
- """
- _, tmp_file_name = tempfile.mkstemp(suffix='.repo',
- dir='/etc/yum.repos.d')
- with open(tmp_file_name, 'w') as f:
- f.writelines(data)
-
- return tmp_file_name
-
-
-def _create_fake_repos_file():
- _, tmp_file_name = tempfile.mkstemp(suffix='.repo',
- dir='/etc/yum.repos.d')
-
- fake_repos = _create_fake_repos(tmp_file_name)
- file_data = ''
- for repo in fake_repos:
- file_data += str(repo) + '\n'
-
- with open(tmp_file_name, 'w') as f:
- f.writelines(file_data)
-
- return tmp_file_name
-
-
-def _generate_yumcheckupdate_output():
- output = """
-Repository 'REPOSITORY1' is missing name in configuration, using id
-Repository 'REPOSITORY1-OPTIONAL' is missing name in configuration, using id
-
-PACKAGE1.noarch 20150611.-gg-FAKE1 REPOSITORY1
-PACKAGE2.x86_64 20150611.-no-FAKE2 REPOSITORY2
-PACKAGE3.dot.dot.i386 20150611.-re-FAKE3 REPOSITORY3
-
-Obsoleting Packages
-OBSOLETE4.dot.dot.i386 20150611.FAKE4 REPOSITORY4
-OBSOLETE5.dot.dot.fakearch 20150611.FAKE5 REPOSITORY5
- """
- return output
-
-
-(a)unittest.skipIf(not _is_yum_distro(), 'Skipping: YUM exclusive test')
-def setUpModule():
- global TEMP_REPO_FILE
- TEMP_REPO_FILE = _create_fake_repos_file()
-
-
-(a)unittest.skipIf(not _is_yum_distro(), 'Skipping: YUM exclusive test')
-def tearDownModule():
- os.remove(TEMP_REPO_FILE)
-
-
-(a)unittest.skipIf(not _is_yum_distro(), 'Skipping: YUM exclusive test')
-class YumParserTests(unittest.TestCase):
-
- def test_get_yum_repositories(self):
- repo_files = get_repo_files()
- repo_objects = get_yum_repositories()
- self.assertGreaterEqual(len(repo_objects), len(repo_files))
-
- def test_empty_repo_file(self):
- with RollbackContext() as rollback:
- repos = get_yum_repositories()
- tmp_file_name = _create_empty_repo_file()
- rollback.prependDefer(os.remove, tmp_file_name)
- repos_after = get_yum_repositories()
- self.assertEqual(len(repos_after), len(repos))
-
- def test_update_repo_attributes(self):
- repos = get_yum_repositories()
- fake_repo_2 = repos['fake-repo-2']
- fake_repo_2.disable()
- fake_repo_2.name = 'This is a fake repo'
- fake_repo_2.baseurl = 'http://a.fake.repo.url'
- fake_repo_2.gpgkey = 'file://a/fake/gpg/key.fake'
- fake_repo_2.gpgcheck = False
- fake_repo_2.metalink = 'this is not a true metalink'
- fake_repo_2.mirrorlist = 'fake mirrorlist'
- write_repo_to_file(fake_repo_2)
-
- repos = get_yum_repositories()
- fake_repo_2 = repos['fake-repo-2']
- self.assertEqual(False, fake_repo_2.enabled)
- self.assertEqual(False, fake_repo_2.gpgcheck)
- self.assertEqual('This is a fake repo', fake_repo_2.name)
- self.assertEqual('http://a.fake.repo.url', fake_repo_2.baseurl)
- self.assertEqual('file://a/fake/gpg/key.fake', fake_repo_2.gpgkey)
- self.assertEqual('this is not a true metalink', fake_repo_2.metalink)
- self.assertEqual('fake mirrorlist', fake_repo_2.mirrorlist)
-
- def test_delete_repo_from_file(self):
- repos = get_yum_repositories()
- fake_repo_3 = repos['fake-repo-3']
- delete_repo_from_file(fake_repo_3)
-
- repos = get_yum_repositories()
- repos_id = repos.keys()
- self.assertNotIn('fake-repo-3', repos_id)
-
- def test_yum_checkupdate_parsing(self):
- output = _generate_yumcheckupdate_output()
- packages = get_yum_packages_list_update(output)
- self.assertEqual(len(packages), 3)
- self.assertEqual(packages[0].ui_from_repo, 'REPOSITORY1')
- self.assertEqual(packages[1].version, '20150611.-no-FAKE2')
- self.assertEqual(packages[2].name, 'PACKAGE3.dot.dot')
- self.assertEqual(packages[2].arch, 'i386')
diff --git a/plugins/kimchi/tests/utils.py b/plugins/kimchi/tests/utils.py
deleted file mode 100644
index ecaa87f..0000000
--- a/plugins/kimchi/tests/utils.py
+++ /dev/null
@@ -1,260 +0,0 @@
-#
-# Project Kimchi
-#
-# Copyright IBM, Corp. 2013-2015
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-#
-
-import base64
-import cherrypy
-import grp
-import httplib
-import inspect
-import json
-import os
-import socket
-import ssl
-import sys
-import threading
-import time
-import unittest
-from contextlib import closing
-from lxml import etree
-
-import wok.server
-from wok.config import config, PluginPaths
-from wok.auth import User, USER_NAME, USER_GROUPS, USER_ROLES, tabs
-from wok.exception import NotFoundError, OperationFailed
-from wok.utils import wok_log
-
-from wok.plugins.kimchi import mockmodel
-
-
-_ports = {}
-
-# provide missing unittest decorators and API for python 2.6; these decorators
-# do not actually work, just avoid the syntax failure
-if sys.version_info[:2] == (2, 6):
- def skipUnless(condition, reason):
- if not condition:
- sys.stderr.write('[expected failure] ')
- raise Exception(reason)
- return lambda obj: obj
-
- unittest.skipUnless = skipUnless
- unittest.expectedFailure = lambda obj: obj
-
- def assertGreater(self, a, b, msg=None):
- if not a > b:
- self.fail('%s not greater than %s' % (repr(a), repr(b)))
-
- def assertGreaterEqual(self, a, b, msg=None):
- if not a >= b:
- self.fail('%s not greater than or equal to %s'
- % (repr(a), repr(b)))
-
- def assertIsInstance(self, obj, cls, msg=None):
- if not isinstance(obj, cls):
- self.fail('%s is not an instance of %r' % (repr(obj), cls))
-
- def assertIn(self, a, b, msg=None):
- if a not in b:
- self.fail("%s is not in %b" % (repr(a), repr(b)))
-
- def assertNotIn(self, a, b, msg=None):
- if a in b:
- self.fail("%s is in %b" % (repr(a), repr(b)))
-
- unittest.TestCase.assertGreaterEqual = assertGreaterEqual
- unittest.TestCase.assertGreater = assertGreater
- unittest.TestCase.assertIsInstance = assertIsInstance
- unittest.TestCase.assertIn = assertIn
- unittest.TestCase.assertNotIn = assertNotIn
-
-
-def get_free_port(name='http'):
- global _ports
- if _ports.get(name) is not None:
- return _ports[name]
- sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
- with closing(sock):
- try:
- sock.bind(("0.0.0.0", 0))
- except:
- raise Exception("Could not find a free port")
- _ports[name] = sock.getsockname()[1]
- return _ports[name]
-
-
-def run_server(host, port, ssl_port, test_mode, cherrypy_port=None,
- model=None, environment='development'):
-
- if cherrypy_port is None:
- cherrypy_port = get_free_port('cherrypy_port')
-
- if ssl_port is None:
- ssl_port = get_free_port('https')
-
- args = type('_', (object,),
- {'host': host, 'port': port, 'ssl_port':
ssl_port,
- 'cherrypy_port': cherrypy_port, 'max_body_size':
'4*1024',
- 'ssl_cert': '', 'ssl_key': '',
- 'test': test_mode, 'access_log': '/dev/null',
- 'error_log': '/dev/null', 'environment':
environment,
- 'log_level': 'debug'})()
- if model is not None:
- setattr(args, 'model', model)
-
- s = wok.server.Server(args)
- t = threading.Thread(target=s.start)
- t.setDaemon(True)
- t.start()
- cherrypy.engine.wait(cherrypy.engine.states.STARTED)
- return s
-
-
-def silence_server():
- """
- Silence server status messages on stdout
- """
- cherrypy.config.update({"environment": "embedded"})
-
-
-def running_as_root():
- return os.geteuid() == 0
-
-
-def _request(conn, path, data, method, headers):
- if headers is None:
- headers = {'Content-Type': 'application/json',
- 'Accept': 'application/json'}
- if 'AUTHORIZATION' not in headers.keys():
- user, pw = mockmodel.fake_user.items()[0]
- hdr = "Basic " + base64.b64encode("%s:%s" % (user, pw))
- headers['AUTHORIZATION'] = hdr
- conn.request(method, path, data, headers)
- return conn.getresponse()
-
-
-def request(host, port, path, data=None, method='GET', headers=None):
- # verify if HTTPSConnection has context parameter
- if "context" in inspect.getargspec(httplib.HTTPSConnection.__init__).args:
- context = ssl._create_unverified_context()
- conn = httplib.HTTPSConnection(host, port, context=context)
- else:
- conn = httplib.HTTPSConnection(host, port)
-
- return _request(conn, path, data, method, headers)
-
-
-def get_remote_iso_path():
- """
- Get a remote iso with the right arch from the distro files shipped
- with kimchi.
- """
- host_arch = os.uname()[4]
- remote_path = ''
- with open(os.path.join(PluginPaths('kimchi').conf_dir, 'distros.d',
- 'fedora.json')) as fedora_isos:
- # Get a list of dicts
- json_isos_list = json.load(fedora_isos)
- for iso in json_isos_list:
- if (iso.get('os_arch')) == host_arch:
- remote_path = iso.get('path')
- break
-
- return remote_path
-
-
-class FakeUser(User):
- auth_type = "fake"
- sudo = True
-
- def __init__(self, username):
- self.user = {}
- self.user[USER_NAME] = username
- self.user[USER_GROUPS] = None
- self.user[USER_ROLES] = dict.fromkeys(tabs, 'user')
-
- def get_groups(self):
- return sorted([group.gr_name for group in grp.getgrall()])[0:3]
-
- def get_roles(self):
- if self.sudo:
- self.user[USER_ROLES] = dict.fromkeys(tabs, 'admin')
- return self.user[USER_ROLES]
-
- def get_user(self):
- return self.user
-
- @staticmethod
- def authenticate(username, password, service="passwd"):
- try:
- return mockmodel.fake_user[username] == password
- except KeyError, e:
- raise OperationFailed("WOKAUTH0001E", {'username':
'username',
- 'code': e.message})
-
-
-def patch_auth(sudo=True):
- """
- Override the authenticate function with a simple test against an
- internal dict of users and passwords.
- """
- config.set("authentication", "method", "fake")
- FakeUser.sudo = sudo
-
-
-def normalize_xml(xml_str):
- return etree.tostring(etree.fromstring(xml_str,
- etree.XMLParser(remove_blank_text=True)))
-
-
-def wait_task(task_lookup, taskid, timeout=10):
- for i in range(0, timeout):
- task_info = task_lookup(taskid)
- if task_info['status'] == "running":
- wok_log.info("Waiting task %s, message: %s",
- taskid, task_info['message'])
- time.sleep(1)
- else:
- return
- wok_log.error("Timeout while process long-run task, "
- "try to increase timeout value.")
-
-
-# The action functions in model backend raise NotFoundError exception if the
-# element is not found. But in some tests, these functions are called after
-# the element has been deleted if test finishes correctly, then NofFoundError
-# exception is raised and rollback breaks. To avoid it, this wrapper ignores
-# the NotFoundError.
-def rollback_wrapper(func, resource, *args):
- try:
- func(resource, *args)
- except NotFoundError:
- # VM has been deleted already
- return
-
-
-# This function is used to test storage volume upload.
-# If we use self.request, we may encode multipart formdata by ourselves
-# requests lib take care of encode part, so use this lib instead
-def fake_auth_header():
- headers = {'Accept': 'application/json'}
- user, pw = mockmodel.fake_user.items()[0]
- hdr = "Basic " + base64.b64encode("%s:%s" % (user, pw))
- headers['AUTHORIZATION'] = hdr
- return headers
diff --git a/plugins/kimchi/ui/Makefile.am b/plugins/kimchi/ui/Makefile.am
deleted file mode 100644
index 21fe703..0000000
--- a/plugins/kimchi/ui/Makefile.am
+++ /dev/null
@@ -1,20 +0,0 @@
-#
-# Kimchi
-#
-# Copyright IBM, Corp. 2013
-#
-# 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.
-
-SUBDIRS = config css images js pages spice-html5
-
-uidir = $(datadir)/wok/plugins/kimchi/ui
diff --git a/plugins/kimchi/ui/config/Makefile.am b/plugins/kimchi/ui/config/Makefile.am
deleted file mode 100644
index e3b3d19..0000000
--- a/plugins/kimchi/ui/config/Makefile.am
+++ /dev/null
@@ -1,22 +0,0 @@
-#
-# Kimchi
-#
-# Copyright IBM, Corp. 2013
-#
-# 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.
-
-xmldir = $(datadir)/wok/plugins/kimchi/ui/config
-
-dist_xml_DATA = \
- tab-ext.xml \
- $(NULL)
diff --git a/plugins/kimchi/ui/config/tab-ext.xml b/plugins/kimchi/ui/config/tab-ext.xml
deleted file mode 100644
index ee88c88..0000000
--- a/plugins/kimchi/ui/config/tab-ext.xml
+++ /dev/null
@@ -1,38 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<tabs-ext>
- <tab>
- <access role="admin" mode="admin"/>
- <access role="user" mode="none"/>
-
- <title>Host</title>
- <path>plugins/kimchi/host.html</path>
- </tab>
- <tab>
- <access role="admin" mode="admin"/>
- <access role="user" mode="byInstance"/>
-
- <title>Guests</title>
- <path>plugins/kimchi/guests.html</path>
- </tab>
- <tab>
- <access role="admin" mode="admin"/>
- <access role="user" mode="none"/>
-
- <title>Templates</title>
- <path>plugins/kimchi/templates.html</path>
- </tab>
- <tab>
- <access role="admin" mode="admin"/>
- <access role="user" mode="read-only"/>
-
- <title>Storage</title>
- <path>plugins/kimchi/storage.html</path>
- </tab>
- <tab>
- <access role="admin" mode="admin"/>
- <access role="user" mode="read-only"/>
-
- <title>Network</title>
- <path>plugins/kimchi/network.html</path>
- </tab>
-</tabs-ext>
diff --git a/plugins/kimchi/ui/css/Makefile.am b/plugins/kimchi/ui/css/Makefile.am
deleted file mode 100644
index 5071d29..0000000
--- a/plugins/kimchi/ui/css/Makefile.am
+++ /dev/null
@@ -1,26 +0,0 @@
-#
-# Kimchi
-#
-# Copyright IBM, Corp. 2013
-#
-# 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.
-
-EXTRA_DIST = theme-default
-
-cssdir = $(datadir)/wok/plugins/kimchi/ui/css
-dist_css_DATA = theme-default.min.css
-
-theme-default.min.css: theme-default/*.css
- cat $^ > $@
-
-CLEANFILES = theme-default.min.css
diff --git a/plugins/kimchi/ui/css/theme-default/guest-edit.css
b/plugins/kimchi/ui/css/theme-default/guest-edit.css
deleted file mode 100644
index b661159..0000000
--- a/plugins/kimchi/ui/css/theme-default/guest-edit.css
+++ /dev/null
@@ -1,424 +0,0 @@
-/*
- * Project Kimchi
- *
- * Copyright IBM, Corp. 2013-2015
- *
- * 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.
- */
-#guest-edit-window {
- font-size: 13px;
- height: 420px;
- width: 820px;
-}
-
-#guest-edit-window #action-button-container {
- padding-right: 0;
-}
-
-#guest-edit-window #guest-edit-button-cancel {
- margin-left: 10px;
-}
-
-#guest-edit-tabs {
- background: transparent;
- border: none;
- height: 100%;
- padding: 0;
-}
-
-#form-guest-edit-general {
- padding: 1em;
-}
-
-#form-guest-edit-general .edit-general-inline {
- display: inline-block;
-}
-
-#form-guest-edit-storage input[readonly] {
- background: none;
- border-color: transparent;
- text-overflow: ellipsis;
-}
-
-.guest-edit-fieldset {
- padding-right: 0;
-}
-
-.guest-edit-wrapper-label {
- height: 30px;
- line-height: 30px;
- margin-top: 10px;
- vertical-align: top;
- min-width: 100px;
- font-weight: lighter;
- font-family: 'Helvetica Neue', Helvetica, Arial;
-}
-
-#form-guest-edit-storage .guest-edit-wrapper-label {
- width: 60px;
-}
-
-.guest-edit-wrapper-controls {
- width: 470px;
- margin-top: 5px;��
-}
-
-#form-guest-edit-storage .guest-edit-wrapper-controls {
- width: 486px;
-}
-
-.guest-edit-wrapper-controls input[type="text"] {
- font-size: 16px;
- height: 30px;
- width: 450px;
- border: 1px solid #CCCCCC;
-}
-
-.guest-edit-wrapper-controls input[type="text"][disabled] {
- color: #bbb;
- background-color: #fafafa;
- cursor: not-allowed;
- border: 1px solid #CCCCCC;
-}
-
-.guest-edit-cdrom-row-container {
- max-height: 180px;
- overflow: auto;
-}
-
-.guest-edit-cdrom-row-container input[type="text"] {
- width: 400px;
-}
-
-#form-guest-edit-storage .header,
-.guest-edit-snapshot .header,
-.guest-edit-interface .header,
-#form-guest-edit-permission .ldap .header {
- margin-bottom: 8px;
- padding-bottom: 2px;
- font-weight: bold;
- border-bottom: 1px solid #999999;
- overflow: hidden;
-}
-
-#form-guest-edit-storage .body .item,
-.guest-edit-snapshot .body .item,
-.guest-edit-snapshot .task .item,
-.guest-edit-interface .body .item {
- margin: 5px 0;
-}
-
-#form-guest-edit-storage .cell,
-.guest-edit-interface .cell {
- display: inline-block;
- width: 200px;
-}
-
-.guest-edit-snapshot .cell {
- display: inline-block;
-}
-
-.guest-edit-snapshot .sel {
- width: 25px;
- vertical-align: top;
-}
-
-.guest-edit-snapshot .icon {
- background: url('../images/theme-default/kimchi-loading15x15.gif')
no-repeat;
- display: block;
- width: 16px;
- height: 16px;
- vertical-align: middle;
- margin-left: 2px;
-}
-
-.guest-edit-snapshot .name {
- width: 400px;
-}
-
-.guest-edit-snapshot .created {
- width: 270px;
-}
-
-#form-guest-edit-storage .cell.dev {
- width: 60px;
-}
-
-#form-guest-edit-storage .cell.path {
- width: 440px;
-}
-
-#form-guest-edit-storage .cell.dev input,
-#form-guest-edit-storage .cell.path input {
- box-sizing: border-box;
- width: 100%;
-}
-
-.guest-edit-interface .body select {
- width: 180px;
- padding: 0px;
-}
-
-#form-guest-edit-storage .action-area,
-.guest-edit-snapshot .action-area,
-.guest-edit-interface .action-area {
- float: right;
-}
-
-#form-guest-edit-storage .action-area {
- line-height: 24px;
-}
-
-#form-guest-edit-storage button,
-.guest-edit-snapshot button,
-.guest-edit-interface button {
- width: 20px;
- height: 20px;
-}
-
-#form-guest-edit-storage .body button:not(:last-child),
-.guest-edit-interface .body button:not(:last-child) {
- margin-right: 2px;
-}
-
-.guest-edit-snapshot .hide,
-.guest-edit-interface .hide {
- display: none!important;
-}
-
-.guest-edit-permission .pam {
- height: 220px;
- padding: 5px 10px!important;
-}
-
-.guest-edit-permission .hide {
- display: none;
-}
-
-.guest-edit-permission .pam .column {
- display: inline-block;
- vertical-align: top;
-}
-
-.guest-edit-permission .pam .title {
- margin-bottom: 3px;
-}
-
-.guest-edit-permission .pam input[type="text"] {
- margin-bottom: 3px;
- font-size: 12px;
- width: 97%;
-}
-
-.guest-edit-permission .pam .body {
- border: 1px solid #999999;
- font-size: 12px;
- padding: 1px;
- height: 192px;
- overflow: auto;
-}
-
-.guest-edit-permission .pam .body .head {
- margin-bottom: 3px;
- font-weight: bold;
- background: linear-gradient(to bottom, #E5E5E5 0%, #C4C4C4 100%) repeat scroll 0 0
transparent;
-}
-
-.guest-edit-permission .pam .body .item {
- padding: 2px 3px;
- margin-bottom: 1px;
- cursor: pointer;
-}
-
-.guest-edit-permission .pam .body .item:hover {
- background-color: #AAAAAA;
-}
-
-.guest-edit-permission .pam .body .item-picked {
- background-color: #BBBBBB;
-}
-
-.guest-edit-permission .pam .body .item .icon {
- display: inline-block;
- height: 15px;
- width: 15px;
- vertical-align: bottom;
-}
-
-.guest-edit-permission .pam .body .item .user-icon {
- background: url('../images/theme-default/user.png') no-repeat scroll;
- background-size: 15px 15px;
-}
-
-.guest-edit-permission .pam .body .item .group-icon {
- background: url('../images/theme-default/group.png') no-repeat scroll;
- background-size: 15px 15px;
-}
-
-.guest-edit-permission .pam .body .column-user {
- width: 48%;
-}
-.guest-edit-permission .pam .body .column-group {
- width: 50%;
-}
-
-.guest-edit-permission .pam .control {
- width: 5%;
-}
-
-.guest-edit-permission .pam .control button {
- width: 26px;
- margin-left: 7px;
-}
-
-.guest-edit-permission .pam .control button:first-child {
- margin-top: 110px;
- margin-bottom: 2px;
-}
-
-.guest-edit-permission .pam .control .ui-button-text-only .ui-button-text {
- padding: 2px 8px;
-}
-
-.guest-edit-permission .pam .avail {
- width: 46%;
-}
-
-.guest-edit-permission .pam .selected {
- width: 46%;
- float: right;
-}
-
-#form-guest-edit-permission .ldap .body .item {
- margin: 8px 0;
-}
-
-#form-guest-edit-permission .ldap .cell {
- width: 250px;
-}
-
-#form-guest-edit-permission .ldap .action-area {
- float: right;
- line-height: 24px;
-}
-
-#form-guest-edit-permission .ldap button {
- width: 20px;
- height: 20px;
-}
-
-#form-guest-edit-permission input[type="text"] {
- width: 300px;
-}
-
-#form-guest-edit-permission .ldap .header button {
- margin-bottom: 1px;
-}
-
-#form-guest-edit-permission .ldap .checked {
- border-color: red;
- border-style: solid;
- border-width: 1px;
-}
-
-#form-guest-edit-permission .ldap .checked.hide {
- display: none;
-}
-
-.guest-edit-pci {
- height: 79%;
- overflow: auto;
- font-size: 12px;
-}
-
-.guest-edit-pci .guest-scroll-indent {
- width: 783px;
-}
-
-.guest-edit-pci .filter {
- height: 35px;
- margin-right: 5px;
- overflow: hidden;
-}
-
-.guest-edit-pci .group {
- float: right;
-}
-
-.guest-edit-pci .filter .control {
- border: 1px solid #AAAAAA;
- font-size: 12px;
- background-color: white;
-}
-
-.guest-edit-pci .filter select {
- border-right: 0px!important;
- border-radius: 7px 0px 0px 7px;
- padding: 2px 2px 2px 7px;
- width: 100px;
- height: 24px;
-}
-
-.guest-edit-pci .filter select option {
- padding-left: 7px;
-}
-
-.guest-edit-pci .filter input {
- border-radius: 0px 7px 7px 0px;
- padding: 3px 3px 3px 10px;
- width: 200px;
- height: 16px;
- font-style: italic;
-}
-
-.guest-edit-pci .header {
- margin-bottom: 8px;
- padding-bottom: 2px;
- font-weight: bold;
- border-bottom: 1px solid #999999;
-}
-
-.guest-edit-pci .item {
- margin-bottom: 4px;
- overflow: hidden;
-}
-
-.guest-edit-pci .cell {
- display: inline-block;
- vertical-align: middle;
- margin-right: 10px;
- overflow: hidden;
- text-overflow: ellipsis;
- white-space: nowrap;
-}
-
-.guest-edit-pci .item button {
- width: 20px;
- height: 20px;
- float: right;
-}
-
-.guest-edit-pci .name {
- width: 18%;
- max-width: 18%;
-}
-
-.guest-edit-pci .product {
- width: 45%;
- max-width: 45%;
-}
-
-.guest-edit-pci .vendor {
- width: 25%;
- max-width: 25%;
-}
diff --git a/plugins/kimchi/ui/css/theme-default/guest-storage-add.css
b/plugins/kimchi/ui/css/theme-default/guest-storage-add.css
deleted file mode 100644
index 9cc41e8..0000000
--- a/plugins/kimchi/ui/css/theme-default/guest-storage-add.css
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
- * Project Kimchi
- *
- * Copyright IBM, Corp. 2014
- *
- * 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.
- */
-#guest-storage-add-window {
- font-size: 13px;
- height: 600px;
- width: 700px;
-}
-
-.guest-storage-add-fieldset {
- padding: 1em;
-}
-
-#guest-storage-add-window .btn {
- width: 587px;
-}
-
-#form-guest-storage-add .form-section .field {
- overflow: visible;
-}
-
-#guest-storage-add-window input[type="text"] {
- font-size: 16px;
- height: 38px;
- background: #fff;
- -webkit-border-radius: 5px;
- border-radius: 5px;
- box-shadow: 2px 2px 2px #eee inset;
- border-top: 1px solid #bbb;
- border-left: 1px solid #bbb;
- padding-left: 10px;
- width: 600px;
-}
-
-#guest-storage-add-window input[type="text"][disabled] {
- color: #bbb;
- background-color: #fafafa;
- cursor: not-allowed;
-}
-
-.guest-storage-add-wrapper-label, .guest-storage-add-wrapper-controls {
- display: inline-block;
-}
-
-.guest-storage-add-wrapper-label {
- height: 38px;
- line-height: 38px;
- margin-top: 5px;
- vertical-align: top;
- width: 80px;
-}
-
-.guest-storage-add-wrapper-controls {
- width: 470px;
-}
-
-#vm-storage-button-add[disabled] {
- background: #c0c0c0;
- color: #ddd;
- padding-left: 26px;
-}
-
-#vm-storage-button-add.loading[disabled] {
- background: url("../../images/theme-default/loading.gif") 7px center
no-repeat #c0c0c0;
- color: #ddd;
- padding-left: 26px;
-}
diff --git a/plugins/kimchi/ui/css/theme-default/host.css
b/plugins/kimchi/ui/css/theme-default/host.css
deleted file mode 100644
index a0cccb1..0000000
--- a/plugins/kimchi/ui/css/theme-default/host.css
+++ /dev/null
@@ -1,287 +0,0 @@
-/*
- * Project Kimchi
- *
- * Copyright IBM, Corp. 2013-2014
- *
- * 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.
- */
-.host-panel {
- font-size: 12px;
- margin-bottom: 100px;
-}
-
-.host-panel .logo-container, .host-panel .info-container,
-.host-panel .section-label, .host-panel .section-value {
- display: inline-block;
- vertical-align: top;
-}
-
-.host-panel .section-label {
- display: inline-block;
- margin-right: 1em;
- vertical-align: top;
-}
-
-.host-panel .logo {
- background: url("plugins/kimchi/images/icon-vm.png") no-repeat left top;
- height: 128px;
- width: 128px;
-}
-
-.host-panel .hostname {
- text-decoration: underline;
-}
-
-.host-panel .action-panel {
- margin-top: 2em;
- padding-left: 10px;
-}
-
-.host-panel .button-icon {
- background: url("../images/theme-default/host-icon-sprite.png") no-repeat
- left top;
- display: inline-block;
- height: 12px;
- width: 12px;
-}
-
-.host-panel .action-icon-stop {
- background-position: -14px 0;
-}
-
-.host-panel .action-icon-restart {
- background-position: -28px 0;
-}
-
-.host-panel .action-icon-download {
- background-position: -42px 0;
-}
-
-.host-panel .action-icon-connect {
- background-position: -56px 0;
-}
-
-.host-panel .action-icon-add {
- background-position: -70px 0;
-}
-
-.host-panel .action-icon-edit {
- background-position: -84px 0;
-}
-
-.host-panel .action-icon-remove {
- background-position: -98px 0;
-}
-
-.host-panel button:disabled .action-icon-start {
- background-position: 0 -14px;
-}
-
-.host-panel button:disabled .action-icon-stop {
- background-position: -14px -14px;
-}
-
-.host-panel button:disabled .action-icon-restart {
- background-position: -28px -14px;
-}
-
-.host-panel button:disabled .action-icon-download {
- background-position: -42px -14px;
-}
-
-.host-panel button:disabled .action-icon-connect {
- background-position: -56px -14px;
-}
-
-.host-panel button:disabled .action-icon-add {
- background-position: -70px -14px;
-}
-
-.host-panel button:disabled .action-icon-edit {
- background-position: -84px -14px;
-}
-
-.host-panel button:disabled .action-icon-remove {
- background-position: -98px -14px;
-}
-
-.host-panel .info-container {
- padding-top: 16px;
- width: 890px;
-}
-
-.host-panel .section-header {
- background: #EEE;
- border-radius: 5px;
- cursor: pointer;
- line-height: 2em;
- margin: 1em 0 1em;
- padding-left: 6px;
-}
-
-.host-panel .section-header:hover {
- background: #06f;
- color: white;
-}
-
-.host-panel .section-content {
- padding-left: 1em;
-}
-
-.host-panel .section-header .arrow {
- border-color: transparent;
- border-style: solid;
- display: inline-block;
- margin-right: 6px;
- width: 0;
-}
-
-.host-panel .section-header[aria-expanded="true"] .arrow {
- border-top-color: black;
- border-width: 8px 4px 0;
- border-bottom: none;
-}
-
-.host-panel .section-header[aria-expanded="true"]:hover .arrow {
- border-top-color: white;
-}
-
-.host-panel .section-header[aria-expanded="false"] .arrow {
- border-left-color: black;
- border-right: none;
- border-width: 4px 0 4px 8px;
-}
-
-.host-panel .section-header[aria-expanded="false"]:hover .arrow {
- border-left-color: white;
-}
-
-.host-panel .section-row {
- line-height: 1.6em;
- margin-bottom: 1em;
-}
-
-.host-panel .section-label {
- width: 100px;
-}
-
-#frequency-textbox {
- width: 20px;
-}
-
-#container-chart-cpu,
-#container-chart-memory,
-#container-chart-disk-io,
-#container-chart-network-io {
- border: 1px solid white;
- box-shadow: 2px 2px 2px gray, 2px -2px 2px gray, -2px -2px 2px gray, -2px
- 2px 2px gray;
- height: 100px;
- width: 500px;
-}
-
-#container-chart-disk-io .disk-write,
-#container-chart-network-io .network-sent {
- stroke: #f80;
-}
-
-/* Debug Report */
-.cell-text-wrapper {
- margin-left: 10px;
-}
-
-.host-panel #available-reports-grid {
- border-color: #ddd;
- height: 400px;
- width: 850px;
-}
-
-.host-panel select#available-reports-list {
- width: 300px;
-}
-
-.host-panel select#available-reports-list option {
- margin: .2em 1em;
-}
-
-.debug-report-name,
-.debug-report-time {
- width: 424px;
-}
-
-#id-debug-img {
- background: url(../images/theme-default/kimchi-loading15x15.gif) 12px
- center no-repeat;
- padding-left: 23px;
-}
-
-/* End of Debug Report */
-
-/* Software Updates */
-.host-panel #software-updates-grid {
- border-color: #ddd;
- height: 300px;
- width: 850px;
-}
-
-.software-update-name,
-.software-update-repos {
- width: 224px;
-}
-
-.software-update-version,
-.software-update-arch {
- width: 200px;
-}
-
-.host-panel #software-updates-progress-textarea {
- border: 1px solid #ddd;
- box-sizing: border-box;
- height: 100px;
- padding: .2em .5em;
- resize: vertical;
- width: 852px;
-}
-/* End of Software Updates */
-
-/* Repository */
-.host-panel #repositories-grid {
- border-color: #ddd;
- height: 200px;
- width: 850px;
-}
-
-.host-panel #repositories-grid .repository-id {
- width: 120px;
-}
-
-.host-panel #repositories-grid .repository-name {
- width: 640px;
-}
-
-.host-panel #repositories-grid .repository-enabled {
- width: 88px;
-}
-
-.host-panel #repositories-grid .repository-baseurl.deb {
- width: 400px;
-}
-
-.host-panel #repositories-grid .repository-enabled.deb {
- width: 100px;
-}
-
-.host-panel #repositories-grid .repository-gpgcheck.deb {
- width: 150px;
-}
-/* End of Repository */
diff --git a/plugins/kimchi/ui/css/theme-default/icon.css
b/plugins/kimchi/ui/css/theme-default/icon.css
deleted file mode 100644
index f82d45d..0000000
--- a/plugins/kimchi/ui/css/theme-default/icon.css
+++ /dev/null
@@ -1,106 +0,0 @@
-/*
- * Project Kimchi
- *
- * Copyright IBM, Corp. 2013-2015
- *
- * 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.
- */
-
- /* Generated at
http://colorzilla.com/gradient-editor/ */
-
-.btn.loading {
- box-shadow: none;
- cursor: default;
-}
-
-.btn.loading .icon {
- background: url(../images/theme-default/icon-load.png) center
- center no-repeat;
-}
-
-.btn.pause-gray .icon {
- background: url(../images/theme-default/ac22_pause_grey.png) center
- center no-repeat;
-}
-
-.btn.resume-gray .icon {
- background: url(../images/theme-default/ac24_resume_grey.png) center
- center no-repeat;
-}
-
-.icon.reset {
- background: url(../images/theme-default/icon-reset.png) center
- center no-repeat;
-}
-
-.icon.power-up {
- background: url(../images/theme-default/icon-power-up.png) center
- center no-repeat;
-}
-
-.icon.power-down {
- background: url(../images/theme-default/icon-power-down.png) center
- center no-repeat;
-}
-
-.icon.pause {
- background: url(../images/theme-default/ac22_pause.png) center
- center no-repeat;
-}
-
-.icon.resume {
- background: url(../images/theme-default/ac24_resume.png) center
- center no-repeat;
-}
-
-.icon.search {
- background: url(../images/theme-default/icon-search.png) no-repeat
- center center;
-}
-
-.icon.sort {
- background: url(../images/theme-default/icon-sort.png) no-repeat
- center center;
-}
-
-.icon.design {
- background: url(../images/theme-default/icon-design.png) no-repeat
- center center;
-}
-
-.icon.list {
- background: url(../images/theme-default/icon-list.png) no-repeat
- center center;
-}
-
-.icon.detail {
- background: url(../images/theme-default/icon-detail.png) no-repeat
- center center;
-}
-
-.icon.add {
- line-height: 32px;
- text-align: center;
- text-shadow: -1px -1px 1px #aaa, 1px 1px 1px #eee;
- font-size: 38px;
- font-weight: bold;
- color: #7cae0a;
-}
-
-.icon.tree {
- width: 42px;
- background: url(../images/theme-default/icon-tree.png) no-repeat
- center center;
-}
-
-
diff --git a/plugins/kimchi/ui/css/theme-default/list.css
b/plugins/kimchi/ui/css/theme-default/list.css
deleted file mode 100644
index 8c78623..0000000
--- a/plugins/kimchi/ui/css/theme-default/list.css
+++ /dev/null
@@ -1,326 +0,0 @@
-/*
- * Project Kimchi
- *
- * Copyright IBM, Corp. 2013-2015
- *
- * 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.
- */
-.list-vm {
- margin: 10px;
-}
-
-/* Generated at
http://colorzilla.com/gradient-editor/ */
-.list-vm>li {
- margin-bottom: 10px;
- background: #ffffff;
- background: -moz-linear-gradient(top, #ffffff 0%, #e5e5e5 100%);
- background: -webkit-gradient(linear, left top, left bottom,
- color-stop(0%, #ffffff), color-stop(100%, #e5e5e5));
- background: -webkit-linear-gradient(top, #ffffff 0%, #e5e5e5 100%);
- background: -o-linear-gradient(top, #ffffff 0%, #e5e5e5 100%);
- background: -ms-linear-gradient(top, #ffffff 0%, #e5e5e5 100%);
- background: linear-gradient(to bottom, #ffffff 0%, #e5e5e5 100%);
- filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffff',
- endColorstr='#e5e5e5', GradientType=0);
- border: 1px solid #ccc;
- color: #333;
- -webkit-border-radius: 8px;
- -moz-border-radius: 8px;
- border-radius: 8px;
-}
-
-.list-vm li>* {
- height: 130px;
- display: table-cell;
- vertical-align: top;
- position: relative;
- border-left: 1px solid #ccc;
- border-right: 1px solid #fff;
-}
-
-.list-vm li>*:FIRST-CHILD {
- border-left: none;
-}
-
-.list-vm li>*:LAST-CHILD {
- border-right: none;
-}
-
-.list-vm li>.guest-tile{
- text-align: center;
- vertical-align: middle;
-}
-
-.list-vm .handle {
- display: block;
- width: 50px;
- height: 130px;
- box-sizing: border-box;
- box-shadow: inset 4px 4px 4px #0289e2, inset -4px -4px 4px #04385d;
- background: #0b6bad url(../images/theme-default/arrow_out.png) center
- center no-repeat;
- border-top-right: 1px solid #CCC;
- -webkit-border-top-right-radius: 8px;
- -moz-border-top-right-radius: 8px;
- border-top-right-radius: 8px;
- border-bottom-right: 1px solid #CCC;
- -webkit-border-bottom-right-radius: 8px;
- -moz-border-bottom-right-radius: 8px;
- border-bottom-right-radius: 8px;
-}
-
-.list-vm .subtitle {
- color: #666;
- font-size: 13px;
- text-align: center;
- line-height: 10px;
- font-weight: bold;
-}
-
-.list-vm .tile .imgload {
- display: none;
-}
-
-.list-vm .tile.shutoff .imgactive {
- max-height: 110px;
- max-width: 170px;
- height: auto;
- width: auto;
- display:inline;
- border: none;
- position: relative;
-}
-
-.list-vm .tile.paused .imgactive {
- max-height: 110px;
- max-width: 170px;
- height: auto;
- width: auto;
- display:inline;
- border: none;
- position: relative;
-}
-
-.list-vm .tile.running .imgactive{
- max-height: 110px;
- max-width: 170px;
- height: auto;
- width: auto;
- display:inline;
- border: none;
- cursor: crosshair;
- cursor: -moz-zoom-in;
- cursor: -webkit-zoom-in;
-}
-
-.list-vm .tile .overlay {
- max-height: 110px;
- max-width: 170px;
- height: auto;
- width: auto;
- position:absolute;
- bottom:0;
- right:0;
- display:none;
-}
-
-.guest-type {
- width: 257px;
-}
-
-.guest-cpu {
- width: 91px;
-}
-
-.guest-network {
- width: 91px;
-}
-
-.guest-storage {
- width: 91px;
-}
-
-.guest-tile {
- width: 190px;
-}
-
-.guest-users {
- width: 93px;
-}
-
-.guest-actions {
- width: 125px;
- min-width: 125px;
-}
-
-.guest-handle {
- width: 50px;
-}
-
-.guest-general {
- padding: 10px;
- border-bottom: 1px solid #ccc;
- width: 237px;
-}
-
-.guest-ip {
- padding: 0 10px;
- border-top: 1px solid #fff;
-}
-
-.guest-general .title {
- color: #666;
- font-size: 16px;
- font-weight: normal;
- height: 25px;
- line-height: 25px;
- text-shadow: -1px -1px 1px #ccc, 1px 1px 1px #fff;
- max-width: 237px;
- overflow: hidden;
- text-overflow: ellipsis;
- white-space: nowrap;
-}
-
-.guest-general .text {
- font-weight: bold;
- color: #999;
- font-size: 11px;
- text-shadow: -1px -1px 1px #ccc, 1px 1px 1px #fff;
-}
-
-.guest-users .top {
- border-bottom: 1px solid #ccc;
- padding: 3px 10px;
-}
-
-.guest-users .bottom {
- border-top: 1px solid #fff;
- padding: 3px 10px;
-}
-
-.guest-users .users {
- height: 45px;
- line-height: 45px;
- background: url(../images/theme-default/icon-user.png) left
- center no-repeat;
- padding-left: 50px;
- font-size: 36px;
- font-weight: bold;
-}
-
-.guest-users .snapshots {
- height: 40px;
- line-height: 40px;
- background: url(../images/theme-default/icon-camera.png) left
- center no-repeat;
- padding-left: 50px;
- font-size: 36px;
- font-weight: bold;
-}
-
-.guest-users .mini-text {
- font-size: 11px;
- font-weight: normal;
- text-shadow: -1px -1px 1px #ccc, 1px 1px 1px #fff;
-}
-
-.guest-actions .top {
- padding: 7px 10px;
- width: 200px;
-}
-
-.guest-actions .top button {
- display: inline-block;
- width: 42px;
- height: 42px;
-}
-
-@-moz-document url-prefix() {
- .guest-actions .top button span {
- margin-left: -3px;
- margin-top: -1px;
- }
-}
-
-.guest-actions .bottom {
- padding: 0 10px;
-}
-
-.list-vm .tile {
- max-width: 170px;
- max-height: 110px;
- width: auto;
- height: auto;
- margin: 10px;
-}
-
-.list-vm .tile:not(.shutoff) && .tile:not(.paused) img {
- box-shadow: -1px -1px 2px rgb(0, 0, 0, .25), 3px 3px 3px #fff;
-}
-
-.list-vm .shutoff {
- position: relative;
- box-shadow: none !important;
-}
-
-.list-vm .shutoff img {
- opacity: 0.4;
-}
-
-.list-vm .paused {
- position: relative;
- box-shadow: none !important;
-}
-
-.list-vm .paused img {
- opacity: 0.6;
-}
-
-.list-title {
- color: #666;
- font-weight: bold;
- font-size: 12px;
- overflow: hidden;
- margin: 10px;
-}
-
-.list-title li {
- display: table-cell;
- padding: 0 1px;
-}
-
-.list-no-result {
- font-size: 16px;
- height: 48px;
- line-height: 48px;
- text-shadow: -1px -1px 1px #ccc, 1px 1px 1px #fff;
- padding-left: 10px;
-}
-
-.guest-pending {
- margin: 10px;
-}
-
-.guest-pending .icon {
- background: url('../images/theme-default/kimchi-loading15x15.gif')
no-repeat;
- display: inline-block;
- width: 20px;
- height: 20px;
- vertical-align: middle;
-}
-
-.guest-pending .text {
- color: #666666;
- margin-left: 5px;
- text-shadow: -1px -1px 1px #CCCCCC, 1px 1px 1px #FFFFFF;
-}
diff --git a/plugins/kimchi/ui/css/theme-default/network.css
b/plugins/kimchi/ui/css/theme-default/network.css
deleted file mode 100644
index fc8a24f..0000000
--- a/plugins/kimchi/ui/css/theme-default/network.css
+++ /dev/null
@@ -1,267 +0,0 @@
-/*
- * Project Kimchi
- *
- * Copyright IBM, Corp. 2013-2015
- *
- * 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.
- */
-
-.network {
- margin: 5px;
-}
-
-.network .grid-control {
- height: 40px;
- padding: 5px 0;
-}
-
-.network .grid-control .filter {
- width: 300px;
- padding: 5px;
- float: right;
-}
-
-.network .list .column-name {
- width: 20%;
- max-width: 20%;
- text-overflow: ellipsis;
-}
-
-.network .list .column-state {
- width: 10%;
-}
-
-.network .list .column-type {
- width: 15%;
-}
-
-.network .list .column-interface {
- width: 15%;
-}
-
-.network .list .column-space {
- width: 25%;
-}
-
-.network .list .column-action {
- display: inline-block;
- float: right;
- height: 40px;
-}
-
-.network .list .hide-action-item {
- display: none;
-}
-
-.network .list .menu-container {
- display: none;
- top: 58px;
-}
-
-.network .list .action-button {
- float: right;
- margin-top: 2px;
- margin-left: 5px;
-}
-
-.network .list .action-button-icon {
- background: url("../images/theme-default/arrow-down-black.png") no-repeat
- scroll center center transparent;
-}
-
-.network .list .ui-state-disabled {
- margin: 0px;
-}
-
-.network .list .network-state {
- display: inline-block;
- height: 16px;
- width: 16px;
- border-radius: 8px;
- margin-left: 10px;
-}
-
-.network .list .nw-loading {
- background: #c0c0c0 url(../images/theme-default/loading.gif)
- center no-repeat;
-}
-
-.network .list .up {
- background: linear-gradient(to bottom, #BFD255 0%, #8EB92A 50%,
- #72AA00 51%, #9ECB2D 100%) repeat scroll 0 0 transparent;
-}
-
-.network .list .down {
- background: linear-gradient(to bottom, #AFAFAF 0%, #AFAFAF 50%,
- #AFAFAF 51%, #AFAFAF 100%) repeat scroll 0 0 transparent;
-}
-
-.network-config {
- font-family: Arial;
- font-size: 12px;
- margin-bottom: 40px;
- display: none;
-}
-
-.network-config .section-container {
- margin-top: 20px;
-}
-
-.network-config .section-container:first-child {
- margin-top: 10px;
-}
-
-.network-config .section-container:last-child {
- height: 200px;
-}
-
-.network-config .section-container .bridged-inline {
- display: inline-block;
- vertical-align: top;
- max-width: 520px;
-}
-
-.network-config .section-header {
- font-size: 14px;
- font-weight: lighter;
-}
-
-.network-config .section-content {
- margin-top: 10px;
-}
-
-.network-config input[type="text"] {
- border: 1px solid #CCCCCC;
- font-size: 16px;
- height: 30px;
- width: 300px;
- line-height: 30px;
- padding: 0 5px;
-}
-
-.network-config input.invalid-field[type="text"] {
- border-color: #FF4444;
-}
-
-.network-config input.invalid-field[type="text"][disabled] {
- border-color: #666666;
-}
-
-.network-config input[type="radio"] {
- margin-right: 5px;
- margin-top: 0px;
-}
-
-.network-config select {
- color: #666666;
- border: solid 1px;
- background-color: white;
- padding: 3px 4px 3px 0;
-}
-
-.network-config .input-container {
- height: 20px;
-}
-
-.network-config label {
- vertical-align: top;
-}
-
-.network-type-wrapper-controls input[type="text"] {
- height: 38px;
- line-height: 38px;
- background: #fff;
- -webkit-border-radius: 5px;
- border-radius: 5px;
- box-shadow: 2px 2px 2px #eee inset;
- border-top: 1px solid #bbb;
- border-left: 1px solid #bbb;
- padding: 0 10px;
- margin-top: 5px;
- width: 50px;
-}
-
-.network-type-wrapper-controls > .dropdown {
- margin: 5px 0 0 1px;
- width: 180px;
-}
-
-.network-type-wrapper-controls input[type="text"][disabled] {
- color: #bbb;
- background-color: #fafafa;
- cursor: not-allowed;
-}
-
-.network-type-wrapper-controls span[type="text"] {
- padding: 0 10px;
-}
-
-.bridge-option-column {
- display: inline-block;
- vertical-align: middle;
-}
-
-.bridge-option-column label {
- margin-left: 42px;
-}
-
-.network-type-wrapper-controls {
- width: 80px;
- display: inline-block;
- vertical-align: top;
- padding: 5px 5px 5px 22px;
-}
-
-#enableVlan {
- margin-left: 42px;
- vertical-align: middle;
-}
-
-#labelEnableVlan {
- vertical-align: middle;
-}
-
-#labelNetworkVlanID {
- margin-left: 42px;
- vertical-align: middle;
- display: none;
-}
-
-#networkVlanID {
- width: 80px;
- vertical-align: middle;
- display: none;
-}
-
-.network-config .input-hint-icon {
- margin: -1px 1px 0 0;
- display: inline-block;
-}
-
-.network-config .input-hint {
- margin-top: 3px;
-}
-
-.network-config .input-hint-text {
- color: #999999;
- font-weight: lighter;
- font-size: 12px;
-}
-
-.ui-state-default a {
- color: #212121;
-}
-
-#networkConfig {
- padding-left: 30px;
-}
diff --git a/plugins/kimchi/ui/css/theme-default/report-add.css
b/plugins/kimchi/ui/css/theme-default/report-add.css
deleted file mode 100644
index 8020182..0000000
--- a/plugins/kimchi/ui/css/theme-default/report-add.css
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Project Kimchi
- *
- * Copyright IBM, Corp. 2013-2015
- *
- * 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.
- */
-#report-add-window {
- height: 300px;
- width: 400px;
-}
-
-#report-add-window .field {
- font-size: 12px;
-}
-
-#report-name-textbox {
- margin: 0;
- width: 100%;
-}
-
-.info-add-debug-report {
- font-size: 12px;
- color: #999999;
- font-weight: lighter;
- font-family: 'Helvetica Neue', Helvetica, Arial;
-}
\ No newline at end of file
diff --git a/plugins/kimchi/ui/css/theme-default/report-rename.css
b/plugins/kimchi/ui/css/theme-default/report-rename.css
deleted file mode 100644
index 2fb2698..0000000
--- a/plugins/kimchi/ui/css/theme-default/report-rename.css
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Project Kimchi
- *
- * Copyright IBM, Corp. 2014-2015
- *
- * 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.
- */
-#report-rename-window {
- height: 300px;
- width: 400px;
-}
-
-#report-rename-window .field {
- font-size: 12px;
-}
-
-#report-name-textbox {
- -moz-box-sizing: border-box;
- box-sizing: border-box;
- margin: 0;
- width: 100%;
-}
-
-.info-debug-report-rename {
- font-size: 12px;
- color: #999999;
- font-weight: lighter;
- font-family: 'Helvetica Neue', Helvetica, Arial;
-}
diff --git a/plugins/kimchi/ui/css/theme-default/repository-add.css
b/plugins/kimchi/ui/css/theme-default/repository-add.css
deleted file mode 100644
index 4344569..0000000
--- a/plugins/kimchi/ui/css/theme-default/repository-add.css
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * Project Kimchi
- *
- * Copyright IBM, Corp. 2014-2015
- *
- * 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.
- */
-#repository-add-window {
- height: 500px;
- width: 1000px;
-}
-
-#repository-add-window span.required {
- color: red;
- padding-left: 5px;
- vertical-align: top;
-}
-
-#repository-add-window .textbox-wrapper input[type="text"] {
- box-sizing: border-box;
- width: 100%;
-}
-
-#repository-add-window .textbox-wrapper label {
- vertical-align: middle;
-}
-
-#isMirrorLabel {
- font-size: 14px;
- font-weight: lighter;
- font-family: 'Helvetica Neue', Helvetica, Arial;
-}
\ No newline at end of file
diff --git a/plugins/kimchi/ui/css/theme-default/repository-edit.css
b/plugins/kimchi/ui/css/theme-default/repository-edit.css
deleted file mode 100644
index 383a7fe..0000000
--- a/plugins/kimchi/ui/css/theme-default/repository-edit.css
+++ /dev/null
@@ -1,88 +0,0 @@
-/*
- * Project Kimchi
- *
- * Copyright IBM, Corp. 2014-2015
- *
- * 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.
- */
-.yum div#repository-edit-window {
- height: 680px;
- width: 1000px;
-}
-
-.deb div#repository-edit-window {
- height: 480px;
- width: 1000px;
-}
-
-
-.repository-edit-fieldset {
- float: left;
- padding: 0 30px;
- width: 95%;
-}
-
-.repository-edit-wrapper-label, .repository-edit-wrapper-controls {
- display: inline-block;
- height: 30px;
- line-height: 30px;
- font-size: 14px;
- vertical-align: top;
-}
-
-.repository-edit-wrapper-label {
- margin-top: 10px;
- width: 150px;
-}
-
-.repository-edit-wrapper-controls label {
- vertical-align: middle;
-}
-
-.repository-edit-wrapper-controls {
- width: 100%;
-}
-
-.repository-edit-wrapper-controls input[type="text"] {
- font-size: 16px;
- height: 30px;
- line-height: 30px;
- padding: 0 10px;
- width: 100%;
- -moz-box-sizing: border-box;
- box-sizing: border-box;
- border: 1px solid #CCCCCC;
-}
-
-
-.repository-edit-wrapper-controls input[type="text"][readonly] {
- color: #bbb;
- background-color: #fafafa;
-}
-
-
-.repository-edit-wrapper-controls input[type="text"][disabled] {
- color: #bbb;
- background-color: #fafafa;
- cursor: not-allowed;
-}
-
-
-.deb .yum{
- display: none;
-}
-
-
-.yum .deb{
- display: none;
-}
diff --git a/plugins/kimchi/ui/css/theme-default/storage.css
b/plugins/kimchi/ui/css/theme-default/storage.css
deleted file mode 100644
index 88447b5..0000000
--- a/plugins/kimchi/ui/css/theme-default/storage.css
+++ /dev/null
@@ -1,550 +0,0 @@
-/*
- * Project Kimchi
- *
- * Copyright IBM, Corp. 2013-2015
- *
- * 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.
- */
-/* STORAGE */
-.storage {
- margin: 5px;
-}
-
-
-.storage .grid-control {
- height: 40px;
- padding: 5px 0;
-}
-
-.storage .grid-control .filter {
- width: 300px;
- padding: 5px;
- float: right;
-}
-
-.storage-allocate-padding-user {
- padding-right: 108px;
-}
-
-.usage {
- float: right;
- margin-right: 30px;
-}
-
-.list-storage .storage-li>.guest-tile {
- text-align: center;
- vertical-align: middle;
-}
-
-.list-storage .subtitle {
- color: #666;
- font-size: 13px;
- text-align: center;
- line-height: 10px;
- font-weight: bold;
-}
-
-.list-storage .tile .imgload {
- display: none;
- max-height: 110px;
- max-width: 170px;
- height: auto;
- width: auto;
-}
-
-.list-storage .tile .imgactive {
- max-height: 110px;
- max-width: 170px;
- height: auto;
- width: auto;
-}
-
-.storage-volum {
- height: 40px;
- width: 186px;
- display: table-cell;
- vertical-align: top;
- position: relative;
- border-left: 1px solid #ccc;
- border-right: 1px solid #fff;
-}
-
-.storage-name {
- width: 15%;
-}
-
-.storage-state {
- width: 10%;
-}
-
-.storage-type {
- width: 10%;
-}
-
-.storage-capacity {
- width: 10%;
-}
-
-.storage-allocate {
- width: 10%;
-}
-
-.storage-location {
- width: 30%;
-}
-
-.storage-button {
- width: 9%;
-}
-
-.handle {
- width: 2%;
-}
-
-.status-dot {
- background: #72AA00;
- background: linear-gradient(to bottom, #BFD255 0%, #8EB92A 50%,
- #72AA00 51%, #9ECB2D 100%) repeat scroll 0 0 transparent;
- border: 1px solid #72AA00;
- border-radius: 13px;
- box-shadow: 3px 3px 3px #FFFFFF, -3px -3px 3px #DDDDDD;
- height: 13px;
- width: 13px;
- margin-left: 10px;
-}
-
-.toolable {
- position: relative;
-}
-
-.toolable .tooltip {
- display: none;
- border: 2px solid #0B6BAD;
- background: #fff;
- padding: 6px;
- position: absolute;
- color: #666666;
- font-weight: bold;
- font-size: 11px;
- -webkit-border-radius: 5px;
- -moz-border-radius: 5px;
- border-radius: 5px;
- z-index: 100;
- top: -300%;
- left: -140%;
- white-space: nowrap;
-}
-
-.toolable:hover .tooltip {
- display: block;
-}
-
-.toolable .tooltip:after {
- -moz-border-bottom-colors: none;
- -moz-border-left-colors: none;
- -moz-border-right-colors: none;
- -moz-border-top-colors: none;
- border-color: #fff transparent transparent;
- border-image: none;
- border-style: solid;
- border-width: 7px;
- content: "";
- display: block;
- left: 15px;
- position: absolute;
- bottom: -14px;
-}
-
-.toolable .tooltip:before {
- -moz-border-bottom-colors: none;
- -moz-border-left-colors: none;
- -moz-border-right-colors: none;
- -moz-border-top-colors: none;
- border-color: #0B6BAD transparent transparent;
- border-image: none;
- border-style: solid;
- border-width: 8px;
- content: "";
- display: block;
- left: 14px;
- position: absolute;
- bottom: -18px;
-}
-
-.inactive {
- background: #E80501;
- background: linear-gradient(to bottom, #E88692 0%, #E84845 50%,
- #E80501 51%, #E84845 100%) repeat scroll 0 0 transparent;
- border: 1px solid #FF340C;
-}
-
-.storage-volumes {
- width: 90px;
-}
-
-.storage-actions {
- width: 125px;
-}
-
-.storage-action {
- width: 70px;
-}
-
-.detail-view-icon {
- background: url(../images/large_details_icon.png) no-repeat center
- center;
- height: 30px;
- width: 42px;
-}
-
-.volumes {
- background: #73716F;
- width: 1004px;
- display: none;
- margin-top: 10px;
- border: 1px solid rgb(204, 204, 204);
-}
-
-.volumeslist {
- padding: 7px;
- max-height: 272px;
- min-height: 136px;
- overflow: auto;
- color: #ffffff;
-}
-
-.volumes>.footer {
- height: 48px;
- z-index: 100;
- box-shadow: 0 -1px 1px rgba(0, 0, 0, 0.15);
-}
-
-.volume-title {
- float: left;
- padding: 4px;
- margin-bottom: 5px;
- width: 130px;
-}
-
-.pool-empty {
- text-align:center;
- line-height:136px;
-}
-.volume-title>.volume-name {
- font-size: 14px;
- font-weight: normal;
- padding-bottom: 5px;
- max-width: 120px;
- overflow: hidden;
- text-overflow: ellipsis;
- white-space: nowrap;
-}
-
-.volume-box {
- border-radius: 8px;
- background: white;
- color: #666666;
- float: left;
- height: 100px;
- margin: 7px;
- padding: 10px;
- width: 205px;
- border: 1px solid rgb(204, 204, 204);
-}
-
-.volume-box .volume-state {
- font-size: 75%;
-}
-
-.volume-box .label {
- color: white;
- font-weight: bold;
- padding: 1px 5px;
- text-shadow: none;
-}
-
-.volume-box .used {
- background-color: #FF7121;
- border-radius: 5px 5px 5px 5px;
-}
-
-.volume-box .free {
- background: none repeat scroll 0 0 #72AA00;
- border-radius: 5px 5px 5px 5px;
-}
-
-.volume-setting {
- float: right;
- padding: 5px;
-}
-
-.volume-setting>* {
- height: 16px;
- width: 16px;
- border: none;
- float: left;
- padding: 2px;
- cursor: pointer;
-}
-
-.field>select {
- height: 30px;
- width: 160px;
- font-size: 14px;
- padding-left: 8px;
-}
-
-.clear {
- clear: both;
-}
-
-.volume-text {
- color: #999999;
- float: left;
- font-size: 10px;
- font-weight: bold;
- height: 18px;
- line-height: 18px;
- width: 142px;
- max-width: 85px;
- overflow: hidden;
- text-overflow: ellipsis;
-}
-
-.volume-textquota {
- color: #999999;
- float: left;
- font-size: 10px;
- font-weight: bold;
- height: 18px;
- line-height: 18px;
- width: 142px;
- max-width: 95px;
- overflow: hidden;
- text-overflow: ellipsis;
-}
-
-.volume-type-position {
- display: inline;
- padding-right: 5px;
- clear: both;
- width: 90px;
- border-right: 1px solid #999;
- float: left;
- white-space: nowrap;
-}
-
-.volume-quota-position {
- display: inline;
- width: 90px;
- padding-left: 5px;
- float: left;
- border-left: 1px solid #eee;
- white-space: nowrap;
-}
-
-.list-storage .storage-li[data-stat="active"]>.handle>.arrow-down {
- background: url(../images/theme-default/arrow-down.png) no-repeat center
- center;
- height: 18px;
- width: 18px;
-}
-
-.list-storage .storage-li[data-stat="inactive"]>.handle>.arrow-down {
- background: url(../images/theme-default/arrow-down-disable.png) no-repeat
- center center;
- height: 18px;
- width: 18px;
-}
-
-.arrow-up {
- background: url(../images/theme-default/arrow-up.png) no-repeat center
- center;
- height: 18px;
- width: 18px;
-}
-
-.storage-icon {
- border: 1px solid #CCCCCC;
- border-radius: 8px 8px 8px 8px;
- height: 40px;
- width: 40px;
- margin: 0 10px 10px 0;
- float: left;
- display: inline;
-}
-
-.volume-default {
- background: url(../images/theme-default/icon-volume-default.png)
- no-repeat center center;
-}
-
-.icon-raw {
- background: url(../images/theme-default/icon-raw.png) no-repeat center
- center;
-}
-
-.icon-qcow2 {
- background: url(../images/theme-default/icon-qcow2.png) no-repeat center
- center;
-}
-
-.icon-iso {
- background: url(../images/theme-default/icon-iso.png) no-repeat center
- center;
-}
-
-.host-partition {
- padding-left:13px;
-}
-
-.host-partition>div {
- font-size: 13px;
- height: 18px;
- padding: 10px;
- color: #666;
- float: left;
- max-width: 200px;
- overflow: hidden;
- text-overflow: ellipsis;
- font-weight: bold;
- line-height: 18px;
- white-space: nowrap;
-}
-
-.storage-type-wrapper-controls {
- width: 300px;
- display: inline-block;
- vertical-align: top;
- padding: 5px 5px 5px 22px;
-}
-
-.storage-type-wrapper-controls input[type="text"] {
- height: 38px;
- line-height: 38px;
- background: #fff;
- -webkit-border-radius: 5px;
- border-radius: 5px;
- box-shadow: 2px 2px 2px #eee inset;
- border-top: 1px solid #bbb;
- border-left: 1px solid #bbb;
- padding: 0 10px;
- margin-top: 5px;
- width: 250px;
-}
-
-.storage-type-wrapper-controls > .dropdown {
- margin: 5px 0 0 1px;
- width: 200px;
-}
-
-.storage-type-wrapper-controls input[type="text"][disabled] {
- color: #bbb;
- background-color: #fafafa;
- cursor: not-allowed;
-}
-
-.storage-add-input-width {
- width: 285px;
-}
-
-.form-section .storage-field {
- overflow: visible;
-}
-
-.storage-base-input-width {
- width: 300px;
-}
-
-.storage-window {
- width: 600px;
- height: 700px;
-}
-
-.storage-port-width {
- width:40px;
-}
-
-.storage-auth-width {
- width: 150px;
-}
-
-.storage-window .form-section .field {
- overflow: visible;
-}
-
-#pool-loading {
- margin: 10px 15px;
- background: #C0C0C0 url(../images/theme-default/loading.gif) 7px
- center no-repeat;
- padding: 0 20px 0 26px;
-}
-
-.storage-admin .filter-select {
- display: inline-block;
- position: relative;
-}
-
-#iscsiportId, .storage-admin .filter-select input {
- border: 1px solid #CCCCCC;
- border-radius: 1px;
- font-size: 14px;
- padding: 3px 3px 3px 10px;
- height: 30px;
-}
-
-.storage-admin .filter-select input::-ms-clear {
- display: none;
-}
-
-#iSCSIServer input {
- width: 410px;
-}
-
-#iscsiportId {
- width: 60px;
-}
-
-#iSCSITarget input {
- width: 493px;
-}
-
-/* Progress bar */
-.volume-progress {
- clear: both;
- width: 140px;
-}
-
-.volume-progress .progress-bar-outer {
- background: #ccc;
- height: 4px;
- overflow: hidden;
- width: 100%;
-}
-
-.volume-progress .progress-bar-inner {
- background: #090;
- height: 100%;
- width: 0%;
-}
-
-.volume-progress .progress-label {
- color: #999;
- font-size: 10px;
- line-height: 16px;
-}
-
-.volume-progress .progress-transferred {
- float: right;
-}
-/* End of Progress bar */
diff --git a/plugins/kimchi/ui/css/theme-default/storagepool-add-volume.css
b/plugins/kimchi/ui/css/theme-default/storagepool-add-volume.css
deleted file mode 100644
index 6e8a551..0000000
--- a/plugins/kimchi/ui/css/theme-default/storagepool-add-volume.css
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * Project Kimchi
- *
- * Copyright IBM, Corp. 2014
- *
- * 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.
- */
-#sp-add-volume-window {
- height: 400px;
- width: 500px;
-}
-
-#sp-add-volume-window .textbox-wrapper input[type="text"] {
- box-sizing: border-box;
- width: 100%;
-}
-
-#sp-add-volume-window .textbox-wrapper label {
- vertical-align: middle;
-}
-
-#sp-add-volume-window input[type="text"][disabled] {
- color: #bbb;
- background-color: #fafafa;
- cursor: not-allowed;
-}
diff --git a/plugins/kimchi/ui/css/theme-default/template-edit.css
b/plugins/kimchi/ui/css/theme-default/template-edit.css
deleted file mode 100644
index 7c93117..0000000
--- a/plugins/kimchi/ui/css/theme-default/template-edit.css
+++ /dev/null
@@ -1,175 +0,0 @@
-/*
- * Project Kimchi
- *
- * Copyright IBM, Corp. 2013-2015
- *
- * 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.
- */
-#template-edit-window {
- font-size: 13px;
- height: 500px;
- width: 800px;
-}
-
-#edit-template-tabs {
- background: none repeat scroll 0 0 transparent;
- border: medium none;
- height: 100%;
- padding: 0;
-}
-
-#edit-template-tabs .form-template-inline-wrapper {
- display: inline-block;
- vertical-align: top;
-}
-
-.template-edit-wrapper-label {
- vertical-align: top;
- min-width: 100px;
- height: 35px;
- line-height: 35px;
- margin: 7px 0 8px;
-}
-
-.template-edit-wrapper-controls {
- vertical-align: top;
- width: 400px;
-}
-
-.template-edit-wrapper-controls input[type="text"] {
- height: 38px;
- line-height: 38px;
- background: #fff;
- -webkit-border-radius: 5px;
- border-radius: 5px;
- box-shadow: 2px 2px 2px #eee inset;
- box-sizing: border-box;
- -moz-box-sizing: border-box;
- -webkit-box-sizing: border-box;
- border-top: 1px solid #bbb;
- border-left: 1px solid #bbb;
- padding: 0 10px;
- margin-top: 5px;
- width: 100%;
-}
-
-.template-edit-wrapper-controls > .dropdown {
- margin: 5px 0 0 1px;
- width: 372px;
-}
-
-.template-edit-wrapper-controls input[type="text"][disabled] {
- color: #bbb;
- background-color: #fafafa;
- cursor: not-allowed;
-}
-
-#edit-template-tabs .template-tab-header {
- margin-bottom: 8px;
- padding-bottom: 2px;
- font-weight: bold;
- border-bottom: 1px solid #999999;
- overflow: hidden;
-}
-
-#edit-template-tabs .template-tab-header .action-area {
- float: right;
- height: 20px;
- width: 20px;
-}
-
-#edit-template-tabs .template-interface-cell {
- display: inline-block;
- width: 250px;
-}
-
-#edit-template-tabs .template-storage-cell{
- display: inline-block;
- width: 180px;
-}
-
-#edit-template-tabs .template-storage-cell label {
- height: 25px;
- padding: 2px;
- border: 1px;
-}
-
-#form-template-storage .template-tab-body select {
- width: 140px;
-}
-
-#form-template-storage .template-tab-body input {
- width: 56px;
- height: 17px;
-}
-
-#form-template-storage .template-tab-body .template-storage-name {
- width: 170px;
-}
-
-#form-template-storage .template-tab-body .template-storage-disk-format {
- width: 160px;
-}
-
-#edit-template-tabs .template-tab-body input[readonly] {
- background: none repeat scroll 0 0 rgba(0, 0, 0, 0);
- border-color: transparent;
- text-overflow: ellipsis;
-}
-
-#edit-template-tabs .template-tab-body .item {
- height: 25px;
-}
-
-#form-template-interface .template-tab-body select {
- width: 180px;
-}
-
-#edit-template-tabs .template-tab-body .action-area {
- float: right;
-}
-
-#edit-template-tabs .template-tab-body .action-area button {
- width: 20px;
- height: 20px;
-}
-
-#edit-template-tabs .hide {
- display: none;
-}
-
-#form-template-processor select,
-#form-template-processor input[type="text"] {
- margin-left: 10px;
-}
-
-#form-template-processor input[type="checkbox"] {
- margin-right: 5px;
-}
-
-#form-template-processor .manual {
- margin-top: 10px;
- margin-left: -3px;
-}
-
-#form-template-processor .topology {
- margin: 10px 30px;
-}
-
-#form-template-processor .topology div {
- margin-bottom: 10px;
-}
-
-#form-template-processor .topology select {
- width: 80px;
-}
diff --git a/plugins/kimchi/ui/css/theme-default/template.css
b/plugins/kimchi/ui/css/theme-default/template.css
deleted file mode 100644
index 27fe404..0000000
--- a/plugins/kimchi/ui/css/theme-default/template.css
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- * Project Kimchi
- *
- * Copyright IBM, Corp. 2013-2014
- *
- * 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.
- */
-.tile-template>li>label:hover .summary {
- opacity: 0.1;
-}
-
-.tile-template>li>label:hover .list-info {
- top: 0;
-}
-
-.tile-template .summary {
- -webkit-transition: opacity 0.25s;
- -moz-transition: opacity 0.25s;
- transition: opacity 0.25s;
-}
-
-.tile-template .list-info {
- -webkit-transition: top 0.25s;
- -moz-transition: top 0.25s;
- transition: top 0.25s;
- position: absolute;
- top: 100%;
- width: 100%;
-}
-
-.tile-template .list-info>li {
- border-bottom: 1px dotted #ccc;
- padding: 5px;
- font-size: 12px;
- line-height: 20px;
- overflow: hidden;
- width: 96%;
-}
-
-.tile-template .list-info>li>label {
- display: inline-block;
- color: #111;
- width: auto;
- text-align: left;
- cursor: pointer;
-}
-
-.tile-template .list-info>li>span {
- float: right;
- color: #444693;
- width: auto;
- text-align: right;
-}
-
-.os-icon {
- text-align: center;
-}
-
-.os-icon .title {
- display: block;
- font-size: 14px;
- margin-bottom: 5px;
- overflow: hidden;
- width: 260px;
- word-break: break-all;
- word-wrap: break-word;
- height: 50px;
- line-height: 25px;
-}
-
-.os-icon img {
- margin-top: 7px;
- width: 64px;
- height: 64px;
-}
diff --git a/plugins/kimchi/ui/css/theme-default/template_add.css
b/plugins/kimchi/ui/css/theme-default/template_add.css
deleted file mode 100644
index f1e28c5..0000000
--- a/plugins/kimchi/ui/css/theme-default/template_add.css
+++ /dev/null
@@ -1,317 +0,0 @@
-/*
- * Project Kimchi
- *
- * Copyright IBM, Corp. 2013-2015
- *
- * 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.
- */
-.page-list {
- position: absolute;
- left: 0;
- right: 0;
- top: 0;
- bottom: 0;
- overflow: hidden;
-}
-
-.page {
- position: absolute;
- left: 100%;
- width: 100%;
- height: 100%;
- overflow: auto;
-}
-
-.page>header {
- position: relative;
- overflow: hidden;
-}
-
-.button-group {
- margin-left: 5px;
-}
-
-.back {
- float: left; display : block;
- width: 50px;
- height: 52px;
- background: url(../images/theme-default/icon-back.png) center
- center no-repeat;
- cursor: pointer;
- display: block;
-}
-
-.step-title {
- color: #333;
- font-size: 18px;
- font-weight: normal;
- padding: 15px 10px;
-}
-
-.step-choose>li>a {
- display: block;
- margin: 0 10px 10px;
- padding: 20px 10px 20px 65px;
- border: 2px solid #ccc;
- background: url(../images/theme-default/icon-local.png) 15px
- center no-repeat;
- cursor: pointer;
-}
-
-.step-choose>li>a.local {
- background-image: url(../images/theme-default/icon-local.png);
-}
-
-.step-choose>li>a.remote {
- background-image: url(../images/theme-default/icon-remote.png);
-}
-
-.step-choose>li>a:HOVER {
- border: 2px solid #06C;
-}
-
-.step-subtitle {
- font-size: 16px;
- height: 48px;
- line-height: 48px;
- color: #06C;
- margin: 0 10px;
- font-weight: bold;
- text-shadow: -1px -1px 1px #eaeaea, 1px 1px 1px #fff;
-}
-
-.custom-iso-field {
- position: relative;
- padding: 0 10px 10px;
-}
-
-.custom-iso-field>.input-wrapper {
- margin-right: 110px;
-}
-
-.custom-iso-field>.input-wrapper>input.text {
- padding: 10px;
- color: #333;
- font-size: 13px;
- background: #fff;
- -webkit-border-radius: 5px;
- -moz-border-radius: 5px;
- border-radius: 5px;
- box-shadow: 2px 2px 2px #eee inset;
- border-top: 1px solid #bbb;
- border-left: 1px solid #bbb;
- width: 100%;
-}
-
-.custom-iso-field>button {
- position: absolute;
- top: -6px;
- right: 8px;
-}
-
-.iso-field .button-field {
- padding: 0 20px;
- text-align: right;
-}
-
-.check-all {
- display: inline-block;
- position: relative;
- height: 38px;
- line-height: 38px;
- margin: 5px;
- font-size: 13px;
-}
-
-.check-all input {
- margin: 0 5px 0 0;
-}
-
-.box {
- background: #ffffff;
- background: -moz-linear-gradient(top, #ffffff 0%, #e5e5e5 100%);
- background: -webkit-gradient(linear, left top, left bottom,
- color-stop(0%, #ffffff), color-stop(100%, #e5e5e5));
- background: -webkit-linear-gradient(top, #ffffff 0%, #e5e5e5 100%);
- background: -o-linear-gradient(top, #ffffff 0%, #e5e5e5 100%);
- background: -ms-linear-gradient(top, #ffffff 0%, #e5e5e5 100%);
- background: linear-gradient(to bottom, #ffffff 0%, #e5e5e5 100%);
- filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffff',
- endColorstr='#e5e5e5', GradientType=0);
- border: 1px solid #ccc;
- color: #333;
- text-shadow: -1px -1px 1px #ccc, 1px 1px 1px #fff;
- -webkit-border-radius: 8px;
- -moz-border-radius: 8px;
- border-radius: 8px;
-}
-
-.box:HOVER {
- border: 1px solid #aaa;
- -webkit-box-shadow: #bbb 0px 0px 5px;
- box-shadow: #bbb 0px 0px 5px;
-}
-
-.box-iso {
- padding: 10px;
- margin: 5px;
- overflow: hidden;
-}
-
-.iso-icon {
- float: left;
- width: 58px;
- height: 58px;
- margin: 0 5px 0 0;
- border: 1px solid #CCCCCC;
- border-radius: 8px;
- background: url(../images/icon-vm.png) center center no-repeat;
- background-size: 58px;
-}
-
-.iso-icon.centos {
- background-image: url(../images/icon-centos.png);
-}
-
-.iso-icon.debian {
- background-image: url(../images/icon-debian.png);
-}
-
-.iso-icon.fedora {
- background-image: url(../images/icon-fedora.png);
-}
-
-.iso-icon.opensuse {
- background-image: url(../images/icon-opensuse.png);
-}
-
-.iso-icon.ubuntu {
- background-image: url(../images/icon-ubuntu.png);
-}
-
-.iso-icon.gentoo {
- background-image: url(../images/icon-gentoo.png);
-}
-
-.list-iso {
- overflow: hidden;
- margin: 5px;
-}
-
-.list-iso li {
- float: left;
- width: 320px;
-}
-
-.list-iso>li>label {
- display: block;
- cursor: pointer;
-}
-
-.list-iso>li>label>input[type="checkbox"] {
- display: none;
-}
-
-.list-iso>li>label>input[type="checkbox"]:CHECKED+.box-iso {
- border: 1px solid rgb(11, 107, 173);
- -webkit-box-shadow: rgb(11, 107, 173) 0px 0px 4px;
- box-shadow: rgb(11, 107, 173) 0px 0px 4px;
-}
-
-.iso-title {
- margin: 0;
- display: block;
- position: relative;
- height: 23px;
- line-height: 23px;
- font-size: 14px;
- font-weight: normal;
- max-width: 100%;
- overflow: hidden;
- text-overflow: ellipsis;
- white-space: nowrap;
-}
-
-.iso-title>label>input {
- display: block;
- position: absolute;
- top: 0;
- right: 2px;
-}
-
-.iso-info {
- margin-top: 5px;
- overflow: hidden;
-}
-
-.iso-info-col {
- float: left;
- width: 50%;
- -moz-box-sizing: border-box;
- box-sizing: border-box;
- padding: 0 0 0 5px;
-}
-
-.iso-info-col:FIRST-CHILD {
- padding: 0 5px 0 0;
- border-right: 1px solid #999;
-}
-
-.iso-info-item {
- font-weight: bold;
- color: #999;
- font-size: 11px;
- line-height: 18px;
- max-width: 106px;
- overflow: hidden;
- text-overflow: ellipsis;
- white-space: nowrap;
-}
-
-#iso-search {
- margin: 10px 15px;
-}
-
-#iso-search-loading {
- margin: 10px 15px;
- background: #C0C0C0 url(../images/theme-default/loading.gif) 7px
- center no-repeat;
- padding: 0 20px 0 26px;
-}
-
-#iso-more-loading {
- background: #C0C0C0 url(../images/theme-default/loading.gif) 7px
- center no-repeat;
- padding: 0 20px 0 26px;
-}
-
-#vm-image-local-box .body {
- margin: 30px 0 0 26px;
-}
-
-#vm-image-local-box .body input {
- background: none repeat scroll 0 0 #FFFFFF;
- border-left: 1px solid #BBBBBB;
- border-radius: 5px 5px 5px 5px;
- border-top: 1px solid #BBBBBB;
- box-shadow: 2px 2px 2px #EEEEEE inset;
- color: #333333;
- font-size: 13px;
- padding: 10px;
- margin-left: 10px;
- width: 600px;
-}
-
-#vm-image-local-box .body button {
- margin-left: 10px;
-}
diff --git a/plugins/kimchi/ui/css/theme-default/template_list.css
b/plugins/kimchi/ui/css/theme-default/template_list.css
deleted file mode 100644
index 3161a33..0000000
--- a/plugins/kimchi/ui/css/theme-default/template_list.css
+++ /dev/null
@@ -1,267 +0,0 @@
-/*
-* Project Kimchi
-*
-* Copyright IBM, Corp. 2013-2014
-*
-* 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.
-*/
-.list-template.framework {
- float: left;
- clear: both;
-}
-
-.template-box {
- border-radius: 8px 8px 8px 8px;
- box-shadow: none;
- color: #666666;
- float: left;
- height: auto;
- margin: 10px 11px 10px 0;
- padding: 10px;
- width: 308px;
-}
-
-.template-title {
- font-size: 16px;
- height: 25px;
- line-height: 25px;
-}
-
-.template-icon {
- border: 1px solid #CCCCCC;
- border-radius: 8px 8px 8px 8px;
- height: 58px;
- margin: 0 10px 10px 0;
- width: 48px;
-}
-
-.template-icon img {
- width: 58px;
-}
-
-.template-text {
- color: #999999;
- float: left;
- font-size: 11px;
- font-weight: bold;
- height: 18px;
- line-height: 18px;
- width: 142px;
- display: table;
-}
-
-.white-box {
- background: #ffffff;
- background: -moz-linear-gradient(top, #ffffff 0%, #e5e5e5 100%);
- background: -webkit-gradient(linear, left top, left bottom,
- color-stop(0%, #ffffff), color-stop(100%, #e5e5e5));
- background: -webkit-linear-gradient(top, #ffffff 0%, #e5e5e5 100%);
- background: -o-linear-gradient(top, #ffffff 0%, #e5e5e5 100%);
- background: -ms-linear-gradient(top, #ffffff 0%, #e5e5e5 100%);
- background: linear-gradient(to bottom, #ffffff 0%, #e5e5e5 100%);
- filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffff',
- endColorstr='#e5e5e5', GradientType=0);
- border: 1px solid #CCCCCC;
- color: #333333;
- text-shadow: -1px -1px 1px #CCCCCC, 1px 1px 1px #FFFFFF;
-}
-
-.row-select {
- -moz-border-bottom-colors: none;
- -moz-border-left-colors: none;
- -moz-border-right-colors: none;
- -moz-border-top-colors: none;
- background: linear-gradient(to bottom, #FFFFFF 0%, #E5E5E5 100%) repeat
- scroll 0 0 transparent;
- border-color: #999999 #AAAAAA #AAAAAA #999999;
- border-image: none;
- border-radius: 5px 5px 5px 5px;
- border-right: 1px solid #AAAAAA;
- border-style: solid;
- border-width: 1px;
- float: left;
- font-size: 13px;
- height: 42px;
- line-height: 42px;
- margin: 5px 0 0 10px;
- padding-left: 10px;
- text-align: left;
- text-shadow: -1px -1px 1px #AAAAAA, 1px 1px 1px #FFFFFF;
- width: 100px;
-}
-
-.bevel3 {
- box-shadow: -2px -2px 2px #EAEAEA, 2px 2px 2px #FFFFFF, 3px 3px 3px white
- inset, -3px -3px 3px rgba(0, 0, 0, 0.25) inset;
- color: #333333;
-}
-
-.row-drop {
- left: 10px;
- position: relative;
- top: 50px;
-}
-
-.template-action-hidden {
- visibility: hidden;
-}
-
-.template-action-show {
- visibility: visible;
- display: block;
-}
-
-template-hidden {
- display: none;
-}
-
-.select-drop {
- background: none repeat scroll 0 0 #EEEEEE;
- border: 2px solid #096AAD;
- border-radius: 5px 5px 5px 5px;
- box-shadow: 6px 6px 6px;
- height: 147px;
- left: 0;
- position: absolute;
- top: 8px;
- width: 250px;
- z-index: 2147483647;
-}
-
-.button-drop {
- background: linear-gradient(to bottom, #EEEEEE 0%, #CCCCCC 10px, #CCCCCC
- 96%, #A5A5A5 100%) repeat scroll 0 0 transparent;
-}
-
-.action-bevel {
- box-shadow: -1px -1px 1px #CCCCCC, 1px 1px 1px #EEEEEE;
-}
-
-.template-border {
- border: 1px solid rgb(204, 204, 204);
-}
-
-.template-button-position {
- position: relative;
- left: 250px;
- top: 55px;
- z-index: 5555;
-}
-
-.tempate-action-position {
- float: right;
- width: 83px;
- margin: 0;
-}
-
-.template-actiontext-position {
- width: 250px;
- height: 160px;
-}
-
-.template-line {
- left: 200px;
-}
-
-.template-os-position {
- padding-right: 10px;
- clear: both;
- width: 142px;
- border-right: 1px solid #999;
- float: left;
-}
-
-.template-cpu-position {
- border-left: 1px solid #eee;
- padding-left: 10px;
- float: left;
- width: 132px;
-}
-
-.template-icon-position {
- float: left;
- height: 58px;
- width: 58px;
-}
-
-.template-icon img.template-type-icon-position {
- width: 20px;
- height: 20px;
- position: relative;
- top: -15px;
- left: 49px;
-}
-
-.template-title-position {
- float: left;
- width: 120px;
-}
-
-.template-results {
- background: linear-gradient(to bottom, #FFFFFF 35px, rgba(255, 255, 255, 0)
- 100%) repeat scroll 0 0 transparent;
- float: left;
- height: 60px;
- margin-bottom: -22px;
- padding-left: 10px;
- width: 1014px;
-}
-
-.select-row-action {
- background: linear-gradient(to bottom, #FFFFFF 0%, #E5E5E5 100%) repeat
- scroll 0 0 transparent;
- border: 1px solid #CCCCCC;
- border-radius: 5px 5px 5px 5px;
- float: left;
- font-size: 13px;
- height: 38px;
- line-height: 38px;
- margin: 10px 10px 0;
- text-align: center;
- text-shadow: -1px -1px 1px #CCCCCC, 1px 1px 1px #FFFFFF;
- width: 230px;
-}
-
-.select-row-delete {
- background: linear-gradient(to bottom, #FF3019 0%, #CF0404 100%) repeat
- scroll 0 0 transparent;
- border: 1px solid #B10F14;
- border-radius: 5px 5px 5px 5px;
- color: #FFFFFF;
- float: left;
- font-size: 13px;
- font-weight: bold;
- height: 38px;
- line-height: 38px;
- margin: 10px 10px 0;
- text-align: center;
- text-shadow: -1px -1px 1px #9E0505, 1px 1px 1px #FC5D4C;
- width: 230px;
-}
-
-.template-general .title {
- color: black;
- font-size: 16px;
- font-weight: normal;
- height: 25px;
- line-height: 25px;
- text-shadow: -1px -1px 1px #ccc, 1px 1px 1px #fff;
- max-width: 130px;
- overflow: hidden;
- text-overflow: ellipsis;
- white-space: nowrap;
-}
-
-.processing {
- cursor: wait;
-}
diff --git a/plugins/kimchi/ui/images/Makefile.am b/plugins/kimchi/ui/images/Makefile.am
deleted file mode 100644
index ca3ee6e..0000000
--- a/plugins/kimchi/ui/images/Makefile.am
+++ /dev/null
@@ -1,22 +0,0 @@
-#
-# Kimchi
-#
-# Copyright IBM, Corp. 2013
-#
-# 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.
-
-SUBDIRS = theme-default
-
-imagedir = $(datadir)/wok/plugins/kimchi/ui/images
-
-dist_image_DATA = *.png
diff --git a/plugins/kimchi/ui/images/icon-centos.png
b/plugins/kimchi/ui/images/icon-centos.png
deleted file mode 100644
index 5afb7b4b63462412d825f63542beb1f7e26b3d7f..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001
literal 4734
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
M07*qoM6N<$f~4IfuK)l5
diff --git a/plugins/kimchi/ui/images/icon-debian.png
b/plugins/kimchi/ui/images/icon-debian.png
deleted file mode 100644
index ff49a39696fdfa5f232b0e79de04d90af6557111..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001
literal 4239
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
D^V29c
diff --git a/plugins/kimchi/ui/images/icon-fedora.png
b/plugins/kimchi/ui/images/icon-fedora.png
deleted file mode 100644
index 7b9dd06d1f766a3285cd0fb587c0be4114bfac47..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001
literal 4449
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
S9$oyI0D9VncWN{pBmW0TFKp8Q
diff --git a/plugins/kimchi/ui/images/icon-gentoo.png
b/plugins/kimchi/ui/images/icon-gentoo.png
deleted file mode 100644
index 50d928fbfa30560fe873cf3de438a8f0c10a8f96..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001
literal 15307
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
diff --git a/plugins/kimchi/ui/images/icon-opensuse.png
b/plugins/kimchi/ui/images/icon-opensuse.png
deleted file mode 100644
index 83fe4d5df0f59b52dd609b3bd16838f4d2570ab8..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001
literal 3046
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
diff --git a/plugins/kimchi/ui/images/icon-ubuntu.png
b/plugins/kimchi/ui/images/icon-ubuntu.png
deleted file mode 100644
index d92c00f357b6b0e1542413f6aaf0de8ef4b8d130..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001
literal 4818
zcmb7Ig;!Kv_a1VFPU&ut7*J4<Zs`<6YUl>(W>CbDj+c1pW*7<S96}_eTUzNFy6YQ%
z@dtc&t$oir=j^l3UF+`W+3`h3ON9uZ4j%vj5WQAa)I*QZzXHNVzq_R&KhXoWm;7r3
z5c&xQ*}%|qJP*~kUTFQ<zk(splj)CMr1e%Z_SSc|^Y(*y+5-Ii`~)4{oV~0e9=3w+
zp7xn2Njd<4T>G`6oPmGVL3V(@!Sqs}Os#FrXATWaMN$=b)07FBLtU{UzX%&9N-x^P
zuR8vzp=_|DfH9SBZi_*klK;~tgHLRPM~JBk1O6sS7z>z<6>lIR!lq`#cSQ!pX_q;a
z-MlrTk$x>XDoLH>HF`ZPzLFI*D&BGW3ioxAYGNDBnyYNoRT8;uQu2Qx)^Uv(fxkWH
zPM~CiTLv2@gzJD`jFo^`XlZvn{v1(og{j{{HtNQBp7|+Z-%rnPKOxTmh2aB(ThF_c
z_AzJpa$S8(Z=2vv(gJ|AZaW-7KnWlj8ZOM<(H!$5^g?wd5+yXY?{e3n2JefH@s@
zXCxhd*m~?g4suaM(axZ4x4c}SAPZ6cyASjSG%@!_)r#jkU@`$y=d#_j+hTPUz7uqA
ze0vLBfHuqOW)17AiyrYDwJq&j^em(=s~ThQ2>BRcoQ5Z_xoFkx12+LxoV)7Q^7!a8
zu~<}?>}#&kEDcyB^VulBHCI(5ay9f#uApy(O+3pD+dsHg-?UDKfR`f~*df@fo^xv9
zjS1Y&arOvknQv*3a~n}O_P_YP;x3cn0t}C_Bqx501;JZQ6thfd^R(f8(3PHH*i{WE
z-PW(=<FN>f8>WZ2%dbwpb=o!?J4Wy@%KJrc;ZYL^txcr#@W=i~n+GGfsF*$AUA;{;
zMY@e&3kj@RRZ5r|`V&I`aq+4lor<4S-<&l--<{k3?s<&(HO&xJ8}M@M?6=IZi+OBE
z3x9^oQa{_3;<sibxjqI@*!9A8cWkcsu6)$i9nnY8!oC$Com1J(y-ywL=6S~cQs=hu
z1-38+^kis7jTv=O(LG`__Q!{2;#rU;cfh-{EUzaOuL|jQ4zSg%&$URCA$cba9Z}MY
zR{*8jN4kb%xlnGNw(GD0flWfo6g~SEimw6CzU?*l+Zp|lUJ(xm>>ZV)_cL=2(U}pZ
z_AQ02fPe7frDaA&CETrkTo&a9#-*}_QAZE3nc?JV912d>#u!6X_pXbpUc@xxm_(bE
zOy#?6Z&D)o_uFuc&-oOHaFc2GV2SC`pDhLXx)wXIy~gp<T~DSh8%U3)$j%rzx68VX
zPzA1sTXi9)w98l)?AIF`ca{pS>z{z4+DC808%>E99FSBAXJ`24$_!f<6{T647dS>q
z_orp)C-^~{&Vme}Pc^R~HzcE+_TPN~*iOV=N0GIOchYSusHnNfO>HqHH-EpV#68as
zu%VWMpJ1K0qhTuky$~=7jr_>9QGyhTkDt>jSQW9kqB^PK{;{inbxY=l$Q2NQBA7Bf
zU8)KNC4F;zAUHqbCVe2z^FQII%&ww4;aX9CID7k@j+tdPzwPsDIj6Kyqv^b)6_xX(
zRz)%CPWfWDPX&GItA;-YllvTY&sJIt)j?ukmO2uT*DNe)y~zQZ?_TKCuX1s?3z@HW
z0aS9@(oz}UMa+krmKuE-F@OUofg{&!r-Yx%^3vthXA*@^?k;k1q<p3-%=sEvK89n&
zw?{QQfB~A!NX;IswAFyE6fLV{%uvZpBYoe!X8+|7!*ZgPXBK7F5KssZ?Z$o>VN|IQ
zP&xYuq;oM1{DgAt>B?ySLLb{T5<tW6NNC>h<P^#(|MQHwEYI`e$<^RR!{d;pR=4Dl
z;)hrjJh3TOoIClSgkA0jT9=arA`~-NJfXK<N*mNsS$G|GV}I(?@z*gTi`Q*V1X~O5
zFOx>q4^C7*r8%QyU~<v3i2)-o3AqA}IIfXs%j9scKEyG`CZCT0Hbe>ymRqSKSi+F}
z*x_yvPZLC|F;~4}_@5=cs7F<$+flU~4=cueM=n8*uHM4uVK;)qkH1tG+J(R*FUiyg
z28`9TdW|lKi1sWdiWiCRx=`LK$hk2xR!p4+=al@lxa{)kWZuwi9Prs4+u~Ih9fG;F
z`2KOHG}dZtjb4HqANOdMp*O7PLuaDeTW}Yk<c{rHUq@p;ff*{N(8u%IK%nVMN&Jjb
zu8MyKw2Q4F|4Rla0~QzSE@jK1bSXnobBs~br`1&p!4a?s#+Kcy)ONgaVEnh3*reks
zq4#oj?Cg*Tn?C-+B$c-+VaQ96!|P0FfX0WlHwM&^+9f+aWM2lCR$O?ItK?f1Sd*}K
zcWCmAd>X5b*fd|fkO@ppRI*++oPKjok~tIPL9*fZP;ejMvOCMn@kKU7)4(><lc2xV
z3O68anS26+gEG9uY4ETa6n35uAAHj#v#)iTV)AU9A7C4OL3TD*><rd9`Jr51npJU=
znnBH!|1i82kpUTO)b;4@UXRJ88V_*|k}17IMJsB97z@d^t9+bWV7i?++jUB>whAni
zrmm72i5?-x&RpRVFHqd5lEC9^RaXJTVJ)#tw5hF`9Iz&F&zyn{8>}SDv;?->_-hz3
z38atL6TkJ$ctDzycmW)O4}As?nV1v%PpWcbg`a8*B|o1<a$)dzO}6;oP-=wn?DH)P
z-%Wq!>2PPOu-G}&*}Hdpky0zft+VweW%(Z?)d!!J>u!yS7U{ftAWbYW<n2Ucjv9*d
z1w!p<y_mlEo=C9m3QUZhqkRyIA#|PYgTU^cm>2iG@;RSX1finaNBB4&bb#*gFp;6}
z%#A=QA0F_YsXfa599(ELe-ZK}=r|iOL8oEo$-SJH#+xzE@*CR{{O`cSwSl4Iy9W1s
z$i3${7reyrYjR2a%9|9ipnb~eg1Ce$knERkZV5_yTJ}++^L-Mr>9x>5ZsR>F8pB?-
zcw(PPfHs4TX#B&G5kYIuiv<eg)k(ne-ALAfcG;yx<?hIoD`&oQFe}@gXv);1!qOkp
zxWPjz9Nk7GdAv?bk!10}Hbh;{@K;4@W>KO{BRMdsn3>&956#2``j8;zOVJ5>eokM{
zUJLa{T7n%JYgX~KsvbQn_eUh<k=NNYclYLG%c;y2@j-N*{}O15q2zk<2o=~H!#@$J
zZ0hO+lh7B4mO~iYe=E}UxOWLyYTr}Kq%1<a2;8h1FtD|;{Z-qF@q)c3H1Ku*on)qY
z+`I$w=x)VHq%YzS$^Y^5UbQM^8k20w&&IB#-n?S16T#f^Q<1M-s>>VCXzHfEbS2?J
zgLcf2aeJ8!5{0$KDkgre`YD135x)Z|nd@(nR2c9RHQuIBu^EVcq^3QiFBi`2C@#y~
zgktxC6v^QS&GYY!GD@WIuW#yi9cT-p0R<PN6Kv3L1hT2*LEL^79_wblDz~rX;2k_+
zh6Y{KRv#`Gs=k-JrY}dUn#W9@5R<;~*(r_xGSu2@$#H)sd~(4*YouB+ywqTQiy-Iv
zVgADDK?JBDnz$cNdgRxPn}8Y0k!uuRP>8~)1F@9vmUoXvz0}`3sy%WsC+Y%J1T`cd
z7v}ohgveh4Rt_Q$eftWx;X%*{7)3f;sKX8hUAXzBOyj}5<R6WNL*Wcnnc`bqcCX`A
z*lElYNA5VCa}Z1fX5g;KsHGeYkc=Rc-80JVN9j1NU=>;3X0%U-2FCw3=I^n35ezFj
zy10fEez+QJ&)=UpRitJ-|AlSBgaI+!dg`aNo@?~D>2)<|1}Ms%ITi6ke-3vxlUQtH
z_Xu0K;u4kv8I*5&y3$w{O`6>$&I^~E^-rn#m2GW4d4q)QHg<Nbo`|Ap&+uz{`^Od#
zi=dQjN`@kuz<WZ7cUSyN><^83RqyFXb>8O|hQMrE4|mL^9BR}U$KRH-=LeQo`jhOi
z0SsNoDNL3zd<!RN<xT?1(10QuNh!*eE(!6UYq<0>>9{FEE&u~=jokMDEI|Z8%K@B$
zKYduX(q<8ATa#O4q~~+`(SY{2GhB;i0*hvKrmah8mrcpa^ku{__kB#Rr8va+dpRfr
zADAHSWIE^FmCDryWUCYtRm?6+Re>JSlJKsU1}xYaI<hYn<#RW$m6my4IxV-zIqU4`
zC@xXqaRL%T4yO}>j=ja3^s|Jii8&6VS`CWN;dgGjq(K-w_B+Z<5>E*Q78>CuhR^Ia
zAg!0Yf3f?UkpOHLnHxni)$Dk^k0qrsSG-|rU7_FQEV{fxgue9nzR{p~m?l8FnPU2Y
zdF*4k9`Nnf`NQ|Xm|l_@xF>xyrlxCx2PWX?r4gdC{CnnBJ@9=LC)&rYGOx=Kb$Xpu
z_G7Rnd`tQhxk343rYnge1yv)$oqq{~_cf8e%V#j#RUO>B-%ny_cd35U&D?8NWvi$3
zyON4#VCQ8;mZ|f^%%_CuA*)tQy)ik}XMa8bC6ayrfN%x<vGm(po(W-|i%#8#B${uQ
zPX@A;!8TS!F;BLYzm?_8r#-+WkixCZSk!HDGtG%A=Wo=}$(7#8)FzBAVY<RNuaqEj
zvxS-!dO7xuW}H4pQ)sfm{`2lx<nymbM;<JPyVXm#luFNXV|nyc7nVmI=iuT|>O6FR
zBR~dDo+5k>E}F}f$bq0*)L7jnGaNvoGv99)pDrFVZ_bU7J#E|?%{Y{Ic7h72?(zPA
zcy)|4r<vWSo=Si^l`F>OWK9#`_1l!}{T61uzXN849mY)v9g!+IRRI_ITE{mxqsElC
zEV}*nxQsb|**VAIvST3rCtQL9-9L&km6W@VDS7nP!^za43*l_x0lt6G>_rZ*%72WJ
zfq+ZvAKTo{C$wU7rF^3VW0~PqT}T^Tfn4Ouj_%smtJGA+M{;v>5F&BU1oXY_!+};K
zkd(Qoksv4bQN3qq0Ncry8Dw$&pyg(dt4@dWB8uegzKot+&(Q1VkC#gqy)V)yzY#LU
z@vh7;$-KmsL`>C_D!#jy^dMnD{fK08Sh%+!zV~J5ArUG?ZS))@e#h_>LcYDy88bQ-
zNU0Tczuc@xN7F@hcebxn<ER`ioV(}kw-PEAK{d%Aqb)DkXRE;x%(QEsbCtMOYn9f|
zeN3K#H`kxpT$fsf;BtPc$?U7^V;#KN;iMeCQ{N_g4Mwx>QeZZ%N9@uLRYo-vy@EMb
z!(M{BUkg9YhIWu_Q@6uU`^TI1V|Aet{|k#C<~TadvyLr1kr8Pb?~LuaIMYUXGC_c?
z+l}1#H6lOs;B=}Yn9$-n6cQlz(rEAzOvBssJ`TZJ(B+c99bQ^b#NB$DHxuxfGj?#~
zkk;Km)})#?WJo$t{XT!&-^KLJP7kF_4O_wOQ|2uBpJ~i0hQ8Edzp~xT;$kOHr_bN4
z7Y{aNG0rvE16_lBby{626F#y}YDG!1m~3iu!ANDFc$)2gaKrreY6)mYykKBS@Lp2N
z0RL*^z>coFU)hJyMQDp2UPP3Rm@UiCJ4IQxP9mQ$PSdM%RNe6W?t|?%{Tf+B{4G@4
zr4~`%RoLFAFxV4KW)-GSZ9efOmO9b@v`nTL_W;vBY2_$X7r2fR2d4np)T(|T_51Yu
zl)MrqgD&k5V@^V|t9i7A5Y&qiQ}YaB+3T*wn>_*JRJ9c8B~$;Re(=k~mUi3}rQgY#
z<=tZ!xvr$0j8`MG=*S)5#hx>^b*Px#@dI2gUY{ov-kCtqr~j!Kd&*7`8nPMzpVl>z
z*;&Vv=>KXBes{#Qs4)5Y@kecdPaT<ToM`()skt}HCME!#)+;0`c_<GN%wi~*w9H6_
zy-K8igwjM$QKYfx4pIvg$9K>$DOj&nVX3W+Uy=6lKnA_s@cX(*b+MwMyw$;*ew>2w
z(8?x;hMi84KQFCmtmhNB1H75HKC`o81OB&whE2}P5thm4EKmDHY75{|@aUB#jCYp!
zFBGt6LdU;MTqVd#$*Q0WwU?HxV^VrHD>koA0z<F#IjuClp8*(k`J5;{h-#QkEo@~@
z{Af~Ou_So&Sl&PWuLrQb?J1b<WJ9vEg+`gsa_^b)cY;-#|L-0!`ms0`;rTNdvrYKC
z)4quT#O1pvWWpE<JuoG*O_?xa`!lU)G53^QW}`UKO$o;L;x2F2*{4cbgr4{CxfpYv
z5H8cLN|CjCuPNnH$*TOLU#G%;NtjF)hS(8Y?>MRN6qAzlUh8_#4z1+rD~r>SF6EoG
zT3<7)d1Wex>Xl-wH0-awY=2YPS|4GhZWH$oqew?Zegvxs#>k7oA^zXUBZ(xz@KQls
T?|XFr3GiA;OR-Yk^22`sn~zF<
diff --git a/plugins/kimchi/ui/images/icon-vm.png b/plugins/kimchi/ui/images/icon-vm.png
deleted file mode 100644
index 50dac50c5a0ee59f4e79170434f53bb3b94390e3..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001
literal 2976
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
diff --git a/plugins/kimchi/ui/images/theme-default/Makefile.am
b/plugins/kimchi/ui/images/theme-default/Makefile.am
deleted file mode 100644
index 7e11d75..0000000
--- a/plugins/kimchi/ui/images/theme-default/Makefile.am
+++ /dev/null
@@ -1,20 +0,0 @@
-#
-# Kimchi
-#
-# Copyright IBM, Corp. 2013
-#
-# 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.
-
-imagedir = $(datadir)/wok/plugins/kimchi/ui/images/theme-default
-
-dist_image_DATA = *.png *.gif
diff --git a/plugins/kimchi/ui/images/theme-default/ac22_pause.png
b/plugins/kimchi/ui/images/theme-default/ac22_pause.png
deleted file mode 100644
index 9258aee87f0e2f430cf1fb12a4588f763f3c0a62..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001
literal 1219
zcmbVMO>Em#9CtTbM!QYZ3R7EwV!5LOiP*7Yo5gCV96yIfTDmTcw6Ieh`=v3h{fzyx
zq`hSAssY^&+X3-;7(IbDF^V*#0ostNNpJ&chiPJ(*f=3gfS^*?io$c-6b{vpux!5%
z|9-#!$NT^N=IF@FyE^+iDT>;a83s8r_K~M&M+bTTG<W|x8G5l^z+<R{tA-CL)j~x`
zXB=Y!=AdCszxFL0q^RvBJ72(s>><TO4r_!Mw&r+*O;LkGHP0|7A*PFP!giC)FJE3`
zXxmCMN2P2m>uIoT56}2;Y-S{H&P<vKiy3-}9;_)uz=7DHYtED#D77TBrmK*7xXm&2
z8U#-!nRTZM*-=_UKBOf!9yMb;Ps=jPi;^t!FVI4a7q}R?<tQ&IlB@_X(i;~;toc?+
z$$|8SEwV~7WsE(A<EqsvTaB~GpWygJA`xl`LX;q)!L*BwTGS2tTM7UMrf+-LMlKyH
z8bwsWNrrg39)ja#vzx+hu#qT|GOlKL9M8r$#|h(FLkBnq|8ZkWbdaC+AeVyys`w^3
zk5Ye&Omg>VLm`lOqa5~aawx_WKxV~(F3x}?L%y(<Z7H#MN&~u_5<ptiMV?RbaS4!>
zrVD8v@O(>SE3PK#KozA#S`-LU7gZ6cs;KfBkmKouAhfs{H^7E#!j@f|*xleBd?Z)V
zd}v_g=MkD}RlsN&VHA{+M{8p;{oGO8wNN#9K0KcFXaV%?<Iqa`$f4KrtJquEkBR>k
z_d3`5KRM%wGhA34|0<T&7OB8+x>@>UvDrM(B^~3F);Mrp0;H{e&j2-FyH#9mHixz+
zsjfH1Eo=U_E3<{C2X?pDPc)w0Q`h${U)cTry;r_#-0i-(^1+#R+i$(o+oLyy)rrPR
zGqQa6RQ*y<Z%_B&waD#}Gs^kZ<Eed1jiuqwm$peKfB56{kCElaPu<xWX*Tygy#8yQ
z9UWc(m4ngZo|4tA&$sX2aW%f${zc=`{>0DYC!VN3CJ3Lly+xgTeKuD)G@tA0Klky%
zS!JL@nLTnk9qqeZzOi_&{C$L3`Rl_Qi*JAZ>Yq=2M&<4|=XMg!2b~wc+G{MR(t(fO
w>*#y%<Tu#??U}`^+b$Q*9#iveH;<`QTL-02da<sDMK=7cWb_g6NosuVZ*kO>5C8xG
diff --git a/plugins/kimchi/ui/images/theme-default/ac22_pause_grey.png
b/plugins/kimchi/ui/images/theme-default/ac22_pause_grey.png
deleted file mode 100644
index 7cde85bcb26ca808b9b02d5336872f10556585a0..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001
literal 1175
zcmbVMUue{J98c{SYPo?ZqV0n};)|2JOMXc%y~}#Gy(HIO+0}Br&chc?lV97|CciBC
z)w`CVuHZZen`;>q!NH~v?x9Y7Dzb+TRHmS);FB+cii#l4hoNGz{?hikJroBENq)cY
zFW=AS`#;Bfx;rB48`m=o6UlXI1-drUXUp1;>HE>d^Q&~(O7s%x#RH^l_=st@a6bY$
z#~4HfWLRTgUPmnqQ$JuAOQe+lTrsf|H$t6w#qlVbVOm-%o?#9n0{YRQ?WWlmzt6G2
zw$kjLM4r!kDjKpo$9>d0-d!}uhs~75w(bHg6@?Nwh!~*ajJSbPNwbT*3f+gt919jz
z$Z(ona;lW?0V?(pNW{gM$wLTaIS!?SEW;=ecqni@z2z8`l!UAZ&0zUrsWsmkPzqXh
z*%p=3><}TI!g1wtIbIgy*dOFzDwPU31R+K>V!@b8j7rQ6w$~Um6qvs45gWT8WHkEm
zC`q%_)1?p`FP~o_c7x?a(Ufr&!{cC_=Nu=DYf(EO1@w;_t7-?uF%NMC6yQ<cr1cos
zUIWwIeb`W_NWD>Z`!+3#F`{8})Il!EX=#>ziCea%@M1>QbU7nvSxJ{5%s?@rQAyQ>
zEYu*Zajb?-3eBR(C#7sshY;#gQphxC+ck+-)ufnJ#Tqu}2E=epRI_VSyUSSdgIGoN
zkwLIu#CW9E0X;*Q;9v-QK<$;mjy<+(;d1b4Se~V5HRRg|k(Kqa0~YhE*sIv*rT>b1
z32XhIoN?3{E^Ll}HB0S?c3`+&X?-fJ3=eYY#Q1bH&XxYUOvmcaoYr2f-0PoTSZJ+J
zGaKuFVj6^FlarIb%*@=_c<offl__vP^D+Rfmu6?npH+9yD5o}m%``PNmBebKF#qJ%
zwr}PRFLb?o`wG|fbgrw;O`ZPatR9U<r+E2BU)xQvuUdEVLEBd+HjQdmH|(hH-!gr<
z+Sf6Ag+FlTSN+W9@AgUu?sylUrsSi4bUlxpeCF-_aZPc)@rz)Bzwqs$H?Lnl-1+nE
zZNlC5ogI&|9~C0kBj>)K9Pawz@pRkY`;PY=8`;oyq>edy=*0QyXoDR7Dsp<a_FHEE
F#Cyajgunm*
diff --git a/plugins/kimchi/ui/images/theme-default/ac24_resume.png
b/plugins/kimchi/ui/images/theme-default/ac24_resume.png
deleted file mode 100644
index 6f1f16f52f2c000a7413e22a0105c5d0b09c7a2b..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001
literal 1341
zcmeAS@N?(olHy`uVBq!ia0vp^Qa~)h!3HFsG`&3vq$EpRBT9nv(@M${i&7aJQ}UBi
z6+Ckj(^G>|6H_V+Po~;1FfgZOhD4M^`1)8S=jZArg4F0$<Q4#RGcefLR}>^BXQ!4Z
zB&DWj=GiK}-@RW+Av48RDcsc8z_-9TH6zobswg$M$}c3jDm&RSMakYy!KT6rXh3di
zNuokUZcbjYRfVk**jy_h8zii+qySb@l5ML5aa4qFfP!;=QL2Kep0RGSfuW&-nVFuU
ziK&^Hp^k!)fuWJU0T7w#8k$&{npqi{D?ot~(6*wKG^-#NH>h1eo~=?wNlAf~zJ7Um
zxn8-kUVc%!zM-Y1CCCgTBVC{h-Qvo;lEez#ykcdT2`;I{$wiq3C7Jno3Lp~`lk!VT
zY?Xj6g?J&iz}FXUa9%MqpnyT9Uy)d#Z>VRWpPLKv7g%+1Nl+@n8CX>phg24%>IbD3
z=a&{G1LGr28KxN+cK9s<DFnL4%D*TR7%7Q4F8Rr&xv6<2o-VdZKpDN1%oHmVGXql#
zXG>!vb2k%L6GKBMLt|4HCnFbUS0gt=7ehms8QAn18<-kc7?=Qc8Ua<hnpheen>)I>
zSh!jkI9dYZ2Bz0Duec;JFF6%vZzj-Qs9rO?daay`QWHz^i$e1Ab6_bTAS1sdzc?em
zK*2fKOhF?&GcP5-yjT+yJrLizq!wkCrKY$Q<>xAZ!`CVki~T0%g!~QBn?g>Q=>r|3
z4@w+Ji3KJEOo1RKJm~{D@XV8%2h1@=z^w7aYe@nF17ohIi(^Q|tu52`dL3~PIG%1+
z{qdYj)BS{nN)a4Uzgfz@U5|{==-~Rr(X?J+hS&Y0>>I9~a|+n7!)e0@qjPDSCqysa
zelqu;f#OV^&$nmJ^%d*n=n)W<QMqBXLNn7=f3xbe`~%;@s_sSHJo4k~OgVK%Rrc$T
zR+%%`o}PbiUixvh#eaiq9=uWhwou#SM&C=8Uq&o5x)^q~e*7C)>7$^?RXt(u(xzEy
zOPU;}B=89}ep{<6u&4Nh>w+5DRCa}Vt_$zQ-(mgo)$`M{6pJ-XGfMySzIu_fqb8xM
zIo&>rjjbj2?e)nA^GjETTIn!NmEN#PGO#~*Y439ez4xkDnXXRN&Pke}eTMr4>oZ;x
zKDC3Jd3;tjEd1V+bK{)Y%G$QIDJfg_xop@z_u<1l?(CE;R_hhlnjVf9c&{M6XkYI=
z$N!Fd8jm^dX^2q>UEnA^L2H7Q^pY(86$;1V><mnqe;9lYxu>o-;m`U@4@9nbC@(Pk
bs(gUqpHO<9rrQcmP=V&@>gTe~DWM4fDsR{!
diff --git a/plugins/kimchi/ui/images/theme-default/ac24_resume_grey.png
b/plugins/kimchi/ui/images/theme-default/ac24_resume_grey.png
deleted file mode 100644
index 1714ba2d00294e99222f833b8cf5e33da31448f9..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001
literal 1282
zcmeAS@N?(olHy`uVBq!ia0vp^Qa~)h!3HFsG`&3vq$EpRBT9nv(@M${i&7aJQ}UBi
z6+Ckj(^G>|6H_V+Po~;1FfgZOhD4M^`1)8S=jZArg4F0$<Q4#RGcefLR}>^BXQ!4Z
zB&DWj=GiK}-@RW+Av48RDcsc8z_-9TH6zobswg$M$}c3jDm&RSMakYy!KT6rXh3di
zNuokUZcbjYRfVk**jy_h8zii+qySb@l5ML5aa4qFfP!;=QL2Kep0RGSfuW&-nVFuU
ziK&^Hp^k!)fuWJU0T7w#8k$&{npqi{D?ot~(6*wKG^-#NH>h1eo~=?wNlAf~zJ7Um
zxn8-kUVc%!zM-Y1CCCgTBVC{h-Qvo;lEez#ykcdT2`;I{$wiq3C7Jno3Lp~`lk!VT
zY?Xj6g?J&iz}FXUa9%MqpnyT9Uy)d#Z>VRWpPLKv7g%+1Nl+@n8CX>phg24%>IbD3
z=a&{G1LGr28KxN+cK9s<DFnL4%D*TR7%7Q4F8Rr&xv6<2o-VdZKpDN1%oHmVGXql#
zXG>!vb2k%L6GKBMLt|4HCnFbUS0gt=7ehms8QAn1xSBb;n7f#|S-2V*8oHV|I=Y#<
zS~!~;n_HL~7+4y?^m^tMmn7yTr^4*b1lkMLYl2s=m2**QVo82cNPd0}ECmE)<d@_Z
zXXF<sI0u_4XoP3xrR0|vYl5N&;#-&0qRg_?6t|-MTm^9WT4iFf-^84dzae^4$O$uj
zpkwqwi32IIz=VJ)5X6KheIN&(c~bL$Ii?7hH7ag6?Pg$LH1c$D45_%aXWGTy76pMe
z#*54EzIj}xurI?=?19(<x7iySHaBM<W7^hSeW!Y#j`idYMV)ys4*D7$JRonE*5IhM
zRONpX$ECYRU+uDc`!t~V)3Qvv1uJ>(TJRk9Wv+EDZnJyEl{9T%m!aDtjZ3lzucwwy
zndkU9=XRJJn_^3`-z1gDJsMmxyH<Q*>Nrw(reMu$E6&J{ZI{m9FXEiM!sA2qLEql4
zs%w7|zTdl|J2^M+!yb)}zAv@<{Ec(`CoA{--l4?RW_EbR_l}&24;eYxZZ#R+pPI&d
z%xQ`#>*>!j(GTAm-0<OWJhe&0QQ7NqNc)}Uh8%(S3rsu0FXRj4E66fk{VliT+D?am
zJVmW*?k+Ywy~(S-d0FN!6W0ZWZ4v(^pOtgWf7`vVwxRwd<J#Omaudp{ISm*X#7kc9
TIKK2Js8sTF^>bP0l+XkKJo~{m
diff --git a/plugins/kimchi/ui/images/theme-default/arrow-down-black.png
b/plugins/kimchi/ui/images/theme-default/arrow-down-black.png
deleted file mode 100644
index 2c05f00498232213a081497051c94d16537daab8..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001
literal 2942
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
diff --git a/plugins/kimchi/ui/images/theme-default/arrow-down-disable.png
b/plugins/kimchi/ui/images/theme-default/arrow-down-disable.png
deleted file mode 100644
index 2d04c841780fa57153d4a73f3bee69824f6efb57..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001
literal 472
zcmV;}0Vn>6P)<h;3K|Lk000e1NJLTq000sI000sQ1^@s6R?d!B00004b3#c}2nYxW
zd<bNS0004xNkl<ZIE~%Wzi-W99L4e1`D&V|3LS(5xxKfOSt3TG2s0reX(TMQ_!VNZ
zh#xUYy4w5!VnqmI7D4*Gx9xXeu`;OkG58Xc5{txVd6FmRyg%nW5C821>bed}RaJVu
z-XEK1W@bjQKFOP^uIrRiwwF?NFD@>w`cp_<*TXo4o7h=lGtOZe`|G;?Ev(<~594T(
zsU*8_bqJG5_F)J&FwyV#r}1`TV&Z3z5gcomk6{7tsw5ARJWBF0$yk!pxP+}gLS|=Y
zD@@`{k_|}~lH5)*RpB8{;0~6s7Kd?pFc^G=4F-d%l(IL;xg?vCXak&2@+z$eMsNj(
zunvoOf(uEWmQoJlV*92Gcz`2#-Rt!}fB!epM{yie-&A{vTWzIrd}!03$IEWF3*UoU
z*c$A?b!=&`-(z*FzuPW)(d~B27vC}v%+1XOJ8-Q%hub=j+dA{(<Ky3XehPy5`T1ZQ
zPT~OW;VhnaI-O<uUxJ`%8l{wtE$BX;bvm7;l{_m>(==7nG=J^?H}eT{w|+~olSG{W
O0000<MNUMnLSTa0@YLi0
diff --git a/plugins/kimchi/ui/images/theme-default/arrow-down.png
b/plugins/kimchi/ui/images/theme-default/arrow-down.png
deleted file mode 100644
index 3f5239bbb93ad8660f47d3def443e42b8f57c6e6..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001
literal 537
zcmV+!0_OdRP)<h;3K|Lk000e1NJLTq000sI000sQ1^@s6R?d!B00004b3#c}2nYxW
zd<bNS0005dNkl<ZIE~$sze^Nw7>A$d6~#>G7g3=>Q#G^&cL#z*Q$%}FLnMWF=;0ky
z&|yo<#f2xjw6^sJL}L+>rbk<lQf`6m4I+8ox1kd>!=xqXGrqjf!~62S@ZUy&d_HeP
zq|VMxrlzL$3=a<v_W}piuaVE^O(~t<*x0zVwzk%>S4p8z=mPEn&wyM2ed+_?sd}|g
zDEv`2GBVPo-j0Z3L|jmxbYwD_l6og14yzZ{&P*orF`Lb<HX4l`lF`x89-yE;RF9}l
zbve`-b+%nN6cP8-Dsb{wNx57Obtoe4t4Gy!^@UpO$Y!%&)b|n5ubx)BBjTLem&@fE
z3kwV107|7&q?E1zkJS?@?IFtQCjrLB#sGR!N;UNca6sJv-T~w4LQ3g6@CfJw)`1z|
zW~<d&nVz2hdHyY<_X2sKxVf6T1Uv_ZQc9<Q@4!o-0xV5VP6BKfwPpJw;xbSN`rGAI
zU|+lcHBd|`E!OMxw8`x__5A$&`oO@zVnocUXCvZxM07_)Q+=!60+uHxCbn_E{h7JB
zIR*y@SJZj6S3RS?Qp*wXxmK&~V0NswHRI#sG@H$1z%}5F`k`8_wsvE7O{G$aN~QAG
b{J+T$+X03p_V~Q~00000NkvXXu0mjf`lS0g
diff --git a/plugins/kimchi/ui/images/theme-default/arrow-up.png
b/plugins/kimchi/ui/images/theme-default/arrow-up.png
deleted file mode 100644
index 40ce708941a35d8e1578e3cafb13d330fcf37c10..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001
literal 510
zcmV<a0RjGrP)<h;3K|Lk000e1NJLTq000sI000sQ1^@s6R?d!B00004b3#c}2nYxW
zd<bNS0005CNkl<ZIE~$rJ!?~O6vlt&78gOQf)-b$iZ2KSmn<r{=pcRoKR^>nFL|-K
z<P!wcpd?CfHn&cG04E2BSc>ALR0_q4C<tzXLwz0xuM%P+9mQw+bI$X7&N+YhZxw$l
zw%cuhqd)?D=yW<$dy{E}EXzXDIorAIN0Jt@ESnlU6=eH_?XILNk}lfr+Foe2S`+*K
zNN6^jGZAqXSOrdwgb8>L+_1gY?RIxYeKVtvMx(I@xN7?WaJqnO0H1(4;DGH5z`IhZ
zv^5+KzfWAv_T^%QGm=8mhNNXlHA$}}Vf&cvySA^_>-FFM07%nxFK`XWfmt9TVjW16
zBv}KHbRM`}OccO3AO%)?z24WTR;&AgMW7iGM~Z-T;AX$ye=$07nx?00KLjoTVfzbk
z2gnoK%eGs#=OiKNne7_za{MEDz1|z!4M|TW+4iBrpCyv!CC%!mp4eWr{k-4rdmL2U
z@s;he?Z=XKB<+(lALVlSxb1s@BVsAf^X*B1aaAgn!;<a;2P2}E09!x<ShBq<2*Aq9
z%4gsfPy;rTJkJGe0^5VZV7HuK`Ut!&82^}l07Tsjb=)@&!~g&Q07*qoM6N<$f&;VO
AtpET3
diff --git a/plugins/kimchi/ui/images/theme-default/arrow_out.png
b/plugins/kimchi/ui/images/theme-default/arrow_out.png
deleted file mode 100644
index f5b4b8ed7de68dc79673472aab7c9672233bc8a7..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001
literal 3048
zcmV<E3m5c>P)<h;3K|Lk000e1NJLTq000jF003YJ1^@s6!gMIb00009a7bBm000XU
z000XU0RWnu7ytkYPiaF#P*7-ZbZ>KLZ*U+<Lqi~Na&Km7Y-Iodc-oy)XH-+^7Crag
z^g>IBfRsybQWXdwQbLP>6p<z>Aqfylh#{fb6;Z(vMMVS~$e@S=j*ftg6;Uh<iVD~V
z<RPMtgQJLw%KPDaqifc@_vX$1wbwr9tn;0-&j-K=43<bUQ8j=JsX`tR;Dg7+#^K~H
zK!FM*Z~zbpvt%K2{UZSY_<lS*D<Z%Lz5oGu(+dayz)hRLFdT>f59&ghTmgWD0l;*T
zI7<kC6aYYajzXpYKt=(8otP$50H6c_V9R4-;{Z@C0AMG7=F<Rxo%or10RUT+Ar%3j
zkpLhQWr#!oXgdI`&sK^>09Y^p6lP1rIRMx#05C~cW=H_Aw*bJ-5DT&Z2n+x)QHX^p
z00esgV8|mQcmRZ%02D^@S3L16t`O%c004NIvOKvYIYoh62rY33S640`D9%Y2D-<?i
z0%4j!F2Z@488U%158(66005wo6%pWr^Zj_v4zAA5HjcIqUoGmt2LB>rV&neh&#Q1i
z007~1e$oCcFS8neI|hJl{-P!B1ZZ9hpmq0)X0i`JwE&>$+E?>%_<lS*MWK+n+1cgf
z<k(8YLR(?VSAG6x!e78w{cQPuJpA|d;J)G{fihizM+Erb!p!tcr5w+a34~(Y=8s4G
zw+sLL9n&JjNn*KJDiq^U5^;`1nvC-@r6P$!k}1U{(*I=Q-z@tBKHoI}uxdU5dyy@u
zU1J0GOD7Ombim^G008p4Z^6_k2m^p<gW=D2|L;HjN1!DDfM!XOaR2~bL?kX$%CkSm
z2mk;?pn)o|K^yeJ7%adB9Ki+L!3+FgHiSYX#KJ-lLJDMn9CBbOtb#%)hRv`YDqt_v
zKpix|QD}yfa1JiQRk#j4a1Z)n2%f<xynzV>LC6RbVIkUx0b+_+BaR3cnT7Zv!AJxW
zizFb)h!jyGOOZ85F;a?DAXP{m@;!0_Ifq<Ex{*7`05XF7hP+2Hl!3BQJ=6@fL%FCo
z8iYoo3(#bAF`ADSpqtQgv>H8(HlgRxt7s3}k3K`kFu>>-2Q$QMFfPW!La{h336o>X
zu_CMttHv6zR;&ZNiS=X8v3CR#fknUxHUxJ<AYmRsNLWl*PS{AOARHt#5!wki2?K;t
z!Y3k=s7tgax)J%r7-BLphge7~Bi0g+6E6^Zh(p9TBoc{3GAFr^0!gu?RMHaCM$&Fl
zBk3%un>0uoBa_M6WNWeqIg~6QE69c9o#eyhGvpiOA@W-aonk<7r1(?fC{oI5N*U!4
z<uv66WtcKSRim0x-Ke2d5jBrmLam{;Qm;{ms1r1GnmNsb7D-E`t)i9F8fX`2_i3-_
zbh;7Ul^#x)&{xvS=|||7=mYe33=M`AgU5(xC>fg=2N-7=cNnjjOr{yriy6mMFgG#l
znCF=fnQv8CDz++o6_Lscl}eQ+l^ZHARH>?_s@|##Rr6KLRFA1%Q+=*RRWnoLsR`7U
zt5vF<Q0r40Q)j6=sE4X&sBct1q<&fbi3VB2Ov6t@q*0);U*o*SAPZv|vv@2aYYnT0
zb%8a+Cb7-ge0D0knEf5Qi#@8Tp*ce{N;6lpQuCB%KL_KOarm5cP6_8Ir<e17iry6O
zDdH&`rZh~sF=bq9s+O0QSgS~@QL9Jmy*94xr=6y~MY~!1fet~(N+(<=M`w@D1)b+p
z*;C!83a1uLJv#NSE~;y#8=<>IcfW3@?wFpwUVxrVZ>QdQz32KIeJ}k~{cZZE^+ya?
z2D1z#2HOnI7(B%_ac?{wFUQ;QQA1tBKtrWrm0_3Rgps+?Jfqb{jYbcQX~taRB;#$y
zZN{S}1|}gUOHJxc?wV3fxuz+mJ4`!F$IZ;mqRrNsHJd##*D~ju=bP7?-?v~|cv>vB
zsJ6IeNwVZxrdjT`yl#bBIa#GxRa#xMMy;K#CDyyGyQdMSxlWT#tDe?p!?5wT$+oGt
z8L;Kp2HUQ-ZMJ=3XJQv;x5ci*?vuTfeY$;({XGW_huIFR9a<fJbF^|4I#xQ~n$Dc=
zKYhjYmgz5NSkDm8*fZm{6U!;YX`NG>(?@3)XSs8O^N5RyOM=TTmp(3=8^+zpz2r)C
z^>JO{deZfso3oq3?Wo(Y?l$ge?uXo;%ru`Vo>?<<(8I_>;8Eq#KMS9gFl*neeosSB
zfoHYnBQIkwkyowPu(zdms`p{<7e4kra-ZWq<2*OsGTvEV%s0Td$hXT+!*8Bnh2KMe
zBmZRodjHV?r+_5^X9J0WL4jKW`}lf%A-|44I@@LTvf1rHjG(ze6+w@Jt%Bvjts!X0
z?2xS?_ve_-k<Mujg;0Lz*3buG=3$G&ehepthlN*$KaOySSQ^nWmo<0M+(UEUMEXRQ
zMBbZcF;6+KElM>iKB_KiJlZ$9G`c^=E@oNG)mWWaNo-3TIW8)$Hg0Ub-~8?KhvJ>$
z3*&nim@mj(aCxE5!t{lw7O5^0EIO7zOo&c6l<+|iDySBWCGrz@C5{St!X3hAA}`T4
z(TLbXTq+(;@<=L8dXnssyft|w#WSTW<++3>sgS%(4NTpeI-VAqb|7ssJvzNHgOZVu
zaYCvgO_R1~>SyL=cFU|~g|hy|Zi}}s9+d~lYqOB71z9Z$wnC=pR9Yz4DhIM>Wmjgu
z&56o6maCpC&F##y%G;1PobR9i?GnNg;gYtchD%p19a!eQtZF&3JaKv33gZ<8D~47E
ztUS1iwkmDaPpj=$m#%)jCVEY4fnLGNg2A-`YwHVD3gv};>)hAvT~AmqS>Lr``i7kw
zJ{5_It`yrBmlc25DBO7E8;5VoznR>Ww5hAaxn$2~(q`%A-YuS64wkBy=9dm`4cXeX
z4c}I@?e+FW+b@^RDBHV(wnMq2zdX3SWv9u`%{xC-q*U}&`cyXV(%rRT*Z6MH?i+i&
z_B8C(+grT%{XWUQ+f@NoP1R=AW&26{v-dx)iK^-Nmiuj8txj!m?Z*Ss1N{dh4z}01
z)YTo*JycSU)+_5r4#yw9{+;i4Ee$peRgIj+;v;ZGdF1K$3E%e~4LaI(jC-u%2h$&R
z9cLXcYC@Xwnns&bn)_Q~Te?roKGD|d-g^8;+aC{{G(1^(O7m37Y1-+6)01cN&y1aw
zoqc{T`P^XJqPBbIW6s}d4{z_f5Om?vMgNQEJG?v2T=KYd^0M3I6IZxbny)%vZR&LD
zJpPl@Psh8QyPB@KTx+@RdcC!KX7}kEo;S|j^u2lU7XQ}Oo;f|;z4Ll+_r>@1-xl3|
zawq-H%e&ckC+@AhPrP6BK<z=<L*0kfKU@CX*zeqbYQT4(^U>T#_XdT7&;F71j}Joy
zkC~6lh7E@6o;W@^IpRNZ{ptLtL(gQ-CY~4mqW;US7Zxvm_|@yz&e53Bp_lTPlfP|z
zrTyx_>lv@x#=^!PzR7qqF<$gm`|ZJZ+;<)Cqu&ot<a{81DF0~rvGr5Xr~8u`lav1h
z1DNytV>2z=0000WV@Og>004R=004l4008;_004mL004C`008P>0026e000+nl3&F}
z0003KNkl<Zc-rjPy=ucS6o%nfjYQFsL4y`Up|{ngV{Xx_Z@^RUpit=64z(dod%7qP
zJC1#vLWgn$#=`RR`A^nxoQQC3yWtnjA3M&uSh@$`3;3RcA~LvgsO!1|0<h8C)!+p0
zJx$Ym6ucO4Iw&zla?Z4E+iL;_10e)bN>o*)3OGCHy;lcJCTasNK943~_H9lCNZE8V
zY!vV*B6lJZ2Qy3)kaK<jD&P(1)pOf>zXLkp73kOe7`uX=fM@62UW+H82493{b9)UO
z<HH&_{#1K_l+q*cz61f>$r`o=?#upV35v)7-vY;_sGEaR_-|KF!-fqTHf-3iVZ(+E
q|3_?f604I~oy6)SRwucp{R{vP7|{U{#BK5b0000<MNUMnLSTa7ET*pj
diff --git a/plugins/kimchi/ui/images/theme-default/group.png
b/plugins/kimchi/ui/images/theme-default/group.png
deleted file mode 100644
index 1160bd97178375f202c3c20fef689ddf4a6dcfae..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001
literal 1703
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
diff --git a/plugins/kimchi/ui/images/theme-default/host-icon-sprite.png
b/plugins/kimchi/ui/images/theme-default/host-icon-sprite.png
deleted file mode 100644
index da1cd3f2562a5905a526446bcc8fc18bea06c734..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001
literal 1034
zcmV+l1oiugP)<h;3K|Lk000e1NJLTq003?P000^Y1^@s6R_JLg00006VoOIv0RI60
z0RN!9r;`8x010qNS#tmY3ljhU3ljkVnw%H_000McNliru-3t>283nlSO%wnC03B&m
zSad^gZEa<4bN~PV002XBWnpw>WFU8GbZ8()Nlj2>E@cM*00VAGL_t(&-tAexPZU8E
z{`PW&1_K4^OH?eZvAftnL5(5A#KOeLoryLc6xvbn7idfrLqY*-qLqe%L|Ypgg$i36
z(dbjkBSwPpvl)`j+}`fa-u^(2muzw~^LF01^X{8@Zysm_jzUN2Fh`A~Pjc5hKFL~I
z+Z}W#NVXC{Y>}KuY7;pNNspw5tO0f7IFeP8D-r4|QCJ)u*CII!fKd<0S(2@?9Y=DD
z<R_9!@=PZG-V7bLl9r_@9LG4P1)Rq+9Y?Z{<af)|`7qr|9MBxV)c`acbbCfT&pQC{
z%j$mX<hUFic+YA-2XN6mak_;`9K$+|XK?mUTkTPj&CIsEF5cU<hDHKoBi7iJvbM^i
z*Tus8!czN9a>$8s1<N-8RRC8_`$GnE?vb2Jz_2+0dq-p)ngI3#?S24@sTh|bQ+;d5
zH%uEL`5>TIAzA4bYua?6Ovagcnjz|Ai5Da5sM6$aQ8E^l$E3xZb^24#IlFC{{Sv!X
zdPZ`HoHhZhMyRZj95%WP!xe@3m<5`5?4yL_;89M%??>JmIN;83>nfaa#_lVU`y{Vr
z67H9I<>i9?7&xxqKI>29L{6meTNYI%0Emdw!G8E&QVE-1Rcq#UWYToK0q{&jHq+Sd
zU}FNnI)H(=d=J2sh`dW;({;UEMO8gxC-hsZHn6+_8Cz8V%OQ7`GXQ2(brnD(BP{Cx
z=6&CP5~WnH*XNDysWO?Qs#^et%pdJCfS-x(Dpi%PY)T=^F&E8^3~dd>ISl}e&Opgd
z>jQ8Oz$E}@0sK%^x9UJ%4m8_i!$G%aL_`u-2dYWWvJAJ-u<F2q`TaRWw_eh}pDyEv
z>yyFRKMi0z&>mIQrid&iVqA_4oV3~tBC;bQJ7_QMEcIHnC?X#LytKL>s%r052kP~D
zY<0ls{5RDBFDZ*`N~hftRMj`pW7t-CT|^!ky^4A7udB@<*0kwB7vI-)nq=l_0(fe5
zkBi7gBF9Bcoc6<NF-#g4k&RAyOj^9%=3_<YamMC0fYCtLR}r}oxmAjYmj^hLTt`+1
zRCTyh@)?Dxh{Y^e+NuMpIv5&N7WDCVBl5M=0B!+z9Oa;-3`iRt9+5!hy{f(jFa_X-
zh^)1x14RNBkv{-#tLjpkD=*u5$B=13xe4GPc-8~JKL<=Y@!??g0{{R307*qoM6N<$
Ef;%S0RsaA1
diff --git a/plugins/kimchi/ui/images/theme-default/icon-back.png
b/plugins/kimchi/ui/images/theme-default/icon-back.png
deleted file mode 100644
index eca9948ca7f0c4eaa3c36d20e4fb2d72ac79b2d8..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001
literal 244
zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=ffJ-JULvArbCxuSRn<C<w3y#71eK
zT)K72v}tTjuGj8VdL~>5@BMC(b=2TTSM%q?EFRVyo~rsxN}a;s^<!54Nr^X)q~g@x
z^JN^q%lN$@{6O#y=>_6_at*5DZ*m1wnKN6b$4D%Y<YV4)Sh2y?LNY=0pS;7ws8U8N
zRxu8ago~UK3wje6O$2ieNH=}5eE-k*!lQ-zA6s=>GtE7+RQk>%v4gUYTRgh7os8Nz
s0?gB1y)!t(JaL}EzvtS*278#<8D&)ztBkXBf!<*7boFyt=akR{0KU{)8UO$Q
diff --git a/plugins/kimchi/ui/images/theme-default/icon-camera.png
b/plugins/kimchi/ui/images/theme-default/icon-camera.png
deleted file mode 100644
index f181545ed44db658aa6373c28ca33724f84a3d05..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001
literal 4860
zcmV<Y5(DjtP)<h;3K|Lk000e1NJLTq001oj001Be1^@s6hJ^7%00009a7bBm000XU
z000XU0RWnu7ytkYPiaF#P*7-ZbZ>KLZ*U+<Lqi~Na&Km7Y-Iodc-oy)XH-+^7Crag
z^g>IBfRsybQWXdwQbLP>6p<z>Aqfylh#{fb6;Z(vMMVS~$e@S=j*ftg6;Uh<iVD~V
z<RPMtgQJLw%KPDaqifc@_vX$1wbwr9tn;0-&j-K=43<bUQ8j=JsX`tR;Dg7+#^K~H
zK!FM*Z~zbpvt%K2{UZSY_<lS*D<Z%Lz5oGu(+dayz)hRLFdT>f59&ghTmgWD0l;*T
zI7<kC6aYYajzXpYKt=(8otP$50H6c_V9R4-;{Z@C0AMG7=F<Rxo%or10RUT+Ar%3j
zkpLhQWr#!oXgdI`&sK^>09Y^p6lP1rIRMx#05C~cW=H_Aw*bJ-5DT&Z2n+x)QHX^p
z00esgV8|mQcmRZ%02D^@S3L16t`O%c004NIvOKvYIYoh62rY33S640`D9%Y2D-<?i
z0%4j!F2Z@488U%158(66005wo6%pWr^Zj_v4zAA5HjcIqUoGmt2LB>rV&neh&#Q1i
z007~1e$oCcFS8neI|hJl{-P!B1ZZ9hpmq0)X0i`JwE&>$+E?>%_<lS*MWK+n+1cgf
z<k(8YLR(?VSAG6x!e78w{cQPuJpA|d;J)G{fihizM+Erb!p!tcr5w+a34~(Y=8s4G
zw+sLL9n&JjNn*KJDiq^U5^;`1nvC-@r6P$!k}1U{(*I=Q-z@tBKHoI}uxdU5dyy@u
zU1J0GOD7Ombim^G008p4Z^6_k2m^p<gW=D2|L;HjN1!DDfM!XOaR2~bL?kX$%CkSm
z2mk;?pn)o|K^yeJ7%adB9Ki+L!3+FgHiSYX#KJ-lLJDMn9CBbOtb#%)hRv`YDqt_v
zKpix|QD}yfa1JiQRk#j4a1Z)n2%f<xynzV>LC6RbVIkUx0b+_+BaR3cnT7Zv!AJxW
zizFb)h!jyGOOZ85F;a?DAXP{m@;!0_Ifq<Ex{*7`05XF7hP+2Hl!3BQJ=6@fL%FCo
z8iYoo3(#bAF`ADSpqtQgv>H8(HlgRxt7s3}k3K`kFu>>-2Q$QMFfPW!La{h336o>X
zu_CMttHv6zR;&ZNiS=X8v3CR#fknUxHUxJ<AYmRsNLWl*PS{AOARHt#5!wki2?K;t
z!Y3k=s7tgax)J%r7-BLphge7~Bi0g+6E6^Zh(p9TBoc{3GAFr^0!gu?RMHaCM$&Fl
zBk3%un>0uoBa_M6WNWeqIg~6QE69c9o#eyhGvpiOA@W-aonk<7r1(?fC{oI5N*U!4
z<uv66WtcKSRim0x-Ke2d5jBrmLam{;Qm;{ms1r1GnmNsb7D-E`t)i9F8fX`2_i3-_
zbh;7Ul^#x)&{xvS=|||7=mYe33=M`AgU5(xC>fg=2N-7=cNnjjOr{yriy6mMFgG#l
znCF=fnQv8CDz++o6_Lscl}eQ+l^ZHARH>?_s@|##Rr6KLRFA1%Q+=*RRWnoLsR`7U
zt5vF<Q0r40Q)j6=sE4X&sBct1q<&fbi3VB2Ov6t@q*0);U*o*SAPZv|vv@2aYYnT0
zb%8a+Cb7-ge0D0knEf5Qi#@8Tp*ce{N;6lpQuCB%KL_KOarm5cP6_8Ir<e17iry6O
zDdH&`rZh~sF=bq9s+O0QSgS~@QL9Jmy*94xr=6y~MY~!1fet~(N+(<=M`w@D1)b+p
z*;C!83a1uLJv#NSE~;y#8=<>IcfW3@?wFpwUVxrVZ>QdQz32KIeJ}k~{cZZE^+ya?
z2D1z#2HOnI7(B%_ac?{wFUQ;QQA1tBKtrWrm0_3Rgps+?Jfqb{jYbcQX~taRB;#$y
zZN{S}1|}gUOHJxc?wV3fxuz+mJ4`!F$IZ;mqRrNsHJd##*D~ju=bP7?-?v~|cv>vB
zsJ6IeNwVZxrdjT`yl#bBIa#GxRa#xMMy;K#CDyyGyQdMSxlWT#tDe?p!?5wT$+oGt
z8L;Kp2HUQ-ZMJ=3XJQv;x5ci*?vuTfeY$;({XGW_huIFR9a<fJbF^|4I#xQ~n$Dc=
zKYhjYmgz5NSkDm8*fZm{6U!;YX`NG>(?@3)XSs8O^N5RyOM=TTmp(3=8^+zpz2r)C
z^>JO{deZfso3oq3?Wo(Y?l$ge?uXo;%ru`Vo>?<<(8I_>;8Eq#KMS9gFl*neeosSB
zfoHYnBQIkwkyowPu(zdms`p{<7e4kra-ZWq<2*OsGTvEV%s0Td$hXT+!*8Bnh2KMe
zBmZRodjHV?r+_5^X9J0WL4jKW`}lf%A-|44I@@LTvf1rHjG(ze6+w@Jt%Bvjts!X0
z?2xS?_ve_-k<Mujg;0Lz*3buG=3$G&ehepthlN*$KaOySSQ^nWmo<0M+(UEUMEXRQ
zMBbZcF;6+KElM>iKB_KiJlZ$9G`c^=E@oNG)mWWaNo-3TIW8)$Hg0Ub-~8?KhvJ>$
z3*&nim@mj(aCxE5!t{lw7O5^0EIO7zOo&c6l<+|iDySBWCGrz@C5{St!X3hAA}`T4
z(TLbXTq+(;@<=L8dXnssyft|w#WSTW<++3>sgS%(4NTpeI-VAqb|7ssJvzNHgOZVu
zaYCvgO_R1~>SyL=cFU|~g|hy|Zi}}s9+d~lYqOB71z9Z$wnC=pR9Yz4DhIM>Wmjgu
z&56o6maCpC&F##y%G;1PobR9i?GnNg;gYtchD%p19a!eQtZF&3JaKv33gZ<8D~47E
ztUS1iwkmDaPpj=$m#%)jCVEY4fnLGNg2A-`YwHVD3gv};>)hAvT~AmqS>Lr``i7kw
zJ{5_It`yrBmlc25DBO7E8;5VoznR>Ww5hAaxn$2~(q`%A-YuS64wkBy=9dm`4cXeX
z4c}I@?e+FW+b@^RDBHV(wnMq2zdX3SWv9u`%{xC-q*U}&`cyXV(%rRT*Z6MH?i+i&
z_B8C(+grT%{XWUQ+f@NoP1R=AW&26{v-dx)iK^-Nmiuj8txj!m?Z*Ss1N{dh4z}01
z)YTo*JycSU)+_5r4#yw9{+;i4Ee$peRgIj+;v;ZGdF1K$3E%e~4LaI(jC-u%2h$&R
z9cLXcYC@Xwnns&bn)_Q~Te?roKGD|d-g^8;+aC{{G(1^(O7m37Y1-+6)01cN&y1aw
zoqc{T`P^XJqPBbIW6s}d4{z_f5Om?vMgNQEJG?v2T=KYd^0M3I6IZxbny)%vZR&LD
zJpPl@Psh8QyPB@KTx+@RdcC!KX7}kEo;S|j^u2lU7XQ}Oo;f|;z4Ll+_r>@1-xl3|
zawq-H%e&ckC+@AhPrP6BK<z=<L*0kfKU@CX*zeqbYQT4(^U>T#_XdT7&;F71j}Joy
zkC~6lh7E@6o;W@^IpRNZ{ptLtL(gQ-CY~4mqW;US7Zxvm_|@yz&e53Bp_lTPlfP|z
zrTyx_>lv@x#=^!PzR7qqF<$gm`|ZJZ+;<)Cqu&ot<a{81DF0~rvGr5Xr~8u`lav1h
z1DNytV>2z=0000WV@Og>004R=004l4008;_004mL004C`008P>0026e000+nl3&F}
z000OlNkl<Zc-quhU2GM{75>hdnVq|LuT8-}*kHi?*lw|mkwt_|3oTMnkQzm$YEVU^
z76l|K+A2mWlEo8M+b4Kv6jjPYr55D{TBSmLX{AVQ`cOg=g{F}bYQmo)XhX4$@x|Bs
zGdt6V%wAo<fRRz!9%&zT_v|^}oH_HIbC#TQ_<s`#07P`}a{|Bsl-F?pjK8eE7XX?7
zbOLDedKSPGfZJYY5rEHmT?1eozzqP?{vO^(1wh%`$N|&<%m7He&HF*mAq*e{umnKl
zKfLX))B_3tED=Ji)ms0Qhz9+)*PL^|1~B8C>tyC{0O<1XJ}}07D@l?&4S{I_(5aLf
zB%(5al!(T&EPKmZJLP@3xj>VTMgTzjt63>EAf@~!5s`E5N|t56GR905iz1?qAPAmk
z=0PbXm>JAGon_g{+1c5Ih*m45zAS|3VrBs7&-46%we}}jmK6(Mq_zHvlya1a0w17E
z2=V<|t@alm`Ltn|>!6k2#x?+ph^PWUF!MTQUMGY|0cdM&kF|CNK<J!vLWp)|ZVH0n
zkL7Z?*4*42#Bn^GB+2)rltG^7QYm$*R4QGGqDZ7^nx|>HBu&$ed7h_!Hw6)OF!N=l
zRF#=?0HrL;mJ1<z@;tBkl$!#O0LaNX2O??*uu>^Cq?CFNz#4B1N+}xzLC(x%j6s^F
zWQ-wy7KD`2hGCdQQDmi*aL&mr%fi{&SvJNvA;fGLh9(FCM?^5j=vu8twOY+(Sw;Ye
znW42#OQn*LQUU-QV^kc+NRs5bG3M1cj(=aIXA$YeK@e<}QobmJSS5r25rLTz1Ob8|
z05iiF17=2^=kSY#loCM@008nlujido3PK1lGl&S*+PmJBN+tM3-sMLK@#&#rhG(|5
zQpz4FW$DhHJFhtB>gl1Sl+Q{jS7@!FwT6_k4!m$IrG!!n&bc~hB0{mqI`w$nyXdIl
zJu}w<H$E%;6#9M#V2tTZ({yjOTKz46xUlS)xm#<^Q4~RIeV2hoQA*99Po>PmFieCH
z);VXbwG_v(%Cf99Upvk@SZh(KRF(l)4d8kK+6p1i80CeC*4nIJzkYnvrcM9exN+mZ
zT3cHu0nAQJOxSbh&P8X=oawrB>CzXHBx!w=ts>$|DfaZMWW&q6psj_-(xpqQd-m+P
zyl>yWzXSLXz}o;Wc<SodwryM2$jC_f`0?YbPoF;h%+%D>m*!*F<01f5fKHfMJfJ$x
zTb3_hK6Uiy(RYW3hu;M7G7*IU+QTsXA^=X)^kSap?*jP5IX5sgH1wy#hYuf)<M_Ep
z`Sl#$3_uj1?*OP0k@2V3H58pkinUg@w6x5OjEuZDJUsjdB6<bDK&4W78o*WnD*(ta
z3~yR%&!%bmOCq}HoC|mF-hJfc$&+1anhyKipDV992m<o8gbUCz%d#Kmd2V}qdn@H~
zSy^kH-xhiRP^Xj<-QC@t?d|RTy}iA>ef#!zi0BspHdQK>LjZOVQIim&pt3dA+NXpN
zLur~GBBJ-5bF-&To%&8oOUu?3D^@6Groy*B%-r7I-qzXKDFIvqFjEwl{^sW9mztWI
zI!mQeLPTyJr<#b!5s_+ZYrAsn*s<5PY}xWVB3ctg(IF!Gu9T9r)^+|RBIJ3FEXxqb
z@$0o(?fE20CYX6~M@Pqx!Z7?g5zWk%(nNIm!i5Wm0Mv>|3nJ<_#&o1<`q+7$B*|n?
zPtV6hB!eLMJP|#kl%jIETrVQU0e8+J&vPiHb};kKBuQR%&hgC53;^^!h`E?~nePTo
zp^*bfgb?+j@)+VaY}jzEt*wm#l!OpNLWrg?3{ftZp_IDMUQtN2)-Q~YkH0}gx3Vnz
zhqX3gW<3{!X{{ZA_Qv7@B0>-Z&{{thXlBlvnwoC<{ue~lp_EdMRdp`z6+$2k!)0+C
zuLLk|t(_sFNu^ZhT+!BAlW*+!F3<&$KMrUjqKS!#qG?Z<xhkc!Qc8Xp=Mxdi<+4&r
zwfeTWWUVbVaPnL{{b}`H=;-5|6IZWZZS$aK0K6rHF!L!=eSLkO2q8*-YFX}_TWqbx
zqej35g9d=f$;sX$M~)ch9A{bfx^wP>M>*D7rw0xkI1k`55w$XN?|h5f69H|l-FV`}
zi48=Q1VM1a81o_#{qteK_wL>M{^re_&lAy@5Mm88Z!1#sQNW)FXl7odl=?vwMXRdS
zs<?6E#z(t$?HXOSY}r|6HjTR7-QBlGM@P>cJb3WW0FDFb3xeQTDdpPv_CE4Sfc6v4
zjwp&o<2e2q5#4moof#V&%g>)b|J2ynSU(Xp_x1H9gM))Ny1TpIB%+rAY$}(_JDK_0
zMX&yuf|gQ>FbrR4Zf*{yr>9>cqMHC-bIzRw(39u+A|b>CfH#O}1rcp6m&;!zq8~~r
zL#_2^3%Z~rt+k4xXfJ^EaUB09P1E;;5Yx`N>j173QN+wU!!TSag!meOr-cwQ3`2xr
zIPX5bKDp3BdeVjwD-1&du$h@RODQkrdHy#5w}>bQP$8l|0Go)2rIaX@N)N1@bGd2k
zr{jBnh%6wt>lH6al66^@tt$rMdnOSCL2zGh@(|n7_a60r`j&I<Z2+sDP=41ZY-0?J
zF(`@#GeZagrBq#SKAYUq(lQI61Hgv`=&6B$fuF~5ytZ1c4lOWK>X9xQuwr^|%>ViD
zaUoq@UDNyb@Bhe``-Hr)CIHI;Yy{Bn|KTb8_k|jMY<>*juK?aDKo|Ma=G(u>uj+q6
iasaacZWe!B|1$t|HV7wlk?hg{0000<MNUMnLSTY1+a*>2
diff --git a/plugins/kimchi/ui/images/theme-default/icon-design.png
b/plugins/kimchi/ui/images/theme-default/icon-design.png
deleted file mode 100644
index c8931dae58e4d3d95d7a1ebba04ed0481f4b74ff..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001
literal 4562
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
diff --git a/plugins/kimchi/ui/images/theme-default/icon-detail.png
b/plugins/kimchi/ui/images/theme-default/icon-detail.png
deleted file mode 100644
index 978df03ca7480d0f9ebb3b4f1a1f73226fcbe246..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001
literal 3079
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
Voc;M?!D;{i002ovPDHLkV1gS<wu1lw
diff --git a/plugins/kimchi/ui/images/theme-default/icon-iso.png
b/plugins/kimchi/ui/images/theme-default/icon-iso.png
deleted file mode 100644
index d76290427e75fd1c6ad914acde114e065760b30d..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001
literal 4188
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
diff --git a/plugins/kimchi/ui/images/theme-default/icon-list.png
b/plugins/kimchi/ui/images/theme-default/icon-list.png
deleted file mode 100644
index 7b3b595ffce5fab49dbd2588cebd113922b9dcbd..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001
literal 2983
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
diff --git a/plugins/kimchi/ui/images/theme-default/icon-load.png
b/plugins/kimchi/ui/images/theme-default/icon-load.png
deleted file mode 100644
index 2ad195ca84691697a63e720003fe48b1573590f9..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001
literal 3678
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
diff --git a/plugins/kimchi/ui/images/theme-default/icon-local.png
b/plugins/kimchi/ui/images/theme-default/icon-local.png
deleted file mode 100644
index 092026fbc9301b311d5e9bb8556450cd6fa93ff9..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001
literal 425
zcmV;a0apHrP)<h;3K|Lk000e1NJLTq001BW001Be1^@s6b9#F80004SNkl<ZSV!%a
z3vt3g5QaekH~<v14oDTWC}^snNB{>oAXQKt6bFEU4h~uc@P9LR3`t0`$1CkjcIF>Q
z*t`919|`SN&DO3teyag!GGNU>tY)1DHtd`Hld3fqfJmEsRc%!8`;+c3%hpx_Ji6dr
zeNLr`5o9L6cj-q0VqLVZ41l1V9EcBzGKAPd&d)A55WwWD41m-PrH%9=eL5Hm1ScLz
zKs-q71%w$Ok>{)QEA=H(%5{jb2W11MBXLb*rtDM(VtLT<1drSXA%U~LlyK#4<|ZQx
zKtSK|rZF;-`9tBJnv7$BY{yeSU}(lm%ufOkxykSV*^VE}`TGjNJva~pDUni>;Q^NV
z!FN1mI5{$xq`|G_pu{>%1^`eUcl@n_d;Y$@93}&R-4#xD_7?vNfKufiBn3yO<4teR
z&<t20%)x;V1vtCbMGG5%Kal|*JiIRJuq_#g+|#gkXM(Nb#Z~_aZ_d;J)SiJoPBKc^
Ts5X1J00000NkvXXu0mjf;iIrQ
diff --git a/plugins/kimchi/ui/images/theme-default/icon-power-down.png
b/plugins/kimchi/ui/images/theme-default/icon-power-down.png
deleted file mode 100644
index 2c653bc6af72f628cea721d618849d912c1aa186..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001
literal 4372
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
O0000<MNUMnLSTY^CsYvt
diff --git a/plugins/kimchi/ui/images/theme-default/icon-power-up.png
b/plugins/kimchi/ui/images/theme-default/icon-power-up.png
deleted file mode 100644
index a4575f90120e56d21d42dc4fbefcfc571a30ef71..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001
literal 4367
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
JPDHLkV1k37QX&8V
diff --git a/plugins/kimchi/ui/images/theme-default/icon-qcow2.png
b/plugins/kimchi/ui/images/theme-default/icon-qcow2.png
deleted file mode 100644
index a5220093e8143db08887f31decf8af059d654ba7..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001
literal 4684
zcmV-S60_}zP)<h;3K|Lk000e1NJLTq001Ze001Zm1^@s6jQ+T7000U_X+uL$Nkc;*
zP;zf(X>4Tx0C?J+Q)g6D=@vcr-t<CCh=7z!Z&DQqAW}k$fE1A?Dj^9FN{At$*%eX2
z5k*A=8_1xD1CEY>j1^HV42lZa2jn55j)S9!ipu-pd!uXCy!YnK{<YUW=dAOcv(E>>
z2n?1;Gf_2w45>mM5#WQz#Kz&|E<k|_Bya!_2(x4%bNwR$0Qi19JS!r=2fhFSc+(3A
z0KiR~z%U$#{}1XynOp&YgaN>GkvK~TfD`~gdX7S-06<0ofSs5oQvjd@0AR~wV&ec%
zEdXFAf9BHwfSvf6djSAjlpz%XppgI|6J>}*0BAb^tj|`8MF3bZ02F3R#5n-iEdVe{
zS7t~6u(trf&JYW-00;~KFj0twDF6g}0AR=?BX|IWnE(_<@>e|ZE3OddDgXd@nX){&
zBsoQaTL>+22Uk}v9w^R97b_GtVFF>AKrX_0nHe&HG!NkO%m4tOkrff(gY*4(&JM25
z&Nhy=4qq+mzXtyzVq)X|<<F~dKmY*YbbitPEHASffI9|&ZT_Mq?gVIF3!ruPi)OM9
zK(zp%>DpKGaQJ>aJVl|9x!Kv}<mA{nwP%2$2<XTo2=SN&}Hemwm5_29nZB!Mzr
zfky=R;KI!GOr;#pk_m)j+~$u*{I?7L{2kLG#7SbgSSl3bQ4(>EM4F8AGNmGkLXs)P
zCDQ+7;@>R$13uq10I+I40eg`xs9j?N_Dd%aSaiVR_W%I$yKlkNC<p_9XoKO;cmMA{
z{YRiB0Dxvml5qe4UPL4=RLZkI#|QubM4*8xut6L2!5A#S1{}c!+`$X{U^aw8B*el(
z5JC!MfE;pQDXfA*D2C0j9V%ci)Ic3Hz)@(1lW-0$!d18qJ#Y{DVF;eVD7=9Q1VP9M
z6Ja6Rhyh}XSR;-I7nz0lA;Cxl5{o1t$%qtDB1@4qNHJ21R3KGI9r8VL0y&3VM!JzZ
z$N(~e{D!<oF_eL_Q9aZQwL`h6HyVUSq6^SubTOKb7NDEZa<m#fj5eX?(5q+<+K)a%
z$1uR?7zZ=NY%ngy!$Pq*ED4ii%dsM?46DW(uvV-CyNUH<&#`v|5`jg)2{r_GLLgxt
zK}c9kSWehTs3069G!fbfHwgoTQNkx8lc-CyCb|*%#28{SF^5=4EF;zuj}tEtdx%5C
zHzX2?Loz41kOE1uq*T%p(niv5QX}asshc!N8Y7d*+GK082RW21AS=j)<elWh<TK<O
z<RS7~3Y}s=aisWD;wVzeYDyX95al%G24$EsK~<xgQr)PbR1r0gT0*U%wo<QAho}=Y
zb(%TNgBD3krLCfs(;8?OX!mKa=ybXf-IX3rm(W+z%jrkxm*@lZcMJ`N6@$l!XDAt)
z7zY?<8Fv`3m`tV_(~B9$R4_L&>zL=651DUOSSq$Ed=-((3YAKgCY2j1FI1_jrmEhm
z3sv(~%T$l4UQ>OpMpZLY<EaVMmaA2&olxsj8&hYgJE(`MXQ*#fKcs$H{fP!y!%V|Z
zL!?olv0vl7#vlu08MAmSA!`k*hIN58#3r%L*?e{?yO{kQyNf-lsi8STGfFd8vr_Yv
zW<Lkxm~r@=bWRE9D5sb6eu~}{?<wLb8>Tc&xiMv2YpRx)mRPGut5K^*>%BIv?Wdil
zy+ylO`+*KY$4Vz$Cr4+G&IO(4Q`uA9rwXSQO+7mGt}d!;r5mBUM0dY#r|y`ZzFvTy
zOmC;&dA;ZQ9DOhSRQ+xGr}ak+SO&8UBnI0I&KNw!HF0k|9WTe*@liuv!$3o&VU=N*
z;e?U7(LAHoMvX=fjA_PP<0Rv4#%;!<CI%)UCQD7~P41dfO}VBiraMeKOvla4&7#fL
znKhd|G1oHZo9CO?o8Px!T6kJ4wy3taWl6H+TBcd<w!ChIS~*#zSXEkGvqr6*ttHmG
zt-GfYr@2m(POF~QXTz}Zw#l}sw;8bI*aq9Kwr#e3VP|3&XSc<!!|s#4lYP2<jr~0b
z4Tsqds~uV$esi>P6gpNq-kQ#w?mvCS^p@!_XIRe=&)75LwiC-K#A%&Vo6|>U7iYP1
zgY$@siA#dZE|)$on;XX6$i3uBboFsv;d;{botv|p!tJQrukJSPY3_&IpUgC$DV|v~
zbI`-cL*P;6(LW2Hl`w1HtbR{JPl0E(=OZs;FOgTR*RZ#xcdGYc?-xGyK60PqKI1$$
z-ZI`<U(7eax5&54Ps4AXUxnX8e<S~7|9bz?0H=T@0cQh=fkA;=0{i%Sd?CM%KRVlG
z_OjXSL5!feK@~xdf~|t(!L1=^$n21<A@}E)&XLY(4uw#D=+@8&Vdi0r!+s1Wg@=V#
zhChyQh*%oYF_$%W(cD9G-$eREmPFp0XE9GXuPsV7Dn6<%YCPIEx-_~!#x7=A%+*+(
zSV?S4962s3t~PFLzTf=q^M~S{;tS(@7nm=|U2u7!&cgJCrxvL$5-d8FKum~EIF#@~
z5Gtq^j3x3DcO{MrdBPpSXCg1rHqnUKLtH8zPVz`9O?r~-k-Rl|B*inOEaka`C#jIU
zObtxkn>wBrnsy*<GCexIF@utkka0q)Ax)FEXX<C>W_HW0Wrec-#cqqYFCLW#$!oKa
ztOZ#u3bsO~=u}!L*D43HXJuDrzs-rtIhL!QE6wf9v&!3$H=OUE|LqdO65*1zrG`sa
zEge|qy{u|EvOIBl+X~|q1uKSD2CO`|inc0k)laMKSC_7Sy(W51Yk^+D%7VeQ0c-0E
zRSM;Wee2xU?Ojh;FInHUVfu!h8$K0@imnvf7nc=(*eKk1<r{}@%D<W1l(ea<#JOb8
zX3}Qq=H4xyTMm}0m*$raZVlPmv<=@@wC(lwMcXfz%_!TugSJDtqrW`3yk)1!&dobN
zRHRh&RQgml?$X`0Vb}O>(e4|2y!JHg)!SRV_x(P}zS~s+RZZ1q)n)rh`?L2yu8FGY
z_?G)^U9C=SaqY(g(gXbmBM!FLxzyDi(mhmCkJc;eM-ImyzW$x>cP$Mz4ONYt#^NJz
zM0w=t_X*$k9t}F$c8q(h;Rn+nb{%IOFKR-X@|s4QQ=0o*Vq3aT%s$c9>fU<%N829{
zoHRUHc}nwC$!Xf@g42^{^3RN&m7RTlF8SPG+oHC6=VQ*_Y7cMkx)5~X(nbG^=R3SR
z&Rp`ibn>#><r7!9SDLRnUv27i>OB6F(@)2{oV%K?xm;_x?s~noduI3P8=g1L-SoYA
z@fQEq)t)&$-M#aAZ}-Lb_1_lVesU-M&da;mcPH+xyidGe^g!)F*+boj)jwPQ+}Q8j
ze`>&Yp!3n(NB0JWgU|kv^^Xrj1&^7J%Z3ex>z+71IXU7#a{cN2r$f(V&nBK1{-XZN
zt``<Be)!ev*Ur(H(V>^}my^G3e5L*B!0Q>W+s4Ai9=^$VGcjKDR{QP2cieX!@1x%j
zPvm?ce<=TG`LXp=(5L&88IzO$1Ou4!{1CdwXaE2J24YJ`L;(K){{a7>y{D4^000Sa
zNLh0L01FcU01FcV0GgZ_00007bV*G`2i*w^2nIR7DLxkf00)RkL_t(o!|j-Ra8y?v
z$3N%ZeQ%zd4M_-TNKzAE1C){kLBXjMQ0#~>tzbr|NU61z4rSW<8pl!VAIb<b)>16*
z>EI}eMW@q31C)YOX;KJz(hw4pAdfsY@9g{D;~%>TDcMXC4DCNXGyBJ$d+xoT^ZR{&
zk8|O(@&64Gb#g~(8n6Y(1Z;p4umXKRXp$K`KrOIaZYydY6Hx3Z6+ks`svyPI5@S^T
zPOG6S-lY0EeOgRNm&#<C#~ad(CtG@RfYm^*+*TxqFEK>9Z7SdhZ7m4ulI;T_op_Tv
z$wre%1ib+byFo!!#4GB~G7B&bxHf#{kTq5xsZbw2R5~NZD6)Z84K^=5T1Wb;7kT|k
z*Q6`!z(;P<UoB_F-|Em{g#>qwO%yIad@(61V7*VZc3SKW{XrQ3e7=yRqRqpAN8|MM
z{z(`Ah1LNEd?CtPJ@f=MDL^)OWaCZUq(yac^@jX@0K?8wLr5Zx0?OCBxY*(4Yxl(x
z(DX?K+`cHChce<QOtumugcyv6s`dHZqXtRZuCk}ye)&>Bm+>ZpqKHo@l}L#U>bkV6
ze2^JqSXZ-Ye#;2J*q6(e^apuQN}ceAKG`8<ICxB|@<w25;hGT|><eH6$)~^;wv-6}
z0#aC`YETG3hHa_}`1!(gHoBZxRE1*=T|9TDh5n#^??EFNBP=-F;aldVu+in@nbXZY
z_U2U{oML19l8i|O`Bt8Tn@>J~`}^~Fu^@HSb%s0gCkWV_pUe->UE`k(;edMbWE1bN
zoynGWTljpMo&C$RNU<4tt*V_D&R%1V)5@M@)5&+*sP6Evxul884lfn!UA$iFru5bT
zXTCXuFZ}s3E3@KRoF2<ehlO9Bzd>!Mms5|<U|)3yZeMT&U{niEk2h26_6<#c)ak>h
zDonK-dF9KQ{PjvFOO9M-RZaq*OE9x{Sr)Z!A2SbDQS0{c+Op{Yywlvv!l^M7rP}HB
zYZRv1S&(YyL~{=-k6mG3bvr>_(ihO^3u;j<7`3i8_4t|TumG?&*TGYBrXZ!H%@ZUy
z!NNZpx~XXQl6#<v`ffiir<MIR?X>g-I8f8UY^M!?lI9*3rp2%z&CdRsc8XH%6sFpF
zr@4m<tsYk8Byw<h7AyW<M?jO~0F12JQ{B#Q7H9BCb^;61>}+3>!HMQxe43=O$It5f
z6PcTArS|cBvg6Ivba?r$E1COZO>A^Isp{|maPE3PiDs3h8FB2YXyfbI350aG*y`cg
zc`5wvOBrk`Y2xNU5W^^0*AUIcFPFEHWHGRNX(sVzmE%o4<R+LgtAb}vH?wbf7EjNe
z!XGZR(%9qYiIV@YcUcyfzcZWa4i8V1Gy&iZ>72XXN3zYx)owrCevN<K=tBa}&rfA)
zjEQ$2n*qSggH_aZc}MRD#g4MCAm!T#8MRGJG^=#^wR@eeL8!;&a|K@=;bJKflF_sD
zy@!in$Wb&HXTqx}a;W5d8nsS>Fe|z@ss>j~QLE2)YMa`8eA};6@K8pKO+gHGssUZ%
z_JuI20x2P=>Gb$D`hz;z31;GqD#l?#9|-BxclmI8f}n`o6+)LR&WOV_xK@B)(>?Fs
z7|?7gM`p(>2hNYy&8+-WS;~7Iq<cbgUubJVju0Yt_=3#c<y`9xfI$HvaafFeus)w3
zoND5DT_=w}n2Il;@o-i=n`Sr=LU7{0eXM<>o}OU%D3fe6(e~5>cPg)5-B~t}ZR5x3
z3HFk+>s(sYH1k$*VXG%3^%3k5VXSdEkwyg>)L5D2;7su>Rv)e7czq|rsBozK7JsQ}
zXY*SP{QARNVb4s9rRjTf`RT%R&?IZ}93Ok;@X_eu)^NDd&LkhNdqbTBY@Fp}*M(M|
zU7SI2o`d=OD+vHX4ewJJZtwSJXIcnI_(f3~2_}`77N)bom5fP*BVoKPoidT|nv-PZ
z{Q7+23<?E@stJTcKYDX#Q25o^7S_GpFm!)zoQdhNrU~_%;|3H$Af;qpl7&lc9`ukt
ztVbK!+zBZWs=|>PH;=yAaMy?F37v5VA&)+i!wX-WhAJg8GAHj4$KZcefjp-bgAjL>
zybKfk=r9EN+ePUV=Q`Ma;TFfPbmHj`+}6E-m{=35avl6=ek%D%*09^}qFo<fkVJt*
z!rUYahgW3bUp}3y-2p1y9)y574lDO3m@!2*Gd$2H5pe9@To48|3xO-qj4RPRvb2sL
zECd)Qs6iRMK#r}1F|XZzrW|~Y7qCnKP!I@7$~t}bto)X_y?8@%a3cZ0G;Tnzu9La1
zlA=Fe;>Ca8oOHOKoWDWQo(gjJR?-{NiMTg79zX@qRUw4aYCxD3Qf!7Xg)my0ks}*+
z032om!mQ%78ZatC0QQKR#|)A#Ala;llcmM8zR~U1m})mh1=AzD5qAKHQO>!;=bxXK
zLUEo0hgn6DvL09jG>-QJW~EUPA8yEZ22$-tzmzZ#)J%R&8iv1gG%$GwoQPt<!RrBC
z%EPrC!WWWxa$C{j@qPkM1~vc%k<Y(_QFbpPMn)|6d%3OXCZCN-9{&S%4huE#v8l}f
O0000<MNUMnLSTX?tJj49
diff --git a/plugins/kimchi/ui/images/theme-default/icon-raw.png
b/plugins/kimchi/ui/images/theme-default/icon-raw.png
deleted file mode 100644
index b5def8f3dddd81a3a570f3acbd3b206684275cbf..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001
literal 4679
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
JPDHLkV1mo3<ud>P
diff --git a/plugins/kimchi/ui/images/theme-default/icon-remote.png
b/plugins/kimchi/ui/images/theme-default/icon-remote.png
deleted file mode 100644
index e316dc0701db28b51db92b5e6e6985f3b82b25e9..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001
literal 1005
zcmV<J0}}j+P)<h;3K|Lk000e1NJLTq001BW001Be1^@s6b9#F8000BDNkl<ZSVxuC
zkM$Ep5C?FmK&Zf@0<Z$l3WN#>6^IoWD-bF$Rv=bjr~s(IPytwh&gb4t+~2yJgn4gX
z_U7i#cjw>b{=F}wr=k9R@DltW_(__-kKfP1r{Fiif86T!{tb$P{S+*?ptle(fc%)i
zrZ(3A?8EYhCh&)Jd`!n~j${J3HGw`(IUuisf1V+j0pRS<bj<d*U|>$STt9S{)PJ7(
zfPR;t@3<HNa2vsa_?S1Uo8B1ztR^Fe;IA_{5O;j_00jLjgG=|zJXe!R>6en;`8EBp
zf7E881<<Gcl#w3B?=iuYtOrr@rFr4}E(5pvF7r(ZS^)bH>h_+b4FIL_UPB3ZDI06N
zck32V>z5Dl?iGL;S~`Lqg3Y!YA<v@`lSO6YT=$!x5uHm>0646Uo!D$ySQCgdn?4Im
z$nfq4e<o{J066+8SmV_U&w!lMH&FmUBby)@;aB#YzYTtyzhXWFK$rfW!ELWmA5^Rj
z^$c0a*I*;8$pi$3zF<Ik|19l2KLg+pEd6Q<z%kg|_T)wy@lx{%x=(xhHO7FD`;M?b
zrLWfj2q-nx?Q4Pp;_qN%!+_pl0IU@W_)8;jA;gw{09twrfB@<)ZO(`zEbyALC7(MV
z=SS~Hb6*Nod(Xfq)q4Q`NsWFh?nACLY9_UndZ0#Spns`<*jZ|t@=TWiP*U?<@G-d3
z+1j_~YXIo#3qa_~z_y601klYI%%l_`y<r-FY6;j{R5OtL8{<Rpr{E8xCY%|sg*p{v
zq(-W200l(JoJZ62I^=9+U~58X)cV?jDZLipi?kns7Nqa`+9NeB+ZaM>5h=y_D>d*q
z0zmB)EVaFD`E6ZQnXByEB0?PK&PVBRbfYDNw%3TP+Uk>fzs6x}w1$8biyu4YK>;|#
zgECxOwWGB1-;Xfa2!Q$D2U~nwtTNOzr(jvAjX1n&2y1WDdkaRep7_-1MVjvztlVzD
z1b=RkLuQev4-m7FYyn99?t*UB8VKJS{|^K{H+-MEGJq6_p4JdlUERVnn;8M;pOMcz
z;6~Kh??yd<wiKgGltZ>|^y)%zuWBE-xuECN&j659JO=BBQ?Ob0jP}9GWC3Z&YqW-f
zuVV%Gd?#b0?&TD6LF?bqA<nfz^+rE(J&+}V?(&7S3;w^pngJ+>Zft9{UogPPIW30(
z11kt{RbwevCi+9V27nRgoN#>SQ#x}Ra)Ffy_}MgV=C=T7;{bt|1Xd-gY^d)sgI~b+
b->ZKC*A4Oh7Gf$=00000NkvXXu0mjfz>VSq
diff --git a/plugins/kimchi/ui/images/theme-default/icon-reset.png
b/plugins/kimchi/ui/images/theme-default/icon-reset.png
deleted file mode 100644
index eae8449a556d68a44c28144727f7bb3c5d2fc13c..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001
literal 4576
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
KMNUMnLSTYcw5GuT
diff --git a/plugins/kimchi/ui/images/theme-default/icon-search.png
b/plugins/kimchi/ui/images/theme-default/icon-search.png
deleted file mode 100644
index b38cf6cba2ae18095f990c7dd3736365d9965fe1..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001
literal 4197
zcmV-r5Ss6aP)<h;3K|Lk000e1NJLTq000~S001Be1^@s60ks%H00009a7bBm000XU
z000XU0RWnu7ytkYPiaF#P*7-ZbZ>KLZ*U+<Lqi~Na&Km7Y-Iodc-oy)XH-+^7Crag
z^g>IBfRsybQWXdwQbLP>6p<z>Aqfylh#{fb6;Z(vMMVS~$e@S=j*ftg6;Uh<iVD~V
z<RPMtgQJLw%KPDaqifc@_vX$1wbwr9tn;0-&j-K=43<bUQ8j=JsX`tR;Dg7+#^K~H
zK!FM*Z~zbpvt%K2{UZSY_<lS*D<Z%Lz5oGu(+dayz)hRLFdT>f59&ghTmgWD0l;*T
zI7<kC6aYYajzXpYKt=(8otP$50H6c_V9R4-;{Z@C0AMG7=F<Rxo%or10RUT+Ar%3j
zkpLhQWr#!oXgdI`&sK^>09Y^p6lP1rIRMx#05C~cW=H_Aw*bJ-5DT&Z2n+x)QHX^p
z00esgV8|mQcmRZ%02D^@S3L16t`O%c004NIvOKvYIYoh62rY33S640`D9%Y2D-<?i
z0%4j!F2Z@488U%158(66005wo6%pWr^Zj_v4zAA5HjcIqUoGmt2LB>rV&neh&#Q1i
z007~1e$oCcFS8neI|hJl{-P!B1ZZ9hpmq0)X0i`JwE&>$+E?>%_<lS*MWK+n+1cgf
z<k(8YLR(?VSAG6x!e78w{cQPuJpA|d;J)G{fihizM+Erb!p!tcr5w+a34~(Y=8s4G
zw+sLL9n&JjNn*KJDiq^U5^;`1nvC-@r6P$!k}1U{(*I=Q-z@tBKHoI}uxdU5dyy@u
zU1J0GOD7Ombim^G008p4Z^6_k2m^p<gW=D2|L;HjN1!DDfM!XOaR2~bL?kX$%CkSm
z2mk;?pn)o|K^yeJ7%adB9Ki+L!3+FgHiSYX#KJ-lLJDMn9CBbOtb#%)hRv`YDqt_v
zKpix|QD}yfa1JiQRk#j4a1Z)n2%f<xynzV>LC6RbVIkUx0b+_+BaR3cnT7Zv!AJxW
zizFb)h!jyGOOZ85F;a?DAXP{m@;!0_Ifq<Ex{*7`05XF7hP+2Hl!3BQJ=6@fL%FCo
z8iYoo3(#bAF`ADSpqtQgv>H8(HlgRxt7s3}k3K`kFu>>-2Q$QMFfPW!La{h336o>X
zu_CMttHv6zR;&ZNiS=X8v3CR#fknUxHUxJ<AYmRsNLWl*PS{AOARHt#5!wki2?K;t
z!Y3k=s7tgax)J%r7-BLphge7~Bi0g+6E6^Zh(p9TBoc{3GAFr^0!gu?RMHaCM$&Fl
zBk3%un>0uoBa_M6WNWeqIg~6QE69c9o#eyhGvpiOA@W-aonk<7r1(?fC{oI5N*U!4
z<uv66WtcKSRim0x-Ke2d5jBrmLam{;Qm;{ms1r1GnmNsb7D-E`t)i9F8fX`2_i3-_
zbh;7Ul^#x)&{xvS=|||7=mYe33=M`AgU5(xC>fg=2N-7=cNnjjOr{yriy6mMFgG#l
znCF=fnQv8CDz++o6_Lscl}eQ+l^ZHARH>?_s@|##Rr6KLRFA1%Q+=*RRWnoLsR`7U
zt5vF<Q0r40Q)j6=sE4X&sBct1q<&fbi3VB2Ov6t@q*0);U*o*SAPZv|vv@2aYYnT0
zb%8a+Cb7-ge0D0knEf5Qi#@8Tp*ce{N;6lpQuCB%KL_KOarm5cP6_8Ir<e17iry6O
zDdH&`rZh~sF=bq9s+O0QSgS~@QL9Jmy*94xr=6y~MY~!1fet~(N+(<=M`w@D1)b+p
z*;C!83a1uLJv#NSE~;y#8=<>IcfW3@?wFpwUVxrVZ>QdQz32KIeJ}k~{cZZE^+ya?
z2D1z#2HOnI7(B%_ac?{wFUQ;QQA1tBKtrWrm0_3Rgps+?Jfqb{jYbcQX~taRB;#$y
zZN{S}1|}gUOHJxc?wV3fxuz+mJ4`!F$IZ;mqRrNsHJd##*D~ju=bP7?-?v~|cv>vB
zsJ6IeNwVZxrdjT`yl#bBIa#GxRa#xMMy;K#CDyyGyQdMSxlWT#tDe?p!?5wT$+oGt
z8L;Kp2HUQ-ZMJ=3XJQv;x5ci*?vuTfeY$;({XGW_huIFR9a<fJbF^|4I#xQ~n$Dc=
zKYhjYmgz5NSkDm8*fZm{6U!;YX`NG>(?@3)XSs8O^N5RyOM=TTmp(3=8^+zpz2r)C
z^>JO{deZfso3oq3?Wo(Y?l$ge?uXo;%ru`Vo>?<<(8I_>;8Eq#KMS9gFl*neeosSB
zfoHYnBQIkwkyowPu(zdms`p{<7e4kra-ZWq<2*OsGTvEV%s0Td$hXT+!*8Bnh2KMe
zBmZRodjHV?r+_5^X9J0WL4jKW`}lf%A-|44I@@LTvf1rHjG(ze6+w@Jt%Bvjts!X0
z?2xS?_ve_-k<Mujg;0Lz*3buG=3$G&ehepthlN*$KaOySSQ^nWmo<0M+(UEUMEXRQ
zMBbZcF;6+KElM>iKB_KiJlZ$9G`c^=E@oNG)mWWaNo-3TIW8)$Hg0Ub-~8?KhvJ>$
z3*&nim@mj(aCxE5!t{lw7O5^0EIO7zOo&c6l<+|iDySBWCGrz@C5{St!X3hAA}`T4
z(TLbXTq+(;@<=L8dXnssyft|w#WSTW<++3>sgS%(4NTpeI-VAqb|7ssJvzNHgOZVu
zaYCvgO_R1~>SyL=cFU|~g|hy|Zi}}s9+d~lYqOB71z9Z$wnC=pR9Yz4DhIM>Wmjgu
z&56o6maCpC&F##y%G;1PobR9i?GnNg;gYtchD%p19a!eQtZF&3JaKv33gZ<8D~47E
ztUS1iwkmDaPpj=$m#%)jCVEY4fnLGNg2A-`YwHVD3gv};>)hAvT~AmqS>Lr``i7kw
zJ{5_It`yrBmlc25DBO7E8;5VoznR>Ww5hAaxn$2~(q`%A-YuS64wkBy=9dm`4cXeX
z4c}I@?e+FW+b@^RDBHV(wnMq2zdX3SWv9u`%{xC-q*U}&`cyXV(%rRT*Z6MH?i+i&
z_B8C(+grT%{XWUQ+f@NoP1R=AW&26{v-dx)iK^-Nmiuj8txj!m?Z*Ss1N{dh4z}01
z)YTo*JycSU)+_5r4#yw9{+;i4Ee$peRgIj+;v;ZGdF1K$3E%e~4LaI(jC-u%2h$&R
z9cLXcYC@Xwnns&bn)_Q~Te?roKGD|d-g^8;+aC{{G(1^(O7m37Y1-+6)01cN&y1aw
zoqc{T`P^XJqPBbIW6s}d4{z_f5Om?vMgNQEJG?v2T=KYd^0M3I6IZxbny)%vZR&LD
zJpPl@Psh8QyPB@KTx+@RdcC!KX7}kEo;S|j^u2lU7XQ}Oo;f|;z4Ll+_r>@1-xl3|
zawq-H%e&ckC+@AhPrP6BK<z=<L*0kfKU@CX*zeqbYQT4(^U>T#_XdT7&;F71j}Joy
zkC~6lh7E@6o;W@^IpRNZ{ptLtL(gQ-CY~4mqW;US7Zxvm_|@yz&e53Bp_lTPlfP|z
zrTyx_>lv@x#=^!PzR7qqF<$gm`|ZJZ+;<)Cqu&ot<a{81DF0~rvGr5Xr~8u`lav1h
z1DNytV>2z=0000WV@Og>004R=004l4008;_004mL004C`008P>0026e000+nl3&F}
z000G$Nkl<Zc-p*|ONd+79mc<N?zs=?>gsBS8P7<#)?_?m*OpR4pn}QMi_+9?LP#JO
z;w-Xh@od}}ZvqK;lU*Q`LcH>1*DgZB5R-u0O<O25UX((}*ltpft;xe<tQn8S(%h%+
z*F}z8#ZGL+4mlunb+0(T^M8EbUlJtoV=e^%LWurnq3`7YlmHa<wV|IU0JZ?M0o(u(
z0O$c2>eM8^1`fb14ccZH#)M^AzmQTsDumdf!5xzS&9dxt5Ck7+a7Q0xD5xOWkI)1#
z3ZP=!_9IHEm!*_D4a0zx5>m>WrzD9qP5%}}(W_AuE$OJ!yFp3b1WEutfbEXs{L(bd
z*QJz>Wm)ij|Hkz6^cT5YZnM>D6|Y^pHXX;Y9mg@EC|cgy+Il_+g7W|(0NJo9wE+00
zY0jFa`I=J7aU2H+4jedp{P^*Y_U_&LC4db8?S+Mf;;B=o4sUF1?2n>oS}FC1Ua$A-
zIF4go7T&dxx;bk3eEz*ssl-a9!lOrz{)OZ#Bwr-?Fv-0n_mKSQxpU{n>-GBkwOWlk
zckbl2ZQBkH+cbUPm{RKTVzIb3F)_ipxw(r;lFXBQisTNGHc3I!Aejds%jI&dR;z8)
z>vitlz55JFpQLj)pw!ofQfkUDj8VsNP^;Dcu9Rv5I1k_}Aw(pEpb(-5AOv7sxpJko
zwY7B?08G<-@XVPr72U~qTzz0Br7S6>U|AMi*ZmKGuK=tGA<}QOwGf%srQPXtzD$w?
zQc8byb+rn>B`JpiCID_IrC=BaE?v6R18`MGbDNZOljYMi^^+ul5F)Kst2qG9z@B#m
zMkGHILWELEEH5wrObBsR2oc}1fdF6wC`l<tNj{Wi8C=(0Ycv|^FkN~x!YGO^ko=bx
z_H&bylaFg{y87e}01v<ffC<~SpOaEf2_dj+*RCbkb%oAIHViP$vTQR=)3>rLgAl^a
z<#KO(p7$t#NdVgc>;UipfU@H_zfwxgE2WUn=R5QB^Z(So+7&|ZuI8-^oeCk|@jP$8
zX_~*aZTkVw^Zq1+_#lqsf0NvlQkJEZPe>`BFijJV<KWPtLyL_@;{t$-05*pbqt=*7
zGPk(6IM!%1{#dWqIXgScN~OZl(NX%o&tkF2QmMqTu`yPw)#TW*V{eh%uG8&mKNiDy
zDM<Dkq5!}@a^%PhOG`_KTdmfvFbqYKBp?aPvf|m<*$W2`9{l~ulP52d{7t9RN!so9
zLJ$O>0O)?#$od9Q-{?bq0FyxwlouBlAG&<`@=O#(Ub$S3_U+rZGB-DOdS+&3Tq*T#
z5Cm2jhDeg+Vh{w+gkiY+T}FNzZ~&?R<n_23)9-oRWS<Km&R46|(^;17CkZJfNFofw
z#a65J63I}HtL#n#xbGwckdWNe!}W@;k<uG%0Pwrr?hV_vk<aI0Syn&Y&yxIWtJPZ2
z-{q~Ty)D8am+AZd&r7A!pFPhjDE0NZ(=<i5+g)E@Uw^XQZhxX3toLo^J@nEY&33ze
zmgH-L&kVzW<2a**Lg7uzvI^RB<+lkR_X1v7SveWU@rPNK^~(X%G~v4LV<RIYztb`?
z2Bq@7fx5>1G$osxn@7_$z1sh|DW!yM+i+d?_{hk}!?#9xPZ9Q^B-QHb>g8^?`*N?>
z`+wS`gyT3l&-30a6bd5)#((cA)lia@&1Uo6Fbv<mHMO~1u3jt_=e3I&_XX?^Ze7pb
z_3PJPNs{E#erkmfuq+GX<Ks^Qn9&Y)f53ry8f$B7t!}q_Bu&$7uxt11*|QGdCtAz*
z9pPYV&1SRtQMp`xLkJNFAviTP)jV<H#6Ps_#P=io+a#j9(bLiF22jxftpNBKKodax
vg8&Dhrmoef9#;u~>-rS|p!l)>uKjNSf7rQAZ2gwc00000NkvXXu0mjfr62uF
diff --git a/plugins/kimchi/ui/images/theme-default/icon-sort.png
b/plugins/kimchi/ui/images/theme-default/icon-sort.png
deleted file mode 100644
index 78e8b3930368c9ee163ea6f28a0c5a1d631241a9..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001
literal 3421
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
diff --git a/plugins/kimchi/ui/images/theme-default/icon-tree.png
b/plugins/kimchi/ui/images/theme-default/icon-tree.png
deleted file mode 100644
index 5f7ed5312dac8d3bfb26010ea6555682f5a43f3d..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001
literal 3526
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
A0ssI2
diff --git a/plugins/kimchi/ui/images/theme-default/icon-user.png
b/plugins/kimchi/ui/images/theme-default/icon-user.png
deleted file mode 100644
index f4258d420b98a019332bc742e15d53497e1012cf..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001
literal 5366
zcmV<S6bb8zP)<h;3K|Lk000e1NJLTq001Na001Zm1^@s6mcm%$00009a7bBm000XU
z000XU0RWnu7ytkYPiaF#P*7-ZbZ>KLZ*U+<Lqi~Na&Km7Y-Iodc-oy)XH-+^7Crag
z^g>IBfRsybQWXdwQbLP>6p<z>Aqfylh#{fb6;Z(vMMVS~$e@S=j*ftg6;Uh<iVD~V
z<RPMtgQJLw%KPDaqifc@_vX$1wbwr9tn;0-&j-K=43<bUQ8j=JsX`tR;Dg7+#^K~H
zK!FM*Z~zbpvt%K2{UZSY_<lS*D<Z%Lz5oGu(+dayz)hRLFdT>f59&ghTmgWD0l;*T
zI7<kC6aYYajzXpYKt=(8otP$50H6c_V9R4-;{Z@C0AMG7=F<Rxo%or10RUT+Ar%3j
zkpLhQWr#!oXgdI`&sK^>09Y^p6lP1rIRMx#05C~cW=H_Aw*bJ-5DT&Z2n+x)QHX^p
z00esgV8|mQcmRZ%02D^@S3L16t`O%c004NIvOKvYIYoh62rY33S640`D9%Y2D-<?i
z0%4j!F2Z@488U%158(66005wo6%pWr^Zj_v4zAA5HjcIqUoGmt2LB>rV&neh&#Q1i
z007~1e$oCcFS8neI|hJl{-P!B1ZZ9hpmq0)X0i`JwE&>$+E?>%_<lS*MWK+n+1cgf
z<k(8YLR(?VSAG6x!e78w{cQPuJpA|d;J)G{fihizM+Erb!p!tcr5w+a34~(Y=8s4G
zw+sLL9n&JjNn*KJDiq^U5^;`1nvC-@r6P$!k}1U{(*I=Q-z@tBKHoI}uxdU5dyy@u
zU1J0GOD7Ombim^G008p4Z^6_k2m^p<gW=D2|L;HjN1!DDfM!XOaR2~bL?kX$%CkSm
z2mk;?pn)o|K^yeJ7%adB9Ki+L!3+FgHiSYX#KJ-lLJDMn9CBbOtb#%)hRv`YDqt_v
zKpix|QD}yfa1JiQRk#j4a1Z)n2%f<xynzV>LC6RbVIkUx0b+_+BaR3cnT7Zv!AJxW
zizFb)h!jyGOOZ85F;a?DAXP{m@;!0_Ifq<Ex{*7`05XF7hP+2Hl!3BQJ=6@fL%FCo
z8iYoo3(#bAF`ADSpqtQgv>H8(HlgRxt7s3}k3K`kFu>>-2Q$QMFfPW!La{h336o>X
zu_CMttHv6zR;&ZNiS=X8v3CR#fknUxHUxJ<AYmRsNLWl*PS{AOARHt#5!wki2?K;t
z!Y3k=s7tgax)J%r7-BLphge7~Bi0g+6E6^Zh(p9TBoc{3GAFr^0!gu?RMHaCM$&Fl
zBk3%un>0uoBa_M6WNWeqIg~6QE69c9o#eyhGvpiOA@W-aonk<7r1(?fC{oI5N*U!4
z<uv66WtcKSRim0x-Ke2d5jBrmLam{;Qm;{ms1r1GnmNsb7D-E`t)i9F8fX`2_i3-_
zbh;7Ul^#x)&{xvS=|||7=mYe33=M`AgU5(xC>fg=2N-7=cNnjjOr{yriy6mMFgG#l
znCF=fnQv8CDz++o6_Lscl}eQ+l^ZHARH>?_s@|##Rr6KLRFA1%Q+=*RRWnoLsR`7U
zt5vF<Q0r40Q)j6=sE4X&sBct1q<&fbi3VB2Ov6t@q*0);U*o*SAPZv|vv@2aYYnT0
zb%8a+Cb7-ge0D0knEf5Qi#@8Tp*ce{N;6lpQuCB%KL_KOarm5cP6_8Ir<e17iry6O
zDdH&`rZh~sF=bq9s+O0QSgS~@QL9Jmy*94xr=6y~MY~!1fet~(N+(<=M`w@D1)b+p
z*;C!83a1uLJv#NSE~;y#8=<>IcfW3@?wFpwUVxrVZ>QdQz32KIeJ}k~{cZZE^+ya?
z2D1z#2HOnI7(B%_ac?{wFUQ;QQA1tBKtrWrm0_3Rgps+?Jfqb{jYbcQX~taRB;#$y
zZN{S}1|}gUOHJxc?wV3fxuz+mJ4`!F$IZ;mqRrNsHJd##*D~ju=bP7?-?v~|cv>vB
zsJ6IeNwVZxrdjT`yl#bBIa#GxRa#xMMy;K#CDyyGyQdMSxlWT#tDe?p!?5wT$+oGt
z8L;Kp2HUQ-ZMJ=3XJQv;x5ci*?vuTfeY$;({XGW_huIFR9a<fJbF^|4I#xQ~n$Dc=
zKYhjYmgz5NSkDm8*fZm{6U!;YX`NG>(?@3)XSs8O^N5RyOM=TTmp(3=8^+zpz2r)C
z^>JO{deZfso3oq3?Wo(Y?l$ge?uXo;%ru`Vo>?<<(8I_>;8Eq#KMS9gFl*neeosSB
zfoHYnBQIkwkyowPu(zdms`p{<7e4kra-ZWq<2*OsGTvEV%s0Td$hXT+!*8Bnh2KMe
zBmZRodjHV?r+_5^X9J0WL4jKW`}lf%A-|44I@@LTvf1rHjG(ze6+w@Jt%Bvjts!X0
z?2xS?_ve_-k<Mujg;0Lz*3buG=3$G&ehepthlN*$KaOySSQ^nWmo<0M+(UEUMEXRQ
zMBbZcF;6+KElM>iKB_KiJlZ$9G`c^=E@oNG)mWWaNo-3TIW8)$Hg0Ub-~8?KhvJ>$
z3*&nim@mj(aCxE5!t{lw7O5^0EIO7zOo&c6l<+|iDySBWCGrz@C5{St!X3hAA}`T4
z(TLbXTq+(;@<=L8dXnssyft|w#WSTW<++3>sgS%(4NTpeI-VAqb|7ssJvzNHgOZVu
zaYCvgO_R1~>SyL=cFU|~g|hy|Zi}}s9+d~lYqOB71z9Z$wnC=pR9Yz4DhIM>Wmjgu
z&56o6maCpC&F##y%G;1PobR9i?GnNg;gYtchD%p19a!eQtZF&3JaKv33gZ<8D~47E
ztUS1iwkmDaPpj=$m#%)jCVEY4fnLGNg2A-`YwHVD3gv};>)hAvT~AmqS>Lr``i7kw
zJ{5_It`yrBmlc25DBO7E8;5VoznR>Ww5hAaxn$2~(q`%A-YuS64wkBy=9dm`4cXeX
z4c}I@?e+FW+b@^RDBHV(wnMq2zdX3SWv9u`%{xC-q*U}&`cyXV(%rRT*Z6MH?i+i&
z_B8C(+grT%{XWUQ+f@NoP1R=AW&26{v-dx)iK^-Nmiuj8txj!m?Z*Ss1N{dh4z}01
z)YTo*JycSU)+_5r4#yw9{+;i4Ee$peRgIj+;v;ZGdF1K$3E%e~4LaI(jC-u%2h$&R
z9cLXcYC@Xwnns&bn)_Q~Te?roKGD|d-g^8;+aC{{G(1^(O7m37Y1-+6)01cN&y1aw
zoqc{T`P^XJqPBbIW6s}d4{z_f5Om?vMgNQEJG?v2T=KYd^0M3I6IZxbny)%vZR&LD
zJpPl@Psh8QyPB@KTx+@RdcC!KX7}kEo;S|j^u2lU7XQ}Oo;f|;z4Ll+_r>@1-xl3|
zawq-H%e&ckC+@AhPrP6BK<z=<L*0kfKU@CX*zeqbYQT4(^U>T#_XdT7&;F71j}Joy
zkC~6lh7E@6o;W@^IpRNZ{ptLtL(gQ-CY~4mqW;US7Zxvm_|@yz&e53Bp_lTPlfP|z
zrTyx_>lv@x#=^!PzR7qqF<$gm`|ZJZ+;<)Cqu&ot<a{81DF0~rvGr5Xr~8u`lav1h
z1DNytV>2z=0000WV@Og>004R=004l4008;_004mL004C`008P>0026e000+nl3&F}
z000UhNkl<Zc-pL3ON<=Xbv^gKS6y8_Gu@owkRlz*6o*5@V}q6@Bo3fJiC|=rI9ddO
zkYp1Z77W9mMGzp{AfJ_C!wC=wK{n1Niy&EfWynGtuSggHY%uaiwBXR<NJ9?iLr(vy
ztKNI}-YlxRO(l%j3Q|C!yQ*Jxox1njbI&dM`d|MImf461ckbT7y}SE3bLI?;Y}-5k
zscznVHqY~ObqF$<O!j88*>~!?{`O=tIXQps9Ijm1#{1d)`&mo?)a*it@pJwD+8+)E
zgAWb*1M=QOR56`Qad3F>M~8=p-&NJWGT8U<J~wY>OD$w(IOndUl>VNXKe@Kn$J*)|
zeC9z!AS2{?2d4&uZdsPUeROoRL!d7b(W}ee0|0zc6icNm#<;P!clYnQ-R>ugqJW5C
zR##9H5EyEPx~@@&fXsXJdcCLi?;X5y@u`b1X5Qai77%yy9FN;qdOh5|d-tW|<KySE
zEJFwZbzLLW0aX=H*8!of5kf#p2{9$)d5+<5c=^_?pMRN%VTPr4KN^i5i#p3P93CA0
zYMys;RYgjI7$fSchN{9b!(fOpBE|#}g@~ft&9S??`+HlLE`3!*-d-wYufF!$QlT`p
zU+VYQAR<U9BE|@2hM6^=Fr=7}QiO^Cs&MR3*LCms{{73Ux*VY4$;sovn4u_oYzCy%
zMkpl!3{eA96K;`&7!#5R)D&h0Q^PxZd$ugGy{aw+2rv;5s5a?xbrT&i0Reyk(*Bkt
zK~#|>!DU%EfByV|EpZ<J@SB^POI2ANf`l01U0db^h$_6xz)S#ul+q%d&38es*WK+E
z#T$~+a)7okUw-@|@1MT;(>FgH>Kfj8fC(T#)S%wLOfWMfk*3OGgro#(#Pamv!O^b~
z(Y2)jy><KcGNSn0bTYZ*Gmn%ah?+F2C``2_w>JEeCPE=bs2T1bA7APgZ@<XQ%K?fp
zE(7SeuImznRp;Wv<btY#m|zCzLlK&%udZsTs%n^bax6n^|I9NVf9#@8r}Lfb*S~k`
z@bKtkgF&Opb3Jm70VXg25rIg8iXx?i@o0?xss70eFTC(?CnqN$qQ?U|bLPx4!gze?
z(o?UP*&mNaqmOpcg^GYVftf)d7yvVELA4d;-GgU7{><05wl4kqwQJYW>2#K9u8%KA
z(S)KXzOlW%{pO7uH@-D1XT8jOuyZXSz+kQX8)67BGi-lo`!6?6Z~kqJX{qP{fWNc1
zzf{@7pxr!w{q)AhkAD8v?N6+(tN<cl<~gBSju0l(DbAifbNk#APyA~PmHqVQO?0yC
zk)Y=1=KS*ItX$fl5mA|U^B<|nC&UEMhBp9#7%){dY925+HTc2i>CJbT8LEnvm6b;d
zu84q$;GBE6Qa^n1JwVm{{^0vXw|Lo9(L5Xhrcgn9Y{>H*y`uNyI)w3i$Ui!Hj-%uI
zSX*7i2S4~EQcCcbx3(H3t}2`ihXB!{2R$lEZs2}+;lhOn$HzzO(w4aqfedi$K#sAt
zHVCIqt-m>)mipgYlbQnBJcsusB&CI}nHl`f&JMiyI6OSW^o^S!0%Az$^l|`-#>>15
z-0gGco_Ir5o-1cF#I~Kxn<+D+zqWQPl6Ggaa&hgv0{i^|ie3Q_P}NoAiytO+2mvBZ
zQ=F4hM35w5ZFLpn@dSC^0WrfGk$iCW?AgN*0`BeaV^)?(F+wDPiP0Yn!0h6|!C}3q
z(j?f}SVw=*ha`b^6a@MoVBXW@ONwA7s0u=iSYKa<iondw5oy2Q$E++d9#1fui~%#O
z^i}{6n29$}pQZ&-y+@vR;WLjEBVc$Wn8!>VO*?2vYhWT6F#tUqW88M^;Ij-xuW0Os
zG(Alu0l-GDC_YfEtY9=8qSML13@l@Hc<B*{$f@d;YF7QlbTYYGmL;lL1xeBrfN4Wm
z03n3l?mN4GUY66(6X^WhFaN*IWz2kaR+cZ#s`~eb!{LX^$pj~(5r(57s(J=#Qi&83
z>Z*qK9$A)MJwCqwO0QRZhMB+Vv+TP>^g4j>e*#1VIL8-M_2m%4%hT!f;%qj<WHQBg
zJi=%+Mp>4Kp@yn8gl|>Xd50|PAcT;0vh2A);W<>e<Jf)EXa1j<`MTlJJ<I<u^m#TV
z`Qp*h@vo;8w^Y?vRfXxa#CSBqWI91Ln<3OS8vD}ZLy18I)O7{tJeUbt=E07E8XsWh
zFNGLhDyQY^8yg${2;iRq)Q<$z_LR-KuKr{?oqoYNx6v3cpss7oW;4vn60>TCx~dUk
zY*VF+qA>_kB5+6uKA@WUM*R)QyE(F~12Q_RBENa(?w#N07TrH!;y)vzAIy82_rAG^
zna}R;?|&nN`o-1NHHa!=Y|K{O4u(}#HA7(vNGT#|S|}_)Z6!9ID8vBA4Cfj*Agbte
z1l~D#@8H;FlhOE7!_oNJet+;;QGJz};SUZDu(Gm3Kl{&He|mI${Nm}2^~Mux(-u;Q
zh$$h2fDi+cG?7tNKn?S0!pxx56fUtY#5KeKVuG4NQiO9JS?1xq2eX4?KKJ(9yI(0f
z`OS-$F23b<c0PjPaQO6%8~^cDW?IX<M+gxy#fBr2kXjeG0AdY+nW_0x=it0+pWeg!
z44HR}n>O~P>5rz0qzY33%-|ej|K7cGz15Zdi%&jz%`-bXI5_;R>12F<ePaWu9al^Z
zOii<Njv?N+irZPt@N<CHk{SlEV=(^$nD@;wfg0~k08}BufHjV@+wEd+@6M;++THz@
z4<S6czrX)GKFb;|IR^s33>dVXE(iogWQB>r(0FQTqc*QHP~#kl8ogx#m>AwU5HlRN
z{+kF)3?c?Iq3GrqPbOQpZrys`i^|n<R_<ipF9>R_`%6jMJtC#p@Td+5?Nl*0^o<G|
zh-m&EsS(FchRkQkIvsSftchCY!QKNzjT``NTA3d_IJxMny84wm)EnwrlDVd<t16^@
zwKDfTF$AR4P8KOaRhyJ80%XlZ(mqs^dO+2XQe#sVAhQhW91MgQ17O-wl_z{%)h8*Y
zo1v;d5@JM_Weel303<ap4`d##HY#e?TGoft1&}rTQ&9*Bh?<D08iW*-WHEMw8Vj6)
z43nhqCy{Huljr~7oO><Q_4A_oyD_F;_Kw%h%taAMN>CA~86+uG1u%uE!BpDur$It(
zza~<s(!w(*NpQ^YnTKnm1JhE~Zi~pb$?z(OZWwUS!)yfLCm{R;z`qb-$3Pz~dd1bQ
z>C+*Et?9HpUyjEv#ekF)+8TTVK-`Arp)si8MdQ&sSqH^R4@FUox<zr@G2axC8zA@N
zB;ki<*khoc8>DyjG6Nm}xXw)1vn<PsqF7sBKeg@H?TE;g$z-%OnUtH8>7+L+XT1<Y
zM^v1dF@eC&r7ZKQn-_Iabf>GUtHb`Fe}{;F7Gr#~uItw)lgWXZ)xXe+cW?hS0K=Ts
U)&>o#U;qFB07*qoM6N<$f|wvR(EtDd
diff --git a/plugins/kimchi/ui/images/theme-default/icon-volume-default.png
b/plugins/kimchi/ui/images/theme-default/icon-volume-default.png
deleted file mode 100644
index ac906c7723e9c26900c347cf5e47e3192a5b2f88..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001
literal 4265
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
LNkvXXu0mjfnm8lp
diff --git a/plugins/kimchi/ui/images/theme-default/kimchi-loading15x15.gif
b/plugins/kimchi/ui/images/theme-default/kimchi-loading15x15.gif
deleted file mode 100644
index aaa4f85a0560dcb59d4bb70154a9144417aae926..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001
literal 1653
zcmZ?wbhEHb6krfwcz&0`fx$V3fzy*s(30KRoyj+pP0*a%B9B4Xkl)0X$H9|dJd8D}
zo<ZDBSSFF7*jZT0OhTc9Q7nTgk3rREDud*7MxI>8&Ju=(ISf+93MQOdag7Y~1hic{
z8T#{u6)cohTNtM^7+W$J#50+i$>`cj=^O84k`pyFn#{1$Ur8%a&i6QjtgEuCfQhw>
zh77A6gQ$gokA@_-E$2dp^>Sv?oMy2Rvbjr`S1FsTIOwZtnQE_R*m$2oUC1KhF@wT7
z#vS5TPBXdYi#jqhIC*|#&}Xr)`pY25?86wZk@$x}Azj<#4}*rAu{Vcnu(UhJUj}_&
zGsWW!mvn9Irz#jqI|d0m<_4Kq$D4?%x#%8bJFV#KwS(tqvz9fdTmMyIV-~+CKU<>^
zTODbStQ;$e9OEp8kfaJrQB(IojUXN?PfLA&1ruKlE$<Ybz{O>Dnh|c+IZj3l84L_z
z+ZiGkGQ_8gg)Ec{ZB|VbVu;;p8Ir+}TJcZ8St};J)7e)ugI_wAy~kUSA^Gq;v#nzB
zo6<uZ9TN=&l6EuXHCx41&a>X&p6tkweNrgxtWY&KLrITauKX0wDL;*ZSPITdWuHCl
z7S2#|o1wN-skGcGd-j}YNrw7v?ff;HUH7htly%83WoVk=SR=P3TA8QnVNZtdt|Td^
z4tBRT;l<gOCKJSuq^f)gOk<w3o@>%d>z1S5joVY2V;E+x4Cszxn7#dGQiZ}|@k{wq
ze5<)H#@>~ixp+mvx~nC^*GqKvReGJxyd=J8Z|Hp0)LG8{Q?7j|(|J;(^S(;?X-VtX
z{Ej0{$vo>WNUb@RHtpd12Emt&YTJ7ve>HRaY*WxWB$BmO<7<oVrMfE&d+u577yI7H
zdv${AuTG6`J!)PD74G*(XRN&WpI$)mKewN2NU*bGfUA+70W%{51B2pE7EU3C{|q`n
zHZYS2Ffee)GW_S1@z}87U^9oXR?LYF3lFyoD0|KE*tqCuBO@a=9coY=j!k!j<aB0i
zc<9u4hfS*nq@!EHIP1=djf>s;v1`@Ep>^V-!(BqkNq@`*laF`Fn|H~0Zd!7(0h{Hf
zM42F;^~FLc<zy?bzucZ38xtI`nPf?{Nk)rZI#dI#a%KcAJ>AR3%!JJ}Tb!mjcL>V+
z&Dl|qe5_B>QtnB`#6;Il`9QBD85<TlO;@&EX5(p~fXzf_h=~b~c^s@tPtrczcWUF8
zl$)Y)G4W`lxU|rj6$Xj!z4E$EBA!9O@K)2-%Q<1V)NzW4rQ4Q{qQ@s^Df6<iU^CYa
zVJ@$f%ZvcUgKd2BZZRt+Jap&~-N|`mN5EtIK6cxtnin4*pO_@<TefG1V5)aFPwc)q
zGcP6L3rdhvk&Uz{R5;QluAbJjV`8#<o~Uk<jm4+?Cwh5=mxY`NNH{%#3wux+Vs{|2
sX~(-16pJpOC{Q`pufUDnn>s|9;tWh`McC5^G?`;~3OSj#0+YEl0GD)I?EnA(
diff --git a/plugins/kimchi/ui/images/theme-default/loading.gif
b/plugins/kimchi/ui/images/theme-default/loading.gif
deleted file mode 100644
index 60d46d2683817f81a678c5e3eef14ef35089d119..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001
literal 2190
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
L$~1kj8oc@+?)_VM
diff --git a/plugins/kimchi/ui/images/theme-default/user.png
b/plugins/kimchi/ui/images/theme-default/user.png
deleted file mode 100644
index c57a81a92757ef31c424a4e6c741f71db62a1092..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001
literal 1322
zcmV+_1=aeAP)<h;3K|Lk000e1NJLTq001BW001Be1^@s6b9#F80000PbVXQnQ*UN;
zcVTj606}DLVr3vnZDD6+Qe|Oed2z{QJOBU$%t=H+RCwCFS6xgTRTRGSvwt(QEW2!%
zZEC<RY*%PmU|~TT(9l}brY~)zO*HkzHZ`VcV>GER{yyo84?Y{zXpHs6S4l9Y#$eJ`
zmI9TeNz<hS;wC6n(*0#;*YAuwlVv;L6r^`@m^(Xj@A=NT=X~eDmCI%J$6w2=dc>kV
zY@@+(9ODK4xF85;1zu=k91CHOq^hbvsYP|PR4&aWrYD(|;jiDtI5Pm<(b&U^nWnhO
zZnuB!bUFte4hIuOQ3F&emDt+a8q4K!YCf0$1oO+2)4!@#0EkwQl5$ualok1!EXhHq
z%gJmu8{>K206<bG6ogDB^F}6}*^Ol{S=pO6{k6PaIG$r3kLNqL+Z|Ng3M1<QNK>wD
z0wClKm&?WQ4U=X0#ew+2^IHe7-h8rlfP@r~VhtmXu2yJ}XCzr-e!u_2cz2($B>?5B
zi|2UO+S2;E!|Bj0HB)Q`0>S806y@n{9{~c7$%@p!ndP-YM`IIhEY=e{_Fn+RjXY4D
zb{x;w(OtLDQsClyUxV+7?FS)7Fxa?e#qxE6tFbYV-gXdDdWFN`J9K{(0F)I&&kRj$
zI|#vW?8M0vpCb(|D<`nShlY!hry^t9K7x{3LJ-PdzWUnvKdl1r@A9)#r$@fP4l7&p
zK#etB9o>b2g9B$ST)a@CRMeTzOi1}V@4bC5&=`2jO0Zg@ViXxFP-BUi$(LJN_Ksfp
z=3D3WYuB~o(FYyT;UkCH$jA$KK}644v0lp-vto3ht%C^2h1~xbJa874jpHaz!TRjf
zY@!{XyqnEtPcAMl+BGYX^P$j_DNIKpA3+{;9_VVv`tOm%b^yJ6^VZZ?maAd3z0;0@
z^8+}4h*+&yEHYHNtJz%k6}(OoDNW5J6wD))C57Iu_-s)vYB2+#M<hwQVt3em#0U9&
zo&oSVtQoZgARg=c6uf^<=YBd{Y`}8a9F^U1Jl{ry%u<!a_#1N%?h2Ge@cpwW*%8Sl
zF#ymAiApspWGS6aAB88zHwA!z8&qWFXDTRUy%7gEZ}J3fMsuAPv~1!2Wj+Ec3L+D2
zqQ(OhuzFCF7qC8cf8~C7W^Vd{X+O}>78M%&4WH3QB-PYQo53<|<J#h5P&Rc-l^#J?
ztdGi32J7nTKEUIfrfCS5pT-%6Ny$cqM^~a*D~g8DbG5~0>&O6nb1AyN(`O36>+`;^
zE8i^Fw<;AciT(!v#fQ?cbAMMCx}7NsJl&F=7!*g?e<hVl1yaAKR6|o}Z|D*QkY09o
zN@#y%ln=dSY#kHg^-=2m9;N1QW$4+`+|+aik2gd;`n?U_M)dhR4nPNiKf{Ix&_Fij
z3wd5}JSG6RifhF^Mi%tOdm`1jyVF9%1!9s64=8STpq4mxa*!S{s%Us%UnHDGZax<4
zb!iSYtJOTviuu)rdkcFeCVpX4i3FROnWX~qzgZm!1kk2;v%da**4x{|>b>>js0Gj0
z79%RJ$03IxgUidyp5)ymo1dR&^T~O(w6w(16;L1%wz|4%C<yKjGVr{ij5;GUFVxVY
zR|qke<XXV1A0cCv`|^h6xNTp%_8-x2w{KCTwpR&x%A<1^#8<T}S=9xRvL(nY<R)Z}
gniR8!<R1YB09_*wa#VgYhyVZp07*qoM6N<$f^kM~^#A|>
diff --git a/plugins/kimchi/ui/js/Makefile.am b/plugins/kimchi/ui/js/Makefile.am
deleted file mode 100644
index c9d1218..0000000
--- a/plugins/kimchi/ui/js/Makefile.am
+++ /dev/null
@@ -1,27 +0,0 @@
-#
-# Kimchi
-#
-# Copyright IBM, Corp. 2013
-#
-# 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.
-
-EXTRA_DIST = src
-
-jsdir = $(datadir)/wok/plugins/kimchi/ui/js
-
-dist_js_DATA = kimchi.min.js $(filter-out kimchi.min.js, $(wildcard *.js))
-
-kimchi.min.js: src/*.js
- cat $(sort $^) > $@
-
-CLEANFILES = kimchi.min.js
diff --git a/plugins/kimchi/ui/js/src/kimchi.api.js
b/plugins/kimchi/ui/js/src/kimchi.api.js
deleted file mode 100644
index fde803a..0000000
--- a/plugins/kimchi/ui/js/src/kimchi.api.js
+++ /dev/null
@@ -1,1355 +0,0 @@
-/*
- * Project Kimchi
- *
- * Copyright IBM, Corp. 2013-2015
- *
- * 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.
- */
-var kimchi = {
-
- widget: {},
-
- trackingTasks: [],
-
- /**
- *
- * Get host capabilities
- * suc: callback if succeed err: callback if failed
- */
- getCapabilities : function(suc, err, done) {
- done = typeof done !== 'undefined' ? done: function(){};
- wok.requestJSON({
- url : "plugins/kimchi/config/capabilities",
- type : "GET",
- contentType : "application/json",
- dataType : "json",
- success: suc,
- error: err,
- complete: done
- });
- },
-
- /**
- * Get the i18 strings.
- */
- getI18n: function(suc, err, url, sync) {
- wok.requestJSON({
- url : url ? url : 'plugins/kimchi/i18n.json',
- type : 'GET',
- resend: true,
- dataType : 'json',
- async : !sync,
- success : suc,
- error: err
- });
- },
-
- /**
- * Get the host static information.
- */
- getHost: function(suc, err) {
- wok.requestJSON({
- url : 'plugins/kimchi/host',
- type : 'GET',
- resend: true,
- contentType : 'application/json',
- dataType : 'json',
- success : suc,
- error: err
- });
- },
-
- /**
- * Get the dynamic host stats (usually used for monitoring).
- */
- getHostStats : function(suc, err) {
- wok.requestJSON({
- url : 'plugins/kimchi/host/stats',
- type : 'GET',
- contentType : 'application/json',
- headers: {'Wok-Robot': 'wok-robot'},
- dataType : 'json',
- success : suc,
- error: err
- });
- },
-
- /**
- * Get the historic host stats.
- */
- getHostStatsHistory : function(suc, err) {
- wok.requestJSON({
- url : 'plugins/kimchi/host/stats/history',
- type : 'GET',
- resend: true,
- contentType : 'application/json',
- headers: {'Wok-Robot': 'wok-robot'},
- dataType : 'json',
- success : suc,
- error: err
- });
- },
-
- /**
- *
- * Create a new Virtual Machine. Usage: kimchi.createVM({ name: 'MyUbuntu',
- * template: '/templates/ubuntu_base' }, creationSuc, creationErr);
- *
- * settings: name *(optional)*: The name of the VM. Used to identify the VM
- * in this API. If omitted, a name will be chosen based on the template
- * used. template: The URI of a Template to use when building the VM
- * storagepool *(optional)*: Assign a specific Storage Pool to the new VM
- * suc: callback if succeed err: callback if failed
- */
- createVM : function(settings, suc, err) {
- wok.requestJSON({
- url : "plugins/kimchi/vms",
- type : "POST",
- contentType : "application/json",
- data : JSON.stringify(settings),
- dataType : "json"
- }).done(suc).fail(err);
- },
-
- /**
- *
- * Create a new Template. settings name: The name of the Template. Used to
- * identify the Template in this API suc: callback if succeed err: callback
- * if failed
- */
- createTemplate : function(settings, suc, err) {
- wok.requestJSON({
- url : "plugins/kimchi/templates",
- type : "POST",
- contentType : "application/json",
- data : JSON.stringify(settings),
- dataType : "json",
- success: suc,
- error: err
- });
- },
-
- deleteTemplate : function(tem, suc, err) {
- wok.requestJSON({
- url : 'plugins/kimchi/templates/' + encodeURIComponent(tem),
- type : 'DELETE',
- contentType : 'application/json',
- dataType : 'json',
- success : suc,
- error : err
- });
- },
-
- cloneTemplate : function(tem, suc, err) {
- wok.requestJSON({
- url : 'plugins/kimchi/templates/' + encodeURIComponent(tem) +
"/clone",
- type : 'POST',
- contentType : 'application/json',
- dataType : 'json',
- success : suc,
- error : err
- });
- },
-
- listTemplates : function(suc, err) {
- wok.requestJSON({
- url : 'plugins/kimchi/templates',
- type : 'GET',
- contentType : 'application/json',
- dataType : 'json',
- success : suc,
- error : err
- });
- },
-
- /**
- * Retrieve the information of a template by the given name.
- */
- retrieveTemplate : function(templateName, suc, err) {
- wok.requestJSON({
- url : 'plugins/kimchi/templates/' +
encodeURIComponent(templateName),
- type : 'GET',
- contentType : 'application/json',
- dataType : 'json'
- }).done(suc);
- },
-
- /**
- * Update a template with new information. TODO: Update me when the RESTful
- * API is available. Now work it around by remove the template and then
- * recreate it with new information.
- */
- updateTemplate : function(name, settings, suc, err) {
- $.ajax({
- url : 'plugins/kimchi/templates/' + encodeURIComponent(name),
- type : 'PUT',
- contentType : 'application/json',
- data : JSON.stringify(settings),
- dataType : 'json'
- }).done(suc).fail(err);
- },
-
- /**
- * Create a new Storage Pool. settings name: The name of the Storage Pool
- * path: The path of the defined Storage Pool type: The type of the defined
- * Storage Pool capacity: The total space which can be used to store volumes
- * The unit is MBytes suc: callback if succeed err: callback if failed
- */
- createStoragePool : function(settings, suc, err) {
- wok.requestJSON({
- url : 'plugins/kimchi/storagepools',
- type : 'POST',
- contentType : 'application/json',
- data : JSON.stringify(settings),
- dataType : 'json'
- }).done(suc).fail(err);
- },
-
- updateStoragePool : function(name, content, suc, err) {
- $.ajax({
- url : "plugins/kimchi/storagepools/" + encodeURIComponent(name),
- type : 'PUT',
- contentType : 'application/json',
- dataType : 'json',
- data : JSON.stringify(content)
- }).done(suc).fail(err ? err : function(data) {
- wok.message.error(data.responseJSON.reason);
- });
- },
-
- startVM : function(vm, suc, err) {
- wok.requestJSON({
- url : 'plugins/kimchi/vms/' + encodeURIComponent(vm) +
'/start',
- type : 'POST',
- contentType : 'application/json',
- dataType : 'json',
- success : suc,
- error : err
- });
- },
-
- poweroffVM : function(vm, suc, err) {
- wok.requestJSON({
- url : 'plugins/kimchi/vms/' + encodeURIComponent(vm) +
'/poweroff',
- type : 'POST',
- contentType : 'application/json',
- dataType : 'json',
- success : suc,
- error : err
- });
- },
-
- shutdownVM : function(vm, suc, err) {
- wok.requestJSON({
- url : 'plugins/kimchi/vms/' + encodeURIComponent(vm) +
'/shutdown',
- type : 'POST',
- contentType : 'application/json',
- dataType : 'json',
- success : suc,
- error : err
- });
- },
-
- resetVM : function(vm, suc, err) {
- wok.requestJSON({
- url : 'plugins/kimchi/vms/' + encodeURIComponent(vm) +
'/reset',
- type : 'POST',
- contentType : 'application/json',
- dataType : 'json',
- success : suc,
- error : err
- });
- },
-
- suspendVM : function(vm, suc, err) {
- wok.requestJSON({
- url : 'plugins/kimchi/vms/' + encodeURIComponent(vm) +
'/suspend',
- type : 'POST',
- contentType : 'application/json',
- dataType : 'json',
- success : suc,
- error : err
- });
- },
-
- resumeVM : function(vm, suc, err) {
- wok.requestJSON({
- url : 'plugins/kimchi/vms/' + encodeURIComponent(vm) +
'/resume',
- type : 'POST',
- contentType : 'application/json',
- dataType : 'json',
- success : suc,
- error : err
- });
- },
-
- /**
- * Retrieve the information of a given VM by its name.
- *
- * @param vm VM name
- * @param suc callback for success
- * @param err callback for error
- */
- retrieveVM : function(vm, suc, err) {
- $.ajax({
- url : 'plugins/kimchi/vms/' + encodeURIComponent(vm),
- type : 'GET',
- contentType : 'application/json',
- dataType : 'json',
- success: suc,
- error: err
- });
- },
-
- /**
- * Update a VM with new information.
- */
- updateVM : function(name, settings, suc, err) {
- $.ajax({
- url : "plugins/kimchi/vms/" + encodeURIComponent(name),
- type : 'PUT',
- contentType : 'application/json',
- data : JSON.stringify(settings),
- dataType : 'json',
- success: suc,
- error: err
- });
- },
-
- deleteVM : function(vm, suc, err) {
- wok.requestJSON({
- url : 'plugins/kimchi/vms/' + encodeURIComponent(vm),
- type : 'DELETE',
- contentType : 'application/json',
- dataType : 'json',
- success : suc,
- error : err
- });
- },
-
- vncToVM : function(vm) {
- wok.requestJSON({
- url : 'plugins/kimchi/config',
- type : 'GET',
- dataType : 'json'
- }).done(function(data, textStatus, xhr) {
- proxy_port = data['display_proxy_port'];
- wok.requestJSON({
- url : "plugins/kimchi/vms/" + encodeURIComponent(vm) +
"/connect",
- type : "POST",
- dataType : "json"
- }).done(function() {
- url = 'https://' + location.hostname + ':' + proxy_port;
- url += "/console.html?url=";
- url +=
encodeURIComponent("plugins/kimchi/novnc/vnc_auto.html");
- url += "&port=" + proxy_port;
- /*
- * From python documentation base64.urlsafe_b64encode(s)
- * substitutes - instead of + and _ instead of / in the
- * standard Base64 alphabet, BUT the result can still
- * contain = which is not safe in a URL query component.
- * So remove it when needed as base64 can work well without it.
- * */
- url += "&path=?token=" +
wok.urlSafeB64Encode(vm).replace(/=*$/g, "");
- url += "&wok=" + location.port;
- url += '&encrypt=1';
- window.open(url);
- });
- }).error(function() {
- wok.message.error.code('KCHAPI6002E');
- });
- },
-
- spiceToVM : function(vm) {
- wok.requestJSON({
- url : 'plugins/kimchi/config',
- type : 'GET',
- dataType : 'json'
- }).done(function(data, textStatus, xhr) {
- proxy_port = data['display_proxy_port'];
- wok.requestJSON({
- url : "plugins/kimchi/vms/" + encodeURIComponent(vm) +
"/connect",
- type : "POST",
- dataType : "json"
- }).done(function(data, textStatus, xhr) {
- url = 'https://' + location.hostname + ':' + proxy_port;
- url += "/console.html?url=plugins/kimchi/spice_auto.html";
- url += "&port=" + proxy_port + "&listen=" +
location.hostname;
- /*
- * From python documentation base64.urlsafe_b64encode(s)
- * substitutes - instead of + and _ instead of / in the
- * standard Base64 alphabet, BUT the result can still
- * contain = which is not safe in a URL query component.
- * So remove it when needed as base64 can work well without it.
- * */
- url += "&token=" + wok.urlSafeB64Encode(vm).replace(/=*$/g,
"");
- url += "&wok=" + location.port;
- url += '&encrypt=1';
- window.open(url);
- });
- }).error(function() {
- wok.message.error.code('KCHAPI6002E');
- });
- },
-
- listVMs : function(suc, err) {
- wok.requestJSON({
- url : 'plugins/kimchi/vms',
- type : 'GET',
- contentType : 'application/json',
- headers: {'Wok-Robot': 'wok-robot'},
- dataType : 'json',
- resend: true,
- success : suc,
- error : err
- });
- },
-
- listTemplates : function(suc, err) {
- wok.requestJSON({
- url : 'plugins/kimchi/templates',
- type : 'GET',
- contentType : 'application/json',
- dataType : 'json',
- resend: true,
- success : suc,
- error : err
- });
- },
-
- listStoragePools : function(suc, err) {
- wok.requestJSON({
- url : 'plugins/kimchi/storagepools',
- type : 'GET',
- contentType : 'application/json',
- dataType : 'json',
- resend: true,
- success : suc,
- error : err
- });
- },
-
- listStorageVolumes : function(poolName, suc, err) {
- $.ajax({
- url : 'plugins/kimchi/storagepools/' + encodeURIComponent(poolName) +
'/storagevolumes',
- type : 'GET',
- contentType : 'application/json',
- dataType : 'json',
- success : suc,
- error : err
- });
- },
-
- listIsos : function(suc, err) {
- wok.requestJSON({
- url : 'plugins/kimchi/storagepools/kimchi_isos/storagevolumes',
- type : 'GET',
- contentType : 'application/json',
- dataType : 'json',
- success : suc,
- error : err
- });
- },
-
- listDistros : function(suc, err) {
- wok.requestJSON({
- url : 'plugins/kimchi/config/distros',
- type : 'GET',
- contentType : 'application/json',
- dataType : 'json',
- success : suc,
- error : err
- });
- },
-
- stepListDeepScanIsos : function(suc, err) {
- var deepScanHandler = {
- stop : false
- };
- var isoPool = 'iso' + new Date().getTime();
- kimchi.createStoragePool({
- name : isoPool,
- type : 'kimchi-iso',
- path : '/'
- }, function(result) {
- var taskId = result.task_id;
- function monitorTask() {
- if (deepScanHandler.stop) {
- return;
- }
- kimchi.getTask(taskId, function(result) {
- var status = result.status;
- if (status === "finished") {
- if (deepScanHandler.stop) {
- return;
- }
- kimchi.listStorageVolumes(isoPool, function(isos) {
- if (deepScanHandler.stop) {
- return;
- }
- suc(isos, true);
- }, err);
- } else if (status === "running") {
- if (deepScanHandler.stop) {
- return;
- }
- kimchi.listStorageVolumes(isoPool, function(isos) {
- if (deepScanHandler.stop) {
- return;
- }
- suc(isos, false);
- setTimeout(monitorTask, 2000);
- }, err);
- } else if (status === "failed") {
- if (deepScanHandler.stop) {
- return;
- }
- err(result.message);
- }
- }, err);
- }
- setTimeout(monitorTask, 2000);
- }, err);
- return deepScanHandler;
- },
-
- getTask : function(taskId, suc, err) {
- wok.requestJSON({
- url : 'tasks/' + encodeURIComponent(taskId),
- type : 'GET',
- contentType : 'application/json',
- dataType : 'json',
- success : suc,
- error : err
- });
- },
-
- getTasksByFilter : function(filter, suc, err, sync) {
- wok.requestJSON({
- url : 'tasks?' + filter,
- type : 'GET',
- contentType : 'application/json',
- dataType : 'json',
- async : !sync,
- success : suc,
- error : err
- });
- },
-
- deleteStoragePool : function(poolName, suc, err) {
- $.ajax({
- url : 'plugins/kimchi/storagepools/' + encodeURIComponent(poolName),
- type : 'DELETE',
- contentType : 'application/json',
- dataType : 'json',
- success : suc,
- error : err
- });
- },
-
- changePoolState : function(poolName, state, suc, err) {
- if (state === 'activate' || state === 'deactivate')
- $.ajax({
- url : 'plugins/kimchi/storagepools/' +
encodeURIComponent(poolName) + '/' + state,
- type : 'POST',
- contentType : 'application/json',
- dataType : 'json',
- success : suc,
- error : err
- });
- },
-
- listNetworks : function(suc, err) {
- wok.requestJSON({
- url : 'plugins/kimchi/networks',
- type : 'GET',
- contentType : 'application/json',
- dataType : 'json',
- resend : true,
- success : suc,
- error : err ? err : function(data) {
- wok.message.error(data.responseJSON.reason);
- }
- });
- },
-
- toggleNetwork : function(name, on, suc, err) {
- var action = on ? "activate" : "deactivate";
- wok.requestJSON({
- url : 'plugins/kimchi/networks/' + encodeURIComponent(name) +
'/' + action,
- type : 'POST',
- contentType : 'application/json',
- dataType : 'json',
- success : suc,
- error : err ? err : function(data) {
- wok.message.error(data.responseJSON.reason);
- }
- });
- },
-
- createNetwork : function(network, suc, err) {
- wok.requestJSON({
- url : 'plugins/kimchi/networks',
- type : 'POST',
- contentType : 'application/json',
- dataType : 'json',
- data : JSON.stringify(network),
- success : suc,
- error : err ? err : function(data) {
- wok.message.error(data.responseJSON.reason);
- }
- });
- },
-
- getInterfaces : function(suc, err) {
- wok.requestJSON({
- url : 'plugins/kimchi/interfaces',
- type : 'GET',
- contentType : 'application/json',
- dataType : 'json',
- resend : true,
- success : suc,
- error : err ? err : function(data) {
- wok.message.error(data.responseJSON.reason);
- }
- });
- },
-
- deleteNetwork : function(name, suc, err) {
- wok.requestJSON({
- url : 'plugins/kimchi/networks/' + encodeURIComponent(name),
- type : 'DELETE',
- contentType : 'application/json',
- dataType : 'json',
- success : suc,
- error : err ? err : function(data) {
- wok.message.error(data.responseJSON.reason);
- }
- });
- },
-
- listReports : function(suc, err) {
- wok.requestJSON({
- url : 'plugins/kimchi/debugreports',
- type : 'GET',
- contentType : 'application/json',
- dataType : 'json',
- resend: true,
- success : suc,
- error : err
- });
- },
-
- trackTask : function(taskID, suc, err, progress) {
- var onTaskResponse = function(result) {
- var taskStatus = result['status'];
- switch(taskStatus) {
- case 'running':
- progress && progress(result);
- setTimeout(function() {
- kimchi.trackTask(taskID, suc, err, progress);
- }, 2000);
- break;
- case 'finished':
- suc && suc(result);
- break;
- case 'failed':
- err && err(result);
- break;
- default:
- break;
- }
- };
-
- kimchi.getTask(taskID, onTaskResponse, err);
- if(kimchi.trackingTasks.indexOf(taskID) < 0)
- kimchi.trackingTasks.push(taskID);
- },
-
- createReport: function(settings, suc, err, progress) {
- var onResponse = function(data) {
- taskID = data['id'];
- kimchi.trackTask(taskID, suc, err, progress);
- };
-
- wok.requestJSON({
- url : 'plugins/kimchi/debugreports',
- type : "POST",
- contentType : "application/json",
- data : JSON.stringify(settings),
- dataType : "json",
- success : onResponse,
- error : err
- });
- },
-
- renameReport : function(name, settings, suc, err) {
- $.ajax({
- url : "plugins/kimchi/debugreports/" + encodeURIComponent(name),
- type : 'PUT',
- contentType : 'application/json',
- data : JSON.stringify(settings),
- dataType : 'json',
- success: suc,
- error: err
- });
- },
-
- deleteReport: function(settings, suc, err) {
- var reportName = encodeURIComponent(settings['name']);
- wok.requestJSON({
- url : 'plugins/kimchi/debugreports/' + reportName,
- type : 'DELETE',
- contentType : 'application/json',
- dataType : 'json',
- success : suc,
- error : err
- });
- },
-
- downloadReport: function(settings, suc, err) {
- window.open(settings['file']);
- },
-
- shutdown: function(settings, suc, err) {
- var reboot = settings && settings['reboot'] === true;
- var url = 'plugins/kimchi/host/' + (reboot ? 'reboot' :
'shutdown');
- wok.requestJSON({
- url : url,
- type : 'POST',
- contentType : 'application/json',
- dataType : 'json',
- success : suc,
- error : err
- });
- },
-
- listHostPartitions : function(suc, err) {
- wok.requestJSON({
- url : 'plugins/kimchi/host/partitions',
- type : 'GET',
- contentType : 'application/json',
- dataType : 'json',
- success : suc,
- error : err
- });
- },
-
- getStorageServers: function(type, suc, err) {
- var url = 'plugins/kimchi/storageservers?_target_type=' + type;
- wok.requestJSON({
- url : url,
- type : 'GET',
- contentType : 'application/json',
- dataType : 'json',
- success : suc,
- error : err ? err : function(data) {
- wok.message.error(data.responseJSON.reason);
- }
- });
- },
-
- getStorageTargets: function(server,type, suc, err) {
- var url = 'plugins/kimchi/storageservers/' + server +
'/storagetargets?_target_type=' + type;
- wok.requestJSON({
- url : url,
- type : 'GET',
- contentType : 'application/json',
- timeout: 2000,
- dataType : 'json',
- success : suc,
- error : err
- });
- },
-
- getStoragePool: function(poolName, suc, err) {
- var url = 'plugins/kimchi/storagepools/' + encodeURIComponent(poolName);
- wok.requestJSON({
- url : url,
- type : 'GET',
- contentType : 'application/json',
- timeout: 2000,
- dataType : 'json',
- success : suc,
- error : err
- });
- },
-
- getStoragePoolVolume: function(poolName, volumeName, suc, err) {
- var url = 'plugins/kimchi/storagepools/' + encodeURIComponent(poolName) +
'/storagevolumes/' + encodeURIComponent(volumeName);
- wok.requestJSON({
- url : url,
- type : 'GET',
- contentType : 'application/json',
- timeout: 2000,
- dataType : 'json',
- success : suc,
- error : err
- });
- },
-
- addVMStorage : function(settings, suc, err) {
- var vm = encodeURIComponent(settings['vm']);
- delete settings['vm'];
- wok.requestJSON({
- url : 'plugins/kimchi/vms/' + vm + '/storages',
- type : 'POST',
- contentType : 'application/json',
- data : JSON.stringify(settings),
- dataType : 'json',
- success : suc,
- error : err
- });
- },
-
- retrieveVMStorage : function(settings, suc, err) {
- var vm = encodeURIComponent(settings['vm']);
- var dev = encodeURIComponent(settings['dev']);
- wok.requestJSON({
- url : "plugins/kimchi/vms/" + vm + '/storages/' + dev,
- type : 'GET',
- contentType : 'application/json',
- dataType : 'json',
- success: suc,
- error: err
- });
- },
-
- replaceVMStorage : function(settings, suc, err) {
- var vm = encodeURIComponent(settings['vm']);
- var dev = encodeURIComponent(settings['dev']);
- wok.requestJSON({
- url : 'plugins/kimchi/vms/' + vm + '/storages/' + dev,
- type : 'PUT',
- contentType : 'application/json',
- data : JSON.stringify({
- path: settings['path']
- }),
- dataType : 'json',
- success : suc,
- error : err
- });
- },
-
- deleteVMStorage : function(settings, suc, err) {
- var vm = settings['vm'];
- var dev = settings['dev'];
- wok.requestJSON({
- url : 'plugins/kimchi/vms/' + encodeURIComponent(vm) +
- '/storages/' + encodeURIComponent(dev),
- type : 'DELETE',
- contentType : 'application/json',
- dataType : 'json',
- success : suc,
- error : err
- });
- },
-
- listVMStorages : function(params, suc, err) {
- var vm = encodeURIComponent(params['vm']);
- var type = params['storageType'];
- var url = 'plugins/kimchi/vms/' + vm + '/storages';
- if(type) {
- url += '?type=' + type;
- }
- wok.requestJSON({
- url : url,
- type : 'GET',
- contentType : 'application/json',
- dataType : 'json',
- success : suc,
- error : err
- });
- },
-
- listSoftwareUpdates : function(suc, err) {
- wok.requestJSON({
- url : 'plugins/kimchi/host/packagesupdate',
- type : 'GET',
- contentType : 'application/json',
- dataType : 'json',
- resend: true,
- success : suc,
- error : err
- });
- },
-
- updateSoftware : function(suc, err, progress) {
- var taskID = -1;
- var onResponse = function(data) {
- taskID = data['id'];
- trackTask();
- };
-
- var trackTask = function() {
- kimchi.getTask(taskID, onTaskResponse, err);
- };
-
- var onTaskResponse = function(result) {
- var taskStatus = result['status'];
- switch(taskStatus) {
- case 'running':
- progress && progress(result);
- setTimeout(function() {
- trackTask();
- }, 200);
- break;
- case 'finished':
- case 'failed':
- suc(result);
- break;
- default:
- break;
- }
- };
-
- wok.requestJSON({
- url : 'plugins/kimchi/host/swupdate',
- type : "POST",
- contentType : "application/json",
- dataType : "json",
- success : onResponse,
- error : err
- });
- },
-
- createRepository : function(settings, suc, err) {
- wok.requestJSON({
- url : "plugins/kimchi/host/repositories",
- type : "POST",
- contentType : "application/json",
- data : JSON.stringify(settings),
- dataType : "json",
- success: suc,
- error: err
- });
- },
-
- retrieveRepository : function(repository, suc, err) {
- var reposID = encodeURIComponent(repository);
- wok.requestJSON({
- url : "plugins/kimchi/host/repositories/" + reposID,
- type : 'GET',
- contentType : 'application/json',
- dataType : 'json',
- success : suc,
- error : err
- });
- },
-
- updateRepository : function(name, settings, suc, err) {
- var reposID = encodeURIComponent(name);
- $.ajax({
- url : "plugins/kimchi/host/repositories/" + reposID,
- type : 'PUT',
- contentType : 'application/json',
- data : JSON.stringify(settings),
- dataType : 'json',
- success : suc,
- error : err
- });
- },
-
- enableRepository : function(name, enable, suc, err) {
- var reposID = encodeURIComponent(name);
- $.ajax({
- url : "plugins/kimchi/host/repositories/" + reposID +
- '/' + (enable === true ? 'enable' :
'disable'),
- type : 'POST',
- contentType : 'application/json',
- dataType : 'json',
- success : suc,
- error : err
- });
- },
-
- deleteRepository : function(repository, suc, err) {
- var reposID = encodeURIComponent(repository);
- wok.requestJSON({
- url : 'plugins/kimchi/host/repositories/' + reposID,
- type : 'DELETE',
- contentType : 'application/json',
- dataType : 'json',
- success : suc,
- error : err
- });
- },
-
- listRepositories : function(suc, err) {
- wok.requestJSON({
- url : 'plugins/kimchi/host/repositories',
- type : 'GET',
- contentType : 'application/json',
- dataType : 'json',
- resend: true,
- success : suc,
- error : err
- });
- },
-
- getHostFCDevices: function(suc, err) {
- var url = 'plugins/kimchi/host/devices?_cap=fc_host';
- wok.requestJSON({
- url : url,
- type : 'GET',
- contentType : 'application/json',
- dataType : 'json',
- success : suc,
- error : err ? err : function(data) {
- wok.message.error(data.responseJSON.reason);
- }
- });
- },
-
- getGuestInterfaces: function(name, suc, err) {
- var url = 'plugins/kimchi/vms/' + encodeURIComponent(name) +
'/ifaces';
- wok.requestJSON({
- url : url,
- type : 'GET',
- contentType : 'application/json',
- dataType : 'json',
- success : suc,
- error : err || function(data) {
- wok.message.error(data.responseJSON.reason);
- }
- });
- },
-
- createGuestInterface : function(name, interface, suc, err) {
- wok.requestJSON({
- url : 'plugins/kimchi/vms/' + encodeURIComponent(name) +
'/ifaces',
- type : 'POST',
- contentType : 'application/json',
- dataType : 'json',
- data : JSON.stringify(interface),
- success : suc,
- error : err || function(data) {
- wok.message.error(data.responseJSON.reason);
- }
- });
- },
-
- deleteGuestInterface : function(vm, mac, suc, err) {
- wok.requestJSON({
- url : 'plugins/kimchi/vms/' + encodeURIComponent(vm) +
'/ifaces/' + encodeURIComponent(mac),
- type : 'DELETE',
- contentType : 'application/json',
- dataType : 'json',
- success : suc,
- error : err ? err : function(data) {
- wok.message.error(data.responseJSON.reason);
- }
- });
- },
-
- updateGuestInterface : function(vm, mac, interface, suc, err) {
- $.ajax({
- url : 'plugins/kimchi/vms/' + encodeURIComponent(vm) +
'/ifaces/' + encodeURIComponent(mac),
- type : 'PUT',
- contentType : 'application/json',
- data : JSON.stringify(interface),
- dataType : 'json',
- success: suc,
- error: err ? err : function(data) {
- wok.message.error(data.responseJSON.reason);
- }
- });
- },
-
- getUserById : function(data, suc, err) {
- wok.requestJSON({
- url : 'plugins/kimchi/users?_user_id=' + data.user_id,
- type : 'GET',
- contentType : 'application/json',
- dataType : 'json',
- resend : true,
- async : false,
- success : suc && suc(data),
- error : err ? err : function(data) {
- wok.message.error(data.responseJSON.reason);
- }
- });
- },
-
- getUsers : function(suc, err) {
- wok.requestJSON({
- url : 'plugins/kimchi/users',
- type : 'GET',
- contentType : 'application/json',
- dataType : 'json',
- resend : true,
- success : suc,
- error : err ? err : function(data) {
- wok.message.error(data.responseJSON.reason);
- }
- });
- },
-
- getGroups : function(suc, err) {
- wok.requestJSON({
- url : 'plugins/kimchi/groups',
- type : 'GET',
- contentType : 'application/json',
- dataType : 'json',
- resend : true,
- success : suc,
- error : err ? err : function(data) {
- wok.message.error(data.responseJSON.reason);
- }
- });
- },
-
- getHostPCIDevices : function(suc, err) {
- wok.requestJSON({
- url : 'plugins/kimchi/host/devices?_passthrough=true&_cap=pci',
- type : 'GET',
- contentType : 'application/json',
- dataType : 'json',
- resend : true,
- success : suc,
- error : err ? err : function(data) {
- wok.message.error(data.responseJSON.reason);
- }
- });
- },
-
- getPCIDeviceCompanions : function(pcidev, suc, err) {
- wok.requestJSON({
- url : 'plugins/kimchi/host/devices?_passthrough_affected_by=' +
pcidev,
- type : 'GET',
- contentType : 'application/json',
- dataType : 'json',
- resend : true,
- success : suc,
- error : err ? err : function(data) {
- wok.message.error(data.responseJSON.reason);
- }
- });
- },
-
- getISCSITargets : function(server, port, suc, err) {
- server = encodeURIComponent(server);
- port = port ? '&_server_port='+encodeURIComponent(port) :
'';
- wok.requestJSON({
- url : 'plugins/kimchi/storageservers/' + server +
'/storagetargets?_target_type=iscsi' + port,
- type : 'GET',
- contentType : 'application/json',
- dataType : 'json',
- resend : true,
- success : suc,
- error : err ? err : function(data) {
- wok.message.error(data.responseJSON.reason);
- }
- });
- },
-
- getPeers : function(suc, err) {
- wok.requestJSON({
- url : 'plugins/kimchi/peers',
- type : 'GET',
- contentType : 'application/json',
- dataType : 'json',
- resend : true,
- success : suc,
- error : err ? err : function(data) {
- wok.message.error(data.responseJSON.reason);
- }
- });
- },
-
- getVMPCIDevices : function(id, suc, err) {
- wok.requestJSON({
- url : 'plugins/kimchi/vms/' + encodeURIComponent(id) +
'/hostdevs',
- type : 'GET',
- contentType : 'application/json',
- dataType : 'json',
- resend : true,
- success : suc,
- error : err ? err : function(data) {
- wok.message.error(data.responseJSON.reason);
- }
- });
- },
-
- addVMPCIDevice : function(vm, device, suc, err) {
- wok.requestJSON({
- url : 'plugins/kimchi/vms/'+ encodeURIComponent(vm)
+'/hostdevs',
- type : 'POST',
- contentType : 'application/json',
- dataType : 'json',
- data : JSON.stringify(device),
- success : suc,
- error : err ? err : function(data) {
- wok.message.error(data.responseJSON.reason);
- }
- });
- },
-
- removeVMPCIDevice : function(vm, device, suc, err) {
- wok.requestJSON({
- url : 'plugins/kimchi/vms/'+ encodeURIComponent(vm)
+'/hostdevs/' + encodeURIComponent(device),
- type : 'DELETE',
- contentType : 'application/json',
- dataType : 'json',
- success : suc,
- error : err ? err : function(data) {
- wok.message.error(data.responseJSON.reason);
- }
- });
- },
-
- /**
- * Create a new volume with capacity
- */
- createVolumeWithCapacity: function(poolName, settings, suc, err) {
- wok.requestJSON({
- url : 'plugins/kimchi/storagepools/' + encodeURIComponent(poolName) +
'/storagevolumes',
- type : 'POST',
- contentType : "application/json",
- data : JSON.stringify(settings),
- dataType : "json",
- success : suc,
- error : err
- });
- },
-
- /**
- * Upload volume content
- */
- uploadVolumeToSP: function(poolName, volumeName, settings, suc, err) {
- var url = 'plugins/kimchi/storagepools/' + encodeURIComponent(poolName) +
'/storagevolumes/' + encodeURIComponent(volumeName);
- var fd = settings['formData'];
- wok.requestJSON({
- url : url,
- type : 'PUT',
- data : fd,
- processData : false,
- contentType : false,
- dataType: 'json',
- success : suc,
- error : err
- });
- },
-
- /**
- * Add a volume to a given storage pool by URL.
- */
- downloadVolumeToSP: function(settings, suc, err) {
- var sp = encodeURIComponent(settings['sp']);
- delete settings['sp'];
- wok.requestJSON({
- url : 'plugins/kimchi/storagepools/' + sp +
'/storagevolumes',
- type : 'POST',
- data : JSON.stringify(settings),
- contentType : 'application/json',
- dataType : 'json',
- success : suc,
- error : err
- });
- },
-
- cloneGuest: function(vm, suc, err) {
- wok.requestJSON({
- url : 'plugins/kimchi/vms/' + encodeURIComponent(vm) +
"/clone",
- type : 'POST',
- contentType : 'application/json',
- dataType : 'json',
- success : suc,
- error : err ? err : function(data) {
- wok.message.error(data.responseJSON.reason);
- }
- });
- },
-
- listSnapshots : function(vm, suc, err) {
- wok.requestJSON({
- url : 'plugins/kimchi/vms/' + encodeURIComponent(vm) +
'/snapshots',
- type : 'GET',
- contentType : 'application/json',
- dataType : 'json',
- resend : true,
- success : suc,
- error : err ? err : function(data) {
- wok.message.error(data.responseJSON.reason);
- }
- });
- },
-
- getCurrentSnapshot : function(vm, suc, err, sync) {
- wok.requestJSON({
- url : 'plugins/kimchi/vms/' + encodeURIComponent(vm) +
'/snapshots/current',
- type : 'GET',
- contentType : 'application/json',
- dataType : 'json',
- async : !sync,
- resend : true,
- success : suc,
- error : err ? err : function(data) {
- wok.message.error(data.responseJSON.reason);
- }
- });
- },
-
- revertSnapshot : function(vm, snapshot, suc, err) {
- wok.requestJSON({
- url : 'plugins/kimchi/vms/' + encodeURIComponent(vm) +
'/snapshots/' + encodeURIComponent(snapshot) + '/revert',
- type : 'POST',
- contentType : 'application/json',
- dataType : 'json',
- success : suc,
- error : err ? err : function(data) {
- wok.message.error(data.responseJSON.reason);
- }
- });
- },
-
- createSnapshot : function(vm, suc, err) {
- wok.requestJSON({
- url : 'plugins/kimchi/vms/' + encodeURIComponent(vm) +
'/snapshots',
- type : 'POST',
- contentType : 'application/json',
- dataType : 'json',
- success : suc,
- error : err ? err : function(data) {
- wok.message.error(data.responseJSON.reason);
- }
- });
- },
-
- deleteSnapshot : function(vm, snapshot, suc, err) {
- wok.requestJSON({
- url : 'plugins/kimchi/vms/' + encodeURIComponent(vm) +
'/snapshots/' + encodeURIComponent(snapshot),
- type : 'DELETE',
- contentType : 'application/json',
- dataType : 'json',
- success : suc,
- error : err ? err : function(data) {
- wok.message.error(data.responseJSON.reason);
- }
- });
- },
-
- getCPUInfo : function(suc, err) {
- wok.requestJSON({
- url : 'plugins/kimchi/host/cpuinfo',
- type : 'GET',
- contentType : 'application/json',
- dataType : 'json',
- resend : true,
- success : suc,
- error : err ? err : function(data) {
- wok.message.error(data.responseJSON.reason);
- }
- });
- }
-};
diff --git a/plugins/kimchi/ui/js/src/kimchi.guest_add_main.js
b/plugins/kimchi/ui/js/src/kimchi.guest_add_main.js
deleted file mode 100644
index 6be6f9a..0000000
--- a/plugins/kimchi/ui/js/src/kimchi.guest_add_main.js
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
- * Project Kimchi
- *
- * Copyright IBM, Corp. 2013-2014
- *
- * 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.
- */
-kimchi.guest_add_main = function() {
- var showTemplates = function() {
- wok.topic('templateCreated').unsubscribe(showTemplates);
- kimchi.listTemplates(function(result) {
- if (result && result.length) {
- $('#prompt-create-template').addClass('hidden');
- $('#prompt-choose-template').removeClass('hidden');
- var html = '';
- var tmpl = $('#tmpl-template').html();
- $.each(result, function(index, value) {
- html += wok.substitute(tmpl, value);
- });
- $('#templateTile').html(html);
- return;
- }
-
- $('#btn-create-template').on('click', function(event) {
- wok.topic('templateCreated').subscribe(showTemplates);
-
- wok.window.open('plugins/kimchi/template-add.html');
-
- event.preventDefault();
- });
-
- $('#prompt-choose-template').addClass('hidden');
- $('#prompt-create-template').removeClass('hidden');
- }, function(err) {
- wok.message.error(err.responseJSON.reason);
- });
- };
-
- function validateForm() {
- if (!$('input[name=template]:checked', '#templateTile').val()) {
- return false;
- }
- return true;
- }
-
- $('#form-vm-add').change(function() {
- if (validateForm()) {
- $('#vm-doAdd').attr('disabled', false);
- }
- });
-
- var addGuest = function(event) {
- $('#vm-doAdd').attr('disabled', true);
- $('#vm-doAdd').attr('style', 'display:none');
- $('#vm-doAdding').attr('style', 'display');
- var formData = $('#form-vm-add').serializeObject();
- kimchi.createVM(formData, function() {
- kimchi.listVmsAuto();
- wok.window.close();
- }, function(jqXHR, textStatus, errorThrown) {
- $('#vm-doAdd').attr('style', 'display');
- $('#vm-doAdding').attr('style', 'display:none');
- var reason = jqXHR &&
- jqXHR['responseJSON'] &&
- jqXHR['responseJSON']['reason'];
- wok.message.error(reason);
- });
-
- return false;
- };
-
- $('#form-vm-add').on('submit', addGuest);
- $('#vm-doAdd').on('click', addGuest);
-
- showTemplates();
-};
diff --git a/plugins/kimchi/ui/js/src/kimchi.guest_edit_main.js
b/plugins/kimchi/ui/js/src/kimchi.guest_edit_main.js
deleted file mode 100644
index 7105c88..0000000
--- a/plugins/kimchi/ui/js/src/kimchi.guest_edit_main.js
+++ /dev/null
@@ -1,759 +0,0 @@
-/*
- * Project Kimchi
- *
- * Copyright IBM, Corp. 2013-2015
- *
- * 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.
- */
-kimchi.guest_edit_main = function() {
- var buttonContainer = $('#action-button-container');
- $('#guest-edit-tabs').tabs({
- beforeActivate: function(event, ui) {
- var display_list = null;
- if(kimchi.thisVMState === "running") {
- display_list = ['form-guest-edit-permission'];
- } else {
- display_list = ['form-guest-edit-general',
'form-guest-edit-permission'];
- }
- $(buttonContainer).addClass('hidden');
- var deactivated = ui['newPanel'];
- if(display_list.indexOf($(deactivated).attr('id')) >= 0) {
- $(buttonContainer).removeClass('hidden');
- }
- }
- });
-
- var guestEditForm = $('#form-guest-edit-general');
- var saveButton = $('#guest-edit-button-save');
- var authType;
-
- var refreshCDROMs = function() {
- kimchi.listVMStorages({
- vm: kimchi.selectedGuest
- }, function(storages) {
- var container = $('#form-guest-edit-storage .body');
- $(container).empty();
- $.each(storages, function(index, storage) {
- storage['vm'] = kimchi.selectedGuest;
- rowHTML = $('#' + storage['type'] +
'-row-tmpl').html();
- var templated = wok.substitute(rowHTML, storage);
- container.append(templated);
- });
-
- $('.replace', container).button({
- icons: {
- primary: 'ui-icon-pencil'
- },
- text: false
- });
-
- $('.detach', container).button({
- icons: {
- primary: 'ui-icon-trash'
- },
- text: false
- });
- if (kimchi.thisVMState === 'running') {
- $('.detach[data-type="cdrom"]', container).remove();
- }
-
- $('.save', container).button({
- icons: {
- primary: 'ui-icon-disk'
- },
- text: false
- });
-
- $('.cancel', container).button({
- icons: {
- primary: 'ui-icon-arrowreturnthick-1-w'
- },
- text: false
- });
- });
- };
-
- var initStorageListeners = function() {
- var container = $('#form-guest-edit-storage .body');
- var toggleCDROM = function(rowNode, toEdit) {
- $('button.replace,button.detach', rowNode)
- [(toEdit ? 'add' : 'remove') +
'Class']('hidden');
- $('button.save,button.cancel', rowNode)
- [(toEdit ? 'remove' : 'add') +
'Class']('hidden');
- var pathBox = $('.path input', rowNode)
- .prop('readonly', !toEdit);
- toEdit && pathBox.select();
- pathBox.val(pathBox.attr('value'));
- };
-
- var replaceCDROM = function(event) {
- event.preventDefault();
- kimchi.selectedGuestStorage = $(this).data('dev');
- $('.item', container).each(function(i, n) {
- toggleCDROM(n);
- });
- var rowNode = $('#cdrom-' + kimchi.selectedGuestStorage);
- toggleCDROM(rowNode, true);
- };
-
- $(container).on('click', 'button.replace', replaceCDROM);
-
- $(container).on('click', 'button.detach', function(e) {
- e.preventDefault();
- var settings = {
- title : i18n['KCHAPI6004M'],
- content : i18n['KCHVMCD6001M'],
- confirm : i18n['KCHAPI6002M'],
- cancel : i18n['KCHAPI6003M']
- };
- if ($(this).data('type') == "disk")
- settings['content'] = i18n['KCHVMCD6009M'];
-
- var dev = $(this).data('dev');
- wok.confirm(settings, function() {
- kimchi.deleteVMStorage({
- vm: kimchi.selectedGuest,
- dev: dev
- }, function() {
- wok.topic('kimchi/vmCDROMDetached').publish();
- });
- });
- });
-
- $(container).on('click', 'button.save', function(event) {
- event.preventDefault();
- var path = $('#cdrom-path-' + kimchi.selectedGuestStorage).val();
- var settings = {
- vm: kimchi.selectedGuest,
- dev: kimchi.selectedGuestStorage,
- path: path
- };
-
- kimchi.replaceVMStorage(settings, function(result) {
- wok.topic('kimchi/vmCDROMReplaced').publish({
- result: result
- });
- }, function(result) {
- var errText = result['reason'] ||
- result['responseJSON']['reason'];
- wok.message.error(errText);
- });
- });
-
- $(container).on('click', 'button.cancel', function(event) {
- event.preventDefault();
- var rowNode = $('#cdrom-' + kimchi.selectedGuestStorage);
- toggleCDROM(rowNode);
- });
- };
-
- var setupInterface = function() {
- $(".add", "#form-guest-edit-interface").button({
- icons: { primary: "ui-icon-plusthick" },
- text: false
- }).click(function(evt){
- evt.preventDefault();
- addItem({
- id: -1,
- mac: "",
- network: "",
- type: "network",
- viewMode: "hide",
- editMode: ""
- });
- });
- var toggleEdit = function(item, on, itemId){
- $("#label-mac-" + itemId, item).toggleClass("hide", on);
- $("#edit-mac-" + itemId, item).toggleClass("hide", !on);
- $("#label-network-" + itemId, item).toggleClass("hide",
false);
- $("select", item).toggleClass("hide", true);
- $(".action-area", item).toggleClass("hide");
- };
- var addItem = function(data) {
- if (data.id == -1) {
- data.id = $('#form-guest-edit-interface >
.body').children().size()
- }
- var itemNode =
$.parseHTML(wok.substitute($('#interface-tmpl').html(),data));
- $(".body",
"#form-guest-edit-interface").append(itemNode);
- $("select", itemNode).append(networkOptions);
- if(data.network!==""){
- $("select", itemNode).val(data.network);
- }
- $(".edit", itemNode).button({
- disabled: kimchi.thisVMState === "running",
- icons: { primary: "ui-icon-pencil" },
- text: false
- }).click(function(evt){
- evt.preventDefault();
- toggleEdit($(this).closest('div'), true, data.id);
- });
- $(".delete", itemNode).button({
- icons: { primary: "ui-icon-trash" },
- text: false
- }).click(function(evt){
- evt.preventDefault();
- var item = $(this).parent().parent();
- kimchi.deleteGuestInterface(kimchi.selectedGuest,
item.prop("id"), function(){
- item.remove();
- });
- });
- $(".save", itemNode).button({
- icons: { primary: "ui-icon-disk" },
- text: false
- }).click(function(evt){
- evt.preventDefault();
- var item = $(this).parent().parent();
- var interface = {
- network: $("select", item).val(),
- type: "network",
- mac: $(":text", item).val()
- };
- var postUpdate = function(mac){
- $("#label-network-" + data.id,
item).text(interface.network);
- $("#label-mac-" + data.id, item).text(mac);
- $("#edit-mac-" + data.id, item).val(mac);
- toggleEdit(item, false, data.id);
- };
- if(item.prop("id")==""){
- kimchi.createGuestInterface(kimchi.selectedGuest, interface,
function(data){
- item.prop("id", data.mac);
- postUpdate(data.mac);
- });
- }else{
- if (item.prop('id') == interface.mac) {
- toggleEdit(item, false, data.id);
- } else {
- kimchi.updateGuestInterface(kimchi.selectedGuest,
item.prop('id'),
- interface, function(data){
- item.prop("id", data.mac);
- postUpdate(data.mac);
- });
- }
- }
- });
- $(".cancel", itemNode).button({
- icons: { primary: "ui-icon-arrowreturnthick-1-w" },
- text: false
- }).click(function(evt){
- evt.preventDefault();
- var item = $(this).parent().parent();
- $("label", item).text()==="" ? item.remove() :
toggleEdit(item, false, data.id);
- });
- };
- var networkOptions = "";
- kimchi.listNetworks(function(data){
- for(var i=0;i<data.length;i++){
- var isSlected = i==0 ? " selected" : "";
- networkOptions +=
"<option"+isSlected+">"+data[i].name+"</option>";
- }
- kimchi.getGuestInterfaces(kimchi.selectedGuest, function(data){
- for(var i=0;i<data.length;i++){
- data[i].viewMode = "";
- data[i].editMode = "hide";
- data[i].id = i;
- addItem(data[i]);
- }
- });
- });
- };
-
- var setupPermission = function() {
- //set up for LDAP
- $(".add", "#form-guest-edit-permission").button({
- icons: { primary: "ui-icon-plusthick" },
- text: false
- }).click(function(evt){
- evt.preventDefault();
- addItem({
- user: "",
- freeze: false,
- viewMode: "hide",
- editMode: "",
- checked: true
- });
- });
- var addItem = function(data) {
- var itemNode =
$.parseHTML(wok.substitute($('#ldap-user-tmpl').html(),data));
- $(".body", "#form-guest-edit-permission
.ldap").append(itemNode);
- $(".delete", itemNode).button({
- icons: { primary: "ui-icon-trash" },
- text: false
- }).click(function(evt){
- evt.preventDefault();
- var item = $(this).parent().parent();
- item.remove();
- });
- $("input").focusout(function() {
- var item = $(this).parent().parent();
- var user= $(this).val();
- item.prop("id", user);
- $("label", item).text(user);
- });
- $("input").focusin(function() {
- $(this).removeClass("checked");
- });
-
- if (data.checked == true) {
- $(".checked", itemNode).addClass("hide");
- }
- };
- var toggleEdit = function(item, on){
- $("label", item).toggleClass("hide", on);
- $("input", item).toggleClass("hide", !on);
- $(".action-area", item).toggleClass("hide");
- };
- //set up for PAM
- var userNodes = {}, groupNodes = {};
- authType = kimchi.capabilities['auth']
- if (authType == 'pam') {
- $("#form-guest-edit-permission .ldap").hide();
- kimchi.retrieveVM(kimchi.selectedGuest, function(vm){
- kimchi.getUsers(function(users){
- kimchi.getGroups(function(groups){
- var subArray = function(a1, a2){ //a1-a2
- for(var i=0; i<a2.length; i++){
- for(var j=0; j<a1.length; j++){
- if(a2[i] == a1[j]){
- a1.splice(j, 1);
- break;
- }
- }
- }
- };
- subArray(users, vm.users); subArray(groups, vm.groups);
- init(users, groups, vm.users, vm.groups);
- });
- });
- });
- } else if (authType == 'ldap') {
- $("#form-guest-edit-permission .pam").hide();
- kimchi.retrieveVM(kimchi.selectedGuest, function(vm){
- for (var i=0; i<vm.users.length; i++) {
- addItem({
- user: vm.users[i],
- viewMode: "",
- freeze: true,
- editMode: "hide",
- checked: true});
- }
- });
- }
- var sortNodes = function(container, isUser){
- nodes = container.children();
- var keys = [];
- nodes.each(function(){
- keys.push($("label", this).text());
- });
- keys.sort();
- container.empty();
- for(var i=0; i<keys.length; i++){
- var itemNode = isUser ? userNodes[keys[i]] : groupNodes[keys[i]];
- $(itemNode).click(function(){
- $(this).toggleClass("item-picked");
- });
- container.append(itemNode);
- }
- };
- var init = function(availUsers, availGroups, selUsers, selGroups){
- var initNode = function(key, isUserNode){
- var nodeGroups = isUserNode ? userNodes : groupNodes;
- nodeGroups[key] =
$.parseHTML(wok.substitute($('#permission-item-pam').html(), {
- val: key,
- class: isUserNode? "user-icon" : "group-icon"
- }));
- };
- for(var i=0; i<availUsers.length; i++){
- initNode(availUsers[i], true);
- $("#permission-avail-users").append(userNodes[availUsers[i]]);
- sortNodes($("#permission-avail-users"), true);
- }
- for(var i=0; i<selUsers.length; i++){
- initNode(selUsers[i], true);
- $("#permission-sel-users").append(userNodes[selUsers[i]]);
- sortNodes($("#permission-sel-users"), true);
- }
- for(var i=0; i<availGroups.length; i++){
- initNode(availGroups[i], false);
-
$("#permission-avail-groups").append(groupNodes[availGroups[i]]);
- sortNodes($("#permission-avail-groups"), false);
- }
- for(var i=0; i<selGroups.length; i++){
- initNode(selGroups[i], false);
- $("#permission-sel-groups").append(groupNodes[selGroups[i]]);
- sortNodes($("#permission-sel-groups"), false);
- }
- };
- var filterNodes = function(key, container){
- container.children().each(function(){
- $(this).css("display", $("label",
this).text().indexOf(key)==-1 ? "none" : "");
- });
- }
- $("#permission-avail-searchBox").on("keyup", function() {
- var key = $(this).val();
- filterNodes(key, $("#permission-avail-users"));
- filterNodes(key, $("#permission-avail-groups"));
- });
- $("#permission-sel-searchBox").on("keyup", function() {
- var key = $(this).val();
- filterNodes(key, $("#permission-sel-users"));
- filterNodes(key, $("#permission-sel-groups"));
- });
- $('#permissionGo').button().click(function(evt) {
- evt.preventDefault();
-
$("#permission-avail-users").children(".item-picked").appendTo("#permission-sel-users").removeClass("item-picked");
- sortNodes($("#permission-sel-users"), true);
-
$("#permission-avail-groups").children(".item-picked").appendTo("#permission-sel-groups").removeClass("item-picked");
- sortNodes($("#permission-sel-groups"), false);
- $("#permission-sel-searchBox").val("");
- filterNodes("", $("#permission-sel-users"));
- filterNodes("", $("#permission-sel-groups"));
- });
- $('#permissionBack').button().click(function(evt) {
- evt.preventDefault();
-
$("#permission-sel-users").children(".item-picked").appendTo("#permission-avail-users").removeClass("item-picked");
- sortNodes($("#permission-avail-users"), true);
-
$("#permission-sel-groups").children(".item-picked").appendTo("#permission-avail-groups").removeClass("item-picked");
- sortNodes($("#permission-avail-groups"), false);
- $("#permission-avail-searchBox").val("");
- filterNodes("", $("#permission-avail-users"));
- filterNodes("", $("#permission-avail-groups"));
- });
- }
- var setupPCIDevice = function(){
- kimchi.getHostPCIDevices(function(hostPCIs){
- kimchi.getVMPCIDevices(kimchi.selectedGuest, function(vmPCIs){
- var pciEnabled = kimchi.capabilities.kernel_vfio;
- for(var i=0; i<hostPCIs.length; i++){
- var itemNode =
$.parseHTML(wok.substitute($('#pci-tmpl').html(),{
- name: hostPCIs[i].name,
- product: hostPCIs[i].product.description,
- vendor: hostPCIs[i].vendor.description
- }));
- $(".body",
"#form-guest-edit-pci").append(itemNode);
- var iconClass = "ui-icon-plus";
- for(var j=0; j<vmPCIs.length; j++){
- if(hostPCIs[i].name==vmPCIs[j].name){
- iconClass = "ui-icon-minus";
- break;
- }
- }
- pciEnabled || $("button", itemNode).remove();
- $("button", itemNode).button({
- icons: { primary: iconClass },
- text: false
- }).click(function(){
- var obj = $(this);
- if(obj.button("option", "icons").primary ==
"ui-icon-minus"){
- kimchi.removeVMPCIDevice(kimchi.selectedGuest,
obj.parent().prop("id"), function(){
- kimchi.getVMPCIDevices(kimchi.selectedGuest,
function(vmPCIs1){
- for(var k=0; k<hostPCIs.length; k++) {
- $("button", "#" +
hostPCIs[k].name).button("option", "icons", {primary:
"ui-icon-plus"});
- }
- for(var k=0; k<vmPCIs1.length; k++) {
- $("button", "#" +
vmPCIs1[k].name).button("option", "icons", {primary:
"ui-icon-minus"});
- }
- });
- filterNodes($("select",
"#form-guest-edit-pci").val(), $("input",
"#form-guest-edit-pci").val());
- });
- } else {
- kimchi.addVMPCIDevice(kimchi.selectedGuest, { name:
obj.parent().prop("id") }, function(){
- kimchi.getVMPCIDevices(kimchi.selectedGuest,
function(vmPCIs1){
- for(var k=0; k<vmPCIs1.length; k++) {
- $("button", "#" +
vmPCIs1[k].name).button("option", "icons", {primary:
"ui-icon-minus"});
- }
- });
- filterNodes($("select",
"#form-guest-edit-pci").val(), $("input",
"#form-guest-edit-pci").val());
- });
- }
- });
- kimchi.getPCIDeviceCompanions(hostPCIs[i].name, function(infoData) {
- var pciTitle = i18n["KCHVMED6007M"] + "\n";
- var haveCompanions = false;
- for(var p=0; p<infoData.length; p++) {
- if(infoData[p].device_type === "net") {
- haveCompanions = true;
- pciTitle += " " + infoData[p].name +
"\n";
- pciTitle += " " +
i18n["KCHVMED6001M"] + " " + infoData[p].interface;
- pciTitle += ", " +
i18n["KCHVMED6002M"] + " " + infoData[p].address;
- pciTitle += ", " +
i18n["KCHVMED6003M"] + " " + infoData[p].link_type + "\n";
- } else if(infoData[p].device_type === "storage") {
- haveCompanions = true;
- pciTitle += " " + infoData[p].name +
"\n";
- pciTitle += " " +
i18n["KCHVMED6004M"] + " " + infoData[p].block;
- pciTitle += ", " +
i18n["KCHVMED6005M"] + " " + infoData[p].drive_type;
- pciTitle += ", " +
i18n["KCHVMED6006M"] + " " + infoData[p].model + "\n";
- }
- }
- for(var q=0; q<infoData.length; q++) {
- haveCompanions && $(".name", "#"
+ infoData[q].parent).attr("title", pciTitle);
- haveCompanions && $(".product",
"#" + infoData[q].parent).attr("title", pciTitle);
- haveCompanions && $(".vendor",
"#" + infoData[q].parent).attr("title", pciTitle);
- }
- });
- }
- });
- });
- var filterNodes = function(group, text){
- text = text.toLowerCase();
- $(".body",
"#form-guest-edit-pci").children().each(function(){
- var textFilter = $(".name",
this).text().toLowerCase().indexOf(text)!=-1;
- textFilter = textFilter || $(".product",
this).text().toLowerCase().indexOf(text)!=-1;
- textFilter = textFilter || $(".vendor",
this).text().toLowerCase().indexOf(text)!=-1;
- var display = "none";
- var itemGroup = $("button", this).button("option",
"icons").primary;
- if(textFilter){
- if(group == "all"){
- display = "";
- }else if(group=="toAdd" &&
itemGroup=="ui-icon-plus"){
- display = ""
- }else if(group == "added" &&
itemGroup=="ui-icon-minus"){
- display = ""
- }
- }
- $(this).css("display", display);
- });
- };
- $("select", "#form-guest-edit-pci").change(function(){
- filterNodes($(this).val(), $("input",
"#form-guest-edit-pci").val());
- });
- $("input", "#form-guest-edit-pci").on("keyup",
function() {
- filterNodes($("select", "#form-guest-edit-pci").val(),
$(this).val());
- });
- };
-
- var setupSnapshot = function() {
- var currentSnapshot;
- var setCurrentSnapshot = function(aSnapshot){
- if(!aSnapshot)
- kimchi.getCurrentSnapshot(kimchi.selectedGuest, function(snapshot){
- if(snapshot&&snapshot.name) aSnapshot = snapshot.name;
- }, null, true);
- if(aSnapshot){
- if(currentSnapshot) $(".ui-icon-check",
"#"+currentSnapshot).addClass("hide");
- $(".ui-icon-check",
"#"+aSnapshot).removeClass("hide");
- currentSnapshot = aSnapshot;
- }
- };
- var addItem = function(data, container) {
- var itemNode =
$.parseHTML(wok.substitute($('#snapshot-tmpl').html(),data));
- $("."+container,
"#form-guest-edit-snapshot").append(itemNode);
- $(".delete", itemNode).button({
- icons: { primary: "ui-icon-trash" },
- text: false
- }).click(function(evt){
- evt.preventDefault();
- var item = $(this).parent().parent();
- $("button",
"#form-guest-edit-snapshot").button("disable");
- kimchi.deleteSnapshot(kimchi.selectedGuest, item.prop("id"),
function(){
- item.remove();
- setCurrentSnapshot();
- $("button",
"#form-guest-edit-snapshot").button("enable");
- }, function(data){
- wok.message.error(data.responseJSON.reason);
- $("button",
"#form-guest-edit-snapshot").button("enable");
- });
- });
- $(".revert", itemNode).button({
- icons: { primary: "ui-icon-arrowthick-1-ne" },
- text: false
- }).click(function(evt){
- evt.preventDefault();
- var item = $(this).parent().parent();
- $(".ui-icon-check", item).addClass("hide");
- $(".icon", item).removeClass("hide");
- $("button",
"#form-guest-edit-snapshot").button("disable");
- kimchi.revertSnapshot(kimchi.selectedGuest, item.prop("id"),
function(){
- $(".icon", item).addClass("hide");
- $("button",
"#form-guest-edit-snapshot").button("enable");
- setCurrentSnapshot(item.prop("id"));
- kimchi.listVmsAuto();
- wok.window.close();
- }, function(data){
- wok.message.error(data.responseJSON.reason);
- $(".icon", item).addClass("hide");
- $("button",
"#form-guest-edit-snapshot").button("enable");
- });
- });
- };
- var addOngoingItem = function(task){
- var uri = task.target_uri;
- addItem({
- name: uri.substring(uri.lastIndexOf('/')+1, uri.length),
- created: "",
- listMode: "hide",
- createMode: ""
- }, 'task');
- if(kimchi.trackingTasks.indexOf(task.id)==-1)
- kimchi.trackTask(task.id, function(task){
- listGeneratingSnapshots();
- $("button",
"#form-guest-edit-snapshot").button("enable");
- }, function(err){
- wok.message.error(err.message);
- listGeneratingSnapshots();
- $("button",
"#form-guest-edit-snapshot").button("enable");
- });
- };
- var listGeneratingSnapshots = function(){
-
kimchi.getTasksByFilter('status=running&target_uri='+encodeURIComponent('^/plugins/kimchi/snapshots/*'),
function(tasks) {
- $(".task", "#form-guest-edit-snapshot").empty();
- for(var i=0;i<tasks.length;i++){
- addOngoingItem(tasks[i]);
- }
- if(tasks.length==0) listSnapshots();
- });
- };
- var listSnapshots = function(){
- kimchi.listSnapshots(kimchi.selectedGuest, function(data){
- $(".body", "#form-guest-edit-snapshot").empty();
- for(var i=0;i<data.length;i++){
- data[i].created = new Date(data[i].created*1000).toLocaleString();
- data[i].createMode = "hide";
- data[i].listMode = "";
- addItem(data[i], 'body');
- }
- setCurrentSnapshot();
- });
- };
- listGeneratingSnapshots();
- $(".add", "#form-guest-edit-snapshot").button({
- icons: { primary: "ui-icon-plusthick" },
- text: false
- }).click(function(evt){
- evt.preventDefault();
- kimchi.createSnapshot(kimchi.selectedGuest, function(task){
- $("button",
"#form-guest-edit-snapshot").button("disable");
- addOngoingItem(task);
- });
- });
- if(kimchi.thisVMState=="running") $("button",
"#form-guest-edit-snapshot").remove();
- };
-
- var initContent = function(guest) {
- guest['icon'] = guest['icon'] ||
'plugins/kimchi/images/icon-vm.png';
- $('#form-guest-edit-general').fillWithObject(guest);
- kimchi.thisVMState = guest['state'];
- refreshCDROMs();
- $('#guest-edit-attach-cdrom-button').button({
- icons: {
- primary: "ui-icon-plusthick"
- },
- text: false
- }).click(function(event) {
- event.preventDefault();
- wok.window.open("plugins/kimchi/guest-storage-add.html");
- });
- if(kimchi.thisVMState === "running") {
- $("#form-guest-edit-general input").prop("disabled",
true);
- } else {
- $("#action-button-container").removeClass("hidden");
- }
-
- var onAttached = function(params) {
- refreshCDROMs();
- };
- var onReplaced = function(params) {
- refreshCDROMs();
- };
- var onDetached = function(params) {
- refreshCDROMs();
- };
-
- initStorageListeners();
- setupInterface();
- setupPermission();
- setupPCIDevice();
- setupSnapshot();
-
- wok.topic('kimchi/vmCDROMAttached').subscribe(onAttached);
- wok.topic('kimchi/vmCDROMReplaced').subscribe(onReplaced);
- wok.topic('kimchi/vmCDROMDetached').subscribe(onDetached);
-
- kimchi.clearGuestEdit = function() {
- wok.topic('kimchi/vmCDROMAttached').unsubscribe(onAttached);
- wok.topic('kimchi/vmCDROMReplaced').unsubscribe(onReplaced);
- wok.topic('kimchi/vmCDROMDetached').unsubscribe(onDetached);
- };
- };
-
- kimchi.retrieveVM(kimchi.selectedGuest, initContent);
-
- var generalSubmit = function(event) {
- $(saveButton).prop('disabled', true);
- var data=$('#form-guest-edit-general').serializeObject();
- if(data['memory']!=undefined) {
- data['memory'] = Number(data['memory']);
- }
- if(data['cpus']!=undefined) {
- data['cpus'] = Number(data['cpus']);
- }
-
- kimchi.updateVM(kimchi.selectedGuest, data, function() {
- kimchi.listVmsAuto();
- wok.window.close();
- }, function(err) {
- wok.message.error(err.responseJSON.reason);
- $(saveButton).prop('disabled', false);
- });
- }
-
- var permissionSubmit = function(event) {
- var content = { users: [], groups: [] };
- authType = kimchi.capabilities['auth']
- if (authType == 'pam') {
- $("#permission-sel-users").children().each(function(){
- content.users.push($("label", this).text());
- });
- $("#permission-sel-groups").children().each(function(){
- content.groups.push($("label", this).text());
- });
- kimchi.updateVM(kimchi.selectedGuest, content, function(){
- wok.window.close();
- });
- } else if (authType == 'ldap') {
- $(saveButton).prop('disabled', true);
- var errors = 0;
-
- $(".body", "#form-guest-edit-permission
.ldap").children().each(function () {
- var elem = $(this);
- content.users.push(elem.attr("id"));
-
- if (!$('input', elem).hasClass('hide')) {
- var user = {'user_id': $(this).attr("id")};
- kimchi.getUserById(user, null, function (data) {
- errors += 1;
- $("input", elem).addClass("checked");
- });
- }
- });
- if (errors == 0) {
- kimchi.updateVM(kimchi.selectedGuest, content, function(){
- wok.window.close();
- });
- } else {
- $(saveButton).prop('disabled', false);
- }
- }
- }
-
- // tap map, "general": 0, "storage": 1, "interface": 2,
"permission": 3, "password": 4
- var submit_map = {0: generalSubmit, 3:permissionSubmit};
- var submitForm = function(event) {
- var current = $('#guest-edit-tabs').tabs( "option",
"active" );
- var submitFun = submit_map[current];
- submitFun && submitFun(event);
- event.preventDefault();
- };
-
- $(guestEditForm).on('submit', submitForm);
- $(saveButton).on('click', submitForm);
-};
diff --git a/plugins/kimchi/ui/js/src/kimchi.guest_main.js
b/plugins/kimchi/ui/js/src/kimchi.guest_main.js
deleted file mode 100644
index 7dd5d84..0000000
--- a/plugins/kimchi/ui/js/src/kimchi.guest_main.js
+++ /dev/null
@@ -1,511 +0,0 @@
-/*
- * Project Kimchi
- *
- * Copyright IBM, Corp. 2013-2015
- *
- * 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.
- */
-
-kimchi.sampleGuestObject = {
- "name": "",
- "uuid": "",
- "state": "shutoff",
- "persistent": true,
- "icon": null,
- "cpus": 0,
- "memory": 0,
- "stats": {
- "net_throughput": 0,
- "io_throughput_peak": 100,
- "cpu_utilization": 0,
- "io_throughput": 0,
- "net_throughput_peak": 100
- },
- "screenshot": null,
- "graphics": {
- "passwd": null,
- "passwdValidTo": null,
- "type": "vnc",
- "port": null,
- "listen": "127.0.0.1"
- },
- "users": [],
- "groups": [],
- "access": "full"
-};
-
-kimchi.vmstart = function(event) {
- var button=$(this);
- if (!button.hasClass('loading')) {
- button.addClass('loading');
- var vm=$(this).closest('li[name=guest]');
- var vm_id=vm.attr("id");
- kimchi.startVM(vm_id, function(result) {
- button.removeClass('loading');
- kimchi.listVmsAuto();
- }, function(err) {
- button.removeClass('loading');
- wok.message.error(err.responseJSON.reason);
- }
- );
- } else {
- event.preventDefault();
- event.stopPropagation();
- return;
- }
-};
-
-kimchi.vmsuspend = function(event) {
- var button=$(this);
- if (!button.hasClass('pause-gray')) {
- button.addClass('pause-gray');
- var vm=$(this).closest('li[name=guest]');
- var vm_id=vm.attr("id");
- kimchi.suspendVM(vm_id, function(result) {
- button.removeClass('pause-gray');
- kimchi.listVmsAuto();
- }, function(err) {
- button.removeClass('pause-gray');
- wok.message.error(err.responseJSON.reason);
- }
- );
- } else {
- event.preventDefault();
- event.stopPropagation();
- return;
- }
-};
-
-kimchi.vmresume = function(event) {
- var button=$(this);
- if (!button.hasClass('resume-gray')) {
- button.addClass('resume-gray');
- var vm=$(this).closest('li[name=guest]');
- var vm_id=vm.attr("id");
- kimchi.resumeVM(vm_id, function(result) {
- button.removeClass('resume-gray');
- kimchi.listVmsAuto();
- }, function(err) {
- button.removeClass('resume-gray');
- wok.message.error(err.responseJSON.reason);
- }
- );
- } else {
- event.preventDefault();
- event.stopPropagation();
- return;
- }
-};
-
-kimchi.vmpoweroff = function(event) {
- var button=$(this);
- if (!button.hasClass('loading')) {
- button.addClass('loading');
- var vm=button.closest('li[name=guest]');
- var vm_id=vm.attr("id");
- var vmObject=vm.data();
- var vm_persistent=vmObject.persistent == true;
- var content_msg = vm_persistent ? i18n['KCHVM6003M'] :
- i18n['KCHVM6009M'];
- var settings = {
- title : i18n['KCHVM6002M'],
- content : content_msg,
- confirm : i18n['KCHAPI6002M'],
- cancel : i18n['KCHAPI6003M']
- };
- wok.confirm(settings, function() {
- kimchi.poweroffVM(vm_id, function(result) {
- button.removeClass('loading');
- kimchi.listVmsAuto();
- }, function(err) {
- wok.message.error(err.responseJSON.reason);
- });
- }, function() {
- });
- } else {
- event.preventDefault();
- event.stopPropagation();
- }
-};
-
-kimchi.vmshutdown = function(event){
- var vm=$(this).closest('li[name=guest]');
- var vm_id=vm.attr("id");
- var settings = {
- title : i18n['KCHVM6006M'],
- content : i18n['KCHVM6007M'],
- confirm : i18n['KCHAPI6002M'],
- cancel : i18n['KCHAPI6003M']
- };
- wok.confirm(settings, function() {
- kimchi.shutdownVM(vm_id, function(result) {
- kimchi.listVmsAuto();
- }, function(err) {
- wok.message.error(err.responseJSON.reason);
- }
- );
- }, function() {
- });
-};
-
-kimchi.vmreset = function(event){
- var vm=$(this).closest('li[name=guest]');
- var vm_id=vm.attr("id");
- var settings = {
- title : i18n['KCHVM6004M'],
- content : i18n['KCHVM6005M'],
- confirm : i18n['KCHAPI6002M'],
- cancel : i18n['KCHAPI6003M']
- };
- wok.confirm(settings, function() {
- kimchi.resetVM(vm_id, function(result) {
- kimchi.listVmsAuto();
- }, function(err) {
- wok.message.error(err.responseJSON.reason);
- }
- );
- }, function() {
- });
-};
-
-kimchi.vmdelete = function(event) {
- var vm = $(this).closest('li[name=guest]');
- var vm_id=vm.attr("id");
- var settings = {
- title : i18n['KCHVM6008M'],
- content : i18n['KCHVM6001M'],
- confirm : i18n['KCHAPI6002M'],
- cancel : i18n['KCHAPI6003M']
- };
- wok.confirm(settings, function() {
- kimchi.deleteVM(vm_id, function(result) {
- kimchi.listVmsAuto();
- }, function(err) {
- wok.message.error(err.responseJSON.reason);
- });
- }, function() {
- });
-};
-
-kimchi.vmedit = function(event) {
- var vm = $(this).closest('li[name=guest]');
- var vm_id=vm.attr("id");
- kimchi.selectedGuest = vm_id;
- wok.window.open({
- url: 'plugins/kimchi/guest-edit.html',
- close: function() {
- kimchi.clearGuestEdit();
- }
- });
-};
-
-kimchi.openVmConsole = function(event) {
- var vm=$(this).closest('li[name=guest]');
- var vmObject=vm.data();
- if (vmObject.graphics['type'] == 'vnc') {
- kimchi.vncToVM(vm.attr('id'));
- }
- else if (vmObject.graphics['type'] == 'spice') {
- kimchi.spiceToVM(vm.attr('id'));
- }
-
-};
-
-kimchi.getVmsCurrentConsoleImgs = function() {
- var res = new Object();
- $('#guestList').children().each(function() {
- res[$(this).attr('id')] =
$(this).find('img.imgactive').attr('src');
- })
- return res;
-};
-
-kimchi.getOpenMenuVmId = function() {
- var result;
- var openMenu = $('#guestList div[name="actionmenu"]
.popover:visible');
- if(openMenu) {
- var li_element=openMenu.closest('li');
- result=li_element.attr('id');
- }
- return result;
-};
-
-kimchi.listVmsAuto = function() {
- if (kimchi.vmTimeout) {
- clearTimeout(kimchi.vmTimeout);
- }
- var getCreatingGuests = function(){
- var guests = [];
-
kimchi.getTasksByFilter('status=running&target_uri='+encodeURIComponent('^/plugins/kimchi/vms/[^/]+$'),
function(tasks) {
- for(var i=0;i<tasks.length;i++){
- var guestUri = tasks[i].target_uri;
- var guestName = guestUri.split('/')[2]
- guests.push($.extend({}, kimchi.sampleGuestObject, {name: guestName,
isCreating: true}));
- if(kimchi.trackingTasks.indexOf(tasks[i].id)==-1)
- kimchi.trackTask(tasks[i].id, null, function(err){
- wok.message.error(err.message);
- }, null);
- }
- }, null, true);
- return guests;
- };
- var getCloningGuests = function(){
- var guests = [];
-
kimchi.getTasksByFilter('status=running&target_uri='+encodeURIComponent('^/plugins/kimchi/vms/.+/clone'),
function(tasks) {
- for(var i=0;i<tasks.length;i++){
- var guestUri = tasks[i].target_uri;
- var guestName = guestUri.split('/')[2]
- guests.push($.extend({}, kimchi.sampleGuestObject, {name: guestName,
isCloning: true}));
- if(kimchi.trackingTasks.indexOf(tasks[i].id)==-1)
- kimchi.trackTask(tasks[i].id, null, function(err){
- wok.message.error(err.message);
- }, null);
- }
- }, null, true);
- return guests;
- };
- kimchi.listVMs(function(result, textStatus, jqXHR) {
- if (result && textStatus=="success") {
- result = getCloningGuests().concat(result);
- result = getCreatingGuests().concat(result);
- if(result.length) {
- var listHtml = '';
- var guestTemplate = kimchi.guestTemplate;
- var currentConsoleImages = kimchi.getVmsCurrentConsoleImgs();
- var openMenuGuest = kimchi.getOpenMenuVmId();
- $('#guestList').empty();
- $('#guestListField').show();
- $('#noGuests').hide();
-
- $.each(result, function(index, vm) {
- var guestLI = kimchi.createGuestLi(vm, currentConsoleImages[vm.name],
vm.name==openMenuGuest);
- $('#guestList').append(guestLI);
- });
- } else {
- $('#guestListField').hide();
- $('#noGuests').show();
- }
- }
-
- kimchi.vmTimeout = window.setTimeout("kimchi.listVmsAuto();", 5000);
- }, function(errorResponse, textStatus, errorThrown) {
- if(errorResponse.responseJSON && errorResponse.responseJSON.reason) {
- wok.message.error(errorResponse.responseJSON.reason);
- }
- kimchi.vmTimeout = window.setTimeout("kimchi.listVmsAuto();", 5000);
- });
-};
-
-kimchi.createGuestLi = function(vmObject, prevScreenImage, openMenu) {
- var result=kimchi.guestElem.clone();
-
- //Setup the VM list entry
- var vmRunningBool=(vmObject.state=="running");
- var vmSuspendedBool = (vmObject.state=="paused");
- var vmPoweredOffBool = (vmObject.state=="shutoff");
- var vmPersistent = (vmObject.persistent == true);
- result.attr('id',vmObject.name);
- result.data(vmObject);
-
- //Add the Name
- var guestTitle=result.find('.title').attr('title',vmObject.name);
- guestTitle.html(vmObject.name);
-
- //Setup the VM console thumbnail display
- var curImg = vmObject.icon;
- if (vmObject.screenshot) {
- curImg = vmObject.screenshot.replace(/^\//,'');
- }
- var load_src = curImg || 'plugins/kimchi/images/icon-vm.png';
- var tile_src = prevScreenImage || vmObject['load-src'];
- var liveTile=result.find('div[name=guest-tile] > .tile');
- liveTile.addClass(vmObject.state);
- liveTile.find('.imgactive').attr('src',tile_src);
- var imgLoad=liveTile.find('.imgload');
- imgLoad.on('load', function() {
- var
oldImg=$(this).parent().find('.imgactive');
-
oldImg.removeClass("imgactive").addClass("imgload");
- oldImg.attr("src","");
-
$(this).addClass("imgactive").removeClass("imgload");
- $(this).off('load');
- });
- imgLoad.attr('src',load_src);
-
- //Link the stopped tile to the start action, the running tile to open the console,
and the paused tile to resume
- if(!(vmObject.isCloning || vmObject.isCreating)){
- if (vmPoweredOffBool) {
- liveTile.off("click", kimchi.openVmConsole);
- liveTile.off("click", kimchi.vmresume);
- liveTile.on("click", kimchi.vmstart);
- liveTile.hover(function(event){$(this).find('.overlay').show()},
function(event){$(this).find('.overlay').hide()});
- } else if (vmSuspendedBool) {
- liveTile.off("click", kimchi.vmstart);
- liveTile.off("click", kimchi.openVmConsole);
- liveTile.on("click", kimchi.vmresume);
- if(vmObject.state="paused") {
-
liveTile.find('.overlay').attr('src',"plugins/kimchi/images/theme-default/ac24_resume.png");
- liveTile.find('.overlay').attr('alt',"Resume");
- }
- liveTile.hover(function(event){$(this).find('.overlay').show()},
function(event){$(this).find('.overlay').hide()});
- } else {
- liveTile.off("click", kimchi.vmstart);
- liveTile.off("click", kimchi.vmresume);
- liveTile.on("click", kimchi.openVmConsole);
- }
- }
-
- //Setup the gauges
- var stats=vmObject.stats;
- var gaugeValue=0;
- gaugeValue=parseInt(stats.net_throughput);
- kimchi.circleGaugeInit(result,
"net_throughput",gaugeValue,(gaugeValue*100/stats.net_throughput_peak));
- gaugeValue=parseInt(stats.io_throughput);
- kimchi.circleGaugeInit(result,
"io_throughput",gaugeValue,(gaugeValue*100/stats.io_throughput_peak));
- gaugeValue=parseInt(stats.cpu_utilization);
- kimchi.circleGaugeInit(result,
"cpu_utilization",gaugeValue+"%",gaugeValue);
-
- //Setup the VM Actions
- var guestActions=result.find("div[name=guest-actions]");
- guestActions.find(".shutoff-disabled").prop("disabled",
!vmRunningBool);
- guestActions.find(".running-disabled").prop("disabled",
vmRunningBool);
- guestActions.find(".non-persistent-disabled").prop("disabled",
!vmPersistent);
- guestActions.find(".reset-disabled").prop("disabled",
vmPoweredOffBool || !vmPersistent);
- guestActions.find(".pause-disabled").prop("disabled",
vmPoweredOffBool || !vmPersistent);
-
- if (vmSuspendedBool) { //VM is paused
- //Hide Start
- guestActions.find(".running-hidden").hide();
- //Hide Pause button and menu
- guestActions.find(".pause-disabled").hide();
- guestActions.find(".pause-hidden").hide();
- }
-
- if (vmRunningBool) { //VM IS running
- //Hide Start
- guestActions.find(".running-hidden").hide();
- //Hide Resume
- guestActions.find(".resume-hidden").hide();
- }
-
- if (vmPoweredOffBool) { //VM is powered off
- //Hide PowerOff
- guestActions.find(".shutoff-hidden").hide();
- //Hide Pause
- guestActions.find(".pause-hidden").hide();
- //Hide Resume
- guestActions.find(".resume-hidden").hide();
- }
-
- var consoleActions=guestActions.find("[name=vm-console]");
-
- if ((vmObject.graphics['type'] == 'vnc') ||
(vmObject.graphics['type'] == 'spice')) {
- consoleActions.on("click", kimchi.openVmConsole);
- consoleActions.show();
- } else { //we don't recognize the VMs supported graphics, so hide the
menu choice
- consoleActions.hide();
- consoleActions.off("click",kimchi.openVmConsole);
- }
-
- //Setup action event handlers
- if(!(vmObject.isCloning || vmObject.isCreating)){
- guestActions.find("[name=vm-start]").on({click : kimchi.vmstart});
- guestActions.find("[name=vm-poweroff]").on({click :
kimchi.vmpoweroff});
- if ((vmRunningBool) || (vmSuspendedBool)) {
- //If the guest is not running, do not enable reset; otherwise, reset is
enabled (when running or paused)
- guestActions.find("[name=vm-reset]").on({click : kimchi.vmreset});
-
- //If the guest is not running, do not enable shutdown;otherwise, shutdown is enabled
(when running or paused)
- guestActions.find("[name=vm-shutdown]").on({click :
kimchi.vmshutdown});
- }
-
- if (vmSuspendedBool) {
- guestActions.find("[name=vm-resume]").on({click :
kimchi.vmresume});
- }
-
- if (vmRunningBool) {
- guestActions.find("[name=vm-pause]").on({click :
kimchi.vmsuspend});
- }
-
- guestActions.find("[name=vm-edit]").on({click : kimchi.vmedit});
- guestActions.find("[name=vm-delete]").on({click : kimchi.vmdelete});
- guestActions.find("[name=vm-clone]").click(function(){
- var guest = $(this).closest('li[name=guest]').attr("id");
- wok.confirm({
- title : i18n['KCHAPI6006M'],
- content : i18n['KCHVM6010M'],
- confirm : i18n['KCHAPI6002M'],
- cancel : i18n['KCHAPI6003M']
- }, function() {
- kimchi.cloneGuest(guest, function(data){
- kimchi.listVmsAuto();
- });
- }, null);
- });
-
- //Maintain menu open state
- var actionMenu=guestActions.find("div[name=actionmenu]");
- if (openMenu) {
- $('.popover', actionMenu).toggle();
- }
-
- }else{
- guestActions.find('.btn').attr('disabled', true);
- $('.popover',
guestActions.find("div[name=actionmenu]")).remove();
-
- result.find('.guest-pending').removeClass('hide-content');
- pendingText = result.find('.guest-pending .text')
- if(vmObject.isCloning)
- pendingText.text(i18n['KCHAPI6009M']);
- else
- pendingText.text(i18n['KCHAPI6008M']);
- }
-
- return result;
-};
-
-kimchi.circleGaugeInit = function(topElement, divName, display, percentage){
- var gauge=topElement.find('div[name="' + divName + '"]
.circleGauge');
- if(gauge) {
- var data=Object();
- data.percentage = percentage;
- data.display = display;
- gauge.data(data);
- }
- gauge.circleGauge();
- return(gauge);
-};
-
-kimchi.guestSetRequestHeader = function(xhr) {
- xhr.setRequestHeader('Accept', 'text/html');
-};
-
-kimchi.guest_main = function() {
- if(wok.tabMode['guests'] === 'admin') {
- $('.tools').attr('style','display');
- $("#vm-add").on("click", function(event) {
- wok.window.open('plugins/kimchi/guest-add.html');
- });
- }
- kimchi.guestTemplate = $('#guest-tmpl').html();
-
kimchi.guestElem=$('<div/>').html(kimchi.guestTemplate).find('li');
- $('#guests-root-container').on('remove', function() {
- kimchi.vmTimeout && clearTimeout(kimchi.vmTimeout);
- });
- kimchi.listVmsAuto()
-};
-
-kimchi.editTemplate = function(guestTemplate, oldPopStat) {
- if (oldPopStat) {
- return guestTemplate.replace("vm-action", "vm-action open");
- }
- return guestTemplate;
-};
diff --git a/plugins/kimchi/ui/js/src/kimchi.guest_media_main.js
b/plugins/kimchi/ui/js/src/kimchi.guest_media_main.js
deleted file mode 100644
index b920527..0000000
--- a/plugins/kimchi/ui/js/src/kimchi.guest_media_main.js
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * Project Kimchi
- *
- * Copyright IBM, Corp. 2014
- *
- * 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.
- */
-kimchi.guest_media_main = function() {
-
- var refreshCDROMs = function() {
- kimchi.listVMStorages({
- vm: kimchi.selectedGuest,
- storageType: 'cdrom'
- }, function(storages) {
- var rowHTML = $('#cdrom-row-tmpl').html();
- var container = $('#guest-edit-cdrom-row-container');
- $(container).empty();
-
- $.each(storages, function(index, storage) {
- storage['vm'] = kimchi.selectedGuest;
- var templated = wok.substitute(rowHTML, storage);
- container.append(templated);
- });
-
- var replaceCDROM = function(event) {
- event.preventDefault();
- kimchi.selectedGuestStorage = $(this).data('dev');
- wok.window.open("plugins/kimchi/guest-cdrom-edit.html");
- };
-
- $('input[type="text"][name="cdrom"]',
container).on('click', replaceCDROM);
- $('.replace', container).on('click', replaceCDROM);
- });
- };
-
- refreshCDROMs();
-
- var onReplaced = function(params) {
- refreshCDROMs();
- };
- wok.topic('kimchi/vmCDROMReplaced').subscribe(onReplaced);
-
- kimchi.clearGuestMedia = function() {
- wok.topic('kimchi/vmCDROMReplaced').unsubscribe(onReplaced);
- };
-};
diff --git a/plugins/kimchi/ui/js/src/kimchi.guest_storage_add.main.js
b/plugins/kimchi/ui/js/src/kimchi.guest_storage_add.main.js
deleted file mode 100644
index bc162e8..0000000
--- a/plugins/kimchi/ui/js/src/kimchi.guest_storage_add.main.js
+++ /dev/null
@@ -1,199 +0,0 @@
-/*
- * Project Kimchi
- *
- * Copyright IBM, Corp. 2014-2015
- *
- * 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.
- */
-kimchi.guest_storage_add_main = function() {
- var types = [{
- label: 'cdrom',
- value: 'cdrom',
- },
- {
- label: 'disk',
- value: 'disk',
- }];
- var typesRunning = [{
- label: 'disk',
- value: 'disk'
- }];
-
- var storageAddForm = $('#form-guest-storage-add');
- var submitButton = $('#guest-storage-button-add');
- var typeTextbox = $('input[name="type"]', storageAddForm);
- var pathTextbox = $('input[name="path"]', storageAddForm);
- var poolTextbox = $('input[name="pool"]', storageAddForm);
- var volTextbox = $('input[name="vol"]', storageAddForm);
-
- typeTextbox.change(function() {
- var pathObject = {'cdrom': ".path-section", 'disk':
'.volume-section'}
- selectType = $(this).val();
- $.each(pathObject, function(type, value) {
- if(selectType == type){
- $(value).removeClass('hidden');
- } else {
- $(value).addClass('hidden');
- }
- });
-
- if ($(".path-section").hasClass('hidden')) {
- $(poolTextbox).val('default');
- $(poolTextbox).change();
- $(pathTextbox).val("");
- }
- else {
- $(poolTextbox).val("");
- $(volTextbox).val("");
- }
- });
-
- kimchi.listStoragePools(function(result) {
- var options = [];
- if (result && result.length) {
- $.each(result, function(index, storagePool) {
- if ((storagePool.state=="active") && (storagePool.type
!== 'kimchi-iso')) {
- options.push({
- label: storagePool.name,
- value: storagePool.name
- });
- }
- });
- wok.select('guest-add-storage-pool-list', options);
- }
- });
-
- poolTextbox.change(function() {
- var options = [];
- kimchi.listStorageVolumes($(this).val(), function(result) {
- var validVolType = { cdrom: /iso/, disk:
/^(raw|qcow|qcow2|bochs|qed|vmdk)$/};
- $('#guest-disk').selectMenu();
- if (result.length) {
- $.each(result, function(index, value) {
- // Only unused volume can be attached
- if (value.used_by.length == 0 && (value.type !=
'file' || validVolType[selectType].test(value.format))) {
- options.push({
- label: value.name,
- value: value.name
- });
- }
- });
- if (options.length) {
- $(volTextbox).val(options[0].value);
- $(volTextbox).change();
- }
- }
- $('#guest-disk').selectMenu("setData", options);
- });
- });
-
-
- typeTextbox.change(function() {
- var pathObject = {'cdrom': ".path-section", 'disk':
'.volume-section'}
- var selectType = $(this).val();
- $.each(pathObject, function(type, value) {
- if(selectType == type){
- $(value).removeClass('hidden');
- } else {
- $(value).addClass('hidden');
- }
- });
- });
-
- if (kimchi.thisVMState === 'running') {
- types =typesRunning;
- $(typeTextbox).val('disk');
- typeTextbox.change();
- poolTextbox.change();
- }
- var selectType = $(typeTextbox).val();
- wok.select('guest-storage-type-list', types);
-
- var validateCDROM = function(settings) {
- if (/^((https|http|ftp|ftps|tftp|\/).*)+$/.test(settings['path']))
- return true;
- else {
- wok.message.error.code('KCHVMSTOR0001E');
- return false;
- }
- }
-
- var validateDisk = function(settings) {
- if (settings['pool'] && settings['vol'])
- return true;
- else {
- wok.message.error.code('KCHVMSTOR0002E');
- return false;
- }
- }
-
- validator = {cdrom: validateCDROM, disk: validateDisk};
- var submitForm = function(event) {
- if (submitButton.prop('disabled')) {
- return false;
- }
-
- var formData = storageAddForm.serializeObject();
- var settings = {
- vm: kimchi.selectedGuest,
- type: typeTextbox.val(),
- };
-
- $(submitButton).prop('disabled', true);
- $.each([pathTextbox, poolTextbox, volTextbox], function(i, c) {
- $(c).prop('disabled', true);
- val = $(c).val()
- if (val && val != '') {
- settings[$(c).attr('name')] = $(c).val();
- }
- });
- // Validate form for cdrom and disk
- validateSpecifiedForm = validator[settings['type']];
- if (!validateSpecifiedForm(settings)) {
- $(submitButton).prop('disabled', false);
- $.each([submitButton, pathTextbox, poolTextbox, volTextbox], function(i, c)
{
- $(c).prop('disabled', false);
- });
- return false;
- }
- $(submitButton).addClass('loading').text(i18n['KCHVMCD6003M']);
-
- kimchi.addVMStorage(settings, function(result) {
- wok.window.close();
- wok.topic('kimchi/vmCDROMAttached').publish({
- result: result
- });
- }, function(result) {
- var errText = result['reason'] ||
- result['responseJSON']['reason'];
- wok.message.error(errText);
-
- $.each([submitButton, pathTextbox, poolTextbox, volTextbox], function(i, c)
{
- $(c).prop('disabled', false);
- });
-
$(submitButton).removeClass('loading').text(i18n['KCHVMCD6002M']);
- });
-
- event.preventDefault();
- };
-
- storageAddForm.on('submit', submitForm);
- submitButton.on('click', submitForm);
- pathTextbox.on('change input propertychange', function(event) {
- $(submitButton).prop('disabled', $(this).val() === '');
- });
- volTextbox.on('change propertychange', function (event) {
- $(submitButton).prop('disabled', $(this).val() === '');
- });
-
-};
diff --git a/plugins/kimchi/ui/js/src/kimchi.host.js
b/plugins/kimchi/ui/js/src/kimchi.host.js
deleted file mode 100644
index e2d2511..0000000
--- a/plugins/kimchi/ui/js/src/kimchi.host.js
+++ /dev/null
@@ -1,858 +0,0 @@
-/*
- * Project Kimchi
- *
- * Copyright IBM, Corp. 2013-2014
- *
- * 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.
- */
-kimchi.host={};
-
-kimchi.host_main = function() {
- var expand = function(header, toExpand) {
- var controlledNode = $(header).attr('aria-controls');
- $('#' + controlledNode)[toExpand ? 'removeClass' :
'addClass']('hidden');
- $(header).attr('aria-expanded', toExpand ? 'true' :
'false');
- };
-
- var repositoriesGrid = null;
- var initRepositoriesGrid = function(repo_type) {
- var gridFields=[];
- if (repo_type == "yum") {
- gridFields=[{
- name: 'repo_id',
- label: i18n['KCHREPO6004M'],
- 'class': 'repository-id'
- }, {
- name: 'config[repo_name]',
- label: i18n['KCHREPO6005M'],
- 'class': 'repository-name'
- }, {
- name: 'enabled',
- label: i18n['KCHREPO6009M'],
- 'class': 'repository-enabled'
- }];
- }
- else if (repo_type == "deb") {
- gridFields=[{
- name: 'baseurl',
- label: i18n['KCHREPO6006M'],
- makeTitle: true,
- 'class': 'repository-baseurl deb'
- }, {
- name: 'enabled',
- label: i18n['KCHREPO6009M'],
- 'class': 'repository-enabled deb'
- }, {
- name: 'config[dist]',
- label: "dist",
- 'class': 'repository-gpgcheck deb'
- }, {
- name: 'config[comps]',
- label: "comps",
- 'class': 'repository-gpgcheck deb'
- }];
- }
- else {
- gridFields=[{
- name: 'repo_id',
- label: i18n['KCHREPO6004M'],
- 'class': 'repository-id'
- }, {
- name: 'enabled',
- label: i18n['KCHREPO6009M'],
- 'class': 'repository-enabled'
- }, {
- name: 'baseurl',
- label: i18n['KCHREPO6006M'],
- makeTitle: true,
- 'class': 'repository-baseurl'
- }];
- }
- repositoriesGrid = new wok.widget.Grid({
- container: 'repositories-grid-container',
- id: 'repositories-grid',
- title: i18n['KCHREPO6003M'],
- toolbarButtons: [{
- id: 'repositories-grid-add-button',
- label: i18n['KCHREPO6012M'],
- onClick: function(event) {
- wok.window.open({url:'plugins/kimchi/repository-add.html',
- class: repo_type});
- }
- }, {
- id: 'repositories-grid-enable-button',
- label: i18n['KCHREPO6016M'],
- disabled: true,
- onClick: function(event) {
- var repository = repositoriesGrid.getSelected();
- if(!repository) {
- return;
- }
- var name = repository['repo_id'];
- var enable = !repository['enabled'];
- $(this).prop('disabled', true);
- kimchi.enableRepository(name, enable, function() {
- wok.topic('kimchi/repositoryUpdated').publish();
- });
- }
- }, {
- id: 'repositories-grid-edit-button',
- label: i18n['KCHREPO6013M'],
- disabled: true,
- onClick: function(event) {
- var repository = repositoriesGrid.getSelected();
- if(!repository) {
- return;
- }
- kimchi.selectedRepository = repository['repo_id'];
- wok.window.open({url:'plugins/kimchi/repository-edit.html',
- class: repo_type});
- }
- }, {
- id: 'repositories-grid-remove-button',
- label: i18n['KCHREPO6014M'],
- disabled: true,
- onClick: function(event) {
- var repository = repositoriesGrid.getSelected();
- if(!repository) {
- return;
- }
-
- var settings = {
- title : i18n['KCHREPO6001M'],
- content : i18n['KCHREPO6002M'],
- confirm : i18n['KCHAPI6004M'],
- cancel : i18n['KCHAPI6003M']
- };
-
- wok.confirm(settings, function() {
- kimchi.deleteRepository(
- repository['repo_id'],
- function(result) {
-
wok.topic('kimchi/repositoryDeleted').publish(result);
- }, function(error) {
- }
- );
- });
- }
- }],
- onRowSelected: function(row) {
- var repository = repositoriesGrid.getSelected();
- if(!repository) {
- return;
- }
- $('#repositories-grid-remove-button').prop('disabled',
false);
- $('#repositories-grid-edit-button').prop('disabled',
false);
- var enabled = repository['enabled'];
- $('#repositories-grid-enable-button')
- .text(i18n[enabled ? 'KCHREPO6017M' :
'KCHREPO6016M'])
- .prop('disabled', false);
- },
- frozenFields: [],
- fields: gridFields,
- data: listRepositories
- });
- };
-
- var listRepositories = function(gridCallback) {
- kimchi.listRepositories(function(repositories) {
- if($.isFunction(gridCallback)) {
- gridCallback(repositories);
- }
- else {
- if(repositoriesGrid) {
- repositoriesGrid.setData(repositories);
- }
- else {
- initRepositoriesGrid();
- repositoriesGrid.setData(repositories);
- }
- }
- },
- function(error) {
- var message = error && error['responseJSON'] &&
error['responseJSON']['reason'];
-
- if($.isFunction(gridCallback)) {
- gridCallback([]);
- }
- repositoriesGrid &&
- repositoriesGrid.showMessage(message || i18n['KCHUPD6008M']);
- });
-
- $('#repositories-grid-remove-button').prop('disabled', true);
- $('#repositories-grid-edit-button').prop('disabled', true);
- $('#repositories-grid-enable-button').prop('disabled', true);
- };
-
- var softwareUpdatesGridID = 'software-updates-grid';
- var softwareUpdatesGrid = null;
- var progressAreaID = 'software-updates-progress-textarea';
- var reloadProgressArea = function(result) {
- var progressArea = $('#' + progressAreaID)[0];
- $(progressArea).text(result['message']);
- var scrollTop = $(progressArea).prop('scrollHeight');
- $(progressArea).prop('scrollTop', scrollTop);
- };
-
- var initSoftwareUpdatesGrid = function(softwareUpdates) {
- softwareUpdatesGrid = new wok.widget.Grid({
- container: 'software-updates-grid-container',
- id: softwareUpdatesGridID,
- title: i18n['KCHUPD6001M'],
- rowSelection: 'disabled',
- toolbarButtons: [{
- id: softwareUpdatesGridID + '-update-button',
- label: i18n['KCHUPD6006M'],
- disabled: true,
- onClick: function(event) {
- var updateButton = $(this);
- var progressArea = $('#' + progressAreaID)[0];
-
$('#software-updates-progress-container').removeClass('hidden');
- $(progressArea).text('');
- !wok.isElementInViewport(progressArea) &&
- progressArea.scrollIntoView();
-
$(updateButton).text(i18n['KCHUPD6007M']).prop('disabled', true);
-
- kimchi.updateSoftware(function(result) {
- reloadProgressArea(result);
-
$(updateButton).text(i18n['KCHUPD6006M']).prop('disabled', false);
- wok.topic('kimchi/softwareUpdated').publish({
- result: result
- });
- }, function(error) {
- var message = error && error['responseJSON']
&& error['responseJSON']['reason'];
- wok.message.error(message || i18n['KCHUPD6009M']);
-
$(updateButton).text(i18n['KCHUPD6006M']).prop('disabled', false);
- }, reloadProgressArea);
- }
- }],
- frozenFields: [],
- fields: [{
- name: 'package_name',
- label: i18n['KCHUPD6002M'],
- 'class': 'software-update-name'
- }, {
- name: 'version',
- label: i18n['KCHUPD6003M'],
- 'class': 'software-update-version'
- }, {
- name: 'arch',
- label: i18n['KCHUPD6004M'],
- 'class': 'software-update-arch'
- }, {
- name: 'repository',
- label: i18n['KCHUPD6005M'],
- 'class': 'software-update-repos'
- }],
- data: listSoftwareUpdates
- });
- };
-
- var listSoftwareUpdates = function(gridCallback) {
- kimchi.listSoftwareUpdates(function(softwareUpdates) {
- if($.isFunction(gridCallback)) {
- gridCallback(softwareUpdates);
- }
- else {
- if(softwareUpdatesGrid) {
- softwareUpdatesGrid.setData(softwareUpdates);
- }
- else {
- initSoftwareUpdatesGrid(softwareUpdates);
- }
- }
-
- var updateButton = $('#' + softwareUpdatesGridID +
'-update-button');
- $(updateButton).prop('disabled', softwareUpdates.length === 0);
- }, function(error) {
- var message = error && error['responseJSON'] &&
error['responseJSON']['reason'];
- if($.isFunction(gridCallback)) {
- gridCallback([]);
- }
- softwareUpdatesGrid &&
- softwareUpdatesGrid.showMessage(message || i18n['KCHUPD6008M']);
- });
- };
-
- var reportGridID = 'available-reports-grid';
- var reportGrid = null;
- var enableReportButtons = function(toEnable) {
- var buttonID = '#{grid}-{btn}-button';
- $.each(['rename', 'remove', 'download'], function(i, n)
{
- $(wok.substitute(buttonID, {
- grid: reportGridID,
- btn: n
- })).prop('disabled', !toEnable);
- });
- };
- var initReportGrid = function(reports) {
- reportGrid = new wok.widget.Grid({
- container: 'available-reports-grid-container',
- id: reportGridID,
- title: i18n['KCHDR6002M'],
- toolbarButtons: [{
- id: reportGridID + '-generate-button',
- label: i18n['KCHDR6006M'],
- onClick: function(event) {
- wok.window.open('plugins/kimchi/report-add.html');
- }
- }, {
- id: reportGridID + '-rename-button',
- label: i18n['KCHDR6008M'],
- disabled: true,
- onClick: function(event) {
- var report = reportGrid.getSelected();
- if(!report) {
- return;
- }
-
- kimchi.selectedReport = report['name'];
- wok.window.open('plugins/kimchi/report-rename.html');
- }
- }, {
- id: reportGridID + '-remove-button',
- label: i18n['KCHDR6009M'],
- disabled: true,
- onClick: function(event) {
- var report = reportGrid.getSelected();
- if(!report) {
- return;
- }
-
- var settings = {
- title : i18n['KCHAPI6004M'],
- content : i18n['KCHDR6001M'],
- confirm : i18n['KCHAPI6002M'],
- cancel : i18n['KCHAPI6003M']
- };
-
- wok.confirm(settings, function() {
- kimchi.deleteReport({
- name: report['name']
- }, function(result) {
- listDebugReports();
- }, function(error) {
- wok.message.error(error.responseJSON.reason);
- });
- });
- }
- }, {
- id: reportGridID + '-download-button',
- label: i18n['KCHDR6010M'],
- disabled: true,
- onClick: function(event) {
- var report = reportGrid.getSelected();
- if(!report) {
- return;
- }
-
- kimchi.downloadReport({
- file: report['uri']
- });
- }
- }],
- onRowSelected: function(row) {
- var report = reportGrid.getSelected();
- // Only enable report buttons if the selected line is not a
- // pending report
- if (report['time'] == i18n['KCHDR6007M']) {
- var gridElement = $('#'+ reportGridID);
- var row = $('tr:contains(' + report['name'] +
')', gridElement);
- enableReportButtons(false);
- row.attr('class', '');
- }
- else {
- enableReportButtons(true);
- }
- },
- frozenFields: [],
- fields: [{
- name: 'name',
- label: i18n['KCHDR6003M'],
- 'class': 'debug-report-name'
- }, {
- name: 'time',
- label: i18n['KCHDR6005M'],
- 'class': 'debug-report-time'
- }],
- data: reports
- });
- };
-
- var getPendingReports = function() {
- var reports = []
- var filter = 'status=running&target_uri=' +
encodeURIComponent('^/plugins/kimchi/debugreports/*')
-
- kimchi.getTasksByFilter(filter, function(tasks) {
- for(var i = 0; i < tasks.length; i++) {
- reportName =
tasks[i].target_uri.replace(/^\/plugins\/kimchi\/debugreports\//, '') ||
i18n['KCHDR6012M'];
- reports.push({'name': reportName, 'time':
i18n['KCHDR6007M']})
-
- if(kimchi.trackingTasks.indexOf(tasks[i].id) >= 0) {
- continue;
- }
-
- kimchi.trackTask(tasks[i].id, function(result) {
- wok.topic('kimchi/debugReportAdded').publish();
- }, function(result) {
- // Error message from Async Task status
- if (result['message']) {
- var errText = result['message'];
- }
- // Error message from standard kimchi exception
- else {
- var errText = result['responseJSON']['reason'];
- }
- result && wok.message.error(errText);
- wok.topic('kimchi/debugReportAdded').publish();
- }, null);
- }
- }, null, true);
-
- return reports;
- };
-
- var listDebugReports = function() {
- kimchi.listReports(function(reports) {
- pendingReports = getPendingReports();
- allReports = pendingReports.concat(reports);
- $('#debug-report-section').removeClass('hidden');
-
- // Row selection will be cleared so disable buttons here
- enableReportButtons(false);
-
- if(reportGrid) {
- reportGrid.setData(allReports);
- }
- else {
- initReportGrid(allReports);
- }
-
- // Set id-debug-img to pending reports
- // It will display a loading icon
- var gridElement = $('#' + reportGridID);
- $.each($('td:contains(' + i18n['KCHDR6007M'] +
')', gridElement), function(index, row) {
- $(row).parent().addClass('no-hover');
- $(row).attr('id', 'id-debug-img');
- });
- }, function(error) {
- if(error['status'] == 403) {
- $('#debug-report-section').addClass('hidden');
- return;
- }
- $('#debug-report-section').removeClass('hidden');
- });
- };
-
- var shutdownButtonID = '#host-button-shutdown';
- var restartButtonID = '#host-button-restart';
- var shutdownHost = function(params) {
- var settings = {
- title : i18n['KCHAPI6004M'],
- content : i18n['KCHHOST6008M'],
- confirm : i18n['KCHAPI6002M'],
- cancel : i18n['KCHAPI6003M']
- };
-
- wok.confirm(settings, function() {
- kimchi.shutdown(params);
- $(shutdownButtonID).prop('disabled', true);
- $(restartButtonID).prop('disabled', true);
- // Check if there is any VM is running.
- kimchi.listVMs(function(vms) {
- for(var i = 0; i < vms.length; i++) {
- if(vms[i]['state'] === 'running') {
- wok.message.error.code('KCHHOST6001E');
- $(shutdownButtonID).prop('disabled', false);
- $(restartButtonID).prop('disabled', false);
- return;
- }
- }
-
- });
- }, function() {
- });
- };
-
- var initPage = function() {
- $('#host-info-container .section-header').each(function(i, header) {
- $('<span
class="arrow"></span>').prependTo(header);
- var toExpand = $(header).attr('aria-expanded') !== 'false';
- expand(header, toExpand);
- });
-
- $('#host-info-container').on('click', '.section-header',
function(event) {
- var toExpand = $(this).attr('aria-expanded') === 'false';
- expand(this, toExpand);
- });
-
- $('#host-button-shutdown').on('click', function(event) {
- shutdownHost(null);
- });
-
- $('#host-button-restart').on('click', function(event) {
- shutdownHost({
- reboot: true
- });
- });
-
- var setupUI = function() {
- if (kimchi.capabilities == undefined) {
- setTimeout(setupUI, 2000);
- return;
- }
-
- if((kimchi.capabilities['repo_mngt_tool']) &&
(kimchi.capabilities['repo_mngt_tool']!="None")) {
- initRepositoriesGrid(kimchi.capabilities['repo_mngt_tool']);
- $('#repositories-section').switchClass('hidden',
kimchi.capabilities['repo_mngt_tool']);
- wok.topic('kimchi/repositoryAdded')
- .subscribe(listRepositories);
- wok.topic('kimchi/repositoryUpdated')
- .subscribe(listRepositories);
- wok.topic('kimchi/repositoryDeleted')
- .subscribe(listRepositories);
- }
-
- if(kimchi.capabilities['update_tool']) {
- $('#software-update-section').removeClass('hidden');
- initSoftwareUpdatesGrid();
- wok.topic('kimchi/softwareUpdated')
- .subscribe(listSoftwareUpdates);
- $('#software-updates-progress-container').accordion({
- collapsible: true
- });
- }
-
- if(kimchi.capabilities['system_report_tool']) {
- listDebugReports();
- wok.topic('kimchi/debugReportAdded')
- .subscribe(listDebugReports);
- wok.topic('kimchi/debugReportRenamed')
- .subscribe(listDebugReports);
- }
- };
- setupUI();
- };
-
- kimchi.getHost(function(data) {
- var htmlTmpl = $('#host-tmpl').html();
- data['logo'] = data['logo'] || '';
- data['memory'] = wok.formatMeasurement(data['memory'], {
- fixed: 2
- });
- var templated = wok.substitute(htmlTmpl, data);
- $('#host-content-container').html(templated);
-
- initPage();
- initTracker();
- });
-
- var StatsMgr = function() {
- var statsArray = {
- cpu: {
- u: {
- type: 'percent',
- legend: i18n['KCHHOST6002M'],
- points: []
- }
- },
- memory: {
- u: {
- type: 'value',
- base: 2,
- fixed: 2,
- legend: i18n['KCHHOST6003M'],
- points: []
- }
- },
- diskIO: {
- r: {
- type: 'value',
- base: 2,
- fixed: 2,
- unit: 'B/s',
- legend: i18n['KCHHOST6004M'],
- points: []
- },
- w: {
- type: 'value',
- base: 2,
- fixed: 2,
- unit: 'B/s',
- legend: i18n['KCHHOST6005M'],
- 'class': 'disk-write',
- points: []
- }
- },
- networkIO: {
- r: {
- type: 'value',
- base: 2,
- fixed: 2,
- unit: 'B/s',
- legend: i18n['KCHHOST6006M'],
- points: []
- },
- s: {
- type: 'value',
- base: 2,
- fixed: 2,
- unit: 'B/s',
- legend: i18n['KCHHOST6007M'],
- 'class': 'network-sent',
- points: []
- }
- }
- };
- var SIZE = 20;
- var cursor = SIZE;
-
- var add = function(stats) {
- for(var key in stats) {
- var item = stats[key];
- for(var metrics in item) {
- var value = item[metrics]['v'];
- var max = item[metrics]['max'];
- var unifiedMetrics = statsArray[key][metrics];
- var ps = unifiedMetrics['points'];
- if(!Array.isArray(value)){
- ps.push(value);
- if(ps.length > SIZE + 1) {
- ps.shift();
- }
- }
- else{
- ps=ps.concat(value);
- ps.splice(0, ps.length-SIZE-1);
- unifiedMetrics['points']=ps;
- }
- if(max !== undefined) {
- unifiedMetrics['max'] = max;
- }
- else {
- if(unifiedMetrics['type'] !== 'value') {
- continue;
- }
- max = -Infinity;
- $.each(ps, function(i, value) {
- if(value > max) {
- max = value;
- }
- });
- if(max === 0) {
- ++max;
- }
- max *= 1.1;
- unifiedMetrics['max'] = max;
- }
- }
- }
- cursor++;
- };
-
- var get = function(which) {
- var stats = statsArray[which];
- var lines = [];
- for(var k in stats) {
- var obj = stats[k];
- var line = {
- type: obj['type'],
- base: obj['base'],
- unit: obj['unit'],
- fixed: obj['fixed'],
- legend: obj['legend']
- };
- if(obj['max']) {
- line['max'] = obj['max'];
- }
- if(obj['class']) {
- line['class'] = obj['class'];
- }
- var ps = obj['points'];
- var numStats = ps.length;
- var unifiedPoints = [];
- $.each(ps, function(i, value) {
- unifiedPoints.push({
- x: cursor - numStats + i,
- y: value
- });
- });
- line['points'] = unifiedPoints;
- lines.push(line);
- }
- return lines;
- };
-
- return {
- add: add,
- get: get
- };
- };
-
- var Tracker = function(charts) {
- var charts = charts;
- var timer = null;
- var statsPool = new StatsMgr();
- var setCharts = function(newCharts) {
- charts = newCharts;
- for(var key in charts) {
- var chart = charts[key];
- chart.updateUI(statsPool.get(key));
- }
- };
-
- var self = this;
-
- var UnifyStats = function(stats) {
- var result= {
- cpu: {
- u: {
- v: stats['cpu_utilization']
- }
- },
- memory: {
- u: {
- }
- },
- diskIO: {
- r: {
- v: stats['disk_read_rate']
- },
- w: {
- v: stats['disk_write_rate']
- }
- },
- networkIO: {
- r: {
- v: stats['net_recv_rate']
- },
- s: {
- v: stats['net_sent_rate']
- }
- }
- };
- if(Array.isArray(stats['memory'])){
- result.memory.u['v']=[];
- result.memory.u['max']=-Infinity;
- for(var i=0;i<stats['memory'].length;i++){
-
result.memory.u['v'].push(stats['memory'][i]['avail']);
-
result.memory.u['max']=Math.max(result.memory.u['max'],stats['memory'][i]['total']);
- }
- }
- else {
- result.memory.u['v']=stats['memory']['avail'],
- result.memory.u['max']=stats['memory']['total']
- }
- return(result);
- };
-
-
- var statsCallback = function(stats) {
- var unifiedStats = UnifyStats(stats);
- statsPool.add(unifiedStats);
- for(var key in charts) {
- var chart = charts[key];
- chart.updateUI(statsPool.get(key));
- }
- timer = setTimeout(function() {
- continueTrack();
- }, 1000);
- };
-
- var track = function() {
- kimchi.getHostStatsHistory(statsCallback,
- function() {
- continueTrack();
- });
- };
-
- var continueTrack = function() {
- kimchi.getHostStats(statsCallback,
- function() {
- continueTrack();
- });
- };
-
- var destroy = function() {
- timer && clearTimeout(timer);
- timer = null;
- };
-
- return {
- setCharts: setCharts,
- start: track,
- stop: destroy
- };
- };
-
- var initTracker = function() {
- // TODO: Extend tabs with onUnload event to unregister timers.
- if(kimchi.hostTimer) {
- kimchi.hostTimer.stop();
- delete kimchi.hostTimer;
- }
-
- var trackedCharts = {
- cpu: new wok.widget.LineChart({
- id: 'chart-cpu',
- node: 'container-chart-cpu',
- type: 'percent'
- }),
- memory: new wok.widget.LineChart({
- id: 'chart-memory',
- node: 'container-chart-memory',
- type: 'value'
- }),
- diskIO: new wok.widget.LineChart({
- id: 'chart-disk-io',
- node: 'container-chart-disk-io',
- type: 'value'
- }),
- networkIO: new wok.widget.LineChart({
- id: 'chart-network-io',
- node: 'container-chart-network-io',
- type: 'value'
- })
- };
-
- if(kimchi.hostTimer) {
- kimchi.hostTimer.setCharts(trackedCharts);
- }
- else {
- kimchi.hostTimer = new Tracker(trackedCharts);
- kimchi.hostTimer.start();
- }
- };
-
- $('#host-root-container').on('remove', function() {
- if(kimchi.hostTimer) {
- kimchi.hostTimer.stop();
- delete kimchi.hostTimer;
- }
-
- repositoriesGrid && repositoriesGrid.destroy();
- wok.topic('kimchi/repositoryAdded')
- .unsubscribe(listRepositories);
- wok.topic('kimchi/repositoryUpdated')
- .unsubscribe(listRepositories);
- wok.topic('kimchi/repositoryDeleted')
- .unsubscribe(listRepositories);
-
- softwareUpdatesGrid && softwareUpdatesGrid.destroy();
- wok.topic('kimchi/softwareUpdated').unsubscribe(listSoftwareUpdates);
-
- reportGrid && reportGrid.destroy();
- wok.topic('kimchi/debugReportAdded').unsubscribe(listDebugReports);
- wok.topic('kimchi/debugReportRenamed').unsubscribe(listDebugReports);
- });
-};
diff --git a/plugins/kimchi/ui/js/src/kimchi.main.js
b/plugins/kimchi/ui/js/src/kimchi.main.js
deleted file mode 100644
index 2fdeb85..0000000
--- a/plugins/kimchi/ui/js/src/kimchi.main.js
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * Project Kimchi
- *
- * Copyright IBM, Corp. 2013-2014
- *
- * 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.
- */
-kimchi.capabilities = undefined;
-kimchi.getCapabilities(function(result) {
- kimchi.capabilities = result;
-
- if(kimchi.capabilities.federation=="on")
- $('#peers').removeClass('hide-content');
-}, function() {
- kimchi.capabilities = {};
-});
diff --git a/plugins/kimchi/ui/js/src/kimchi.network.js
b/plugins/kimchi/ui/js/src/kimchi.network.js
deleted file mode 100644
index c43b59a..0000000
--- a/plugins/kimchi/ui/js/src/kimchi.network.js
+++ /dev/null
@@ -1,442 +0,0 @@
-/*
- * Project Kimchi
- *
- * Copyright IBM, Corp. 2013-2015
- *
- * 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.
- */
-
-kimchi.NETWORK_TYPE_BRIDGE = "bridged";
-
-kimchi.initNetwork = function() {
- if(wok.tabMode['network'] === 'admin') {
- $('.tools').attr('style','display');
- $('#network-content .header
span:last-child').attr('style','display');
- kimchi.initNetworkCreation();
- }
- kimchi.initNetworkListView();
- kimchi.initNetworkDialog();
- kimchi.initNetworkCleanup();
-};
-
-kimchi.initNetworkListView = function() {
- kimchi.listNetworks(function(data) {
- for (var i = 0; i < data.length; i++) {
- var network = {
- name : data[i].name,
- in_use : data[i].in_use,
- state : data[i].state === "active" ? "up" :
"down"
- };
- if (data[i].connection === "bridge") {
- network.type = kimchi.NETWORK_TYPE_BRIDGE;
- } else {
- network.type = data[i].connection;
- }
- network.interface = data[i].interface ? data[i].interface : null;
- network.addrSpace = data[i].subnet ? data[i].subnet : null;
- network.persistent = data[i].persistent;
- kimchi.addNetworkItem(network);
- }
- $('#networkGrid').grid({enableSorting: false});
- $('input', $('.grid-control',
'#network-content')).on('keyup', function(){
- $('#networkGrid').grid('filter', $(this).val());
- });
- });
-};
-
-kimchi.addNetworkItem = function(network) {
- var itemNode = $.parseHTML(kimchi.getNetworkItemHtml(network));
- $("#networkBody").append(itemNode);
- if(wok.tabMode["network"] === "admin") {
- $(".column-action").attr("style","display");
- } else {
- $(".column-space").addClass('column-space-no-border-right');
- }
- kimchi.addNetworkActions(network);
- return itemNode;
-};
-
-kimchi.getNetworkItemHtml = function(network) {
- if(!network.interface) {
- network.interface = i18n["KCHNET6001M"];
- }
- if(!network.addrSpace) {
- network.addrSpace = i18n["KCHNET6001M"];
- }
- if(i18n["network_type_" + network.type]) {
- network.type = i18n["network_type_" + network.type];
- }
-
- var disable_in_use = network.in_use ? "ui-state-disabled" : "";
- var networkItem = wok.substitute($('#networkItem').html(), {
- name : network.name,
- state : network.state,
- type : network.type,
- interface: network.interface,
- addrSpace : network.addrSpace,
- startClass : network.state === "up" ? "hide-action-item" :
"",
- stopClass : network.state === "down" ? "hide-action-item" :
disable_in_use,
- stopDisabled : network.in_use ? "disabled" : "",
- deleteClass : network.state === "up" || network.in_use ?
"ui-state-disabled" : "",
- deleteDisabled: network.state === "up" || network.in_use ?
"disabled" : ""
- });
- return networkItem;
-};
-
-kimchi.stopNetwork = function(network,menu) {
- $(".network-state", $("#" +
wok.escapeStr(network.name))).switchClass("up", "nw-loading");
- $("[nwAct='stop']", menu).addClass("ui-state-disabled");
- kimchi.toggleNetwork(network.name, false, function() {
- $("[nwAct='start']",
menu).removeClass("hide-action-item");
- $("[nwAct='stop']",
menu).addClass("hide-action-item");
- $("[nwAct='stop']",
menu).removeClass("ui-state-disabled");
- if (!network.in_use) {
- $("[nwAct='delete']",
menu).removeClass("ui-state-disabled");
- $(":first-child", $("[nwAct='delete']",
menu)).removeAttr("disabled");
- }
- $(".network-state", $("#" +
wok.escapeStr(network.name))).switchClass("nw-loading", "down");
- }, function(err) {
- $(".network-state", $("#" +
wok.escapeStr(network.name))).switchClass("nw-loading", "up");
- if (!network.in_use) {
- $("[nwAct='stop']",
menu).removeClass("ui-state-disabled");
- }
- wok.message.error(err.responseJSON.reason);
- });
-}
-
-kimchi.addNetworkActions = function(network) {
- $(".menu-container", "#" + wok.escapeStr(network.name)).menu();
-
- $('#' + wok.escapeStr(network.name)).on('click', '.menu-container
li', function(evt) {
- var menu = $(evt.currentTarget).parent();
- if ($(evt.currentTarget).attr("nwAct") === "start") {
- $(".network-state", $("#" +
wok.escapeStr(network.name))).switchClass("down", "nw-loading");
- $("[nwAct='start']",
menu).addClass("ui-state-disabled");
- $("[nwAct='delete']",
menu).addClass("ui-state-disabled");
- $(":first-child", $("[nwAct='delete']",
menu)).attr("disabled", true);
- kimchi.toggleNetwork(network.name, true, function() {
- $("[nwAct='start']",
menu).addClass("hide-action-item");
- $("[nwAct='start']",
menu).removeClass("ui-state-disabled");
- $("[nwAct='stop']",
menu).removeClass("hide-action-item");
- network.state = "up";
- if (network.in_use) {
- $("[nwAct='stop']",
menu).addClass("ui-state-disabled");
- }
- $(".network-state", $("#" +
wok.escapeStr(network.name))).switchClass("nw-loading", "up");
- }, function(err) {
- $(".network-state", $("#" +
wok.escapeStr(network.name))).switchClass("nw-loading","down");
- $("[nwAct='start']",
menu).removeClass("ui-state-disabled");
- if (!network.in_use) {
- $("[nwAct='delete']",
menu).removeClass("ui-state-disabled");
- }
- $(":first-child", $("[nwAct='delete']",
menu)).removeAttr("disabled");
- wok.message.error(err.responseJSON.reason);
- });
- } else if ($(evt.currentTarget).attr("nwAct") === "stop") {
- if (network.in_use) {
- return false;
- }
- if (!network.persistent) {
- var settings = {
- title : i18n['KCHAPI6001M'],
- content : i18n['KCHNET6004M'],
- confirm : i18n['KCHAPI6002M'],
- cancel : i18n['KCHAPI6003M']
- };
- wok.confirm(settings, function() {
- kimchi.stopNetwork(network, menu);
- $('#networkGrid').grid('deleteRow',
$(evt.currentTarget).parents(".row"));
- }, null);
- }
- else {
- kimchi.stopNetwork(network, menu);
- network.state = "down";
- }
- } else if ($(evt.currentTarget).attr("nwAct") === "delete")
{
- if (network.state === "up" || network.in_use) {
- return false;
- }
- wok.confirm({
- title : i18n['KCHAPI6006M'],
- content : i18n['KCHNET6002M'],
- confirm : i18n['KCHAPI6002M'],
- cancel : i18n['KCHAPI6003M']
- }, function() {
- kimchi.deleteNetwork(network.name, function() {
- $('#networkGrid').grid('deleteRow',
$(evt.currentTarget).parents(".row"));
- });
- }, null);
- }
- });
-
- $("#networkBody .column-action .popable").button({
- icons : {
- secondary : "action-button-icon"
- }
- });
-
-};
-
-kimchi.initNetworkCreation = function() {
- $("#networkAdd").on("click", function() {
- kimchi.openNetworkDialog(function() {
- var errorCallback = function(){
- $("#networkFormOk").button("enable");
- $("#networkName").removeAttr("readonly");
- $("#networkFormOk span").text(i18n.KCHAPI6005M);
- };
- var network = kimchi.getNetworkDialogValues();
- var data = {
- name : network.name,
- connection: network.type
- };
- if (network.type === kimchi.NETWORK_TYPE_BRIDGE) {
- data.connection = "bridge";
- data.interface = network.interface;
- if ($("#enableVlan").prop("checked")) {
- data.vlan_id = network.vlan_id;
- if (!(data.vlan_id >=1 && data.vlan_id <= 4094)) {
- wok.message.error.code('KCHNET6001E');
- errorCallback();
- return;
- }
- }
- }
- kimchi.createNetwork(data, function(result) {
- network.state = result.state === "active" ? "up" :
"down";
- network.interface = result.interface ? result.interface :
i18n["KCHNET6001M"];
- network.addrSpace = result.subnet ? result.subnet :
i18n["KCHNET6001M"];
- network.persistent = result.persistent;
- $('#networkGrid').grid('addRow',
kimchi.addNetworkItem(network));
- $("#networkConfig").dialog("close");
- }, function(data) {
- wok.message.error(data.responseJSON.reason);
- errorCallback();
- });
- });
- });
-};
-
-kimchi.initNetworkDialog = function() {
- buttonsObj= {};
- buttonsObj['id'] = "networkFormOk";
- buttonsObj['text'] = i18n.KCHAPI6005M;
- buttonsObj['class'] = "btn-normal";
- buttonsObj['disabled'] = true;
- buttonsObj['click'] = function() { };
- buttonsObjCancel= {};
- buttonsObjCancel['id'] = "networkFormCancel";
- buttonsObjCancel['text'] = i18n.KCHAPI6003M;
- buttonsObjCancel['class'] = "btn-normal";
- buttonsObjCancel['disabled'] = false;
- buttonsObjCancel['click'] = function() {
- $(this).dialog("close");
- };
- $("#networkConfig").dialog({
- autoOpen : false,
- modal : true,
- width : 600,
- draggable : false,
- resizable : false,
- closeText: "X",
- dialogClass : "network-ui-dialog remove-when-logged-off",
- open : function(){
- $(".ui-dialog-titlebar-close",
$("#networkConfig").parent()).removeAttr("title");
- $(".ui-widget-overlay").css({
- "background": "#FFFFFF",
- "opacity": "0.5"
- });
- },
- beforeClose : function() {
- kimchi.cleanNetworkDialog();
- },
- buttons : [buttonsObj, buttonsObjCancel]
- });
- $("#networkConfig").parent().css({
- "background": "#FFFFFF",
- "border-radius": 0,
- "border": "2px solid #999999"
- });
- $(".ui-dialog-titlebar button",
$("#networkConfig").parent()).remove();
- $(".ui-dialog-titlebar span",
$("#networkConfig").parent()).css({
- "font-weight": "lighter",
- "height": "48px",
- "line-height": "48px",
- "margin": "0 30px",
- "color": "#444444",
- "font-size": "22px"
- });
- $(".ui-dialog-titlebar", $("#networkConfig").parent()).css({
- "box-shadow": "none",
- "padding": "0",
- });
- $(".ui-dialog-buttonpane", $("#networkConfig").parent()).css({
- "background": "#008ABF"
- });
- $(".ui-dialog .ui-dialog-buttonpane .ui-dialog-buttonset").css({
- "padding": "0 10px",
- "float": "left"
- });
- $(".ui-dialog-buttonpane .ui-dialog-buttonset
button").removeClass("ui-corner-all");
- $(".ui-dialog-buttonpane .ui-dialog-buttonset button").css({
- "background": "#FFFFFF",
- "color": "#444444",
- "font-size": "13px",
- "border-radius": "0",
- "opacity": "1"
- });
- kimchi.setupNetworkFormEvent();
-};
-
-kimchi.openNetworkDialog = function(okCallback) {
- kimchi.getInterfaces(function(result) {
- var options = [];
- $('#networkDestinationID').selectMenu();
- var nics = {};
- for (var i = 0; i < result.length; i++) {
- options.push({label:result[i].name,value:result[i].name});
- nics[result[i].name] = result[i];
- }
- result.length>0 &&
$("#networkDestinationID").selectMenu("setData", options);
- onChange = function() {
- $("#networkDestinationLabel").text($("#networkDestinationID
li:first-child").text());
- $("#networkDestinationID
li:first-child").addClass("active");
- if (result.length>0 &&
nics[$("#networkDestinationLabel").text()].type === "bridge") {
- $("#enableVlan").prop("checked", false);
- $("#enableVlan").prop("disabled", true);
- $("#networkVlanID").val("");
- $("#networkVlanID").toggle(false);
- $("#labelNetworkVlanID").toggle(false);
- } else {
- $("#enableVlan").prop("disabled",false);
- }
- };
- $("#networkDestinationLabel").on("change", onChange);
- kimchi.setDefaultNetworkType(result.length!==0);
- onChange();
- });
- $("#networkConfig").dialog({
- title : i18n.KCHNET6003M
- });
- $("#networkFormOk").on("click", function() {
- $("#networkFormOk").button("disable");
- $("#networkName").prop("readonly", "readonly");
- $("#networkFormOk span").text(i18n.KCHAPI6008M);
- okCallback();
- });
- $("#enableVlan").on("click", function() {
- $("#networkVlanID").prop("disabled", !this.checked);
- if (!this.checked) {
- $("#networkVlanID").slideUp(100);
- $("#labelNetworkVlanID").slideUp(100);
- $("#networkVlanID").val("");
- }
- else {
- $("#networkVlanID").slideDown(100);
- $("#labelNetworkVlanID").slideDown(100);
- }
- });
- $("#networkConfig").dialog("open");
-};
-
-kimchi.enableBridgeOptions = function(enable) {
- if (!enable) {
- $("#enableVlan").prop("checked", false);
- $("#networkVlanID").toggle(false);
- $("#labelNetworkVlanID").toggle(false);
- $("#networkVlanID").val("");
- $("#networkDestinationLabel").text("");
- $("#bridgeOptions").slideUp(100);
- } else if (!$("#networkDestinationLabel").text()){
- $("#networkDestinationLabel").text($("#networkDestinationID
li:first-child").text());
- $("#bridgeOptions").slideDown(100);
- $("#networkVlanID").toggle(false);
- $("#labelNetworkVlanID").toggle(false);
- }
-};
-
-
-kimchi.setDefaultNetworkType = function(isInterfaceAvail) {
- $("#networkTypeBri").prop("checked", isInterfaceAvail);
- $("#networkTypeBri").prop("disabled", !isInterfaceAvail);
- $("#networkTypeNat").prop("checked", !isInterfaceAvail);
- if (!isInterfaceAvail) {
- kimchi.enableBridgeOptions(false);
- $("#networkBriDisabledLabel").show();
- } else {
- if (kimchi.capabilities && kimchi.capabilities.nm_running) {
- wok.message.warn(i18n['KCHNET6001W']);
- }
- $("#bridgeOptions").slideDown(100);
- $("#networkVlanID").toggle(false);
- $("#labelNetworkVlanID").toggle(false);
- $("#networkBriDisabledLabel").hide();
- }
-};
-
-kimchi.getNetworkDialogValues = function() {
- var network = {
- name : $("#networkName").val(),
- type : $("input:radio[name=networkType]:checked").val()
- };
- if (network.type === kimchi.NETWORK_TYPE_BRIDGE) {
- network.interface = $("#networkDestinationLabel").text();
- network.vlan_id = parseInt($("#networkVlanID").val());
- }
- return network;
-};
-
-kimchi.cleanNetworkDialog = function() {
- $("input:text",
"#networkConfig").val(null).removeClass("invalid-field");
- $("#networkTypeIso").prop("checked", false);
- $("#networkTypeNat").prop("checked", false);
- $("#networkTypeBri").prop("checked", false);
- $("#networkDestinationLabel").text($("#networkDestinationID
li:first-child").text());
- $("#networkFormOk").off("click");
- $("#networkFormOk").button("disable");
- $("#networkFormOk span").text(i18n.KCHAPI6005M);
- $("#networkName").removeAttr("readonly");
- $("#networkVlanID").toggle(false);
- $("#labelNetworkVlanID").toggle(false);
- $("#enableVlan").prop("checked", false);
-
-};
-kimchi.setupNetworkFormEvent = function() {
- $("#networkName").on("keyup", function(event) {
- $("#networkName").toggleClass("invalid-field",
!$("#networkName").val().match(/^[^\"\/]+$/));
- kimchi.updateNetworkFormButton();
- });
- $("#networkTypeIso").on("click", function(event) {
- kimchi.enableBridgeOptions(false);
- });
- $("#networkTypeNat").on("click", function(event) {
- kimchi.enableBridgeOptions(false);
- });
- $("#networkTypeBri").on("click", function(event) {
- kimchi.enableBridgeOptions(true);
- });
-};
-
-kimchi.updateNetworkFormButton = function() {
- if($("#networkName").hasClass("invalid-field")){
- $("#networkFormOk").button("disable");
- }else{
- $("#networkFormOk").button("enable");
- }
-};
-
-kimchi.initNetworkCleanup = function() {
- $("#network-content").on("remove", function() {
- $("#networkConfig").dialog("destroy");
- });
-};
diff --git a/plugins/kimchi/ui/js/src/kimchi.report_add_main.js
b/plugins/kimchi/ui/js/src/kimchi.report_add_main.js
deleted file mode 100644
index 5f098d3..0000000
--- a/plugins/kimchi/ui/js/src/kimchi.report_add_main.js
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * Project Kimchi
- *
- * Copyright IBM, Corp. 2013-2014
- *
- * 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.
- */
-kimchi.report_add_main = function() {
- var reportGridID = 'available-reports-grid';
- var addReportForm = $('#form-report-add');
- var submitButton = $('#button-report-add');
- var nameTextbox = $('input[name="name"]', addReportForm);
- nameTextbox.select();
-
- var submitForm = function(event) {
- if(submitButton.prop('disabled')) {
- return false;
- }
- var reportName = nameTextbox.val();
- var validator = RegExp("^[_A-Za-z0-9-]*$");
- if (!validator.test(reportName)) {
- wok.message.error.code('KCHDR6011M');
- return false;
- }
- var formData = addReportForm.serializeObject();
- var taskAccepted = false;
- var onTaskAccepted = function() {
- if(taskAccepted) {
- return;
- }
- taskAccepted = true;
- wok.window.close();
- wok.topic('kimchi/debugReportAdded').publish();
- };
-
- kimchi.createReport(formData, function(result) {
- onTaskAccepted();
- wok.topic('kimchi/debugReportAdded').publish();
- }, function(result) {
- // Error message from Async Task status
- if (result['message']) {
- var errText = result['message'];
- }
- // Error message from standard kimchi exception
- else {
- var errText = result['responseJSON']['reason'];
- }
- result && wok.message.error(errText);
-
- taskAccepted &&
- $('.grid-body-view table tr:first-child',
- '#' + reportGridID).remove();
- submitButton.prop('disabled', false);
- nameTextbox.select();
- }, onTaskAccepted);
-
- event.preventDefault();
- };
-
- addReportForm.on('submit', submitForm);
- submitButton.on('click', submitForm);
-};
diff --git a/plugins/kimchi/ui/js/src/kimchi.report_rename_main.js
b/plugins/kimchi/ui/js/src/kimchi.report_rename_main.js
deleted file mode 100644
index 1bdb8d9..0000000
--- a/plugins/kimchi/ui/js/src/kimchi.report_rename_main.js
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * Project Kimchi
- *
- * Copyright IBM, Corp. 2014
- *
- * 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.
- */
-kimchi.report_rename_main = function() {
- var renameReportForm = $('#form-report-rename');
- var submitButton = $('#button-report-rename');
- var nameTextbox = $('input[name="name"]', renameReportForm);
- var submitForm = function(event) {
- if(submitButton.prop('disabled')) {
- return false;
- }
- var reportName = nameTextbox.val();
-
- // if the user hasn't changed the report's name,
- // nothing should be done.
- if (reportName == kimchi.selectedReport) {
- wok.message.error.code('KCHDR6013M');
- return false;
- }
-
- var validator = RegExp("^[A-Za-z0-9-]*$");
- if (!validator.test(reportName)) {
- wok.message.error.code('KCHDR6011M');
- return false;
- }
- var formData = renameReportForm.serializeObject();
- submitButton.prop('disabled', true);
- nameTextbox.prop('disabled', true);
- kimchi.renameReport(kimchi.selectedReport, formData, function(result) {
- submitButton.prop('disabled', false);
- nameTextbox.prop('disabled', false);
- wok.window.close();
- wok.topic('kimchi/debugReportRenamed').publish({
- result: result
- });
- }, function(result) {
- var errText = result &&
- result['responseJSON'] &&
- result['responseJSON']['reason'];
- wok.message.error(errText);
- submitButton.prop('disabled', false);
- nameTextbox.prop('disabled', false).focus();
- });
-
- event.preventDefault();
- };
-
- renameReportForm.on('submit', submitForm);
- submitButton.on('click', submitForm);
-
- nameTextbox.val(kimchi.selectedReport).select();
-};
diff --git a/plugins/kimchi/ui/js/src/kimchi.repository_add_main.js
b/plugins/kimchi/ui/js/src/kimchi.repository_add_main.js
deleted file mode 100644
index 656306b..0000000
--- a/plugins/kimchi/ui/js/src/kimchi.repository_add_main.js
+++ /dev/null
@@ -1,96 +0,0 @@
-/*
- * Project Kimchi
- *
- * Copyright IBM, Corp. 2014
- *
- * 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.
- */
-kimchi.repository_add_main = function() {
-
- var addForm = $('#form-repository-add');
- var addButton = $('#button-repository-add');
-
- var validateField = function(event) {
- var valid=($(this).val()!=='');
- $(addButton).prop('disabled', !valid);
- return(valid);
- };
-
- var validateForm = function(event) {
- var valid=false;
- addForm.find('input.required').each( function() {
- valid=($(this).val()!=='');
- return(!valid);
- });
- return(valid);
- }
-
- addForm.find('input.required').on('input propertychange',
validateField);
-
- var weedObject = function(obj) {
- for (var key in obj) {
- if (obj.hasOwnProperty(key)) {
- if((typeof(obj[key])==="object") &&
!Array.isArray(obj[key])) {
- weedObject(obj[key]);
- }
- else if(obj[key] == '') {
- delete obj[key];
- }
- }
- }
- }
-
- var addRepository = function(event) {
- var valid = validateForm();
- if(!valid) {
- return false;
- }
-
- var formData = $(addForm).serializeObject();
-
- if (formData && formData.isMirror!=undefined) {
- formData.isMirror=(String(formData.isMirror).toLowerCase() ===
'true');
- }
- if(formData.isMirror) {
- if(formData.config==undefined) {
- formData.config=new Object();
- }
- formData.config.mirrorlist=formData.baseurl;
- delete formData.baseurl;
- delete formData.isMirror;
- }
- weedObject(formData);
- if(formData.config && formData.config.comps) {
- formData.config.comps=formData.config.comps.split(/[,\s]/);
- for(var i=0; i>formData.config.comps.length; i++) {
- formData.config.comps[i]=formData.config.comps[i].trim();
- }
- for (var j=formData.config.comps.indexOf(""); j!=-1;
j=formData.config.comps.indexOf("")) {
- formData.config.comps.splice(j, 1);
- }
- }
-
- kimchi.createRepository(formData, function() {
- wok.topic('kimchi/repositoryAdded').publish();
- wok.window.close();
- }, function(jqXHR, textStatus, errorThrown) {
- var reason = jqXHR &&
- jqXHR['responseJSON'] &&
- jqXHR['responseJSON']['reason'];
- wok.message.error(reason);
- });
- return false;
- };
-
- $(addForm).on('submit', addRepository);
-};
diff --git a/plugins/kimchi/ui/js/src/kimchi.repository_edit_main.js
b/plugins/kimchi/ui/js/src/kimchi.repository_edit_main.js
deleted file mode 100644
index 5bfc51e..0000000
--- a/plugins/kimchi/ui/js/src/kimchi.repository_edit_main.js
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- * Project Kimchi
- *
- * Copyright IBM, Corp. 2014
- *
- * 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.
- */
-kimchi.repository_edit_main = function() {
-
- var editForm = $('#form-repository-edit');
-
- var saveButton = $('#repository-edit-button-save');
-
- if(kimchi.capabilities['repo_mngt_tool']=="yum") {
- editForm.find('input.deb').prop('disabled', true);
- }
- else if(kimchi.capabilities['repo_mngt_tool']=="deb") {
- editForm.find('input.yum').prop('disabled', true);
- }
-
- kimchi.retrieveRepository(kimchi.selectedRepository, function(repository) {
- editForm.fillWithObject(repository);
-
- $('input', editForm).on('input propertychange', function(event)
{
- if($(this).val() !== '') {
- $(saveButton).prop('disabled', false);
- }
- });
- });
-
-
- var editRepository = function(event) {
- var formData = $(editForm).serializeObject();
-
- if (formData && formData.config) {
- formData.config.gpgcheck=(String(formData.config.gpgcheck).toLowerCase() ===
'true');
- }
-
- if(formData.config && formData.config.comps) {
- formData.config.comps=formData.config.comps.split(/[,\s]/);
- for(var i=0; i>formData.config.comps.length; i++) {
- formData.config.comps[i]=formData.config.comps[i].trim();
- }
- for (var j=formData.config.comps.indexOf(""); j!=-1;
j=formData.config.comps.indexOf("")) {
- formData.config.comps.splice(j, 1);
- }
- }
-
- kimchi.updateRepository(kimchi.selectedRepository, formData, function() {
- wok.topic('kimchi/repositoryUpdated').publish();
- wok.window.close();
- }, function(jqXHR, textStatus, errorThrown) {
- var reason = jqXHR &&
- jqXHR['responseJSON'] &&
- jqXHR['responseJSON']['reason'];
- wok.message.error(reason);
- });
-
- return false;
- };
-
- $(editForm).on('submit', editRepository);
- $(saveButton).on('click', editRepository);
-};
diff --git a/plugins/kimchi/ui/js/src/kimchi.storage_main.js
b/plugins/kimchi/ui/js/src/kimchi.storage_main.js
deleted file mode 100644
index 40a43f6..0000000
--- a/plugins/kimchi/ui/js/src/kimchi.storage_main.js
+++ /dev/null
@@ -1,428 +0,0 @@
-/*
- * Project Kimchi
- *
- * Copyright IBM, Corp. 2013-2015
- *
- * 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.
- */
-kimchi.doListStoragePools = function() {
- kimchi.listStoragePools(function(result) {
- var storageHtml = $('#storageTmpl').html();
- if (result && result.length) {
- var listHtml = '';
- $.each(result, function(index, value) {
- value.usage = Math.round(value.allocated / value.capacity * 100) || 0;
- value.capacity = wok.changetoProperUnit(value.capacity,1);
- value.allocated = wok.changetoProperUnit(value.allocated,1);
- value.enableExt = value.type==="logical" ? "" :
"hide-content";
- if ('kimchi-iso' !== value.type) {
- listHtml += wok.substitute(storageHtml, value);
- }
- });
- if($('#storageGrid').hasClass('grid'))
- $('#storageGrid').grid('destroy');
- $('#storagepoolsList').html(listHtml);
- if(wok.tabMode['storage'] === 'admin') {
- $('.storage-button').attr('style','display');
- } else {
-
$('.storage-allocate').addClass('storage-allocate-padding-user');
- }
- $('#storageGrid').grid({enableSorting: false});
- $('input', $('.grid-control',
'.storage')).on('keyup', function(){
- $('#storageGrid').grid('filter', $(this).val());
- });
- kimchi.storageBindClick();
- } else {
- $('#storagepoolsList').html('');
- }
- }, function(err) {
- wok.message.error(err.responseJSON.reason);
- });
-}
-
-kimchi.storageBindClick = function() {
-
- $('.inactive').each(function(index) {
- if ('active' === $(this).data('state')) {
- $(this).hide();
- } else {
- $(this).show();
- }
- });
-
- $('.list-storage .storage-state .active').each(function(index) {
- if ('active' === $(this).data('state')) {
- $(this).show();
- } else {
- $(this).hide();
- }
- });
-
- $('.pool-activate').each(function(index) {
- if ('active' === $(this).data('stat')) {
- $(this).hide();
- } else {
- $(this).show();
- }
- });
-
- $('.pool-deactivate').each(function(index) {
- if ('active' === $(this).data('stat')) {
- $(this).show();
- } else {
- $(this).hide();
- }
- });
-
- $('.pool-add-volume').each(function(index) {
- var canAddVolume =
- $(this).data('stat') === 'active' &&
- $(this).data('type') !== 'iscsi' &&
- $(this).data('type') !== 'scsi';
- if(canAddVolume) {
- $(this).show();
- }
- else {
- $(this).hide();
- }
- });
-
- if(wok.tabMode['storage'] === 'admin') {
- $('.pool-delete').on('click', function(event) {
- var $pool = $(this);
- var settings = {
- title : i18n['KCHAPI6001M'],
- content : i18n['KCHPOOL6001M'],
- confirm : i18n['KCHAPI6002M'],
- cancel : i18n['KCHAPI6003M']
- };
- wok.confirm(settings, function() {
- var poolName = $pool.data('name');
- kimchi.deleteStoragePool(poolName, function() {
- kimchi.doListStoragePools();
- }, function(err) {
- wok.message.error(err.responseJSON.reason);
- });
- });
- });
-
- $('.pool-activate').on('click', function(event) {
- var poolName = $(this).data('name');
- kimchi.changePoolState(poolName, 'activate', function() {
- kimchi.doListStoragePools();
- }, function(err) {
- wok.message.error(err.responseJSON.reason);
- });
- });
-
- $('.pool-deactivate').on('click', function(event) {
- var poolName = $(this).data('name');
- var settings = {
- title : i18n['KCHAPI6001M'],
- content : i18n['KCHPOOL6012M'],
- confirm : i18n['KCHAPI6002M'],
- cancel : i18n['KCHAPI6003M']
- };
- if (!$(this).data('persistent')) {
- wok.confirm(settings, function() {
- kimchi.changePoolState(poolName, 'deactivate', function() {
- kimchi.doListStoragePools();
- }, function(err) {
- wok.message.error(err.responseJSON.reason);
- });
- }, function() {
- return false;
- });
- }
- else {
- kimchi.changePoolState(poolName, 'deactivate', function() {
- kimchi.doListStoragePools();
- }, function(err) {
- wok.message.error(err.responseJSON.reason);
- });
- }
- });
-
- $('.pool-add-volume').on('click', function(event) {
- var poolName = $(this).data('name');
- kimchi.selectedSP = poolName;
- wok.window.open('plugins/kimchi/storagepool-add-volume.html');
- });
-
- $('.storage-action').on('click', function() {
- var storage_action = $(this);
- var deleteButton = storage_action.find('.pool-delete');
- if ('active' === deleteButton.data('stat')) {
- deleteButton.attr('disabled', 'disabled');
- } else {
- deleteButton.removeAttr('disabled');
- }
- });
-
- $('.pool-extend').on('click', function() {
- $("#logicalPoolExtend").dialog("option",
"poolName", $(this).data('name'));
- $("#logicalPoolExtend").dialog("open");
- });
- }
-
- $('.row').on('click', function(event) {
- if (!$(event.target).parents().hasClass('bottom')) {
- if ($(this).data('stat') === 'active') {
- var that = $(this);
- var volumeDiv = $('#volume' + that.data('name'));
- var slide = $('.volumes', this);
- if (that.hasClass('in')) {
- that.css('height','auto');
- kimchi.doListVolumes(that);
- } else {
- slide.slideUp('slow', function(){
- that.css('height','');
- });
- that.addClass('in');
- kimchi.changeArrow($('.arrow-up', this));
- }
- }
- }
- });
-}
-
-kimchi._generateVolumeHTML = function(volume) {
- if(volume['type'] === 'kimchi-iso') {
- return '';
- }
- var volumeHtml = $('#volumeTmpl').html();
- volume.capacity = wok.changetoProperUnit(volume.capacity,1);
- volume.allocation = wok.changetoProperUnit(volume.allocation,1);
- return wok.substitute(volumeHtml, volume);
-};
-
-kimchi.doListVolumes = function(poolObj) {
- var poolName = poolObj.data('name')
-
- var getOngoingVolumes = function() {
- var result = {}
- var filter = 'status=running&target_uri=' +
encodeURIComponent('^/plugins/kimchi/storagepools/' + poolName + '/*')
- kimchi.getTasksByFilter(filter, function(tasks) {
- for(var i = 0; i < tasks.length; i++) {
- var volumeName = tasks[i].target_uri.split('/').pop();
- result[volumeName] = tasks[i];
-
- if(kimchi.trackingTasks.indexOf(tasks[i].id) >= 0) {
- continue;
- }
-
- kimchi.trackTask(tasks[i].id, function(result) {
- wok.topic('kimchi/volumeTransferFinished').publish(result);
- }, function(result) {
- wok.topic('kimchi/volumeTransferError').publish(result);
- }, function(result) {
- wok.topic('kimchi/volumeTransferProgress').publish(result);
- });
- }
- }, null, true);
- return result;
- };
-
- var volumeDiv = $('#volume' + poolName);
- $(volumeDiv).empty();
- var slide = $('.volumes', poolObj);
- var handleArrow = $('.arrow-down', poolObj);
-
- kimchi.listStorageVolumes(poolName, function(result) {
- var listHtml = '';
- var ongoingVolumes = [];
- var ongoingVolumesMap = getOngoingVolumes();
- $.each(ongoingVolumesMap, function(volumeName, task) {
- ongoingVolumes.push(volumeName)
- var volume = {
- poolName: poolName,
- used_by: [],
- capacity: 0,
- name: volumeName,
- format: '',
- bootable: null,
- os_distro: '',
- allocation: 0,
- os_version: '',
- path: '',
- type: 'file'
- };
- listHtml += kimchi._generateVolumeHTML(volume);
- });
-
- $.each(result, function(index, value) {
- if (ongoingVolumes.indexOf(value.name) == -1) {
- value.poolname = poolName;
- listHtml += kimchi._generateVolumeHTML(value);
- }
- });
-
- if (listHtml.length > 0) {
- volumeDiv.html(listHtml);
- } else {
- volumeDiv.html("<div class='pool-empty'>" +
i18n['KCHPOOL6002M'] + "</div>");
- }
-
- $.each(ongoingVolumesMap, function(volumeName, task) {
- wok.topic('kimchi/volumeTransferProgress').publish(task);
- });
-
- poolObj.removeClass('in');
- kimchi.changeArrow(handleArrow);
- slide.slideDown('slow');
- }, function(err) {
- wok.message.error(err.responseJSON.reason);
- });
-}
-
-kimchi.initLogicalPoolExtend = function() {
- $("#logicalPoolExtend").dialog({
- autoOpen : false,
- modal : true,
- width : 600,
- resizable : false,
- closeText: "X",
- open : function(){
- $('#loading-info',
'#logicalPoolExtend').removeClass('hidden');
- $(".ui-dialog-titlebar-close",
$("#logicalPoolExtend").parent()).removeAttr("title");
- kimchi.listHostPartitions(function(data) {
- $('#loading-info',
'#logicalPoolExtend').addClass('hidden');
- if (data.length > 0) {
- for(var i=0;i<data.length;i++){
- if (data[i].type === 'part' || data[i].type ===
'disk') {
- $('.host-partition',
'#logicalPoolExtend').append(wok.substitute($('#logicalPoolExtendTmpl').html(),
data[i]));
- }
- }
- } else {
- $('.host-partition').html(i18n['KCHPOOL6011M']);
- $('.host-partition').addClass('text-help');
- }
- }, function(err) {
- $('#loading-info',
'#logicalPoolExtend').addClass('hidden');
- $('.host-partition').html(i18n['KCHPOOL6013M'] +
'<br/>(' + err.responseJSON.reason + ')');
- $('.host-partition').addClass('text-help');
- });
- },
- beforeClose : function() { $('.host-partition',
'#logicalPoolExtend').empty(); },
- buttons : [{
- class: "ui-button-primary",
- text: i18n.KCHAPI6007M,
- click: function(){
- var devicePaths = [];
- $("input[type='checkbox']:checked",
"#logicalPoolExtend").each(function(){
- devicePaths.push($(this).prop('value'));
- })
-
kimchi.updateStoragePool($("#logicalPoolExtend").dialog("option",
"poolName"),{disks: devicePaths},function(data){
- var item =
$("#"+$("#logicalPoolExtend").dialog("option",
"poolName"));
- $(".usage", $(".storage-name",
item)).text((Math.round(data.allocated/data.capacity*100)||0)+"%");
- $(".storage-text", $(".storage-capacity",
item)).text(wok.changetoProperUnit(data.capacity,1));
- $(".storage-text", $(".storage-allocate",
item)).text(wok.changetoProperUnit(data.allocated,1));
- });
- $(this).dialog("close");
- }
- }]
- });
-}
-
-kimchi.storage_main = function() {
- if(wok.tabMode['storage'] === 'admin') {
- $('.tools').attr('style','display');
- $('#storage-pool-add').on('click', function() {
- wok.window.open('plugins/kimchi/storagepool-add.html');
- });
- $('.list-title .title-actions').attr('style','display');
- }
- kimchi.doListStoragePools();
- kimchi.initLogicalPoolExtend();
-
- wok.topic('kimchi/storageVolumeAdded').subscribe(function() {
- pool = kimchi.selectedSP;
- var poolNode = $('.storage-li[data-name="' + pool +
'"]');
- kimchi.doListVolumes(poolNode);
- });
-
- wok.topic('kimchi/volumeTransferProgress').subscribe(function(result) {
- var extractProgressData = function(data) {
- var sizeArray = /(\d+)\/(\d+)/g.exec(data) || [0, 0, 0];
- var downloaded = sizeArray[1];
- var percent = 0;
- if(downloaded) {
- var total = sizeArray[2];
- if(!isNaN(total)) {
- percent = downloaded / total * 100;
- }
- }
- var formatted = wok.formatMeasurement(downloaded);
- var size = (1.0 * formatted['v']).toFixed(1) +
formatted['s'];
- return {
- size: size,
- percent: percent
- };
- };
-
- var uriElements = result.target_uri.split('/');
- var poolName = uriElements[2];
- var volumeName = uriElements.pop();
- var progress = extractProgressData(result['message']);
- var size = progress['size'];
- var percent = progress['percent'];
-
- volumeBox = $('#volume' + poolName + ' [data-volume-name="'
+ volumeName + '"]');
- $('.progress-bar-inner', volumeBox).css({
- width: percent + '%'
- });
- $('.progress-transferred', volumeBox).text(size);
- $('.volume-progress', volumeBox).removeClass('hidden');
- $('.progress-status', volumeBox).text(i18n['KCHPOOL6014M']);
- });
-
- wok.topic('kimchi/volumeTransferFinished').subscribe(function(result) {
- var uriElements = result.target_uri.split('/');
- var poolName = uriElements[2];
- var volumeName = uriElements.pop();
- var volumeBox = $('#volume' + poolName + '
[data-volume-name="' + volumeName + '"]');
- $('.volume-progress', volumeBox).addClass('hidden');
- kimchi.getStoragePoolVolume(poolName, volumeName, function(volume) {
- var html = kimchi._generateVolumeHTML(volume);
- $(volumeBox).replaceWith(html);
- }, function(err) {
- wok.message.error(err.responseJSON.reason);
- });
- });
-
- wok.topic('kimchi/volumeTransferError').subscribe(function(result) {
- // Error message from Async Task status
- if (result['message']) {
- var errText = result['message'];
- }
- // Error message from standard kimchi exception
- else {
- var errText = result['responseJSON']['reason'];
- }
- result && wok.message.error(errText);
-
- var uriElements = result.target_uri.split('/');
- var poolName = uriElements[2];
- var volumeName = uriElements.pop();
- volumeBox = $('#volume' + poolName + ' [data-volume-name="'
+ volumeName + '"]');
- $('.progress-status', volumeBox).text(i18n['KCHPOOL6015M']);
- });
-};
-
-kimchi.changeArrow = function(obj) {
- if ($(obj).hasClass('arrow-down')) {
- $(obj).removeClass('arrow-down').addClass('arrow-up');
- } else {
- $(obj).removeClass('arrow-up').addClass('arrow-down');
- }
-}
diff --git a/plugins/kimchi/ui/js/src/kimchi.storagepool_add_main.js
b/plugins/kimchi/ui/js/src/kimchi.storagepool_add_main.js
deleted file mode 100644
index 8c27539..0000000
--- a/plugins/kimchi/ui/js/src/kimchi.storagepool_add_main.js
+++ /dev/null
@@ -1,414 +0,0 @@
-/*
- * Project Kimchi
- *
- * Copyright IBM, Corp. 2013-2015
- *
- * 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.
- */
-
-kimchi.storagepool_add_main = function() {
- kimchi.initStorageAddPage();
- $('#form-pool-add').on('submit', kimchi.addPool);
- $('#pool-doAdd').on('click', kimchi.addPool);
- // 'pool-doAdd' button starts as disabled.
- $("#pool-doAdd").attr("disabled", true);
- // Make any change in the form fields enables the
- // 'pool-doAdd' button if all the visible form
- // fields are filled, disables it otherwise.
- $('#form-pool-add').on('input change propertychange', function() {
- if (!kimchi.inputsNotBlank())
- $("#pool-doAdd").attr("disabled", true);
- else
- $("#pool-doAdd").attr("disabled", false);
- });
-};
-
-kimchi.storageFilterSelect = function(id, isUpdate) {
- var input = $('input', '#'+id);
- var options = $(".option", '#'+id);
- var filter = function(container, key){
- container.children().each(function(){
- $(this).css("display", $(this).text().indexOf(key)==-1 ?
"none" : "");
- });
- };
- if(!isUpdate){
- input.on("keyup", function(){
- filter(options, input.val());
- });
- }
- options.children().each(function(){
- $(this).click(function(){
- options.children().removeClass("active");
- input.val($(this).text());
- input.trigger("change");
- $(this).addClass("active");
- filter(options, "");
- });
- });
-};
-
-kimchi.setupISCSI = function(){
- var loadTargets = function(server, port, callback){
- var isUpdate = $(".option", "#iSCSITarget").children().length
> 0;
- $(".option", "#iSCSITarget").empty();
- $('input', "#iSCSITarget").attr("placeholder",
i18n['KCHPOOL6006M']);
- kimchi.getISCSITargets(server, port, function(data){
- if(data.length==0){
- $('input',
"#iSCSITarget").attr("placeholder", i18n['KCHPOOL6007M']);
- }else{
- for(var i=0; i<data.length; i++){
- var itemNode =
$.parseHTML("<li>"+data[i].target+"</li>");
- $(".option", "#iSCSITarget").append(itemNode);
- }
- $('input',
"#iSCSITarget").attr("placeholder", "");
- $(".popover",
"#iSCSITarget").css("display", "block");
- }
- kimchi.storageFilterSelect('iSCSITarget', isUpdate);
- $('input', "#iSCSITarget").trigger("focus");
- callback();
- }, function(data){
- $('input', "#iSCSITarget").attr("placeholder",
i18n['KCHPOOL6008M']);
- callback();
- wok.message.error(data.responseJSON.reason);
- });
- };
- var triggerLoadTarget = function(){
- $('input', "#iSCSITarget").val("");
- var server = $("#iscsiserverId").val().trim();
- var port = $("#iscsiportId").val().trim();
- if(server!="" &&
!$("#iscsiserverId").hasClass("invalid-field") &&
!$("#iscsiportId").hasClass("invalid-field")){
- $("#iscsiserverId").attr("disabled", true);
- $("#iscsiportId").attr("disabled", true);
- loadTargets(server, port, function(){
- $("#iscsiserverId").attr("disabled", false);
- $("#iscsiportId").attr("disabled", false);
- });
- }
- };
- $("#iscsiserverId").change(function(){
- $('input', "#iSCSITarget").off('focus',
triggerLoadTarget);
- $('input', "#iSCSITarget").one('focus',
triggerLoadTarget);
- });
- $("#iscsiportId").change(function(){
- $('input', "#iSCSITarget").off('focus',
triggerLoadTarget);
- $('input', "#iSCSITarget").one('focus',
triggerLoadTarget);
- });
- var initISCSIServers = function(){
- kimchi.getStorageServers("iscsi", function(data){
- for(var i=0;i<data.length;i++){
- var itemNode =
$.parseHTML("<li>"+data[i].host+"</li>");
- $(".option", "#iSCSIServer").append(itemNode);
- $(itemNode).click(function(){
- $("#iscsiportId").val($(this).prop("port"));
- $("#iscsiserverId").val($(this).text());
- triggerLoadTarget();
- }).prop("port", data[i].port);
- }
- kimchi.storageFilterSelect('iSCSIServer', false);
- });
- };
- initISCSIServers();
-};
-
-kimchi.initStorageAddPage = function() {
- kimchi.listHostPartitions(function(data) {
- if (data.length > 0) {
- var deviceHtml = $('#partitionTmpl').html();
- var listHtml = '';
- valid_types = ['part', 'disk', 'mpath'];
- $.each(data, function(index, value) {
- if (valid_types.indexOf(value.type) != -1) {
- listHtml += wok.substitute(deviceHtml, value);
- }
- });
- $('.host-partition', '#form-pool-add').html(listHtml);
- } else {
- $('.host-partition').html(i18n['KCHPOOL6011M']);
- $('.host-partition').addClass('text-help');
- }
- }, function(err) {
- $('.host-partition').html(i18n['KCHPOOL6013M'] +
'<br/>(' + err.responseJSON.reason + ')');
- $('.host-partition').addClass('text-help');
- });
-
- kimchi.getHostFCDevices(function(data){
- if(data.length>0){
- for(var i=0;i<data.length;i++){
- data[i].label = data[i].name;
- data[i].value = data[i].name;
- }
- $('#scsiAdapter').selectMenu();
- $("input", "#scsiAdapter").val(data[0].name);
- $('#scsiAdapter').selectMenu("setData", data);
- } else {
- $('#scsiAdapter').html(i18n['KCHPOOL6005M']);
- $('#scsiAdapter').addClass('text-help');
- }
- });
-
- $('#poolTypeId').selectMenu();
- $('#serverComboboxId').combobox();
- $('#targetFilterSelectId').filterselect();
- var options = [ {
- label : "DIR",
- value : "dir"
- }, {
- label : "NFS",
- value : "netfs"
- }, {
- label : "iSCSI",
- value : "iscsi"
- }, {
- label : "LOGICAL",
- value : "logical"
- }, {
- label : i18n.KCHPOOL6004M,
- value : "scsi"
- } ];
- $('#poolTypeId').selectMenu("setData", options);
-
- kimchi.getStorageServers('netfs', function(data) {
- var serverContent = [];
- if (data.length > 0) {
- $.each(data, function(index, value) {
- serverContent.push({
- label : value.host,
- value : value.host
- });
- });
- }
- $('#serverComboboxId').combobox("setData", serverContent);
- $('input[name=nfsServerType]').change(function() {
- if ($(this).val() === 'input') {
- $('#nfsServerInputDiv').removeClass('tmpl-html');
- $('#nfsServerChooseDiv').addClass('tmpl-html');
- } else {
- $('#nfsServerInputDiv').addClass('tmpl-html');
- $('#nfsServerChooseDiv').removeClass('tmpl-html');
- }
- });
- $('#nfsserverId').on("change keyup",function() {
- if ($(this).val() !== '' && wok.isServer($(this).val())) {
- $('#nfspathId').prop('disabled',false);
- $(this).removeClass("invalid-field");
- } else {
- $(this).addClass("invalid-field");
- $('#nfspathId').prop( "disabled",true);
- }
- $('#targetFilterSelectId').filterselect('clear');
- });
- $('#nfspathId').focus(function() {
- var targetContent = [];
- kimchi.getStorageTargets($('#nfsserverId').val(), 'netfs',
function(data) {
- if (data.length > 0) {
- $.each(data, function(index, value) {
- targetContent.push({
- label : value.target,
- value : value.target
- });
- });
- }
- $('#targetFilterSelectId').filterselect("setData",
targetContent);
- });
- });
- });
-
- $('#poolTypeInputId').change(function() {
- var poolObject = {'dir': ".path-section", 'netfs':
'.nfs-section',
- 'iscsi': '.iscsi-section', 'scsi':
'.scsi-section',
- 'logical': '.logical-section'}
- var selectType = $(this).val();
- $.each(poolObject, function(type, value) {
- if(selectType == type){
- $(value).removeClass('tmpl-html');
- } else {
- $(value).addClass('tmpl-html');
- }
- });
- });
- $('#authId').click(function() {
- if ($(this).prop("checked")) {
- $('.authenticationfield').removeClass('tmpl-html');
- } else {
- $('.authenticationfield').addClass('tmpl-html');
- }
- });
- $('#iscsiportId').keyup(function(event) {
- $(this).toggleClass("invalid-field",!/^[0-9]*$/.test($(this).val()));
- });
- $('#iscsiserverId').keyup(function(event) {
-
$(this).toggleClass("invalid-field",!wok.isServer($(this).val().trim()));
- }).change(function(event) {
-
$(this).toggleClass("invalid-field",!wok.isServer($(this).val().trim()));
- });
- kimchi.setupISCSI();
-};
-
-/* Returns 'true' if all form fields were filled, 'false' if
- * any field is left blank. The function takes into account
- * the current poolType selected.
- *
- * Any 'field is blank' verification that were done in other
- * validate functions were deleted, since we're doing it here
- * already.
- */
-kimchi.inputsNotBlank = function() {
- if (!$('#poolId').val()) return false;
- var poolType = $("#poolTypeInputId").val();
- if (poolType === "dir") {
- if (!$('#pathId').val()) return false;
- } else if (poolType === "netfs") {
- if (!$('#nfspathId').val()) return false;
- if (!$('#nfsserverId').val()) return false;
- } else if (poolType === "iscsi") {
- if (!$('#iscsiserverId').val()) return false;
- if (!$('#iscsiTargetId').val()) return false;
- } else if (poolType === "logical") {
- if ($("input[name=devices]:checked").length === 0)
- return false;
- }
- return true;
-};
-
-kimchi.validateForm = function() {
- var poolType = $("#poolTypeInputId").val();
- if (poolType === "dir") {
- return kimchi.validateDirForm();
- } else if (poolType === "netfs") {
- return kimchi.validateNfsForm();
- } else if (poolType === "iscsi") {
- return kimchi.validateIscsiForm();
- } else if (poolType === "logical") {
- return kimchi.validateLogicalForm();
- } else {
- return true;
- }
-};
-
-kimchi.validateDirForm = function () {
- var path = $('#pathId').val();
- if (!/(^\/.*)$/.test(path)) {
- wok.message.error.code('KCHAPI6003E');
- return false;
- }
- return true;
-};
-
-kimchi.validateNfsForm = function () {
- var nfspath = $('#nfspathId').val();
- var nfsserver = $('#nfsserverId').val();
- if (!kimchi.validateServer(nfsserver)) {
- return false;
- }
- if (!/((\/([0-9a-zA-Z-_\.]+)))$/.test(nfspath)) {
- wok.message.error.code('KCHPOOL6005E');
- return false;
- }
- $('#nfs-mount-loading').removeClass('hidden');
- return true;
-};
-
-kimchi.validateIscsiForm = function() {
- var iscsiServer = $('#iscsiserverId').val();
- var iscsiTarget = $('#iscsiTargetId').val();
- if (!kimchi.validateServer(iscsiServer)) {
- return false;
- }
- return true;
-};
-
-kimchi.validateServer = function(serverField) {
- if(!wok.isServer(serverField)) {
- wok.message.error.code('KCHPOOL6009E');
- return false;
- }
- return true;
-};
-
-kimchi.validateLogicalForm = function () {
- if ($("input[name=devices]:checked").length === 0) {
- wok.message.error.code('KCHPOOL6006E');
- return false;
- } else {
- return true;
- }
-};
-
-kimchi.addPool = function(event) {
- if (kimchi.validateForm()) {
- var formData = $('#form-pool-add').serializeObject();
- delete formData.authname;
- var poolType = $('#poolTypeId').selectMenu('value');
- if (poolType === 'dir') {
- formData.path = $('#pathId').val();
- } else if (poolType === 'logical') {
- var source = {};
- if (!$.isArray(formData.devices)) {
- var deviceObj = [];
- deviceObj[0] = formData.devices;
- source.devices = deviceObj;
- } else {
- source.devices = formData.devices;
- }
- delete formData.devices;
- formData.source = source;
- } else if (poolType === 'netfs'){
- var source = {};
- source.path = $('#nfspathId').val();
- source.host = $('#nfsserverId').val();
- formData.source = source;
- } else if (poolType === 'iscsi') {
- var source = {};
- source.target = $('#iscsiTargetId').val();
- source.host = $('#iscsiserverId').val();
- $('#iscsiportId').val() !== '' ? source.port =
parseInt($('#iscsiportId').val()): null;
- if ($('#authId').prop("checked")) {
- source.auth = {
- "username" : $('#usernameId').val(),
- "password" : $('#passwordId').val()
- };
- }
- formData.source = source;
- } else if (poolType === 'scsi'){
- formData.source = { adapter_name:
$('#scsiAdapter').selectMenu('value') };
- }
- var storagePoolAddingFunc = function() {
- $('input',
'#form-pool-add').attr('disabled','disabled');
- $('#pool-doAdd').hide();
- $('#pool-loading').show();
- kimchi.createStoragePool(formData, function() {
- kimchi.doListStoragePools();
- wok.window.close();
- }, function(err) {
- wok.message.error(err.responseJSON.reason);
- $('input',
'#form-pool-add').removeAttr('disabled');
- $('#pool-loading').hide();
- $('#pool-doAdd').show();
- });
- };
- if (poolType === 'logical') {
- var settings = {
- title : i18n['KCHAPI6001M'],
- content : i18n['KCHPOOL6003M'],
- confirm : i18n['KCHAPI6002M'],
- cancel : i18n['KCHAPI6003M']
- };
- wok.confirm(settings, function() {
- storagePoolAddingFunc();
- }, function() {
- });
- } else {
- storagePoolAddingFunc();
- }
- }
-};
diff --git a/plugins/kimchi/ui/js/src/kimchi.storagepool_add_volume_main.js
b/plugins/kimchi/ui/js/src/kimchi.storagepool_add_volume_main.js
deleted file mode 100644
index 8479ab2..0000000
--- a/plugins/kimchi/ui/js/src/kimchi.storagepool_add_volume_main.js
+++ /dev/null
@@ -1,179 +0,0 @@
-/*
- * Project Kimchi
- *
- * Copyright IBM, Corp. 2014-2015
- *
- * 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.
- */
-kimchi.sp_add_volume_main = function() {
- // download from remote server or upload from local file
- var type = 'download';
-
- var addButton = $('#sp-add-volume-button');
- var remoteURLBox = $('#volume-remote-url');
- var localFileBox = $('#volume-input-file');
- var typeRadios = $('input.volume-type');
-
- var isValidURL = function() {
- var url = $(remoteURLBox).val();
- return kimchi.template_check_url(url);
- };
-
- var isValidFile = function() {
- var fileName = $(localFileBox).val();
- return fileName.length > 0;
- };
-
- $(typeRadios).change(function(event) {
- $('.volume-input').prop('disabled', true);
- $('.volume-input.' + this.value).prop('disabled', false);
- type = this.value;
- if(type == 'download') {
- $(addButton).prop('disabled', !isValidURL());
- }
- else {
- $(addButton).prop('disabled', !isValidFile());
- }
- });
-
- $(remoteURLBox).on('input propertychange', function(event) {
- $(addButton).prop('disabled', !isValidURL());
- });
-
- $(localFileBox).on('change', function(event) {
- $(addButton).prop('disabled', !isValidFile());
- });
-
- var onError = function(result) {
- $(this).prop('disabled', false);
- $(typeRadios).prop('disabled', false);
- if(!result) {
- return;
- }
- var msg = result['message'] || (
- result['responseJSON'] &&
result['responseJSON']['reason']
- );
- wok.message.error(msg);
- };
-
- var fetchRemoteFile = function() {
- var volumeURL = remoteURLBox.val();
- var volumeName = volumeURL.split(/(\\|\/)/g).pop();
- kimchi.downloadVolumeToSP({
- sp: kimchi.selectedSP,
- url: volumeURL
- }, function(result) {
- wok.window.close();
- wok.topic('kimchi/storageVolumeAdded').publish();
- }, onError);
- };
-
- var uploadFile = function() {
- var chunkSize = 8 * 1024 * 1024; // 8MB
- var uploaded = 0;
-
- var blobFile = $(localFileBox)[0].files[0];
-
- var createUploadVol = function() {
- kimchi.createVolumeWithCapacity(kimchi.selectedSP, {
- name: blobFile.name,
- format: '',
- capacity: blobFile.size,
- upload: true
- }, function(result) {
- wok.window.close();
- trackVolCreation(result.id);
- }, onError);
- };
-
- var uploadRequest = function(blob) {
- var fd = new FormData();
- fd.append('chunk', blob);
- fd.append('chunk_size', blob.size);
-
- kimchi.uploadVolumeToSP(kimchi.selectedSP, blobFile.name, {
- formData: fd
- }, function(result) {
- if (uploaded < blobFile.size)
- setTimeout(doUpload, 500);
- }, onError);
-
- uploaded += blob.size
- };
-
- // Check file exists and has read permission
- try {
- var blob = blobFile.slice(0, 20);
- var reader = new FileReader();
- reader.onloadend = function(e) {
- if (e.loaded == 0)
- wok.message.error.code('KCHAPI6008E');
- else
- createUploadVol();
- };
-
- reader.readAsBinaryString(blob);
- } catch (err) {
- wok.message.error.code('KCHAPI6008E');
- return;
- }
-
- var doUpload = function() {
- try {
- var blob = blobFile.slice(uploaded, uploaded + chunkSize);
- var reader = new FileReader();
- reader.onloadend = function(e) {
- if (e.loaded == 0)
- wok.message.error.code('KCHAPI6009E');
- else
- uploadRequest(blob);
- };
-
- reader.readAsBinaryString(blob);
- } catch (err) {
- wok.message.error.code('KCHAPI6009E');
- return;
- }
- }
-
- var trackVolCreation = function(taskid) {
- var onTaskResponse = function(result) {
- var taskStatus = result['status'];
- var taskMsg = result['message'];
- if (taskStatus == 'running') {
- if (taskMsg != 'ready for upload') {
- setTimeout(function() {
- trackVolCreation(taskid);
- }, 2000);
- } else {
- wok.topic('kimchi/storageVolumeAdded').publish();
- doUpload();
- }
- }
- };
- kimchi.getTask(taskid, onTaskResponse, onError);
- };
- };
-
- $(addButton).on('click', function(event) {
- $(this).prop('disabled', true);
- $(typeRadios).prop('disabled', true);
- if(type === 'download') {
- fetchRemoteFile();
- }
- else {
- uploadFile();
- }
- event.preventDefault();
- });
-};
diff --git a/plugins/kimchi/ui/js/src/kimchi.template_add_main.js
b/plugins/kimchi/ui/js/src/kimchi.template_add_main.js
deleted file mode 100644
index 01a47c2..0000000
--- a/plugins/kimchi/ui/js/src/kimchi.template_add_main.js
+++ /dev/null
@@ -1,441 +0,0 @@
-/*
- * Project Kimchi
- *
- * Copyright IBM, Corp. 2013-2015
- *
- * 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.
- */
-kimchi.switchPage = function(fromPageId, toPageId, direction) {
- direction = direction || 'left';
- var toLeftBegin;
- var fromLeftEnd;
- if('left' === direction) {
- toLeftBegin = '100%';
- fromLeftEnd = '-100%';
- } else if('right' === direction) {
- toLeftBegin = '-100%';
- fromLeftEnd = '100%';
- }
- var formPage = $('#'+fromPageId);
- var toPage = $('#'+toPageId);
- toPage.css({
- left: toLeftBegin
- });
- formPage.animate({
- left: fromLeftEnd,
- opacity: 0.1
- }, 400);
- toPage.animate({
- left: '0',
- opacity: 1
- }, 400);
-};
-
-kimchi.template_add_main = function() {
- kimchi.deepScanHandler = null;
- // 1-1 local iso
- $('#iso-local').click(function() {
- kimchi.switchPage('iso-type-box', 'iso-local-box');
- initLocalIsoField();
- initIsoFileField();
- kimchi.listIsos(function(isos) {
- if (isos && isos.length) {
- showLocalIsoField(isos);
- $('#iso-more').show();
- } else {
- $('#iso-search').show();
- }
- }, function(err) {
- wok.message.error(err.responseJSON.reason);
- });
- });
-
- $('#iso-local-box-back').click(function() {
- if (kimchi.deepScanHandler) {
- kimchi.deepScanHandler.stop = true;
- }
- kimchi.switchPage('iso-local-box', 'iso-type-box',
'right');
- });
-
- $('#iso-search').click(function() {
- var settings = {
- content : i18n['KCHTMPL6002M']
- };
- wok.confirm(settings, function() {
- $('#iso-search').hide();
- $('#iso-search-loading').show();
- deepScan('#iso-search');
- });
- });
-
- $('#iso-more').click(function() {
- var settings = {
- content : i18n['KCHTMPL6002M']
- };
- wok.confirm(settings, function() {
- $('#iso-more').hide();
- $('#iso-more-loading').show();
- deepScan('#iso-more');
- });
- });
-
- $('#iso-search-loading').click(function() {
- $('#iso-search-loading').hide();
- $('#iso-search').show();
- if (kimchi.deepScanHandler) {
- kimchi.deepScanHandler.stop = true;
- }
- });
-
- $('#iso-more-loading').click(function() {
- $('#iso-more-loading').hide();
- $('#iso-more').show();
- if (kimchi.deepScanHandler) {
- kimchi.deepScanHandler.stop = true;
- }
- });
-
- var deepScan = function(button) {
- kimchi.deepScanHandler = kimchi.stepListDeepScanIsos(function(isos, isFinished)
{
- if (isos && isos.length) {
- if(button === '#iso-search') {
- $(button + '-loading').hide();
- button = '#iso-more';
- $(button + '-loading').show();
- }
- showLocalIsoField(isos);
- } else {
- if (isFinished) {
- wok.message.warn(i18n['KCHTMPL6001W']);
- }
- }
- if (isFinished) {
- $(button + '-loading').hide();
- $(button).show();
- }
- }, function(err) {
- wok.message.error(err.responseJSON.reason);
- $(button + '-loading').hide();
- $(button).show();
- });
- };
-
- //1-1-1 local iso list
- var initLocalIsoField = function() {
- kimchi.isoInfo = {};
- $('#local-iso-field').hide();
- $('#select-all-local-iso').prop('checked', false);
- $('#btn-template-local-iso-create').attr('disabled',
'disabled');
- $('#iso-search').hide();
- $('#iso-more').hide();
- $('#iso-search-loading').hide();
- $('#iso-more-loading').hide();
- $('#list-local-iso').empty();
- };
-
- var showLocalIsoField = function(isos) {
- var html = '';
- var template = $('#tmpl-list-local-iso').html();
- $.each(isos, function(index, volume) {
- var isoId = volume.os_distro + '*' + volume.name + '*' +
volume.os_version;
- if (!kimchi.isoInfo[isoId]) {
- volume.isoId = isoId;
- volume.capacity = wok.changetoProperUnit(volume.capacity, 1);
- kimchi.isoInfo[isoId] = volume;
- html += wok.substitute(template, volume);
- }
- });
- $('#list-local-iso').append(html);
- $('#local-iso-field').show();
- };
-
- $('#select-all-local-iso').click(function() {
- $('#list-local-iso [type="checkbox"]').prop('checked',
$(this).prop('checked'));
- if ($(this).prop('checked')) {
- $('#btn-template-local-iso-create').removeAttr('disabled');
- } else {
- $('#btn-template-local-iso-create').attr('disabled',
'disabled');
- }
- });
-
- $('#list-local-iso').on('click',
'[type="checkbox"]', function() {
- var checkedLength = $('#list-local-iso
[type="checkbox"]:checked').length;
- if (checkedLength) {
- $('#btn-template-local-iso-create').removeAttr('disabled');
- var length = $('#list-local-iso
[type="checkbox"]').length;
- $('#select-all-local-iso').prop('checked', length ==
checkedLength);
- } else {
- $('#select-all-local-iso').prop('checked', false);
- $('#btn-template-local-iso-create').attr('disabled',
'disabled');
- }
- });
-
- $('#btn-template-local-iso-create').click(function() {
- submitIso('form-local-iso');
- });
-
- //1-1-2 local iso file
- var initIsoFileField = function() {
- $('#iso-file-check').prop('checked', false);
- $('#iso-file-box').hide();
- $('#iso-file').val('');
- $('#btn-template-file-create').attr('disabled',
'disabled');
- };
-
- $('#iso-file-check').click(function() {
- if ($(this).prop('checked')) {
- $('#iso-file-box').slideDown();
- } else {
- $('#iso-file-box').slideUp();
- }
- });
-
- $('#iso-file').on('input propertychange', function() {
- if ($('#iso-file').val()) {
- $('#btn-template-file-create').removeAttr('disabled');
- } else {
- $('#btn-template-file-create').attr('disabled',
'disabled');
- }
- });
-
- $('#btn-template-file-create').click(function() {
- var isoFile = $('#iso-file').val();
- if (!kimchi.template_check_path(isoFile)) {
- wok.message.error.code('KCHAPI6003E');
- return;
- }
- var data = {
- "cdrom" : isoFile
- };
- addTemplate(data);
- });
-
- //1-2 remote iso
- $('#iso-remote').css('opacity', 0.3).css('cursor',
'not-allowed');
-
- var enabledRemoteIso = function() {
- if (kimchi.capabilities == undefined) {
- setTimeout(enabledRemoteIso, 2000);
- return;
- }
-
- if (kimchi.capabilities.qemu_stream != true) {
- return;
- }
-
- $('#iso-remote').css('opacity', 1).css('cursor',
'pointer');
- $('#iso-remote').click(function() {
- kimchi.switchPage('iso-type-box', 'iso-remote-box');
- initRemoteIsoField();
- initIsoUrlField();
- kimchi.listDistros(function(isos) {
- showRemoteIsoField(isos);
- }, function() {
- });
- });
- };
- enabledRemoteIso();
-
- $('#iso-remote-box-back').click(function() {
- kimchi.switchPage('iso-remote-box', 'iso-type-box',
'right');
- });
-
- //1-2-1 remote iso list
- var initRemoteIsoField = function() {
- $('#load-remote-iso').show();
- $('#remote-iso-field').hide();
- $('#iso-url-field').hide();
- $('#select-all-remote-iso').prop('checked', false);
- $('#btn-template-remote-iso-create').attr('disabled',
'disabled');
- };
-
- var showRemoteIsoField = function(isos) {
- if (isos && isos.length) {
- kimchi.isoInfo = {};
- var html = '';
- var template = $('#tmpl-list-remote-iso').html();
- $.each(isos, function(index, volume) {
- var isoId = volume.os_distro + '*' + volume.name + '*' +
volume.os_version;
- if (!kimchi.isoInfo[isoId]) {
- volume.isoId = isoId;
- kimchi.isoInfo[isoId] = volume;
- html += wok.substitute(template, volume);
- }
- });
- $('#list-remote-iso').html(html);
- $('#load-remote-iso').hide()
- $('#remote-iso-field').show();
- $('#iso-url-field').show();
- } else {
- $('#load-remote-iso').hide()
- $('#iso-url-field').show();
- wok.message.warn(i18n['KCHTMPL6001W']);
- }
- };
-
- $('#select-all-remote-iso').click(function() {
- $('#list-remote-iso [type="checkbox"]').prop('checked',
$(this).prop('checked'));
- if ($(this).prop('checked')) {
- $('#btn-template-remote-iso-create').removeAttr('disabled');
- } else {
- $('#btn-template-remote-iso-create').attr('disabled',
'disabled');
- }
- });
-
- $('#list-remote-iso').on('click',
'[type="checkbox"]', function() {
- var checkedLength = $('#list-remote-iso
[type="checkbox"]:checked').length;
- if (checkedLength) {
- $('#btn-template-remote-iso-create').removeAttr('disabled');
- var length = $('#list-remote-iso
[type="checkbox"]').length;
- $('#select-all-remote-iso').prop('checked', length ==
checkedLength);
- } else {
- $('#select-all-remote-iso').prop('checked', false);
- $('#btn-template-remote-iso-create').attr('disabled',
'disabled');
- }
- });
-
- $('#btn-template-remote-iso-create').click(function() {
- submitIso('form-remote-iso');
- });
-
- //1-2-2 remote iso url
- var initIsoUrlField = function() {
- $('#iso-url-check').prop('checked', false);
- $('#iso-url-box').hide();
- $('#iso-url').val('');
- $('#btn-template-url-create').attr('disabled',
'disabled');
- }
-
- $('#iso-url-check').click(function() {
- if ($(this).prop('checked')) {
- $('#iso-url-box').slideDown();
- } else {
- $('#iso-url-box').slideUp();
- }
- });
-
- $('#iso-url').on('input propertychange', function() {
- if ($('#iso-url').val()) {
- $('#btn-template-url-create').removeAttr('disabled');
- } else {
- $('#btn-template-url-create').attr('disabled',
'disabled');
- }
- });
-
- $('#vm-image-local').click(function(){
- kimchi.switchPage('iso-type-box', 'vm-image-local-box');
- });
- $('#vm-image-local-box-back').click(function(){
- kimchi.switchPage('vm-image-local-box', 'iso-type-box',
'right');
- });
- $('input', '#vm-image-local-box').on('keyup cut paste',
function(){
- setTimeout(function(){
- var isValid = kimchi.template_check_path($('input',
'#vm-image-local-box').val());
- $('input',
'#vm-image-local-box').toggleClass('invalid-field', !isValid);
- $('button', $('.body',
'#vm-image-local-box')).button(isValid ? "enable" :
"disable");
- }, 0);
- });
- $('button', $('.body', '#vm-image-local-box')).button({
- disabled: true
- }).click(function(){
- $('input', '#vm-image-local-box').prop('disabled',
true);
- $(this).button('option', {
- label: i18n['KCHAPI6008M'],
- disabled: true
- });
- addTemplate({disks:[{base:$('input',
'#vm-image-local-box').val()}]}, function(){
- $('input', '#vm-image-local-box').prop('disabled',
false);
- $('button', $('.body',
'#vm-image-local-box')).button('option', {
- label: i18n['KCHAPI6005M'],
- disabled: false
- });
- });
- });
-
- $('#btn-template-url-create').click(function() {
- var isoUrl = $('#iso-url').val();
- if (!kimchi.template_check_url(isoUrl)) {
- wok.message.error.code('KCHAPI6004E');
- return;
- }
- var data = {
- "cdrom" : isoUrl
- };
- addTemplate(data);
- });
-
- //do create
- var addTemplate = function(data, callback) {
- kimchi.createTemplate(data, function() {
- if(callback) callback();
- kimchi.doListTemplates();
- wok.window.close();
- wok.topic('templateCreated').publish();
- }, function(err) {
- if(callback) callback();
- wok.message.error(err.responseJSON.reason);
- });
- };
-
- var submitIso = function(formId) {
- var formData = $('#' + formId).serializeObject();
- if (formData.iso) {
- var length = 0;
- var successNum = 0;
- var addTemplate = function(isoInfo) {
- var data = {
- "os_distro" : isoInfo.os_distro,
- "os_version" : isoInfo.os_version,
- "cdrom" : isoInfo.path
- };
- kimchi.createTemplate(data, function() {
- successNum++;
- $('input[value="' + isoInfo.isoId +
'"]').prop('checked', false);
- $('.check-all>input').prop('checked', false);
- kimchi.doListTemplates();
- wok.topic('templateCreated').publish(data);
- if (successNum === length) {
- wok.window.close();
- }
- }, function(err) {
- wok.message.error(err.responseJSON.reason);
- });
- };
- if (formData.iso instanceof Array) {
- length = formData.iso.length;
- $.each(formData.iso, function(index, value) {
- addTemplate(kimchi.isoInfo[value]);
- });
- } else {
- length = 1;
- addTemplate(kimchi.isoInfo[formData.iso]);
- }
- }
- };
-};
-
-kimchi.template_check_url = function(url) {
- var reg = /(https|http|ftp|ftps|tftp):\/\//;
- if (url.constructor === String) {
- return reg.test(url);
- }
- return false;
-};
-
-kimchi.template_check_path = function(filePath) {
- var reg = /((\/([0-9a-zA-Z-_ \.]+))+)$/;
- if (filePath.constructor === String) {
- return reg.test(filePath);
- }
- return false;
-};
diff --git a/plugins/kimchi/ui/js/src/kimchi.template_edit_main.js
b/plugins/kimchi/ui/js/src/kimchi.template_edit_main.js
deleted file mode 100644
index d40b6c7..0000000
--- a/plugins/kimchi/ui/js/src/kimchi.template_edit_main.js
+++ /dev/null
@@ -1,343 +0,0 @@
-/*
- * Project Kimchi
- *
- * Copyright IBM, Corp. 2013-2015
- *
- * 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.
- */
-kimchi.template_edit_main = function() {
- var templateEditMain = $('#edit-template-tabs');
- var origDisks;
- var origPool;
- var origNetworks;
- var templateDiskSize;
- $('#template-name', templateEditMain).val(kimchi.selectedTemplate);
- templateEditMain.tabs();
-
- var initTemplate = function(template) {
- origDisks = template.disks;
- origPool = template.storagepool;
- origNetworks = template.networks;
- for(var i=0;i<template.disks.length;i++){
- if(template.disks[i].base){
- template["vm-image"] = template.disks[i].base;
- $('.templ-edit-cdrom').addClass('hide');
- $('.templ-edit-vm-image').removeClass('hide');
- break;
- }
- }
- for ( var prop in template) {
- var value = template[prop];
- if (prop == 'graphics') {
- value = value["type"];
- }
- $('input[name="' + prop + '"]',
templateEditMain).val(value);
- }
-
- var vncOpt = [{label: 'VNC', value: 'vnc'}];
- $('#template-edit-graphics').append('<option
selected>VNC</option>');
-
$('#template-edit-graphics').append('<option>Spice</option>');
- wok.select('template-edit-graphics-list', vncOpt);
- var enableSpice = function() {
- if (kimchi.capabilities == undefined) {
- setTimeout(enableSpice, 2000);
- return;
- }
- if (kimchi.capabilities.qemu_spice == true) {
- spiceOpt = [{label: 'Spice', value: 'spice'}]
- wok.select('template-edit-graphics-list', spiceOpt);
- }
- };
- enableSpice();
- var initStorage = function(result) {
- var scsipools = {};
- var addStorageItem = function(storageData) {
- var thisName = storageData.storageName;
- var nodeStorage =
$.parseHTML(wok.substitute($('#template-storage-pool-tmpl').html(),
storageData));
- $('.template-tab-body',
'#form-template-storage').append(nodeStorage);
- var storageOptions = '';
- var scsiOptions = '';
- $('#selectStorageName').find('option').remove();
- $.each(result, function(index, storageEntities) {
- if((storageEntities.state === 'active') &&
(storageEntities.type != 'kimchi-iso')) {
- if(storageEntities.type === 'iscsi' ||
storageEntities.type === 'scsi') {
- kimchi.listStorageVolumes(storageEntities.name,
function(currentVolume) {
- $.each(currentVolume, function(indexSCSI, scsiEntities)
{
- var tmpPath = storageEntities.name + '/' +
scsiEntities.name;
- var isSlected = tmpPath === thisName ? '
selected' : '';
- scsiOptions += '<option' + isSlected +
'>' + tmpPath + '</option>';
- });
- $('#selectStorageName').append(scsiOptions);
- }, function() {});
- } else {
- var isSlected = storageEntities.name === thisName ? '
selected' : '';
- storageOptions += '<option' + isSlected +
'>' + storageEntities.name + '</option>';
- }
- }
- });
- $('#selectStorageName').append(storageOptions);
-
- // Set disk format
- $('#diskFormat').val(storageData.storageDiskFormat);
- $('#diskFormat').on('change', function() {
- $('.template-storage-disk-format').val($(this).val());
- });
-
- $('#selectStorageName').change(function() {
- var selectedItem = $(this).parent().parent();
- var tempStorageNameFull = $(this).val();
- var tempName = tempStorageNameFull.split('/');
- var tempStorageName = tempName[0];
- $('.template-storage-name').val(tempStorageNameFull);
- kimchi.getStoragePool(tempStorageName, function(info) {
- tempType = info.type;
-
selectedItem.find('.template-storage-type').val(tempType);
- if (tempType === 'iscsi' || tempType === 'scsi')
{
- kimchi.getStoragePoolVolume(tempStorageName,
tempName[tempName.length-1], function(info) {
- volSize = info.capacity / Math.pow(1024, 3);
- $('.template-storage-disk',
selectedItem).attr('readonly', true).val(volSize);
- $('#diskFormat').val('raw');
- $('#diskFormat').prop('disabled',
true).change();
- });
- } else if (tempType === 'logical') {
- $('.template-storage-disk',
selectedItem).attr('readonly', false);
- $('#diskFormat').val('raw');
- $('#diskFormat').prop('disabled',
true).change();
- } else {
- $('.template-storage-disk',
selectedItem).attr('readonly', false);
- if ($('#diskFormat').prop('disabled') ==
true) {
- $('#diskFormat').val('qcow2');
- $('#diskFormat').prop('disabled',
false).change();
- }
- }
- });
- });
- };
-
- if ((origDisks && origDisks.length) && (origPool &&
origPool.length)) {
- splitPool = origPool.split('/');
- var defaultPool = splitPool[splitPool.length-1];
- var defaultType;
-
- kimchi.getStoragePool(defaultPool, function(info) {
- defaultType = info.type;
- $.each(origDisks, function(index, diskEntities) {
- var storageNodeData = {
- viewMode : '',
- editMode : 'hide',
- storageName : defaultPool,
- storageType : defaultType,
- storageDisk : diskEntities.size,
- storageDiskFormat : diskEntities.format ? diskEntities.format
: 'qcow2'
- }
-
- if (diskEntities.volume) {
- kimchi.getStoragePoolVolume(defaultPool, diskEntities.volume,
function(info) {
- var volSize = info.capacity / Math.pow(1024, 3);
- var nodeData = storageNodeData
- nodeData.storageName = defaultPool + '/' +
diskEntities.volume;
- nodeData.storageDisk = volSize;
- addStorageItem(nodeData);
-
$('.template-storage-disk').attr('readonly', true);
- $('#diskFormat').val('raw');
- $('#diskFormat').prop('disabled',
true).change();
- });
- } else if (defaultType === 'logical') {
- addStorageItem(storageNodeData);
- $('#diskFormat').val('raw');
- $('#diskFormat').prop('disabled',
true).change();
- } else {
- addStorageItem(storageNodeData);
- }
- });
- });
- }
-
- $('#template-edit-storage-add-button').button({
- icons: {
- primary: "ui-icon-plusthick"
- },
- text: false,
- disabled: true
- }).click(function(event) {
- event.preventDefault();
- var storageNodeData = {
- viewMode : 'hide',
- editMode : '',
- storageName : 'null',
- storageType : 'dir',
- storageDisk : '10'
- }
- addStorageItem(storageNodeData);
- });
- };
- var initInterface = function(result) {
- var networkItemNum = 0;
- var addInterfaceItem = function(networkData) {
- var networkName = networkData.networkV;
- var nodeInterface =
$.parseHTML(wok.substitute($('#template-interface-tmpl').html(), networkData));
- $('.template-tab-body',
'#form-template-interface').append(nodeInterface);
- $('.delete', '#form-template-interface').button({
- icons : {primary : 'ui-icon-trash'},
- text : false
- }).click(function(evt) {
- evt.preventDefault();
- $(this).parent().parent().remove();
- });
- var networkOptions = '';
- for(var i=0;i<result.length;i++){
- if(result[i].state === "active") {
- var isSlected = networkName===result[i].name ? '
selected' : '';
- networkOptions += '<option' + isSlected +
'>' + result[i].name + '</option>';
- }
- }
- $('select', '#form-template-interface #networkID' +
networkItemNum).append(networkOptions);
- networkItemNum += 1;
- };
- if(result && result.length > 0) {
- for(var i=0;i<origNetworks.length;i++) {
- addInterfaceItem({
- networkID : 'networkID' + networkItemNum,
- networkV : origNetworks[i],
- type : 'network'
- });
- }
- }
- $('#template-edit-interface-add-button').button({
- icons: {
- primary: 'ui-icon-plusthick'
- },
- text: false
- }).click(function(evt) {
- evt.preventDefault();
- addInterfaceItem({
- networkID : 'networkID' + networkItemNum,
- networkV : 'default',
- type : 'network'
- });
- });
- };
- var initProcessor = function(){
- var setCPUValue = function(){
-
if(!$('#cores').hasClass("invalid-field")&&$('#cores').val()!=""){
-
$("#cpus").val(parseInt($("#cores").val())*parseInt($("#threads").val()));
- }else{
- $("#cpus").val('');
- }
- };
- $("input:text",
"#form-template-processor").on('keyup', function(){
- $(this).toggleClass("invalid-field",
!$(this).val().match('^[0-9]*$'));
- if($(this).prop('id')=='cores') setCPUValue();
- });
- $("input:checkbox",
"#form-template-processor").click(function(){
- $(".topology",
"#form-template-processor").toggleClass("hide",
!$(this).prop("checked"));
- $("#cpus").attr("disabled",
$(this).prop("checked"));
- setCPUValue();
- });
- $('select', '#form-template-processor').change(function(){
- setCPUValue();
- });
- kimchi.getCPUInfo(function(data){
- var options = "";
- for(var i=0;Math.pow(2,i)<=data.threads_per_core;i++){
- var lastOne = Math.pow(2,i+1)>data.threads_per_core?"
selected":"";
- options +=
"<option"+lastOne+">"+Math.pow(2,i)+"</option>";
- }
- $('select', '#form-template-processor').append(options);
- if(template.cpus) $("#cpus").val(template.cpus);
- var topo = template.cpu_info.topology;
- if(topo&&topo.cores) $("#cores").val(topo.cores);
- if(topo&&topo.threads){
- $('select',
'#form-template-processor').val(topo.threads);
- $("input:checkbox",
"#form-template-processor").trigger('click');
- }
- });
- };
- kimchi.listNetworks(initInterface);
- kimchi.listStoragePools(initStorage);
- initProcessor();
- };
- kimchi.retrieveTemplate(kimchi.selectedTemplate, initTemplate);
-
-
- $('#tmpl-edit-button-save').on('click', function() {
- var editableFields = [ 'name', 'memory', 'disks',
'graphics'];
- var data = {};
- //Fix me: Only support one storage pool now
- var storages = $('.template-tab-body .item',
'#form-template-storage');
- var tempName = $('.template-storage-name', storages).val();
- var tmpItem = $('#form-template-storage .item');
- tempName = tempName.split('/');
- var tempNameHead = tempName[0];
- var tempNameTail = tempNameHead;
- if($('.template-storage-type', tmpItem).val() === 'iscsi' ||
$('.template-storage-type', tmpItem).val() == 'scsi') {
- tempNameTail = tempName[tempName.length-1];
- }
- tempName = '/plugins/kimchi/storagepools/' + tempNameHead;
- data['storagepool'] = tempName;
- $.each(editableFields, function(i, field) {
- /* Support only 1 disk at this moment */
- if (field == 'disks') {
- if($('.template-storage-type', tmpItem).val() === 'iscsi'
|| $('.template-storage-type', tmpItem).val() == 'scsi') {
- origDisks[0]['size'] && delete
origDisks[0]['size'];
- origDisks[0]['volume'] = tempNameTail;
- } else {
- origDisks[0]['volume'] && delete
origDisks[0]['volume'];
- origDisks[0].size = Number($('.template-storage-disk',
tmpItem).val());
- }
- origDisks[0].format = $('.template-storage-disk-format',
tmpItem).val();
- data[field] = origDisks;
- }
- else if (field == 'graphics') {
- var type = $('#form-template-general [name="' + field +
'"]').val();
- data[field] = {'type': type};
- }
- else {
- data[field] = $('#form-template-general [name="' + field +
'"]').val();
- }
- });
- data['memory'] = Number(data['memory']);
- data['cpus'] = parseInt($('#cpus').val());
- if($("input:checkbox",
"#form-template-processor").prop("checked")){
- data['cpu_info'] = {
- topology: {
- sockets: 1,
- cores: parseInt($("#cores").val()),
- threads: parseInt($("#threads").val())
- }
- };
- }else{
- data['cpu_info'] = {};
- }
- var networks = $('.template-tab-body .item',
'#form-template-interface');
- var networkForUpdate = new Array();
- $.each(networks, function(index, networkEntities) {
- var thisValue = $('select', networkEntities).val();
- networkForUpdate.push(thisValue);
- });
- if (networkForUpdate instanceof Array) {
- data.networks = networkForUpdate;
- } else if (networkForUpdate != null) {
- data.networks = [networkForUpdate];
- } else {
- data.networks = [];
- }
-
- kimchi.updateTemplate($('#template-name').val(), data, function() {
- kimchi.doListTemplates();
- wok.window.close();
- }, function(err) {
- wok.message.error(err.responseJSON.reason);
- });
- });
-};
diff --git a/plugins/kimchi/ui/js/src/kimchi.template_main.js
b/plugins/kimchi/ui/js/src/kimchi.template_main.js
deleted file mode 100644
index b09fe12..0000000
--- a/plugins/kimchi/ui/js/src/kimchi.template_main.js
+++ /dev/null
@@ -1,111 +0,0 @@
-/*
- * Project Kimchi
- *
- * Copyright IBM, Corp. 2013-2014
- *
- * 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.
- */
-kimchi.doListTemplates = function() {
- kimchi.listTemplates(function(result) {
- if (result && result.length) {
- $('#noTemplates').hide();
- var listHtml = '';
- var templateHtml = $('#templateTmpl').html();
- $.each(result, function(index, value) {
- var isLocal;
- if(value.cdrom){
- isLocal = /^\//.test(value['cdrom']);
- }else{
- for(var i=0;i<value.disks.length;i++){
- if(value.disks[i].base){
- isLocal = /^\//.test(value.disks[i].base);
- break;
- }
- }
- }
- if(isLocal){
- value.location =
"plugins/kimchi/images/theme-default/icon-local.png";
- }else{
- value.location =
"plugins/kimchi/images/theme-default/icon-remote.png";
- }
- listHtml += wok.substitute(templateHtml, value);
- });
- $('#templateList').html(listHtml);
- kimchi.templateBindClick();
- } else {
- $('#templateList').html('');
- $('#noTemplates').show();
- }
- $('html').removeClass('processing');
- }, function(err) {
- wok.message.error(err.responseJSON.reason);
- $('html').removeClass('processing');
- });
-};
-
-kimchi.templateBindClick = function() {
- $('.template-edit').on('click', function(event) {
- var templateName = $(this).data('template');
- kimchi.selectedTemplate = templateName;
- wok.window.open("plugins/kimchi/template-edit.html");
- });
- $('.template-clone').on('click', function(event) {
- kimchi.selectedTemplate = $(this).data('template');
- $('html').addClass('processing');
- kimchi.cloneTemplate(kimchi.selectedTemplate, function() {
- kimchi.doListTemplates();
- }, function(err) {
- wok.message.error(err.responseJSON.reason);
- kimchi.doListTemplates();
- });
- });
- $('.template-delete').on('click', function(event) {
- var $template = $(this);
- var settings = {
- title : i18n['KCHAPI6001M'],
- content : i18n['KCHTMPL6003M'],
- confirm : i18n['KCHAPI6002M'],
- cancel : i18n['KCHAPI6003M']
- };
- wok.confirm(settings, function() {
- var templateName = $template.data('template');
- kimchi.deleteTemplate(templateName, function() {
- kimchi.doListTemplates();
- }, function(err) {
- wok.message.error(err.responseJSON.reason);
- });
- }, function() {
- });
- });
-}
-kimchi.hideTitle = function() {
- $('#tempTitle').hide();
-};
-
-kimchi.template_main = function() {
- if(wok.tabMode['templates'] === 'admin') {
- $('.tools').attr('style','display');
- $("#template-add").on("click", function(event) {
- wok.window.open({
- url: 'plugins/kimchi/template-add.html',
- close: function() {
- if (kimchi.deepScanHandler) {
- kimchi.deepScanHandler.stop = true;
- }
- }
- });
- });
- }
-
- kimchi.doListTemplates();
-};
diff --git a/plugins/kimchi/ui/pages/Makefile.am b/plugins/kimchi/ui/pages/Makefile.am
deleted file mode 100644
index 56288e3..0000000
--- a/plugins/kimchi/ui/pages/Makefile.am
+++ /dev/null
@@ -1,22 +0,0 @@
-#
-# Kimchi
-#
-# Copyright IBM, Corp. 2013
-#
-# 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.
-
-SUBDIRS = help
-
-htmldir = $(datadir)/wok/plugins/kimchi/ui/pages
-
-dist_html_DATA = $(wildcard *.tmpl) $(NULL)
diff --git a/plugins/kimchi/ui/pages/guest-add.html.tmpl
b/plugins/kimchi/ui/pages/guest-add.html.tmpl
deleted file mode 100644
index 3770d96..0000000
--- a/plugins/kimchi/ui/pages/guest-add.html.tmpl
+++ /dev/null
@@ -1,98 +0,0 @@
-#*
- * Project Kimchi
- *
- * Copyright IBM, Corp. 2013-2015
- *
- * 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.
- *#
-#unicode UTF-8
-#import gettext
-#from wok.cachebust import href
-#silent t = gettext.translation($lang.domain, $lang.localedir, languages=$lang.lang,
fallback=True)
-#silent _ = t.gettext
-#silent _t = t.gettext
-<!DOCTYPE html>
-<html>
-<body>
-<div class="window" style="width: 900px;height: 580px;">
- <header>
- <h1 class="title h1 grey">$_("Create a New Virtual
Machine")</h1>
- </header>
- <div class="content">
- <form id="form-vm-add">
- <section class="form-section">
- <h2>1. $_("Virtual Machine Name")</h2>
- <div class="field">
- <input type="text" class="text" style="width:
300px" name="name"><br>
- <div class="icon-info-circled light-grey c1
help-inline"></div>
- <p class="text-help help-inline">
- $_("The name used to identify the virtual machine. If omitted, a
name will be chosen based on the template used.")
- </p>
- </div>
- </section>
- <section class="form-section">
- <h2>2. $_("Template")</h2>
- <div class="field">
- <div class="text-help">
- <div id="prompt-create-template"
class="hidden">
- <div class="icon-info-circled light-grey c1
help-inline"></div>
- <div class="text-help
help-inline">$_("Please create a template first.")</div>
- <a id="btn-create-template"
class="btn-normal" href="templates.html">
- <span class="text">$_("Create a
Template")</span>
- </a>
- </div>
- <div id="prompt-choose-template"
class="hidden">
- <span class="icon-info-circled light-grey
c1"></span>
- <span class="text-help">$_("Please choose a
template.")</span>
- </div>
- </div>
- <ul id="templateTile" class="tile-check
tile-template">
- </ul>
- <script type="html/text" id="tmpl-template"
class="tmpl-html">
- <li>
- <label>
- <input type="radio" name="template"
value="/plugins/kimchi/templates/{name}">
- <div class="info">
- <div class="summary os-icon">
- <img src="{icon}">
- <span
class="title">{name}</span>
- </div>
- <ul class="list-info">
-
<li><label>$_("OS")</label><span>{os_distro}</span></li>
- <li><label>$_("OS
Version")</label><span>{os_version}</span></li>
-
<li><label>$_("CPUS")</label><span>{cpus}</span></li>
-
<li><label>$_("Memory")</label><span>{memory}M</span></li>
- </ul>
- </div>
- </label>
- </li>
- </script>
- </div>
- </section>
- </form>
- </div>
- <footer>
- <div class="btn-group">
- <button id="vm-doAdd" class="btn-normal"
disabled="disabled" href="javascript:void(0);"><span
class="text">$_("Create")</span></button>
- <button id="vm-doAdding" class="btn-normal"
disabled="disabled" style="display:none"
href="javascript:void(0);"><span
class="text">$_("Creating...")</span></button>
- <button id="vm-add=cancel" class="btn-normal close"
type="button">
- <span class="text">$_("Cancel")</span>
- </button>
- </div>
- </footer>
-</div>
-<script>
- kimchi.guest_add_main();
-</script>
-</body>
-</html>
diff --git a/plugins/kimchi/ui/pages/guest-edit.html.tmpl
b/plugins/kimchi/ui/pages/guest-edit.html.tmpl
deleted file mode 100644
index c5acf04..0000000
--- a/plugins/kimchi/ui/pages/guest-edit.html.tmpl
+++ /dev/null
@@ -1,311 +0,0 @@
-#*
- * Project Kimchi
- *
- * Copyright IBM, Corp. 2013-2015
- *
- * 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.
- *#
-#unicode UTF-8
-#import gettext
-#silent t = gettext.translation($lang.domain, $lang.localedir, languages=$lang.lang,
fallback=True)
-#silent _ = t.gettext
-#silent _t = t.gettext
-
-<div id="guest-edit-window" class="window">
- <header>
- <h1 class="title h1 grey">$_("Edit Guest")</h1>
- </header>
- <div class="content">
- <div id="guest-edit-tabs">
- <ul>
- <li>
- <a
href="#form-guest-edit-general">$_("General")</a>
- </li>
- <li>
- <a
href="#form-guest-edit-storage">$_("Storage")</a>
- </li>
- <li>
- <a
href="#form-guest-edit-interface">$_("Interface")</a>
- </li>
- <li>
- <a
href="#form-guest-edit-permission">$_("Permission")</a>
- </li>
- <li>
- <a href="#form-guest-edit-pci">$_("Host PCI
Device")</a>
- </li>
- <li>
- <a
href="#form-guest-edit-snapshot">$_("Snapshot")</a>
- </li>
- </ul>
- <form id="form-guest-edit-general">
- <fieldset class="guest-edit-fieldset">
- <div class="edit-general-inline">
- <div class="guest-edit-wrapper-label">
- <label for="guest-edit-id-textbox">
- $_("Name")
- </label>
- </div>
- <div class="guest-edit-wrapper-label">
- <label for="guest-edit-cores-textbox">
- $_("CPUs")
- </label>
- </div>
- <div class="guest-edit-wrapper-label">
- <label for="guest-edit-memory-textbox">
- $_("Memory (MB)")
- </label>
- </div>
- <div class="guest-edit-wrapper-label">
- <label for="guest-edit-icon-textbox">
- $_("Icon")
- </label>
- </div>
- </div>
- <div class="edit-general-inline">
- <div class="guest-edit-wrapper-controls">
- <input id="guest-edit-id-textbox"
- name="name" type="text" />
- </div>
- <div class="guest-edit-wrapper-controls">
- <input
- id="guest-edit-cores-textbox"
- name="cpus"
- type="text" />
- </div>
- <div class="guest-edit-wrapper-controls">
- <input id="guest-edit-memory-textbox"
- name="memory"
- type="text" />
- </div>
- <div class="guest-edit-wrapper-controls">
- <input
- id="guest-edit-icon-textbox"
- name="icon"
- type="text"
- disabled="disabled" />
- </div>
- </div>
- </fieldset>
- </form>
- <form id="form-guest-edit-storage">
- <div class="header">
- <span
class="cell">$_("Device")</span>
- <span class="cell">$_("Path")</span>
- <button type="button"
id="guest-edit-attach-cdrom-button" class="action-area
attach"></button>
- </div>
- <div class="body"></div>
- </form>
- <form id="form-guest-edit-interface"
class="guest-edit-interface">
- <div class="header">
- <span
class="cell">$_("Network")</span>
- <span class="cell">$_("Type")</span>
- <span class="cell">$_("MAC
Address")</span>
- <button class="add action-area"></button>
- </div>
- <div class="body"></div>
- </form>
- <form id="form-guest-edit-permission"
class="guest-edit-permission">
- <div class="pam">
- <div class="column avail">
- <div class="title">$_("Available system
users and groups")</div>
- <input type="text"
id="permission-avail-searchBox">
- <div class="body">
- <div class="head">
- <div class="column column-user"><div
class="item">Users</div></div>
- <div class="column column-group"><div
class="item">Groups</div></div>
- </div>
- <div id="permission-avail-users"
class="column column-user"></div>
- <div id="permission-avail-groups"
class="column column-group"></div>
- </div>
- </div>
- <div class="column control">
- <button id="permissionGo"> > </button>
- <button id="permissionBack"> <
</button>
- </div>
- <div class="column selected">
- <div class="title">$_("Selected system users
and groups")</div>
- <input type="text"
id="permission-sel-searchBox">
- <div class="body">
- <div class="head">
- <div class="column column-user"><div
class="item">Users</div></div>
- <div class="column column-group"><div
class="item">Groups</div></div>
- </div>
- <div id="permission-sel-users"
class="column column-user"></div>
- <div id="permission-sel-groups"
class="column column-group"></div>
- </div>
- </div>
- </div>
- <div class="ldap">
- <div class="header">
- <span
class="cell">$_("User")</span>
- <button type="button"
id="guest-edit-add-user-button" class="action-area
add"></button>
- </div>
- <div class="body"></div>
- </div>
- </form>
- <form id="form-guest-edit-pci"
class="guest-edit-pci">
- <div class="guest-scroll-indent">
- <div class="filter">
- <span class="group">
- <select class="control">
- <option
value="all">$_("All")</option>
- <option value="toAdd">$_("To
Add")</option>
- <option
value="added">$_("Added")</option>
- </select><input type="text"
class="control" placeholder="$_("filter")">
- </span>
- </div>
- <div class="header">
- <span class="cell
name">$_("Name")</span>
- <span class="cell
product">$_("Product")</span>
- <span class="cell
vendor">$_("Vendor")</span>
- </div>
- <div class="body"></div>
- </div>
- </form>
- <form id="form-guest-edit-snapshot"
class="guest-edit-snapshot">
- <div class="header">
- <span class="cell sel"></span>
- <span class="cell
name">$_("Name")</span>
- <span class="cell
created">$_("Created")</span>
- <button class="add action-area"></button>
- </div>
- <div class="task"></div>
- <div class="body"></div>
- </form>
- </div>
- </div>
- <footer>
- <div id="action-button-container" class="btn-group
hidden">
- <button id="guest-edit-button-save"
class="btn-normal">
- <span class="text">$_("Save")</span>
- </button>
- </div>
- <button id="guest-edit-button-cancel" class="btn-normal
close">
- <span class="text">$_("Cancel")</span>
- </button>
- </footer>
-</div>
-<script id="cdrom-row-tmpl" type="text/html">
- <div class="item view" id="cdrom-{dev}">
- <span class="cell dev">
- <input type="text" readonly="readonly"
- id="cdrom-dev-{dev}" name="cdrom-dev-{dev}"
value="{dev}" />
- </span>
- <span class="cell path">
- <input id="cdrom-path-{dev}" name="cdrom"
type="text"
- data-vm="{vm}" data-dev="{dev}"
- value="{path}" readonly="readonly" />
- </span>
- <span class="action-area">
- <button type="button" class="guest-edit-cdrom-button
replace"
- data-vm="{vm}" data-dev="{dev}"
- title='$_("Replace")'>
- </button>
- <button type="button" class="guest-edit-cdrom-button
detach"
- data-vm="{vm}" data-dev="{dev}"
data-type="{type}"
- title='$_("Detach")'>
- </button>
- <button type="button" class="guest-edit-cdrom-button save
hidden"
- data-vm="{vm}" data-dev="{dev}"
- title='$_("Save")'>
- </button>
- <button type="button" class="guest-edit-cdrom-button cancel
hidden"
- data-vm="{vm}" data-dev="{dev}"
- title='$_("Cancel")'>
- </button>
- </span>
- </div>
-</script>
-<script id="interface-tmpl" type="text/html">
- <div class="item" id="{mac}">
- <span class="cell">
- <label id="label-network-{id}"
class="{viewMode}">{network}</label>
- <select class="{editMode}"></select>
- </span>
- <span class="cell">
- <span>{type}</span>
- </span>
- <span class="cell">
- <label id="label-mac-{id}"
class="{viewMode}">{mac}</label>
- <input class="{editMode}" type="text"
- id="edit-mac-{id}" name="{mac}"
value="{mac}" />
- </span>
- <span class="action-area {editMode}">
- <button class="save"></button><button
class="cancel"></button>
- </span>
- <span class="action-area {viewMode}">
- <button class="edit"></button><button
class="delete"></button>
- </span>
- <div>
-</script>
-<script id="ldap-user-tmpl" type="text/html">
- <div class="item" id="{user}">
- <span class="cell">
- <label class="{viewMode}">{user}</label>
- <input type="text" placeholder="LDAP User
ID,e.g.foo(a)foo.com" class="{editMode}"/>
- </span>
- <span class="action-area">
- <button class="delete"></button>
- </span>
- <div>
-</script>
-<script id="disk-row-tmpl" type="text/html">
- <div class="item" id="cdrom-{dev}">
- <span class="cell dev">
- <input type="text" readonly="readonly"
- id="disk-dev-{dev}" name="disk-dev-{dev}"
value="{dev}" />
- </span>
- <span class="cell path">
- <input id="disk-path-{dev}" name="path-{dev}"
type="text"
- data-vm="{vm}" data-dev="{dev}"
- value="{path}" readonly="readonly" />
- </span>
- <span class="action-area">
- <button type="button" class="guest-edit-cdrom-button
detach"
- data-vm="{vm}" data-dev="{dev}"
data-type="{type}"
- title="$_("Detach")">
- </button>
- </span>
- </div>
-</script>
-<script id="permission-item-pam" type="text/html">
-<div class="item">
- <span class="icon {class}"></span>
- <label>{val}</label>
-</div>
-</script>
-<script id="pci-tmpl" type="text/html">
-<div class="item" id="{name}">
- <span class="cell name" title="{name}">{name}</span>
- <span class="cell product"
title="{product}">{product}</span>
- <span class="cell vendor"
title="{vendor}">{vendor}</span>
- <button></button>
-</div>
-</script>
-<script id="snapshot-tmpl" type="text/html">
- <div class="item" id="{name}">
- <span class="cell sel">
- <span class="icon {createMode}"></span>
- <span class="ui-icon ui-icon-check hide"></span>
- </span>
- <span class="cell name">{name}</span>
- <span class="cell created">{created}</span>
- <span class="action-area">
- <button class="revert {listMode}"
title="$_("revert")"></button>
- <button class="delete {listMode}"></button>
- </span>
- <div>
-</script>
-<script type="text/javascript">
- kimchi.guest_edit_main();
-</script>
diff --git a/plugins/kimchi/ui/pages/guest-storage-add.html.tmpl
b/plugins/kimchi/ui/pages/guest-storage-add.html.tmpl
deleted file mode 100644
index a26e0f9..0000000
--- a/plugins/kimchi/ui/pages/guest-storage-add.html.tmpl
+++ /dev/null
@@ -1,103 +0,0 @@
-#*
- * Project Kimchi
- *
- * Copyright IBM, Corp. 2014
- *
- * 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.
- *#
-#unicode UTF-8
-#import gettext
-#from wok.cachebust import href
-#silent t = gettext.translation($lang.domain, $lang.localedir, languages=$lang.lang,
fallback=True)
-#silent _ = t.gettext
-#silent _t = t.gettext
-<div id="guest-storage-add-window" class="window">
- <header>
- <h1 class="title">$_("Add a Storage Device to
VM")</h1>
- <div class="close">X</div>
- </header>
- <div class="content">
- <form id="form-guest-storage-add">
- <section class="form-section">
- <h2>1. $_("Device Type")</h2>
- <div class="field">
- <p class="text-help">
- $_("The device type. Currently, \"cdrom\" and
\"disk\" are supported.")
- </p>
- <div class="btn dropdown popable">
- <input id="guest-storage-type" name="type"
value="cdrom" type="hidden" />
- <span class="text"
id="guest-storage-type-label"></span>
- <span class="arrow"></span>
- <div class="popover">
- <ul class="select-list"
id="guest-storage-type-list" data-target="guest-storage-type"
data-label="guest-storage-type-label"></ul>
- </div>
- </div>
- </div>
- </section>
- <div class="volume-section hidden">
- <section class="form-section">
- <h2>2. $_("Storage Pool")</h2>
- <div class="field storage-field">
- <p class="text-help">
- $_("Storage pool which volume located in")
- </p>
- <div class="btn dropdown popable">
- <input value="default"
id="guest-disk-pool" name="pool" type="hidden"/>
- <span class="text"
id="guest-disk-pool-label">default</span><span
class="arrow"></span>
- <div class="popover" style="width:
100%">
- <ul class="select-list"
id="guest-add-storage-pool-list" data-target="guest-disk-pool"
data-label="guest-disk-pool-label"></ul>
- </div>
- </div>
- </div>
- </section>
- <section class="form-section">
- <h2>3. $_("Storage Volume")</h2>
- <div class="field storage-field">
- <p class="text-help">
- $_("Storage volume to be attached")
- </p>
- <div class="btn dropdown popable"
id="guest-disk">
- <input id="guest-disk-vol" name="vol"
type="hidden">
- <span class="text"
id="guest-disk-vol-label"></span><span
class="arrow"></span>
- <div class="popover" style="width:
100%">
- <ul class="select-list"
id="guest-add-storage-pool-list" data-target="guest-disk-vol"
data-label="guest-disk-vol-label"></ul>
- </div>
- </div>
- </div>
- </section>
- </div>
- <div class="path-section">
- <section class="form-section">
- <h2>2. $_("File Path")</h2>
- <div class="field">
- <p class="text-help">
- $_("The ISO file path in the server for CDROM.")
- </p>
- <input type="text" class="text"
name="path" />
- </div>
- </section>
- </div>
- </fieldset>
- </form>
- </div>
- <footer>
- <div class="btn-group">
- <button id="guest-storage-button-add"
class="btn-normal" disabled="disabled">
- <span class="text">$_("Attach")</span>
- </button>
- </div>
- </footer>
-</div>
-<script type="text/javascript">
- kimchi.guest_storage_add_main();
-</script>
diff --git a/plugins/kimchi/ui/pages/guest.html.tmpl
b/plugins/kimchi/ui/pages/guest.html.tmpl
deleted file mode 100644
index 78e9161..0000000
--- a/plugins/kimchi/ui/pages/guest.html.tmpl
+++ /dev/null
@@ -1,77 +0,0 @@
-#*
- * Project Kimchi
- *
- * Copyright IBM, Corp. 2013-2015
- *
- * 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.
- *#
-#unicode UTF-8
-#import gettext
-#from wok.cachebust import href
-#silent t = gettext.translation($lang.domain, $lang.localedir, languages=$lang.lang,
fallback=True)
-#silent _ = t.gettext
-#silent _t = t.gettext
- <li name="guest" class="guest">
- <div class="sortable guest-type">
- <div class="guest-general">
- <h2 class="title"
title="{name}">{name}</h2>
- </div>
- <div class="guest-pending hide-content">
- <span class="icon"></span><span
class="text"></span>
- </div>
- </div>
- <div name="cpu_utilization" class="sortable">
- <div class="circleGauge"></div>
- </div>
- <div name="io_throughput" class="sortable">
- <div class="circleGauge"></div>
- <div class="subtitle">KB/s</div>
- </div>
- <div name="net_throughput" class="sortable">
- <div class="circleGauge"></div>
- <div class="subtitle">KB/s</div>
- </div>
- <div name="guest-tile" class="sortable
guest-tile">
- <div class="tile ">
- <img class="imgactive" alt=""
src="">
- <img class="imgload" alt=""
src="">
- <img class="overlay shutoff-hidden"
alt="$_("Start")"
src="plugins/kimchi/images/theme-default/icon-power-down.png" >
- </div>
- </div>
- <div class="sortable guest-actions"
name="guest-actions">
- <div class="top">
- <button class="btn reset-disabled"
name="vm-reset" href="javascript:void(0);"
title="$_("Reset")"><span class="icon
reset"></span></button>
- <button class="btn pause-disabled" name="vm-pause"
href="javascript:void(0);" title="$_("Pause")"><span
class="icon pause"></span></button>
- <button class="btn resume-hidden" name="vm-resume"
href="javascript:void(0);" title="$_("Resume")"><span
class="icon resume"></span></button>
- <button class="btn running-hidden"
name="vm-start" href="javascript:void(0);"
title="$_("Start")"><span class="icon
power-down"></span></button>
- <button class="btn shutoff-hidden"
name="vm-poweroff" href="javascript:void(0);"
title="$_("Power Off")"><span class="icon
power-up"></span></button>
- </div>
- <div class="bottom">
- <div name="actionmenu" class="btn dropdown popable
vm-action" style="width: 126px">
- <span
class="text">$_("Actions")</span><span
class="arrow"></span>
- <div class="popover actionsheet right-side"
style="width: 250px">
- <button class="button-big shutoff-disabled"
name="vm-console" ><span
class="text">$_("Connect")</span></button>
- <button class="button-big running-disabled"
name="vm-clone"><span
class="text">$_("Clone")</span></button>
- <button class="button-big"
name="vm-edit"><span
class="text">$_("Edit")</span></button>
- <button class="button-big shutoff-hidden
non-persistent-disabled" name="vm-reset"><span
class="text">$_("Reset")</span></button>
- <button class="button-big pause-hidden non-persistent-disabled"
name="vm-pause"><span
class="text">$_("Pause")</span></button>
- <button class="button-big resume-hidden"
name="vm-resume"><span
class="text">$_("Resume")</span></button>
- <button class="button-big shutoff-hidden"
name="vm-shutdown"><span class="text">$_("Shut
Down")</span></button>
- <button class="button-big running-hidden"
name="vm-start"><span
class="text">$_("Start")</span></button>
- <button class="button-big shutoff-hidden"
name="vm-poweroff"><span class="text">$_("Power
Off")</span></button>
- <button class="button-big red
non-persistent-disabled"
name="vm-delete">$_("Delete")</button>
- </div>
- </div>
- </div>
- </div>
- </li>
diff --git a/plugins/kimchi/ui/pages/guests.html.tmpl
b/plugins/kimchi/ui/pages/guests.html.tmpl
deleted file mode 100644
index b8a1259..0000000
--- a/plugins/kimchi/ui/pages/guests.html.tmpl
+++ /dev/null
@@ -1,65 +0,0 @@
-#*
- * Project Kimchi
- *
- * Copyright IBM, Corp. 2013-2014
- *
- * 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.
- *#
-
-#unicode UTF-8
-#import gettext
-#from Cheetah.Template import Template
-#from wok.cachebust import href
-#silent t = gettext.translation($lang.domain, $lang.localedir, languages=$lang.lang,
fallback=True)
-#silent _ = t.gettext
-#silent _t = t.gettext
-
-#silent ht = Template
-
-<!DOCTYPE html>
-<html>
-<head>
-<link rel="stylesheet"
href="plugins/kimchi/css/theme-default.min.css">
-<script src="plugins/kimchi/js/kimchi.min.js"></script>
-</head>
-<body>
-<div id="guests-root-container">
- <div class="toolbar">
- <div class="tools" style="display:none">
- <a id="vm-add" class="btn-tool"
href="javascript:void(0);"><span class="icon
add">+</span></a>
- </div>
- </div>
- <div id="guestListField" style="display: none">
- <ul class="list-title">
- <li class="guest-type">$_("Name")</li>
- <li class="guest-cpu">$_("CPU")</li>
- <li class="guest-storage">$_("Disk
I/O")</li>
- <li class="guest-network">$_("Network
I/O")</li>
- <li class="guest-tile">$_("Livetile")</li>
- <li class="guest-actions">$_("Actions")</li>
- </ul>
- <ul id="guestList" class="list-vm
empty-when-logged-off">
- </ul>
- </div>
- <div id="noGuests" class="list-no-result" style="display:
none;">
- $_("No guests found.")
- </div>
- <script id="guest-tmpl" type="kimchi/template">
- $ht(file=$data.ui_dir + "/pages/guest.html.tmpl", searchList=[self,
{'lang':$lang}])
- </script>
- <script type="text/javascript">
- kimchi.guest_main();
- </script>
-</div>
-</body>
-</html>
diff --git a/plugins/kimchi/ui/pages/help/Makefile.am
b/plugins/kimchi/ui/pages/help/Makefile.am
deleted file mode 100644
index a4ee361..0000000
--- a/plugins/kimchi/ui/pages/help/Makefile.am
+++ /dev/null
@@ -1,34 +0,0 @@
-# Copyright IBM Corp, 2014
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-
-SUBDIRS = zh_CN it_IT en_US zh_TW pt_BR ja_JP ru_RU ko_KR fr_FR de_DE es_ES
-
-DITA_HTML_FILES = $(patsubst %.dita,%.html,$(wildcard */*.dita))
-HTML_FILES = $(if $(DITA_HTML_FILES), $(DITA_HTML_FILES), $(wildcard */*.html))
-DITA_XSL_FILE = dita-help.xsl
-
-EXTRA_DIST = $(DITA_XSL_FILE)
-
-helpdir = $(datadir)/wok/plugins/kimchi/ui/pages/help
-
-dist_help_DATA = kimchi.css
-
-all: $(HTML_FILES) $(wildcard */*.dita)
-
-%.html: %.dita $(DITA_XSL_FILE)
- xsltproc -o $@ $(DITA_XSL_FILE) $<
-
-CLEANFILES = $(HTML_FILES)
diff --git a/plugins/kimchi/ui/pages/help/de_DE/Makefile.am
b/plugins/kimchi/ui/pages/help/de_DE/Makefile.am
deleted file mode 100644
index 3d99aae..0000000
--- a/plugins/kimchi/ui/pages/help/de_DE/Makefile.am
+++ /dev/null
@@ -1,23 +0,0 @@
-# Copyright IBM Corp, 2014
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-
-de_DE_helpdir = $(datadir)/wok/plugins/kimchi/ui/pages/help/de_DE
-
-dist_de_DE_help_DATA = $(wildcard *.html) $(NULL)
-
-EXTRA_DIST = $(wildcard *.dita)
-
-CLEANFILES = $(wildcard *.html)
diff --git a/plugins/kimchi/ui/pages/help/de_DE/guests.dita
b/plugins/kimchi/ui/pages/help/de_DE/guests.dita
deleted file mode 100644
index 1d64469..0000000
--- a/plugins/kimchi/ui/pages/help/de_DE/guests.dita
+++ /dev/null
@@ -1,127 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--Arbortext, Inc., 1988-2011, v.4002-->
-<!DOCTYPE cshelp PUBLIC "-//IBM//DTD DITA CSHelp//EN"
- "..\dtd\cshelp.dtd">
-
-
-<!--This DITA specialized document type is not supported by the Authoring Tools
development team.
-For support please see:
-https://w3.opensource.ibm.com/projects/dita-cshelp/-->
-<cshelp id="kimhvirtm" xml:lang="de-de">
-<title>G��ste</title>
-<shortdesc>Auf der Seite <wintitle>G��ste</wintitle> sind die
definierten virtuellen
-Maschinen von KVM aufgelistet.</shortdesc>
-<csbody>
-<p>F��r jeden Gast werden die folgenden Informationen
angezeigt:<dl><dlentry>
-<dt>Name</dt>
-<dd>Name der virtuellen Maschine.</dd>
-</dlentry><dlentry>
-<dt>CPU</dt>
-<dd>Prozentsatz der Prozessorauslastung in der virtuellen Maschine.</dd>
-</dlentry><dlentry>
-<dt>Netz-E/A</dt>
-<dd>Netz-E/A-��bertragungsrate in KB pro Sekunde.</dd>
-</dlentry><dlentry>
-<dt>Platten-E/A</dt>
-<dd>Platten-E/A-��bertragungsrate in KB pro Sekunde.</dd>
-</dlentry><dlentry>
-<dt>Live Tile</dt>
-<dd>Status der Konsole f��r das Gastbetriebssystem oder ein Symbol, das die
-<tm tmtype="tm" trademark="Linux">Linux</tm>-Verteilung
darstellt, wenn
-der Gast nicht aktiv ist.</dd>
-</dlentry></dl></p>
-<p>Die folgenden Aktionssymbole werden f��r jeden Gast angezeigt:<dl>
-<dlentry>
-<dt>Zur��cksetzen</dt>
-<dd>Klicken Sie hier, um den Gast zur��ckzusetzen. </dd>
-</dlentry><dlentry>
-<dt>Power (Starten oder Stoppen)</dt>
-<dd>Klicken Sie hier, um den Gast ein- bzw. auszuschalten. Wenn das Symbol rot
ist,
-ist er ausgeschaltet. Wenn das Symbol gr��n ist, ist er eingeschaltet.</dd>
-</dlentry></dl> </p>
-<p>Die folgenden Aktionen k��nnen f��r jeden Gast ausgew��hlt werden:<ul>
-<li>W��hlen Sie <uicontrol>Verbinden</uicontrol> aus, um eine
Verbindung zur fernen Konsole
-f��r das Gastbetriebssystem herzustellen.</li>
-<li>W��hlen Sie <uicontrol>Medien verwalten</uicontrol> aus, um den
Pfad zu den
-Installationsmedien zu ��ndern.</li>
-<li>W��hlen Sie <uicontrol>Zur��cksetzen</uicontrol> aus, um den Gast
zur��ckzusetzen.</li>
-<li>W��hlen Sie <uicontrol>Bearbeiten</uicontrol> aus, um die
Eigenschaften eines
-bestehenden Gastes zu bearbeiten. G��ste k��nnen nur bearbeitet werden, wenn sie gestoppt
sind.</li>
-<li>W��hlen Sie <uicontrol>L��schen</uicontrol> aus, um den Gast zu
l��schen.</li>
-</ul>Um einen Gast bzw. eine virtuelle Maschine zu erstellen, klicken Sie auf das
<uicontrol>Plus (+)</uicontrol>-Symbol oben rechts auf der Seite.</p>
-</csbody>
-<cshelp id="kimhvirtmcrt" xml:lang="de-de">
-<title>Virtuelle Maschine erstellen</title>
-<shortdesc>Erstellen Sie eine virtuelle Maschine mithilfe einer bestehenden
Vorlage.</shortdesc>
-<csbody>
-<p> <ol>
-<li>Geben Sie den Namen ein, mit dem die virtuelle Maschine gekennzeichnet
wird.</li>
-<li rev="rev1">W��hlen Sie eine Vorlage aus. <ul>
-<li>Wenn Vorlagen vorhanden sind, w��hlen Sie eine aus den angezeigten Vorlagen
aus.</li>
-<li>Wenn keine Vorlagen vorhanden sind, klicken Sie auf <uicontrol>Vorlage
erstellen</uicontrol>, um eine Vorlage zu erstellen.</li>
-</ul></li>
-<li>Klicken Sie auf <uicontrol>Erstellen</uicontrol>.</li>
-</ol> </p>
-</csbody>
-</cshelp>
-<cshelp id="kimhvirtmedit" xml:lang="de-de">
-<title>Gast bearbeiten</title>
-<shortdesc>Bearbeiten Sie die Eigenschaften einer bestehenden virtuellen Maschine.
Einige Eigenschaften k��nnen nur bearbeitet werden, solange der Gast gestoppt ist. Andere
Eigenschaften treten beim n��chsten Booten in Kraft. </shortdesc>
-<csprolog><csmetadata></csmetadata></csprolog>
-<csbody>
-<p>F��r jeden Gast werden die folgenden Informationen auf der Registerkarte
<wintitle>Allgemein</wintitle> angezeigt:<dl>
-<dlentry>
-<dt>Name</dt>
-<dd>Name der virtuellen Maschine. (Kann nur bearbeitet werden, solange der Gast
gestoppt ist.)</dd>
-</dlentry><dlentry>
-<dt>CPUs</dt>
-<dd>Anzahl der Prozessoren. (Wenn der Gast aktiv ist, tritt die neue Menge beim
n��chsten Booten in Kraft.)
-</dd>
-</dlentry><dlentry>
-<dt>Speicher</dt>
-<dd>Speicherkapazit��t in MB. (Wenn der Gast aktiv ist, tritt die neue Menge beim
n��chsten Booten in Kraft.)
-</dd>
-</dlentry><dlentry>
-<dt>Symbol</dt>
-<dd>Grafikbild, das die Linux-Verteilung darstellt und anstelle des aktuellen
Status (Live Tile) angezeigt werden soll, wenn der Gast nicht aktiv ist.</dd>
-</dlentry></dl></p>
-<p>Die folgenden Informationen werden auf der Registerkarte
<wintitle>Speicher</wintitle> angezeigt.</p>
-<dl><dlentry>
-<dt>Speicher</dt>
-<dd>Zeigt die Position der ISO-Datei an, die f��r die Installation verwendet
wird.</dd>
-</dlentry></dl>
-<p> Felder, die nicht inaktiviert sind, k��nnen bearbeitet werden. Nachdem Sie ein
Feld bearbeitet haben, klicken Sie auf <uicontrol>Speichern</uicontrol>.
</p>
-</csbody>
-</cshelp>
-<cshelp id="kimstoragedevice" xml:lang="de-de">
-<title>Speichereinheit hinzuf��gen, ersetzen oder abh��ngen</title>
-<shortdesc rev="rev1">Sie k��nnen eine Speichereinheit zu Ihrer
virtuellen Maschine hinzuf��gen oder diese ersetzen oder abh��ngen. Die einzige
unterst��tzte Einheit ist CD-ROM. F��hren Sie die folgenden Schritte aus, um Ihre
Speichereinheiten zu bearbeiten:</shortdesc>
-<csbody>
-<ol>
-<li>W��hlen Sie im Fenster <wintitle>Gast bearbeiten</wintitle> die
Option <wintitle>Speicher</wintitle> aus.</li>
-<li>Um eine Speichereinheit zu ersetzen, klicken Sie auf das erste Symbol mit dem
<uicontrol>orangefarbenen Schr��gstrich (/)</uicontrol>. Geben Sie den
ISO-Dateipfad ein und klicken Sie auf
<uicontrol>Ersetzen</uicontrol>.</li>
-<li>Um eine Speichereinheit abzuh��ngen, klicken Sie auf das zweite Symbol mit dem
<uicontrol>roten Gedankenstrich (-)</uicontrol>. Best��tigen Sie den
L��schvorgang und klicken Sie auf <uicontrol>OK</uicontrol>.</li>
-<li>Um eine Speichereinheit hinzuzuf��gen, klicken Sie auf das dritte Symbol mit
dem gr��nen <uicontrol>Pluszeichen (+)</uicontrol>. Geben Sie einen
Einheitennamen und einen ISO-Dateipfad ein und klicken Sie auf
<uicontrol>Anh��ngen</uicontrol>.</li>
-</ol>
-</csbody>
-</cshelp>
-<cshelp id="kimreplacemedia" xml:lang="de-de">
-<title>CD-ROM f��r VM ersetzen</title>
-<shortdesc rev="rev1">Sie k��nnen den Inhalt der CD-ROM f��r eine
virtuelle Maschine nach Abschluss der Installation ersetzen.</shortdesc>
-<csbody>
-<ol>
-<li>Stellen Sie sicher, dass die virtuelle Maschine gestartet ist.</li>
-<li>W��hlen Sie aus dem Aktionsmen�� die Option <uicontrol>Medien
verwalten</uicontrol> aus.</li>
-<li>Um das zu ��ndern, was aktuell in der CD-ROM geladen ist, klicken Sie auf das
Symbol mit dem <uicontrol>orangefarbenen Schr��gstrich (/)</uicontrol> neben
dem hdc-Feld.</li>
-<li>Geben Sie auf der Seite <wintitle>CD-ROM f��r VM
ersetzen</wintitle> den ISO-Dateipfad ein. Die anderen beiden Felder sind
schreibgesch��tzt.</li>
-<li>Klicken Sie auf <uicontrol>Ersetzen</uicontrol>.</li>
-</ol>
-</csbody>
-</cshelp>
-<?tm 1391540919 3?>
-</cshelp>
-
-
-<!-- ENGL1SH_VERS10N 45645_6 DO NOT REMOVE OR CHANGE THIS LINE -->
-<!-- T9N_SRC_ID 231 -->
-<!-- T9N_SH1P_STR1NG KV211AAP001 1 -->
diff --git a/plugins/kimchi/ui/pages/help/de_DE/host.dita
b/plugins/kimchi/ui/pages/help/de_DE/host.dita
deleted file mode 100644
index 33a40e3..0000000
--- a/plugins/kimchi/ui/pages/help/de_DE/host.dita
+++ /dev/null
@@ -1,49 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--Arbortext, Inc., 1988-2011, v.4002-->
-<!DOCTYPE cshelp PUBLIC "-//IBM//DTD DITA CSHelp//EN"
- "..\dtd\cshelp.dtd">
-
-
-<!--This DITA specialized document type is not supported by the Authoring Tools
development team.
-For support please see:
-https://w3.opensource.ibm.com/projects/dita-cshelp/-->
-<cshelp id="kimhhost" xml:lang="de-de">
-<title>Host</title>
-<shortdesc>Die Seite <wintitle>Host</wintitle> zeigt Informationen zum
Hostsystem an und erm��glicht Ihnen, den Host herunterzufahren, erneut zu starten und eine
Verbindung zu ihm herzustellen.</shortdesc>
-<csbody>
-<p>Sie k��nnen die folgenden Aktionen am Host durchf��hren:<ul>
-<li>W��hlen Sie <uicontrol>Herunterfahren</uicontrol> aus, um das
Hostsystem herunterzufahren.</li>
-<li>W��hlen Sie <uicontrol>Erneut starten</uicontrol> aus, um das
Hostsystem erneut zu starten.</li>
-<li>W��hlen Sie <uicontrol>Verbinden</uicontrol> aus, um eine
VNC-Verbindung zum Hostsystem herzustellen, wenn noch keine Verbindung
besteht.</li>
-</ul></p>
-<p>Klicken Sie auf die folgenden Abschnitte, um Informationen zum Host
anzuzeigen:<dl>
-<dlentry>
-<dt>Basisinformationen</dt>
-<dd>Dieser Abschnitt zeigt die Verteilung, die Version und den Codenamen des
Hostbetriebssystems sowie den Prozessortyp und die Speicherkapazit��t in GB
an.</dd>
-</dlentry><dlentry>
-<dt>Systemstatistik</dt>
-<dd>Dieser Abschnitt zeigt mithilfe von Grafiken Statistiken f��r CPU, Speicher,
Platten-E/A und Netz-E/A f��r den Host an. W��hlen Sie <uicontrol>Daten werden nach
dem Verlassen dieser Seite gesammelt</uicontrol> aus, um mit der Sammlung von Daten
fortzufahren, wenn die Host-Registerkarte nicht angezeigt wird.</dd>
-</dlentry><dlentry>
-<dt>Software-Updates</dt>
-<dd>Dieser Abschnitt zeigt Informationen f��r alle Pakete an, bei denen
Aktualisierungen verf��gbar sind, einschlie��lich Paketname, Version, Architektur und
Repository. Sie k��nnen alle aufgelisteten Pakete aktualisieren, indem Sie
<uicontrol>Alle aktualisieren</uicontrol> ausw��hlen. Sie k��nnen nicht
einzelne Pakete zur Aktualisierung ausw��hlen.</dd>
-</dlentry><dlentry>
-<dt>Repositorys</dt>
-<dd>Dieser Abschnitt zeigt Repositorys an, die dem Hostsystem zugeordnet sind. Sie
k��nnen Repositorys hinzuf��gen, aktivieren, bearbeiten oder entfernen. Beim Hinzuf��gen
wird ein Repository dem Hostsystem zugeordnet. Das Aktivieren eines Repositorys dagegen
erm��glicht dem Host den Zugriff auf das Repository. Wenn Ihr System Red Hat Enterprise
-Linux oder Fedora ist, k��nnen Sie <filepath>yum</filepath>-Repositorys
hinzuf��gen.
-Wenn Ihr System Ubuntu oder Debian ist, f��gen Sie
<filepath>deb</filepath>-Repositorys hinzu.<p>Wenn Sie mit
yum-Repositorys arbeiten, k��nnen Sie eine GPG-Pr��fung hinzuf��gen, um sicherzustellen,
dass ein Paket aus diesem Repository nicht besch��digt wurde.
-W��hlen Sie ein Repository und dann <uicontrol>Bearbeiten</uicontrol> aus.
W��hlen Sie <uicontrol>Ja</uicontrol> aus, um die GPG-Pr��fung zu aktivieren,
und geben Sie dann ein URL zur GPG-Schl��sseldatei f��r das Repository
ein.</p></dd>
-</dlentry><dlentry>
-<dt>Debugberichte</dt>
-<dd>Dieser Abschnitt zeigt Debugberichte, einschlie��lich Name und Dateipfad, an.
-Sie haben die M��glichkeit, einen neuen Bericht zu erstellen oder einen bestehenden
Bericht umzubenennen, zu entfernen oder herunterzuladen.<p>Der Debugbericht wird
w��hrend des Befehls <cmdname>sosreport</cmdname> generiert. Er ist verf��gbar
f��r Red Hat Enterprise <tm tmtype="tm"
trademark="Linux">Linux</tm>-, Fedora-
-und Ubuntu-Verteilungen. Der Befehl generiert eine .tar-Datei, die Konfigurations- und
Diagnoseinformationen enth��lt, wie zum Beispiel Kernelversion, geladene Module sowie
System- und Servicekonfigurationdateien.
-Der Befehl f��hrt zudem externe Programme aus, um weitere Informationen zu sammeln, und
speichert diese Ausgabe im resultierenden Archiv.</p> </dd>
-</dlentry></dl></p>
-</csbody>
-<?tm 1392659967 1?>
-</cshelp>
-
-
-<!-- ENGL1SH_VERS10N 47930_4 DO NOT REMOVE OR CHANGE THIS LINE -->
-<!-- T9N_SRC_ID 232 -->
-<!-- T9N_SH1P_STR1NG KVM21AAP001 3 -->
diff --git a/plugins/kimchi/ui/pages/help/de_DE/network.dita
b/plugins/kimchi/ui/pages/help/de_DE/network.dita
deleted file mode 100644
index 49a2935..0000000
--- a/plugins/kimchi/ui/pages/help/de_DE/network.dita
+++ /dev/null
@@ -1,62 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--Arbortext, Inc., 1988-2011, v.4002-->
-<!DOCTYPE cshelp PUBLIC "-//IBM//DTD DITA CSHelp//EN"
- "..\dtd\cshelp.dtd">
-
-
-<!--This DITA specialized document type is not supported by the Authoring Tools
development team.
-For support please see:
-https://w3.opensource.ibm.com/projects/dita-cshelp/-->
-<cshelp id="kimhnetw" xml:lang="de-de">
-<title>Netz</title>
-<shortdesc>Die Seite <wintitle>Netz</wintitle> zeigt Informationen zur
Netzverbindung an.</shortdesc>
-<csbody>
-<p><dl><dlentry>
-<dt>Netzname</dt>
-<dd>Name des Netzes oder <uicontrol>Standard</uicontrol>.</dd>
-</dlentry><dlentry>
-<dt>Status</dt>
-<dd>Status des Netzes, aktiv (gr��n) oder inaktiv (rot). </dd>
-</dlentry><dlentry>
-<dt>Netztyp</dt>
-<dd>Netztyp, zum Beispiel <uicontrol>NAT</uicontrol> (Network
-Address Translation, Netzadressumsetzung).</dd>
-</dlentry><dlentry>
-<dt>Schnittstelle</dt>
-<dd>Netzschnittstelle, zum Beispiel <uicontrol>virbr0</uicontrol>
(Standard).</dd>
-</dlentry><dlentry>
-<dt>Adressraum</dt>
-<dd>IP-Adresse.</dd>
-</dlentry></dl></p>
-<p>Die folgenden Aktionen k��nnen ausgew��hlt werden:<ul>
-<li rev="rev1">W��hlen Sie <uicontrol>Starten</uicontrol>
aus, um die Netzverbindung herzustellen.</li>
-<li>W��hlen Sie <uicontrol>Stoppen</uicontrol> aus, um die
Netzverbindung zu beenden.</li>
-<li>W��hlen Sie <uicontrol>L��schen</uicontrol> aus, um die
Verbindungsinformationen zu l��schen.</li>
-</ul>Um ein Netz zu erstellen, klicken Sie auf das Symbol <uicontrol>Plus
(+)</uicontrol> oben rechts in der Anzeige.</p>
-</csbody>
-<cshelp id="kimhnetwcrt" xml:lang="de-de">
-<title>Netz erstellen</title>
-<shortdesc>Erstellen Sie ein Netz.</shortdesc>
-<csbody>
-<p> <ol>
-<li>Geben Sie den Namen des Netzes ein.</li>
-<li>Klicken Sie hier, um den Netztyp auszuw��hlen. <dl
rev="rev1"><dlentry>
-<dt><uicontrol>Isoliert</uicontrol></dt>
-<dd>Isolierter Modus. G��ste k��nnen keine Kommunikation an externe Systeme senden
oder von ihnen empfangen.</dd>
-</dlentry><dlentry>
-<dt><uicontrol>NAT</uicontrol></dt>
-<dd>Network Address Translation-Modus. Bei der Kommunikation von G��sten mit
externen Systemen wird die Host-IP-Adresse verwendet. Externe Systeme k��nnen keine
Kommunikation mit G��sten initiieren.</dd>
-</dlentry><dlentry>
-<dt><uicontrol>��berbr��ckt</uicontrol></dt>
-<dd>��berbr��ckt-Modus. G��ste k��nnen mit externen Systemen kommunizieren und von
externen Systemen kontaktiert werden, als ob sie physische Systeme im Netz w��ren. F��r
den ��berbr��ckt-Modus m��ssen Sie zus��tzliche Ziel- und VLAN-Informationen
angeben.</dd>
-</dlentry></dl></li>
-<li>Klicken Sie auf <uicontrol>Erstellen</uicontrol>.</li>
-</ol> </p>
-</csbody>
-</cshelp>
-</cshelp>
-
-
-<!-- ENGL1SH_VERS10N 47050_3 DO NOT REMOVE OR CHANGE THIS LINE -->
-<!-- T9N_SRC_ID 230 -->
-<!-- T9N_SH1P_STR1NG KVM21AAP001 3 -->
diff --git a/plugins/kimchi/ui/pages/help/de_DE/storage.dita
b/plugins/kimchi/ui/pages/help/de_DE/storage.dita
deleted file mode 100644
index 7f89603..0000000
--- a/plugins/kimchi/ui/pages/help/de_DE/storage.dita
+++ /dev/null
@@ -1,86 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--Arbortext, Inc., 1988-2011, v.4002-->
-<!DOCTYPE cshelp PUBLIC "-//IBM//DTD DITA CSHelp//EN"
- "..\dtd\cshelp.dtd">
-
-
-<!--This DITA specialized document type is not supported by the Authoring Tools
development team.
-For support please see:
-https://w3.opensource.ibm.com/projects/dita-cshelp/-->
-<cshelp id="kimhstor" xml:lang="de-de">
-<title>Speicher</title>
-<shortdesc>Auf der Seite <wintitle>Speicher</wintitle> werden die
verf��gbaren Speicherpools aufgelistet, einschlie��lich der sofort einsatzf��higen
Speicherpools 'default' und 'ISO'. Wenn Sie ein eigenes ISO-Image
verwenden m��chten, f��gen Sie es zum Speicherpoolpfad 'ISO'
hinzu.</shortdesc>
-<csbody>
-<p>F��r jeden Speicherpool werden die folgenden Informationen angezeigt:<dl>
-<dlentry>
-<dt>Name</dt>
-<dd>Name des Speicherpools und genutzter Prozentsatz.</dd>
-</dlentry><dlentry>
-<dt>Status</dt>
-<dd>Status des Speicherpools, aktiv (gr��n) oder inaktiv (rot). </dd>
-</dlentry><dlentry>
-<dt>Position</dt>
-<dd>Dateipfad zur Position des Speicherpools.</dd>
-</dlentry><dlentry>
-<dt>Typ</dt>
-<dd>Typ des Speicherpools, zum Beispiel
<uicontrol>dir</uicontrol>.</dd>
-</dlentry><dlentry>
-<dt>Kapazit��t</dt>
-<dd>Speicherkapazit��t im Speicherpool.</dd>
-</dlentry><dlentry>
-<dt>Zugeordnet</dt>
-<dd>Speicherplatz, der bereits im Speicherpool zugeordnet ist.</dd>
-</dlentry></dl></p>
-<p>Die folgenden Aktionen k��nnen f��r jeden Speicherpool ausgew��hlt
werden:<ul>
-<li>W��hlen Sie <uicontrol>Aktivieren</uicontrol> aus, um den
Speicherpool zu aktivieren, damit er genutzt werden kann.</li>
-<li>W��hlen Sie <uicontrol>Inaktivieren</uicontrol> aus, um einen
aktiven Speicherpool zu inaktivieren.</li>
-<li>W��hlen Sie <uicontrol>Definition aufheben</uicontrol>, um einen
inaktiven Speicherpool zu entfernen.</li>
-</ul></p>
-<p>Um Details zum Speicherdatentr��ger anzuzeigen, klicken Sie auf den Pfeil auf
der rechten Seite der Speicherpoolzeile. Zu den Details geh��ren folgende
Informationen:<dl><dlentry>
-<dt>Typ</dt>
-<dd>Typ des Datentr��gers, zum Beispiel
<uicontrol>file</uicontrol>.</dd>
-</dlentry><dlentry>
-<dt>Format</dt>
-<dd>Das Format, variiert abh��ngig vom Typ.</dd>
-</dlentry><dlentry>
-<dt>Kapazit��t</dt>
-<dd>Gr����e des Speicherdatentr��gers.</dd>
-</dlentry><dlentry>
-<dt>Zuordnung</dt>
-<dd>Speicherplatz, der bereits im Speicherpool zugeordnet ist.</dd>
-</dlentry></dl>Um einen Speicherpool zu definieren, klicken Sie auf das
Symbol <uicontrol>Plus (+)</uicontrol> oben rechts in der Anzeige.</p>
-</csbody>
-<cshelp id="kimhdefstor" xml:lang="de-de">
-<title>Speicherpool definieren</title>
-<shortdesc> Definieren Sie einen Speicherpool.</shortdesc>
-<csbody>
-<p> <ol>
-<li>Geben Sie im Feld <uicontrol>Speicherpoolname</uicontrol> den Namen
ein, mit dem der Speicherpool gekennzeichnet werden soll.</li>
-<li>W��hlen Sie aus der Liste <uicontrol>Speicherpooltyp</uicontrol>
den Typ aus: <dl><dlentry>
-<dt><uicontrol>DIR</uicontrol></dt>
-<dd>Gibt einen Verzeichnispool an. Wenn Sie <uicontrol>DIR</uicontrol>
ausw��hlen, geben Sie den <uicontrol>Speicherpfad</uicontrol> ein (Dateipfad
zum Speicherpool).</dd>
-</dlentry><dlentry>
-<dt><uicontrol>NFS</uicontrol></dt>
-<dd>Gibt einen Netzdateisystempool an. Wenn Sie
<uicontrol>NFS</uicontrol> ausw��hlen,
-geben Sie <uicontrol>NFS-Server-IP</uicontrol> und
<uicontrol>NFS-Pfad</uicontrol> an (Pfad des exportierten
Verzeichnisses).</dd>
-</dlentry><dlentry>
-<dt><uicontrol>iSCSI</uicontrol></dt>
-<dd>Gibt einen Pool an, der auf einem Ziel basiert, der auf einem iSCSI-Server
zugeordnet ist.
-Wenn Sie <uicontrol>iSCSI</uicontrol> ausw��hlen, geben Sie die IP-Adresse
vom <uicontrol>iSCSI-Server</uicontrol> und das
<uicontrol>Ziel</uicontrol> auf dem iSCSI-Server an. Sie k��nnen optional
iSCSI-Authentifizierung hinzuf��gen.</dd>
-</dlentry><dlentry>
-<dt><uicontrol>Logisch</uicontrol></dt>
-<dd>Gibt einen Speicherpool aus logischen Datentr��gern an. W��hlen Sie die
Position zur Einheit im <uicontrol>Einheitenpfad</uicontrol> aus.</dd>
-</dlentry><dlentry>
-<dt><uicontrol>SCSI-Fibre Channel</uicontrol></dt>
-<dd>Gibt einen Pool an, der auf einem SCSI-Fibre Channel basiert. W��hlen Sie aus,
welcher Adapter verwendet werden soll.</dd>
-</dlentry></dl></li>
-<li>Klicken Sie auf <uicontrol>Erstellen</uicontrol>.</li>
-</ol> </p>
-</csbody>
-</cshelp>
-</cshelp>
-
-
-<!-- ENGL1SH_VERS10N 22336_4 DO NOT REMOVE OR CHANGE THIS LINE -->
-<!-- T9N_SRC_ID 233 -->
-<!-- T9N_SH1P_STR1NG KV211AAP001 1 -->
diff --git a/plugins/kimchi/ui/pages/help/de_DE/templates.dita
b/plugins/kimchi/ui/pages/help/de_DE/templates.dita
deleted file mode 100644
index 5063930..0000000
--- a/plugins/kimchi/ui/pages/help/de_DE/templates.dita
+++ /dev/null
@@ -1,112 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--Arbortext, Inc., 1988-2011, v.4002-->
-<!DOCTYPE cshelp PUBLIC "-//IBM//DTD DITA CSHelp//EN"
- "..\dtd\cshelp.dtd">
-
-
-<!--This DITA specialized document type is not supported by the Authoring Tools
development team.
-For support please see:
-https://w3.opensource.ibm.com/projects/dita-cshelp/-->
-<cshelp id="kimhtempl" xml:lang="de-de">
-<title>Vorlagen</title>
-<shortdesc>Die Seite <wintitle>Vorlagen</wintitle> zeigt die
definierten Vorlagen der virtuellen Maschine an, die zum Erstellen von KVM-G��sten
verwendet werden k��nnen.</shortdesc>
-<csbody>
-<p>F��r jede Vorlage werden die folgenden Informationen angezeigt:<dl>
-<dlentry>
-<dt>BS</dt>
-<dd>Name des Betriebssystems oder der Verteilung.</dd>
-</dlentry><dlentry>
-<dt>Version</dt>
-<dd>Version des Betriebssystems oder der Verteilung.</dd>
-</dlentry><dlentry>
-<dt>CPUs</dt>
-<dd>Anzahl der Prozessoren, die f��r die Vorlage definiert sind.</dd>
-</dlentry><dlentry>
-<dt>Speicher</dt>
-<dd>Gr����e des zuzuordnenden Arbeitsspeichers in MB.</dd>
-</dlentry></dl></p>
-<p>Die folgenden Aktionen k��nnen f��r jede Vorlage ausgew��hlt werden:<ul>
-<li>W��hlen Sie <uicontrol>Bearbeiten</uicontrol> aus, um die Vorlage
zu bearbeiten.</li>
-<li>W��hlen Sie <uicontrol>L��schen</uicontrol> aus, um die Vorlage zu
l��schen.</li>
-</ul>Um eine Vorlage hinzuzuf��gen, klicken Sie auf das Symbol
<uicontrol>Plus (+)</uicontrol> oben rechts in der Anzeige.</p>
-</csbody>
-<cshelp id="kimhedittempl" xml:lang="de-de">
-<title>Vorlage bearbeiten</title>
-<shortdesc>Bearbeiten Sie eine bestehende Vorlage.</shortdesc>
-<csbody>
-<p>F��r jede Vorlage werden die folgenden Informationen angezeigt: <dl>
-<dlentry>
-<dt>Name</dt>
-<dd>Name der Vorlage.</dd>
-</dlentry><dlentry>
-<dt>Anbieter</dt>
-<dd>Der Name des Unternehmens, das das Betriebssystem oder die Verteilung erstellt
hat, f��r die die Vorlage konfiguriert ist.</dd>
-</dlentry><dlentry>
-<dt>Version</dt>
-<dd>Die Version des Betriebssystems oder der Verteilung, f��r die die Vorlage
konfiguriert ist.</dd>
-</dlentry><dlentry>
-<dt>CPU-Anzahl</dt>
-<dd>Anzahl der Prozessoren, die f��r die Vorlage definiert sind.</dd>
-</dlentry><dlentry>
-<dt>Speicher</dt>
-<dd>Speicherkapazit��t in MB, die der virtuellen Maschine zugeordnet werden
soll.</dd>
-</dlentry><dlentry>
-<dt>Platte</dt>
-<dd>Plattengr����e in GB.</dd>
-</dlentry><dlentry>
-<dt>CD-ROM</dt>
-<dd>Dateipfad zur Position der ISO-Datei an, die f��r die Installation des
KVM-Gastes verwendet wird.</dd>
-</dlentry><dlentry>
-<dt>Speicherpool</dt>
-<dd>Bestimmter Speicherpool oder der Standardspeicherpool.</dd>
-</dlentry><dlentry>
-<dt>Netz</dt>
-<dd>Standardnetzschnittstelle, die f��r den KVM-Gast verf��gbar ist. Sie k��nnen
mehrere Netze ausw��hlen.</dd>
-</dlentry></dl> Felder, die nicht inaktiviert sind, k��nnen bearbeitet
werden. Nachdem Sie ein Feld bearbeitet haben, klicken Sie auf
<uicontrol>Speichern</uicontrol>. </p>
-</csbody>
-</cshelp>
-<cshelp id="kimhaddtempl">
-<title>Vorlage hinzuf��gen</title>
-<shortdesc>F��gen Sie eine Vorlage vom Quellendatentr��ger hinzu. Sie k��nnen f��r
eine nachfolgende Erkennung Ihr eigenes ISO-Image zum Speicherpool 'ISO'
hinzuf��gen.</shortdesc>
-<csbody>
-<p>W��hlen Sie die Position des Quellendatentr��gers aus den folgenden Optionen
aus:<dl>
-<dlentry>
-<dt>Lokales ISO-Image</dt>
-<dd>W��hlen Sie diese Option aus, um Speicherpools nach Installations-ISO-Images zu
durchsuchen, die im System verf��gbar sind.</dd>
-</dlentry><dlentry>
-<dt>Fernes ISO-Image</dt>
-<dd>W��hlen Sie diese Option aus, um eine ferne Position f��r ein
Installations-ISO-Image anzugeben.</dd>
-</dlentry></dl></p>
-</csbody>
-</cshelp>
-<cshelp id="kimhaddloct">
-<title>Vorlage hinzuf��gen - lokales ISO-Image</title>
-<shortdesc>F��gen Sie eine Vorlage aus einem lokalen ISO-Image
hinzu.</shortdesc>
-<csbody>
-<p>Die im System verf��gbaren ISO-Images werden
angezeigt.<dl><dlentry>
-<dt>BS</dt>
-<dd>Name des Betriebssystems oder der Verteilung.</dd>
-</dlentry><dlentry>
-<dt>Version</dt>
-<dd>Version des Betriebssystems oder der Verteilung.</dd>
-</dlentry><dlentry>
-<dt>Gr����e</dt>
-<dd>Gr����e des ISO-Image.</dd>
-</dlentry></dl></p>
-<p>Um eine Vorlage aus einem ISO-Image zu erstellen, w��hlen Sie aus den folgenden
-Optionen aus:<ul>
-<li>W��hlen Sie ein ISO-Image aus, aus dem Sie eine Vorlage erstellen m��chten, und
klicken Sie dann auf <uicontrol>Vorlagen aus ausgew��hltem ISO
erstellen</uicontrol>.</li>
-<li>W��hlen Sie <uicontrol>Alle</uicontrol> aus, um eine Vorlage aus
jedem aufgelisteten ISO-Image zu erstellen, und klicken Sie dann auf
<uicontrol>Vorlagen aus ausgew��hltem ISO erstellen</uicontrol>.</li>
-<li>Wenn das ISO-Image, das Sie verwenden m��chten, nicht in den Suchergebnissen
angezeigt wird, k��nnen Sie aus den folgenden Optionen ausw��hlen:<ul>
-<li>W��hlen Sie <uicontrol>Ich m��chte eine bestimmte ISO-Datei
verwenden</uicontrol> aus, um einen Pfad zum ISO-Image anzugeben.</li>
-<li>Klicken Sie auf <uicontrol>Weitere ISOs suchen</uicontrol>, um
weitere ISO-Images zu suchen.</li>
-</ul></li>
-</ul></p>
-</csbody>
-</cshelp>
-</cshelp>
-
-
-<!-- ENGL1SH_VERS10N 61085_5 DO NOT REMOVE OR CHANGE THIS LINE -->
-<!-- T9N_SRC_ID 229 -->
-<!-- T9N_SH1P_STR1NG KV211AAP001 1 -->
diff --git a/plugins/kimchi/ui/pages/help/dita-help.xsl
b/plugins/kimchi/ui/pages/help/dita-help.xsl
deleted file mode 100644
index 45f0a3b..0000000
--- a/plugins/kimchi/ui/pages/help/dita-help.xsl
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<xsl:stylesheet version="1.0"
-
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
-
xmlns="http://www.w3.org/1999/xhtml">
- <xsl:output method="xml" indent="yes"
encoding="UTF-8" />
-
- <xsl:template match="/">
- <html>
- <head>
- <title><xsl:value-of select="/cshelp/title"
/></title>
- <meta charset="UTF-8" />
- <link rel="shortcut icon" href="images/logo.ico"
/>
- <link rel="stylesheet" type="text/css"
href="../kimchi.css" />
- </head>
- <body>
- <xsl:apply-templates select="//cshelp" />
- </body>
- </html>
- </xsl:template>
-
- <xsl:template match="cshelp">
- <h1><xsl:value-of select="title" /></h1>
- <p class="shortdesc"><xsl:value-of
select="shortdesc" /></p>
- <p class="csbody"><xsl:copy-of
select="csbody/node()" /></p>
- </xsl:template>
-</xsl:stylesheet>
diff --git a/plugins/kimchi/ui/pages/help/en_US/Makefile.am
b/plugins/kimchi/ui/pages/help/en_US/Makefile.am
deleted file mode 100644
index d37f03a..0000000
--- a/plugins/kimchi/ui/pages/help/en_US/Makefile.am
+++ /dev/null
@@ -1,23 +0,0 @@
-# Copyright IBM Corp, 2014
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-
-en_US_helpdir = $(datadir)/wok/plugins/kimchi/ui/pages/help/en_US
-
-dist_en_US_help_DATA = $(wildcard *.html) $(NULL)
-
-EXTRA_DIST = $(wildcard *.dita)
-
-CLEANFILES = $(wildcard *.html)
diff --git a/plugins/kimchi/ui/pages/help/en_US/guests.dita
b/plugins/kimchi/ui/pages/help/en_US/guests.dita
deleted file mode 100644
index 1bb437a..0000000
--- a/plugins/kimchi/ui/pages/help/en_US/guests.dita
+++ /dev/null
@@ -1,136 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--Arbortext, Inc., 1988-2011, v.4002-->
-<!DOCTYPE cshelp PUBLIC "-//IBM//DTD DITA CSHelp//EN"
- "..\dtd\cshelp.dtd">
-<?Pub Sty _display FontColor="red"?>
-<?Pub Inc?>
-<!--This DITA specialized document type is not supported by the Authoring Tools
development team.
-For support please see:
-https://w3.opensource.ibm.com/projects/dita-cshelp/-->
-<cshelp id="kimhvirtm" xml:lang="en-us">
-<title>Guests</title>
-<shortdesc>The <wintitle>Guests</wintitle> page lists the defined
-KVM virtual machines.</shortdesc>
-<csbody>
-<p>For each guest, the following information is
displayed:<dl><dlentry>
-<dt>Name</dt>
-<dd>Name of the virtual machine.</dd>
-</dlentry><dlentry>
-<dt>CPU</dt>
-<dd>Percentage of processor utilization in the virtual machine.</dd>
-</dlentry><dlentry>
-<dt>Network I/O</dt>
-<dd>Network input/output transmission rate in KB per seconds.</dd>
-</dlentry><dlentry>
-<dt>Disk I/O</dt>
-<dd>Disk input/output transmission rate in KB per seconds.</dd>
-</dlentry><dlentry>
-<dt>Livetile</dt>
-<dd>State of guest operating system console, or an icon that represents
-the <tm tmtype="tm" trademark="Linux">Linux</tm>
distribution if the
-guest is not active.</dd>
-</dlentry></dl></p>
-<p>The following actions icons are displayed for each guest:<dl>
-<dlentry>
-<dt>Reset</dt>
-<dd>Click to reset the guest. </dd>
-</dlentry><dlentry>
-<dt>Power (Start or Stop)</dt>
-<dd>Click to power on or power off the guest. If the icon is red,
-the power is off; if the icon is green, the power is on.</dd>
-</dlentry></dl> </p>
-<p>The following actions can be selected for each guest:<ul>
-<li>Select <uicontrol>Connect</uicontrol> to connect to the remote
-console for the guest operating system.</li>
-<li>Select <uicontrol>Manage media</uicontrol> to change the path
-to the installation media.</li>
-<li>Select <uicontrol>Reset</uicontrol> to reset the guest.</li>
-<li>Select <uicontrol>Edit</uicontrol> to edit the properties of an
-existing guest. Guests can be edited only while stopped.</li>
-<li>Select <uicontrol>Delete</uicontrol> to delete the
guest.</li>
-</ul>To create a guest, or virtual machine, click the <uicontrol>plus
-(+)</uicontrol> icon in the upper right of the page.</p>
-</csbody>
-<cshelp id="kimhvirtmcrt" xml:lang="en-us">
-<title>Create virtual machine</title>
-<shortdesc>Create a virtual machine by using an existing
template.</shortdesc>
-<csbody>
-<p> <ol>
-<li>Type the name to be used to identify the virtual machine.</li>
-<li rev="rev1">Select a template. <ul>
-<li>If templates exist, select from displayed templates.</li>
-<li>If no templates exist, click <uicontrol>Create a
template</uicontrol> to
-create a template.</li>
-</ul></li>
-<li>Click <uicontrol>Create</uicontrol>.</li>
-</ol> </p>
-</csbody>
-</cshelp>
-<cshelp id="kimhvirtmedit" xml:lang="en-us">
-<title>Edit guest</title>
-<shortdesc>Edit the properties of an existing virtual machine. Some properties
-can be edited only while guest is stopped. Others will take effect in next
boot.</shortdesc>
-<csprolog><csmetadata></csmetadata></csprolog>
-<csbody>
-<p>For each guest, the following information is displayed on the
<wintitle>General</wintitle> tab:<dl>
-<dlentry>
-<dt>Name</dt>
-<dd>Name of the virtual machine. (can only be edited while guest is
stopped)</dd>
-</dlentry><dlentry>
-<dt>CPUs</dt>
-<dd>Number of processors. (if guest is running, new amount will take effect
-in next boot)</dd>
-</dlentry><dlentry>
-<dt>Memory</dt>
-<dd>Amount of memory in MB. (if guest is running, new amount will take effect
-in next boot)</dd>
-</dlentry><dlentry>
-<dt>Icon</dt>
-<dd>Graphic image representing the Linux distribution to be displayed
-in place of current status (Livetile) when the guest is not active.</dd>
-</dlentry></dl></p>
-<p>The following information is displayed on the
<wintitle>Storage</wintitle> tab.</p>
-<dl><dlentry>
-<dt>Storage</dt>
-<dd>Displays the location of the ISO file used for installation.</dd>
-</dlentry></dl><?Pub Caret -2?>
-<p> Fields that are not disabled can be edited. After you edit a field,
-click <uicontrol>Save</uicontrol>. </p>
-</csbody>
-</cshelp>
-<cshelp id="kimstoragedevice" xml:lang="en-us">
-<title>Add, replace, or detach a storage device</title>
-<shortdesc rev="rev1">You can add, replace, or detach a storage device
-to your virtual machine. The only supported device is CDROM. To edit
-your storage devices, follow these steps:</shortdesc>
-<csbody>
-<ol>
-<li>On the <wintitle>Edit Guest</wintitle> window, select
<wintitle>Storage</wintitle>.</li>
-<li>To replace a storage device, click the first icon with the
<uicontrol>orange
-slash (/)</uicontrol>. Enter the ISO file path and click
<uicontrol>Replace</uicontrol>.</li>
-<li>To detach a storage device, click the second icon with the
<uicontrol>red
-dash (-)</uicontrol>. Confirm the deletion and click
<uicontrol>OK</uicontrol>.</li>
-<li>To add a storage device, click the third icon with the green
<uicontrol>plus
-sign (+)</uicontrol>. Enter a device name and ISO file path and click
<uicontrol>Attach</uicontrol>.</li>
-</ol>
-</csbody>
-</cshelp>
-<cshelp id="kimreplacemedia" xml:lang="en-us">
-<title>Replace a CDROM of VM</title>
-<shortdesc rev="rev1">You can replace the contents of the CDROM for
-a virtual machine after the installation is complete.</shortdesc>
-<csbody>
-<ol>
-<li>Ensure that the virtual machine is started.</li>
-<li>From the Actions menu, select <uicontrol>Manage
Media</uicontrol>.</li>
-<li>To change what is currently loaded in the CDROM, click the
<uicontrol>orange
-slash (/)</uicontrol> icon next to the hdc field.</li>
-<li>On the <wintitle>Replace a CDROM of VM</wintitle> page, enter
-the ISO file path. The other two fields are read-only.</li>
-<li>Click <uicontrol>Replace</uicontrol>.</li>
-</ol>
-</csbody>
-</cshelp>
-<?tm 1391540919 3?>
-</cshelp>
-<?Pub *0000005541?>
diff --git a/plugins/kimchi/ui/pages/help/en_US/host.dita
b/plugins/kimchi/ui/pages/help/en_US/host.dita
deleted file mode 100644
index 0dcb670..0000000
--- a/plugins/kimchi/ui/pages/help/en_US/host.dita
+++ /dev/null
@@ -1,70 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--Arbortext, Inc., 1988-2011, v.4002-->
-<!DOCTYPE cshelp PUBLIC "-//IBM//DTD DITA CSHelp//EN"
- "..\dtd\cshelp.dtd">
-<?Pub Sty _display FontColor="red"?>
-<?Pub Inc?>
-<!--This DITA specialized document type is not supported by the Authoring Tools
development team.
-For support please see:
-https://w3.opensource.ibm.com/projects/dita-cshelp/-->
-<cshelp id="kimhhost" xml:lang="en-us">
-<title>Host</title>
-<shortdesc>The <wintitle>Host</wintitle> page shows information about
-the host system, and allows you to shut down, restart, and connect
-to the host.</shortdesc>
-<csbody>
-<p>You can perform the following actions on the host:<ul>
-<li>Select <uicontrol>Shut down</uicontrol> to shut down the host
-system.</li>
-<li>Select <uicontrol>Restart</uicontrol> to restart the host
system.</li>
-<li>Select <uicontrol>Connect</uicontrol> to open a VNC connection
-to the host system, if it is not already connected.</li>
-</ul></p>
-<p>Click the following sections to display information about the host:<dl>
-<dlentry>
-<dt>Basic information</dt>
-<dd>This section displays the host operating system distribution,
-version, and code name, as well as the processor type, the number of
-online CPUs and amount of memory in GB.</dd>
-</dlentry><dlentry>
-<dt>System statistics</dt>
-<dd>This section displays graphs to show statistics for CPU, memory,
-disk I/O, and network I/O for the host. Select <uicontrol>Collecting
-data after leaving this page</uicontrol> to continue collecting data
-when the host tab is out of view.</dd>
-</dlentry><dlentry>
-<dt>Software Updates</dt>
-<dd>This section displays information for all of the packages that
-have updates available, including package name, version, architecture,
-and repository. You can update all of the packages listed by selecting
<uicontrol>Update
-All</uicontrol>. You cannot select individual packages for updates.</dd>
-</dlentry><dlentry>
-<dt>Repositories</dt>
-<dd>This section displays repositories that are associated with the
-host system. You can add, enable, edit, or remove repositories. Adding
-a repository associates it with the host system while enabling a repository
-allows the host to access it. If your system is Red Hat Enterprise
-Linux or Fedora, you can add <filepath>yum</filepath> repositories.
-If your system is Ubuntu or Debian, then add <filepath>deb</filepath>
repositories.<p>If
-you are working with yum repositories, you can add a GPG check to
-verify that a package from this repository have not been corrupted.
-Select a repository and then <uicontrol>Edit</uicontrol>. Select
<uicontrol>Yes</uicontrol> to
-enable GPG Check and then enter a URL to the GPG key file for the
-repository.</p><?Pub Caret 156?></dd>
-</dlentry><dlentry>
-<dt>Debug reports</dt>
-<dd>This section displays debug reports, including name and file path.
-You can select from options to generate a new report, or rename, remove,
-or download an existing report.<p>The debug report is generated using
-the <cmdname>sosreport</cmdname> command. It is available for Red
-Hat Enterprise <tm tmtype="tm"
trademark="Linux">Linux</tm>, Fedora,
-and Ubuntu distributions. The command generates a .tar file that contains
-configuration and diagnostic information, such as the running kernel
-version, loaded modules, and system and service configuration files.
-The command also runs external programs to collect further information
-and stores this output in the resulting archive.</p> </dd>
-</dlentry></dl></p>
-</csbody>
-<?tm 1392659967 1?>
-</cshelp>
-<?Pub *0000003492?>
diff --git a/plugins/kimchi/ui/pages/help/en_US/network.dita
b/plugins/kimchi/ui/pages/help/en_US/network.dita
deleted file mode 100644
index 25c05ff..0000000
--- a/plugins/kimchi/ui/pages/help/en_US/network.dita
+++ /dev/null
@@ -1,68 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--Arbortext, Inc., 1988-2011, v.4002-->
-<!DOCTYPE cshelp PUBLIC "-//IBM//DTD DITA CSHelp//EN"
- "..\dtd\cshelp.dtd">
-<?Pub Sty _display FontColor="red"?>
-<?Pub Inc?>
-<!--This DITA specialized document type is not supported by the Authoring Tools
development team.
-For support please see:
-https://w3.opensource.ibm.com/projects/dita-cshelp/-->
-<cshelp id="kimhnetw" xml:lang="en-us">
-<title>Network</title>
-<shortdesc>The <wintitle>Network</wintitle> page displays information
-about the network connection.</shortdesc>
-<csbody>
-<p><dl><dlentry>
-<dt>Network Name</dt>
-<dd>Name of the network, or <uicontrol>default</uicontrol>.</dd>
-</dlentry><dlentry>
-<dt>State</dt>
-<dd>State of the network, active (green) or inactive (red). </dd>
-</dlentry><dlentry>
-<dt>Network type</dt>
-<dd>Network type, for example, <uicontrol>NAT</uicontrol> (network
-address translation).</dd>
-</dlentry><dlentry>
-<dt>Interface</dt>
-<dd>Network interface, for example, <uicontrol>virbr0</uicontrol>
(default).</dd>
-</dlentry><dlentry>
-<dt>Address space</dt>
-<dd>IP address.</dd>
-</dlentry></dl></p>
-<p>The following actions can be selected:<ul>
-<li rev="rev1">Select <uicontrol>Start</uicontrol> to begin
the network
-connection.</li>
-<li>Select <uicontrol>Stop</uicontrol> to end the network
connection.</li>
-<li>Select <uicontrol>Delete</uicontrol> to delete the connection
-information.</li>
-</ul>To create a network, click the <uicontrol>plus (+)</uicontrol>
icon
-in the upper right of the display.</p>
-</csbody>
-<cshelp id="kimhnetwcrt" xml:lang="en-us">
-<title>Create a network</title>
-<shortdesc>Create a network.</shortdesc>
-<csbody>
-<p> <ol>
-<li>Type the name of the network.</li>
-<li>Click to select the network type. <dl
rev="rev1"><dlentry>
-<dt><uicontrol>Isolated</uicontrol></dt>
-<dd>Isolated mode. Guests cannot send or receive communication to
-or from external systems.</dd>
-</dlentry><dlentry>
-<dt><uicontrol>NAT</uicontrol></dt>
-<dd>Network Address Translation mode. Communication from guests to
-external systems uses the host IP address. External systems cannot
-initiate communication to guests.</dd>
-</dlentry><dlentry>
-<dt><uicontrol>Bridged</uicontrol></dt>
-<dd>Bridged mode. Guests can communicate with external systems and
-be contacted by external systems as if they were physical systems
-on the network. For bridged mode, you must specify additional destination
-and VLAN information.</dd>
-</dlentry></dl><?Pub Caret 224?></li>
-<li>Click <uicontrol>Create</uicontrol>.</li>
-</ol> </p>
-</csbody>
-</cshelp>
-</cshelp>
-<?Pub *0000002571?>
diff --git a/plugins/kimchi/ui/pages/help/en_US/storage.dita
b/plugins/kimchi/ui/pages/help/en_US/storage.dita
deleted file mode 100644
index d9a32f9..0000000
--- a/plugins/kimchi/ui/pages/help/en_US/storage.dita
+++ /dev/null
@@ -1,99 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--Arbortext, Inc., 1988-2011, v.4002-->
-<!DOCTYPE cshelp PUBLIC "-//IBM//DTD DITA CSHelp//EN"
- "..\dtd\cshelp.dtd">
-<?Pub Sty _display FontColor="red"?>
-<?Pub Inc?>
-<!--This DITA specialized document type is not supported by the Authoring Tools
development team.
-For support please see:
-https://w3.opensource.ibm.com/projects/dita-cshelp/-->
-<cshelp id="kimhstor" xml:lang="en-us">
-<title>Storage</title>
-<shortdesc>The <wintitle>Storage</wintitle> page lists the available
-storage pools, including the out of box 'default' and 'ISO' storage
pool.
-If you want to use your own ISO, please add it to 'ISO' storage pool
path.</shortdesc>
-<csbody>
-<p>For each storage pool, the following information is displayed:<dl>
-<dlentry>
-<dt>Name</dt>
-<dd>Name of the storage pool and percentage used.</dd>
-</dlentry><dlentry>
-<dt>State</dt>
-<dd>State of the storage pool, active (green) or inactive (red). </dd>
-</dlentry><dlentry>
-<dt>Location</dt>
-<dd>File path to the location of the storage pool.</dd>
-</dlentry><dlentry>
-<dt>Type</dt>
-<dd>Type of storage pool, for example,
<uicontrol>dir</uicontrol>.</dd>
-</dlentry><dlentry>
-<dt>Capacity</dt>
-<dd>Amount of space in the storage pool.</dd>
-</dlentry><dlentry>
-<dt>Allocated</dt>
-<dd>Amount of space that is already allocated in the storage pool.</dd>
-</dlentry></dl></p>
-<p>The following actions can be selected for each storage pool:<ul>
-<li>Select <uicontrol>Activate</uicontrol> to activate the storage
-pool so that it can be used.</li>
-<li>Select <uicontrol>Deactivate</uicontrol> to deactivate an active
-storage pool.</li>
-<li>Select <uicontrol>Undefine</uicontrol> to remove an inactive
storage
-pool.</li>
-</ul></p>
-<p>To display storage volume details for a storage pool, click the
-arrow on the right side of the storage pool row. Details include
-the following:<dl><dlentry>
-<dt>Type</dt>
-<dd>The type of volume, for example,
<uicontrol>file</uicontrol>.</dd>
-</dlentry><dlentry>
-<dt>Format</dt>
-<dd>The format, varying dependent on the type.</dd>
-</dlentry><dlentry>
-<dt>Capacity</dt>
-<dd>Size of the storage volume.</dd>
-</dlentry><dlentry>
-<dt>Allocation</dt>
-<dd>Amount of space that is already allocated in the storage pool.</dd>
-</dlentry></dl>To define a storage pool, click the <uicontrol>plus
-(+)</uicontrol> icon in the upper right of the display.</p>
-</csbody>
-<cshelp id="kimhdefstor" xml:lang="en-us">
-<title>Define a storage pool</title>
-<shortdesc> Define a storage pool.</shortdesc>
-<csbody>
-<p> <ol>
-<li>In the <uicontrol>Storage pool name</uicontrol> field, type the
-name to be used to identify the storage pool.</li>
-<li>In the <uicontrol>Storage pool type</uicontrol> list, select the
-type: <dl><dlentry>
-<dt><uicontrol>DIR</uicontrol></dt>
-<dd>Specifies a directory pool. When selecting
<uicontrol>DIR</uicontrol>,
-type the <uicontrol>Storage path</uicontrol> (file path to the storage
-pool).</dd>
-</dlentry><dlentry>
-<dt><uicontrol>NFS</uicontrol></dt>
-<dd>Specifies a network filesystem pool. When selecting
<uicontrol>NFS</uicontrol>,
-type the <uicontrol>NFS server IP</uicontrol> address and
<uicontrol>NFS
-path</uicontrol> (path of the exported directory).</dd>
-</dlentry><dlentry>
-<dt><uicontrol>iSCSI</uicontrol></dt>
-<dd>Specifies a pool based on a target allocated on an iSCSI server.
-When selecting <uicontrol>iSCSI</uicontrol>, type the <uicontrol>iSCSI
-server</uicontrol> IP address and <uicontrol>Target</uicontrol> on
-the iSCSI server. You can optionally select to add iSCSI authentication.</dd>
-</dlentry><dlentry>
-<dt><uicontrol>Logical</uicontrol></dt>
-<dd>Specifies a logical volume storage pool. Select the location to
-the device in <uicontrol>Device path</uicontrol>.</dd>
-</dlentry><dlentry>
-<dt><uicontrol>SCSI Fibre Channel</uicontrol></dt>
-<dd>Specifies a pool based on an SCSI Fibre Channel. Select which
-SCSI adapter to use.</dd>
-</dlentry></dl><?Pub Caret 0?></li>
-<li>Click <uicontrol>Create</uicontrol>.</li>
-</ol> </p>
-</csbody>
-</cshelp>
-</cshelp>
-<?Pub *0000003914?>
diff --git a/plugins/kimchi/ui/pages/help/en_US/templates.dita
b/plugins/kimchi/ui/pages/help/en_US/templates.dita
deleted file mode 100644
index 57ee9b5..0000000
--- a/plugins/kimchi/ui/pages/help/en_US/templates.dita
+++ /dev/null
@@ -1,123 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--Arbortext, Inc., 1988-2011, v.4002-->
-<!DOCTYPE cshelp PUBLIC "-//IBM//DTD DITA CSHelp//EN"
- "..\dtd\cshelp.dtd">
-<?Pub Sty _display FontColor="red"?>
-<?Pub Inc?>
-<!--This DITA specialized document type is not supported by the Authoring Tools
development team.
-For support please see:
-https://w3.opensource.ibm.com/projects/dita-cshelp/-->
-<cshelp id="kimhtempl" xml:lang="en-us">
-<title>Templates</title>
-<shortdesc>The <wintitle>Templates</wintitle> page shows the defined
-virtual machine templates that can be used to create KVM guests.</shortdesc>
-<csbody>
-<p>For each template, the following information is displayed:<dl>
-<dlentry>
-<dt>OS</dt>
-<dd>Name of the operating system or distribution.</dd>
-</dlentry><dlentry>
-<dt>Version</dt>
-<dd>Version of the operating system or distribution.</dd>
-</dlentry><dlentry>
-<dt>CPUs</dt>
-<dd>Number of processors that are defined for the template.</dd>
-</dlentry><dlentry>
-<dt>Memory</dt>
-<dd>Amount of random access memory to be allocated, in MB.</dd>
-</dlentry></dl></p>
-<p>The following actions can be selected for each template:<ul>
-<li>Select <uicontrol>Edit</uicontrol> to edit the
template.</li>
-<li>Select <uicontrol>Delete</uicontrol> to delete the
template.</li>
-</ul>To add a template, click the <uicontrol>plus (+)</uicontrol> icon
-in the upper right of the display.</p>
-</csbody>
-<cshelp id="kimhedittempl" xml:lang="en-us">
-<title>Edit template</title>
-<shortdesc>Edit an existing template.</shortdesc>
-<csbody>
-<p>For each template, the following information is displayed: <dl>
-<dlentry>
-<dt>Name</dt>
-<dd>Name of the template.</dd>
-</dlentry><dlentry>
-<dt>Vendor</dt>
-<dd>The name of the company that created the operating system or distribution
-that the template is configured to use.</dd>
-</dlentry><dlentry>
-<dt>Version</dt>
-<dd>The version of the operating system or distribution that the template
-is configured to use.</dd>
-</dlentry><dlentry>
-<dt>CPU number</dt>
-<dd>Number of processors that are defined for the template.</dd>
-</dlentry><dlentry>
-<dt>Memory</dt>
-<dd>Amount of memory in MB to be allocated to the virtual machine.</dd>
-</dlentry><dlentry>
-<dt>Disk</dt>
-<dd>Disk size in GB.</dd>
-</dlentry><dlentry>
-<dt>CDROM</dt>
-<dd>File path to the location of the ISO file used to install the
-KVM guest.</dd>
-</dlentry><dlentry>
-<dt>Storage pool</dt>
-<dd>Specific storage pool or the default storage pool.</dd>
-</dlentry><dlentry>
-<dt>Network</dt>
-<dd>Default network interfaces available to the KVM guest. You can
-select multiple networks.</dd>
-</dlentry></dl> Fields that are not disabled can be edited. After
-you edit a field, click <uicontrol>Save</uicontrol>. </p>
-</csbody>
-</cshelp>
-<cshelp id="kimhaddtempl">
-<title>Add template</title>
-<shortdesc>Add a template from source media.
-You can add your own ISO image to 'ISO' storage pool for following
discovery.</shortdesc>
-<csbody>
-<p>Select the location of the source media from the following options:<dl>
-<dlentry>
-<dt>Local ISO image</dt>
-<dd>Select to scan storage pools for installation ISO images available
-on the system.</dd>
-</dlentry><dlentry>
-<dt>Remote ISO image</dt>
-<dd>Select to specify a remote location for an installation ISO image.</dd>
-</dlentry></dl></p>
-</csbody>
-</cshelp>
-<cshelp id="kimhaddloct">
-<title>Add template - local ISO image</title>
-<shortdesc>Add a template from a local ISO image.</shortdesc>
-<csbody>
-<p>The ISO images available on the system are displayed.<dl><dlentry>
-<dt>OS</dt>
-<dd>Name of the operating system or distribution.</dd>
-</dlentry><dlentry>
-<dt>Version</dt>
-<dd>Version of the operating system or distribution.</dd>
-</dlentry><dlentry>
-<dt>Size</dt>
-<dd>Size of the ISO image.</dd>
-</dlentry></dl></p>
-<p>To create a template from an ISO image, choose from the following
-options:<ul>
-<li>Select an ISO image from which to create a template, then click
<uicontrol>Create
-Templates from Selected ISO</uicontrol>.</li>
-<li>Select <uicontrol>All</uicontrol> to create a template from each
- listed ISO image, then click <uicontrol>Create Templates from Selected
-ISO</uicontrol>.</li>
-<li>If the ISO image that you want to use does not appear in the scan
-results, you can select from the following options:<ul>
-<li>Select <uicontrol>I want to use a specific ISO file</uicontrol> to
-specify a path to the ISO image.</li>
-<li>Click <uicontrol>Search more ISOs</uicontrol> to search for more
-ISO images.</li>
-</ul></li><?Pub Caret 0?>
-</ul></p>
-</csbody>
-</cshelp>
-</cshelp>
-<?Pub *0000004433?>
diff --git a/plugins/kimchi/ui/pages/help/es_ES/Makefile.am
b/plugins/kimchi/ui/pages/help/es_ES/Makefile.am
deleted file mode 100644
index 29c596f..0000000
--- a/plugins/kimchi/ui/pages/help/es_ES/Makefile.am
+++ /dev/null
@@ -1,23 +0,0 @@
-# Copyright IBM Corp, 2014
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-
-es_ES_helpdir = $(datadir)/wok/plugins/kimchi/ui/pages/help/es_ES
-
-dist_es_ES_help_DATA = $(wildcard *.html) $(NULL)
-
-EXTRA_DIST = $(wildcard *.dita)
-
-CLEANFILES = $(wildcard *.html)
diff --git a/plugins/kimchi/ui/pages/help/es_ES/guests.dita
b/plugins/kimchi/ui/pages/help/es_ES/guests.dita
deleted file mode 100644
index 88e77e0..0000000
--- a/plugins/kimchi/ui/pages/help/es_ES/guests.dita
+++ /dev/null
@@ -1,120 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--Arbortext, Inc., 1988-2011, v.4002-->
-<!DOCTYPE cshelp PUBLIC "-//IBM//DTD DITA CSHelp//EN"
- "..\dtd\cshelp.dtd">
-
-
-<!--This DITA specialized document type is not supported by the Authoring Tools
development team.
-For support please see:
-https://w3.opensource.ibm.com/projects/dita-cshelp/-->
-<cshelp id="kimhvirtm" xml:lang="es-es">
-<title>Invitados</title>
-<shortdesc>La p��gina <wintitle>Invitados</wintitle> lista las
m��quinas virtuales KVM definidas.</shortdesc>
-<csbody>
-<p>Se visualiza la siguiente informaci��n para cada
invitado:<dl><dlentry>
-<dt>Nombre</dt>
-<dd>Nombre de la m��quina virtual.</dd>
-</dlentry><dlentry>
-<dt>CPU</dt>
-<dd>Porcentaje de utilizaci��n de procesador en la m��quina virtual.</dd>
-</dlentry><dlentry>
-<dt>E/S de red</dt>
-<dd>Velocidad de transmisi��n de entrada/salida de red en KB por
segundos.</dd>
-</dlentry><dlentry>
-<dt>E/S de disco</dt>
-<dd>Velocidad de transmisi��n de entrada/salida de disco en KB por
segundos.</dd>
-</dlentry><dlentry>
-<dt>Livetile</dt>
-<dd>Estado de la consola del sistema operativo invitado, o un icono que representa
la distribuci��n de <tm tmtype="tm"
trademark="Linux">Linux</tm> si el invitado no est��
activo.</dd>
-</dlentry></dl></p>
-<p>Se visualizan los siguientes iconos de acciones para cada invitado:<dl>
-<dlentry>
-<dt>Restablecer</dt>
-<dd>Pulse aqu�� para restablecer el invitado. </dd>
-</dlentry><dlentry>
-<dt>Alimentaci��n (Iniciar o Detener)</dt>
-<dd>Pulse aqu�� para encender o apagar el invitado. Si el icono es de color rojo,
la alimentaci��n est�� apagada; si el icono es de color verde, la alimentaci��n est��
encendida.</dd>
-</dlentry></dl> </p>
-<p>Se pueden seleccionar las siguientes acciones para cada invitado:<ul>
-<li>Seleccione <uicontrol>Conectar</uicontrol> para conectarse a la
consola remota para el sistema operativo invitado.</li>
-<li>Seleccione <uicontrol>Gestionar soporte</uicontrol> para cambiar la
v��a de acceso al soporte de instalaci��n.</li>
-<li>Seleccione <uicontrol>Restablecer</uicontrol> para restablecer el
invitado.</li>
-<li>Seleccione <uicontrol>Editar</uicontrol> para editar las
propiedades de un invitado existente. Los invitados s��lo pueden editarse mientras est��n
detenidos.</li>
-<li>Seleccione <uicontrol>Suprimir</uicontrol> para suprimir el
invitado.</li>
-</ul>Para crear un invitado o m��quina virtual, pulse el icono
<uicontrol>m��s (+)</uicontrol> en la esquina superior derecha de la
p��gina.</p>
-</csbody>
-<cshelp id="kimhvirtmcrt" xml:lang="es-es">
-<title>Crear m��quina virtual</title>
-<shortdesc>Crear una m��quina virtual utilizando una plantilla
existente.</shortdesc>
-<csbody>
-<p> <ol>
-<li>Escriba el nombre a utilizar para identificar la m��quina virtual.</li>
-<li rev="rev1">Seleccione una plantilla. <ul>
-<li>Si existen plantillas, seleccione entre las plantillas mostradas.</li>
-<li>Si no existen plantillas, pulse <uicontrol>Crear una
plantilla</uicontrol> para crear una plantilla.</li>
-</ul></li>
-<li>Pulse <uicontrol>Crear</uicontrol>.</li>
-</ol> </p>
-</csbody>
-</cshelp>
-<cshelp id="kimhvirtmedit" xml:lang="es-es">
-<title>Editar invitado</title>
-<shortdesc>Editar las propiedades de una m��quina virtual existente. Algunas
propiedades pueden editarse s��lo cuando el invitado se ha detenido. Otras surtir��n
efecto en el arranque siguiente.</shortdesc>
-<csprolog><csmetadata></csmetadata></csprolog>
-<csbody>
-<p>Se visualiza la siguiente informaci��n para cada invitado en la pesta��a
<wintitle>General</wintitle>:<dl>
-<dlentry>
-<dt>Nombre</dt>
-<dd>Nombre de la m��quina virtual.(s��lo puede editarse cuando el invitado se ha
detenido)</dd>
-</dlentry><dlentry>
-<dt>CPUs</dt>
-<dd>N��mero de procesadores.(si el invitado est�� en ejecuci��n, la nueva cantidad
surtir�� efecto en el siguiente arranque)
-</dd>
-</dlentry><dlentry>
-<dt>Memoria</dt>
-<dd>Cantidad de memoria en MB.(si el invitado est�� en ejecuci��n, la nueva
cantidad surtir�� efecto en el siguiente arranque)
-</dd>
-</dlentry><dlentry>
-<dt>Icono</dt>
-<dd>Imagen gr��fica que representa la distribuci��n de Linux a visualizar en lugar
del estado actual (Livetile) cuando el invitado no est�� activo.</dd>
-</dlentry></dl></p>
-<p>Se visualiza la siguiente informaci��n en la pesta��a
<wintitle>Almacenamiento</wintitle>.</p>
-<dl><dlentry>
-<dt>Almacenamiento</dt>
-<dd>Muestra la ubicaci��n del archivo ISO utilizado para la
instalaci��n.</dd>
-</dlentry></dl>
-<p> Los campos que no est��n inhabilitados pueden editarse. Despu��s de editar un
campo, pulse <uicontrol>Guardar</uicontrol>. </p>
-</csbody>
-</cshelp>
-<cshelp id="kimstoragedevice" xml:lang="es-es">
-<title>A��adir, sustituir o desconectar un dispositivo de
almacenamiento</title>
-<shortdesc rev="rev1">Puede a��adir, sustituir o desconectar un
dispositivo de almacenamiento a la m��quina virtual. El ��nico dispositivo soportado es
CDROM. Para editar los dispositivos de almacenamiento, siga estos
pasos:</shortdesc>
-<csbody>
-<ol>
-<li>En la ventana <wintitle>Editar invitado</wintitle>, seleccione
<wintitle>Almacenamiento</wintitle>.</li>
-<li>Para sustituir un dispositivo de almacenamiento, pulse el primer icono con la
<uicontrol>barra inclinada naranja (/)</uicontrol>. Especifique la v��a de
acceso del archivo ISO y pulse <uicontrol>Sustituir</uicontrol>.</li>
-<li>Para desconectar un dispositivo de almacenamiento, pulse el segundo icono con
el <uicontrol>gui��n rojo (-)</uicontrol>. Confirme la supresi��n y pulse
<uicontrol>Aceptar</uicontrol>.</li>
-<li>Para a��adir un dispositivo de almacenamiento, pulse el tercer icono con el
<uicontrol>signo m��s (+)</uicontrol> verde. Especifique un nombre de
dispositivo y la v��a de acceso del archivo ISO y pulse
<uicontrol>Conectar</uicontrol>.</li>
-</ol>
-</csbody>
-</cshelp>
-<cshelp id="kimreplacemedia" xml:lang="es-es">
-<title>Sustituir un CDROM de m��quina virtual</title>
-<shortdesc rev="rev1">Puede sustituir el contenido del CDROM para una
m��quina virtual despu��s de completarse la instalaci��n.</shortdesc>
-<csbody>
-<ol>
-<li>Aseg��rese de que la m��quina virtual se ha iniciado.</li>
-<li>En el men�� Acciones, seleccione <uicontrol>Gestionar
soporte</uicontrol>.</li>
-<li>Para cambiar lo que est�� cargado actualmente en el CDROM, pulse el icono
<uicontrol>barra inclinada naranja (/)</uicontrol> junto al campo
hdc.</li>
-<li>En la p��gina <wintitle>Sustituir un CDROM de m��quina
virtual</wintitle>, especifique la v��a de acceso del archivo ISO. Los otros dos
campos son de s��lo lectura.</li>
-<li>Pulse <uicontrol>Sustituir</uicontrol>.</li>
-</ol>
-</csbody>
-</cshelp>
-<?tm 1391540919 3?>
-</cshelp>
-
-
-<!-- ENGL1SH_VERS10N 45645_6 DO NOT REMOVE OR CHANGE THIS LINE -->
-<!-- T9N_SRC_ID 231 -->
-<!-- T9N_SH1P_STR1NG KV211AAP001 1 -->
diff --git a/plugins/kimchi/ui/pages/help/es_ES/host.dita
b/plugins/kimchi/ui/pages/help/es_ES/host.dita
deleted file mode 100644
index 7734244..0000000
--- a/plugins/kimchi/ui/pages/help/es_ES/host.dita
+++ /dev/null
@@ -1,49 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--Arbortext, Inc., 1988-2011, v.4002-->
-<!DOCTYPE cshelp PUBLIC "-//IBM//DTD DITA CSHelp//EN"
- "..\dtd\cshelp.dtd">
-
-
-<!--This DITA specialized document type is not supported by the Authoring Tools
development team.
-For support please see:
-https://w3.opensource.ibm.com/projects/dita-cshelp/-->
-<cshelp id="kimhhost" xml:lang="es-es">
-<title>Host</title>
-<shortdesc>La p��gina <wintitle>Host</wintitle> muestra informaci��n
sobre el sistema host y le permite concluir, reiniciar y conectar con el sistema
principal.</shortdesc>
-<csbody>
-<p>Puede realizar las acciones siguientes en el host:<ul>
-<li>Seleccione <uicontrol>Concluir</uicontrol> para concluir el sistema
host.</li>
-<li>Seleccione <uicontrol>Reiniciar</uicontrol> para reiniciar el
sistema host.</li>
-<li>Seleccione <uicontrol>Conectar</uicontrol> para abrir una conexi��n
VNC al sistema host, si no est�� conectado a��n.</li>
-</ul></p>
-<p>Pulse en las secciones siguientes para visualizar informaci��n acerca del
host:<dl>
-<dlentry>
-<dt>Informaci��n b��sica</dt>
-<dd>Esta secci��n muestra la distribuci��n del sistema operativo de host, la
versi��n y el nombre de c��digo, as�� como el tipo de procesador y la cantidad de memoria
en GB.</dd>
-</dlentry><dlentry>
-<dt>Estad��sticas del sistema</dt>
-<dd>Esta secci��n muestra gr��ficos para mostrar estad��sticas para CPU, memoria,
E/S de disco y E/S de red para el host. Seleccione <uicontrol>Recoger datos despu��s
de salir de esta p��gina</uicontrol> para continuar la recogida de datos cuando la
pesta��a principal ya no est�� a la vista.</dd>
-</dlentry><dlentry>
-<dt>Actualizaciones de software</dt>
-<dd>En esta secci��n se muestra informaci��n para todos los paquetes que tienen
actualizaciones disponibles, incluido el nombre de paquete, versi��n, arquitectura y
repositorio. Puede actualizar todos los paquetes listados seleccionando
<uicontrol>Actualizar todo</uicontrol>. No puede seleccionar paquetes
individuales para las actualizaciones.</dd>
-</dlentry><dlentry>
-<dt>Repositorios</dt>
-<dd>En esta secci��n se muestran los repositorios que est��n asociados con el
sistema host. Puede a��adir, habilitar, editar o eliminar repositorios. A��adir un
repositorio lo asocia con el sistema host mientras que habilitar un repositorio permite
que el host acceda a ��l. Si el sistema es Red Hat Enterprise
-Linux o Fedora, puede a��adir repositorios <filepath>yum</filepath>.
-Si el sistema es Ubuntu o Debian, a��ada repositorios
<filepath>deb</filepath>.<p>Si est�� trabajando con repositorios yum,
puede a��adir una comprobaci��n GPG para verificar que un paquete de este repositorio no
ha resultado da��ado.
-Seleccione un repositorio y, a continuaci��n, <uicontrol>Editar</uicontrol>.
Seleccione <uicontrol>S��</uicontrol> para habilitar la comprobaci��n GPG y, a
continuaci��n, especifique un URL al archivo de claves GPG para el
repositorio.</p></dd>
-</dlentry><dlentry>
-<dt>Informes de depuraci��n</dt>
-<dd>En esta secci��n se muestran informes de depuraci��n, incluido el nombre y la
ruta de archivo.
-Puede seleccionar entre opciones para generar un informe nuevo, o bien redenominar,
eliminar o descargar un informe existente.<p>El informe de depuraci��n se genera
utilizando el mandato <cmdname>sosreport</cmdname>. Est�� disponible para
distribuciones de Red
-Hat Enterprise <tm tmtype="tm"
trademark="Linux">Linux</tm>, Fedora y Ubuntu. El mandato genera un
archivo .tar que contiene la informaci��n de configuraci��n y de diagn��stico, como la
versi��n de kernel en ejecuci��n, los m��dulos de carga y los archivos de configuraci��n
del sistema y servicio.
-El mandato tambi��n ejecuta programas externos para recopilar informaci��n adicional y
almacena esta salida en el archivo resultante.</p> </dd>
-</dlentry></dl></p>
-</csbody>
-<?tm 1392659967 1?>
-</cshelp>
-
-
-<!-- ENGL1SH_VERS10N 47930_4 DO NOT REMOVE OR CHANGE THIS LINE -->
-<!-- T9N_SRC_ID 232 -->
-<!-- T9N_SH1P_STR1NG KVM21AAP001 3 -->
diff --git a/plugins/kimchi/ui/pages/help/es_ES/network.dita
b/plugins/kimchi/ui/pages/help/es_ES/network.dita
deleted file mode 100644
index 3654531..0000000
--- a/plugins/kimchi/ui/pages/help/es_ES/network.dita
+++ /dev/null
@@ -1,61 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--Arbortext, Inc., 1988-2011, v.4002-->
-<!DOCTYPE cshelp PUBLIC "-//IBM//DTD DITA CSHelp//EN"
- "..\dtd\cshelp.dtd">
-
-
-<!--This DITA specialized document type is not supported by the Authoring Tools
development team.
-For support please see:
-https://w3.opensource.ibm.com/projects/dita-cshelp/-->
-<cshelp id="kimhnetw" xml:lang="es-es">
-<title>Red</title>
-<shortdesc>La p��gina <wintitle>Red</wintitle> muestra informaci��n
sobre la conexi��n de red.</shortdesc>
-<csbody>
-<p><dl><dlentry>
-<dt>Nombre de red</dt>
-<dd>Nombre de la red, o
<uicontrol>predeterminado</uicontrol>.</dd>
-</dlentry><dlentry>
-<dt>Estado</dt>
-<dd>Estado de la red, activa (verde) o inactiva (rojo). </dd>
-</dlentry><dlentry>
-<dt>Tipo de red</dt>
-<dd>Tipo de red, por ejemplo, <uicontrol>NAT</uicontrol> (conversi��n
de direcciones de red).</dd>
-</dlentry><dlentry>
-<dt>Interfaz</dt>
-<dd>La interfaz de red, por ejemplo, <uicontrol>virbr0</uicontrol>
(predeterminada).</dd>
-</dlentry><dlentry>
-<dt>Espacio de direcciones</dt>
-<dd>Direcci��n IP.</dd>
-</dlentry></dl></p>
-<p>Se pueden seleccionar las siguientes acciones:<ul>
-<li rev="rev1">Seleccione <uicontrol>Iniciar</uicontrol> para
iniciar la conexi��n de red.</li>
-<li>Seleccione <uicontrol>Detener</uicontrol> para finalizar la
conexi��n de red.</li>
-<li>Seleccione <uicontrol>Suprimir</uicontrol> para suprimir la
informaci��n de conexi��n.</li>
-</ul>Para crear una red, pulse en el icono <uicontrol>m��s
(+)</uicontrol> en la esquina superior derecha de la pantalla.</p>
-</csbody>
-<cshelp id="kimhnetwcrt" xml:lang="es-es">
-<title>Crear una red</title>
-<shortdesc>Crear una red.</shortdesc>
-<csbody>
-<p> <ol>
-<li>Escriba el nombre de la red.</li>
-<li>Pulse para seleccionar el tipo de red. <dl
rev="rev1"><dlentry>
-<dt><uicontrol>Aislada</uicontrol></dt>
-<dd>Modalidad aislada. Los invitados no pueden enviar ni recibir comunicaci��n a
sistemas externos o desde ellos.</dd>
-</dlentry><dlentry>
-<dt><uicontrol>NAT</uicontrol></dt>
-<dd>Modalidad de Conversi��n de direcciones de red. La comunicaci��n de invitados a
sistemas externos utiliza la direcci��n IP del host. Los sistemas externos no pueden
iniciar la comunicaci��n con los invitados.</dd>
-</dlentry><dlentry>
-<dt><uicontrol>Puenteada</uicontrol></dt>
-<dd>Modalidad puenteada. Los invitados pueden comunicarse con sistemas externos y
ser contactados por sistemas externos como si fueran sistemas f��sicos en la red. Para la
modalidad puenteada, debe especificar informaci��n de destino y VLAN
adicional.</dd>
-</dlentry></dl></li>
-<li>Pulse <uicontrol>Crear</uicontrol>.</li>
-</ol> </p>
-</csbody>
-</cshelp>
-</cshelp>
-
-
-<!-- ENGL1SH_VERS10N 47050_3 DO NOT REMOVE OR CHANGE THIS LINE -->
-<!-- T9N_SRC_ID 230 -->
-<!-- T9N_SH1P_STR1NG KVM21AAP001 3 -->
diff --git a/plugins/kimchi/ui/pages/help/es_ES/storage.dita
b/plugins/kimchi/ui/pages/help/es_ES/storage.dita
deleted file mode 100644
index 0c68951..0000000
--- a/plugins/kimchi/ui/pages/help/es_ES/storage.dita
+++ /dev/null
@@ -1,86 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--Arbortext, Inc., 1988-2011, v.4002-->
-<!DOCTYPE cshelp PUBLIC "-//IBM//DTD DITA CSHelp//EN"
- "..\dtd\cshelp.dtd">
-
-
-<!--This DITA specialized document type is not supported by the Authoring Tools
development team.
-For support please see:
-https://w3.opensource.ibm.com/projects/dita-cshelp/-->
-<cshelp id="kimhstor" xml:lang="es-es">
-<title>Almacenamiento</title>
-<shortdesc>La p��gina <wintitle>Almacenamiento</wintitle> lista las
agrupaciones de almacenamiento disponibles, incluyendo la agrupaci��n de almacenamiento
predefinida 'default' e 'ISO'.
-Si desea utilizar su propia ISO, a����dala a la v��a de acceso de la agrupaci��n de
almacenamiento 'ISO'.</shortdesc>
-<csbody>
-<p>Se visualiza la siguiente informaci��n para cada agrupaci��n de
almacenamiento:<dl>
-<dlentry>
-<dt>Nombre</dt>
-<dd>Nombre de la agrupaci��n de almacenamiento y el porcentaje
utilizado.</dd>
-</dlentry><dlentry>
-<dt>Estado</dt>
-<dd>Estado de la agrupaci��n de almacenamiento, activa (verde) o inactiva (rojo).
</dd>
-</dlentry><dlentry>
-<dt>Ubicaci��n</dt>
-<dd>V��a de acceso de archivo a la ubicaci��n de la agrupaci��n de
almacenamiento.</dd>
-</dlentry><dlentry>
-<dt>Tipo</dt>
-<dd>Tipo de agrupaci��n de almacenamiento, por ejemplo,
<uicontrol>dir</uicontrol>.</dd>
-</dlentry><dlentry>
-<dt>Capacidad</dt>
-<dd>Cantidad de espacio en la agrupaci��n de almacenamiento.</dd>
-</dlentry><dlentry>
-<dt>Asignado</dt>
-<dd>Cantidad de espacio que ya est�� asignado en la agrupaci��n de
almacenamiento.</dd>
-</dlentry></dl></p>
-<p>Se pueden seleccionar las siguientes acciones para cada agrupaci��n de
almacenamiento:<ul>
-<li>Seleccione <uicontrol>Activar</uicontrol> para activar la
agrupaci��n de almacenamiento para que pueda utilizarse.</li>
-<li>Seleccione <uicontrol>Desactivar</uicontrol> para desactivar una
agrupaci��n de almacenamiento activa.</li>
-<li>Seleccione <uicontrol>No definir</uicontrol> para eliminar una
agrupaci��n de almacenamiento inactiva.</li>
-</ul></p>
-<p>Para visualizar detalles de volumen de almacenamiento para una agrupaci��n de
almacenamiento, pulse la flecha situada en el lado derecho de la fila de agrupaci��n de
almacenamiento. Los detalles incluyen lo siguiente:<dl><dlentry>
-<dt>Tipo</dt>
-<dd>El tipo de volumen, por ejemplo,
<uicontrol>archivo</uicontrol>.</dd>
-</dlentry><dlentry>
-<dt>Formato</dt>
-<dd>El formato, variable dependiendo del tipo.</dd>
-</dlentry><dlentry>
-<dt>Capacidad</dt>
-<dd>Tama��o del volumen de almacenamiento.</dd>
-</dlentry><dlentry>
-<dt>Asignaci��n</dt>
-<dd>Cantidad de espacio que ya est�� asignado en la agrupaci��n de
almacenamiento.</dd>
-</dlentry></dl>Para definir una agrupaci��n de almacenamiento, pulse en el
icono <uicontrol>m��s (+)</uicontrol> en la esquina superior derecha de la
pantalla.</p>
-</csbody>
-<cshelp id="kimhdefstor" xml:lang="es-es">
-<title>Definir una agrupaci��n de almacenamiento</title>
-<shortdesc> Definir una agrupaci��n de almacenamiento.</shortdesc>
-<csbody>
-<p> <ol>
-<li>En el campo <uicontrol>Nombre de agrupaci��n de
almacenamiento</uicontrol>, escriba el nombre que se utilizar�� para identificar la
agrupaci��n de almacenamiento.</li>
-<li>En la lista <uicontrol>Tipo de agrupaci��n
almacenamiento</uicontrol>, seleccione el tipo: <dl><dlentry>
-<dt><uicontrol>DIR</uicontrol></dt>
-<dd>Especifica una agrupaci��n de directorio. Al seleccionar
<uicontrol>DIR</uicontrol>, escriba la <uicontrol>V��a de acceso de
almacenamiento</uicontrol> (v��a de acceso de archivo a la agrupaci��n de
almacenamiento).</dd>
-</dlentry><dlentry>
-<dt><uicontrol>NFS</uicontrol></dt>
-<dd>Especifica una agrupaci��n de sistema de archivos de red. Al seleccionar
<uicontrol>NFS</uicontrol>, escriba la direcci��n <uicontrol>IP de
servidor NFS</uicontrol> y <uicontrol>v��a de acceso de NFS</uicontrol>
(v��a de acceso del directorio exportado).</dd>
-</dlentry><dlentry>
-<dt><uicontrol>iSCSI</uicontrol></dt>
-<dd>Especifica una agrupaci��n basada en un destino asignado en un servidor iSCSI.
-Al seleccionar <uicontrol>iSCSI</uicontrol>, escriba la direcci��n IP del
<uicontrol>Servidor iSCSI</uicontrol> y el
<uicontrol>Destino</uicontrol> en el servidor iSCSI. Opcionalmente puede
seleccionar a��adir autenticaci��n iSCSI.</dd>
-</dlentry><dlentry>
-<dt><uicontrol>L��gico</uicontrol></dt>
-<dd>Especifica una agrupaci��n de almacenamiento de volumen l��gico. Seleccione la
ubicaci��n al dispositivo en <uicontrol>V��a de acceso de
dispositivo</uicontrol>.</dd>
-</dlentry><dlentry>
-<dt><uicontrol>Canal de fibra de SCSI</uicontrol></dt>
-<dd>Especifica una agrupaci��n basada en un Canal de fibra SCSI. Seleccione qu��
adaptador SCSI se utilizar��.</dd>
-</dlentry></dl></li>
-<li>Pulse <uicontrol>Crear</uicontrol>.</li>
-</ol> </p>
-</csbody>
-</cshelp>
-</cshelp>
-
-
-<!-- ENGL1SH_VERS10N 22336_4 DO NOT REMOVE OR CHANGE THIS LINE -->
-<!-- T9N_SRC_ID 233 -->
-<!-- T9N_SH1P_STR1NG KV211AAP001 1 -->
diff --git a/plugins/kimchi/ui/pages/help/es_ES/templates.dita
b/plugins/kimchi/ui/pages/help/es_ES/templates.dita
deleted file mode 100644
index 8cceee7..0000000
--- a/plugins/kimchi/ui/pages/help/es_ES/templates.dita
+++ /dev/null
@@ -1,111 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--Arbortext, Inc., 1988-2011, v.4002-->
-<!DOCTYPE cshelp PUBLIC "-//IBM//DTD DITA CSHelp//EN"
- "..\dtd\cshelp.dtd">
-
-
-<!--This DITA specialized document type is not supported by the Authoring Tools
development team.
-For support please see:
-https://w3.opensource.ibm.com/projects/dita-cshelp/-->
-<cshelp id="kimhtempl" xml:lang="es-es">
-<title>Plantillas</title>
-<shortdesc>La p��gina <wintitle>Plantillas</wintitle> muestra las
plantillas de m��quina virtual definidas que se pueden utilizar para crear invitados
KVM.</shortdesc>
-<csbody>
-<p>Se visualiza la siguiente informaci��n para cada plantilla:<dl>
-<dlentry>
-<dt>SO</dt>
-<dd>Nombre del sistema operativo o distribuci��n.</dd>
-</dlentry><dlentry>
-<dt>Versi��n</dt>
-<dd>Versi��n del sistema operativo o distribuci��n.</dd>
-</dlentry><dlentry>
-<dt>CPUs</dt>
-<dd>N��mero de procesadores que est��n definidos para la plantilla.</dd>
-</dlentry><dlentry>
-<dt>Memoria</dt>
-<dd>Cantidad de memoria de acceso aleatorio a asignar, en MB.</dd>
-</dlentry></dl></p>
-<p>Se pueden seleccionar las siguientes acciones para cada plantilla:<ul>
-<li>Seleccione <uicontrol>Editar</uicontrol> para editar la
plantilla.</li>
-<li>Seleccione <uicontrol>Suprimir</uicontrol> para suprimir la
plantilla.</li>
-</ul>Para a��adir una plantilla, pulse en el icono <uicontrol>m��s
(+)</uicontrol> en la esquina superior derecha de la pantalla.</p>
-</csbody>
-<cshelp id="kimhedittempl" xml:lang="es-es">
-<title>Editar plantilla</title>
-<shortdesc>Editar una plantilla existente.</shortdesc>
-<csbody>
-<p>Se visualiza la siguiente informaci��n para cada plantilla: <dl>
-<dlentry>
-<dt>Nombre</dt>
-<dd>Nombre de la plantilla.</dd>
-</dlentry><dlentry>
-<dt>Proveedor</dt>
-<dd>El nombre de la empresa que cre�� el sistema operativo o distribuci��n que la
plantilla est�� configurada para utilizar.</dd>
-</dlentry><dlentry>
-<dt>Versi��n</dt>
-<dd>La versi��n del sistema operativo o distribuci��n que la plantilla est��
configurada para utilizar.</dd>
-</dlentry><dlentry>
-<dt>N��mero de CPU</dt>
-<dd>N��mero de procesadores que est��n definidos para la plantilla.</dd>
-</dlentry><dlentry>
-<dt>Memoria</dt>
-<dd>Cantidad de memoria en MB a asignar a la m��quina virtual.</dd>
-</dlentry><dlentry>
-<dt>Disco</dt>
-<dd>Tama��o de disco en GB.</dd>
-</dlentry><dlentry>
-<dt>CDROM</dt>
-<dd>V��a de acceso de archivo a la ubicaci��n del archivo ISO utilizado para
instalar el invitado KVM.</dd>
-</dlentry><dlentry>
-<dt>Agrupaci��n de almacenamiento</dt>
-<dd>Agrupaci��n de almacenamiento espec��fica o la agrupaci��n de almacenamiento
predeterminada.</dd>
-</dlentry><dlentry>
-<dt>Red</dt>
-<dd>Interfaces de red predeterminadas disponibles para el invitado KVM. Puede
seleccionar varias redes.</dd>
-</dlentry></dl> Los campos que no est��n inhabilitados pueden editarse.
Despu��s de editar un campo, pulse <uicontrol>Guardar</uicontrol>. </p>
-</csbody>
-</cshelp>
-<cshelp id="kimhaddtempl">
-<title>A��adir plantilla</title>
-<shortdesc>A��adir una plantilla desde el soporte de origen. Puede a��adir su
propia imagen ISO a la agrupaci��n de almacenamiento 'ISO' para el siguiente
descubrimiento.</shortdesc>
-<csbody>
-<p>Seleccione la ubicaci��n del soporte de origen entre una de las opciones
siguientes:<dl>
-<dlentry>
-<dt>Imagen ISO local</dt>
-<dd>Seleccione esta opci��n para explorar las agrupaciones de almacenamiento en
busca de im��genes ISO de instalaci��n disponibles en el sistema.</dd>
-</dlentry><dlentry>
-<dt>Imagen ISO remota</dt>
-<dd>Seleccione esta opci��n para especificar una ubicaci��n remota para una imagen
ISO de instalaci��n.</dd>
-</dlentry></dl></p>
-</csbody>
-</cshelp>
-<cshelp id="kimhaddloct">
-<title>A��adir plantilla ��� imagen ISO local</title>
-<shortdesc>A��adir una plantilla desde una imagen ISO local.</shortdesc>
-<csbody>
-<p>Se visualizan las im��genes ISO disponibles en el
sistema.<dl><dlentry>
-<dt>SO</dt>
-<dd>Nombre del sistema operativo o distribuci��n.</dd>
-</dlentry><dlentry>
-<dt>Versi��n</dt>
-<dd>Versi��n del sistema operativo o distribuci��n.</dd>
-</dlentry><dlentry>
-<dt>Tama��o</dt>
-<dd>Tama��o de la imagen ISO.</dd>
-</dlentry></dl></p>
-<p>Para crear una plantilla a partir de una imagen ISO, elija entre las opciones
siguientes:<ul>
-<li>Seleccione una imagen ISO desde la que desea crear una plantilla y, a
continuaci��n, pulse <uicontrol>Crear plantillas desde ISO
seleccionada</uicontrol>.</li>
-<li>Seleccione <uicontrol>Todo</uicontrol> para crear una plantilla
desde cada imagen ISO en la lista y, a continuaci��n, pulse <uicontrol>Crear
plantillas desde ISO seleccionada</uicontrol>.</li>
-<li>Si la imagen ISO que desea utilizar no aparece en los resultados de la
exploraci��n, puede seleccionar entre las opciones siguientes:<ul>
-<li>Seleccione <uicontrol>Deseo utilizar un archivo ISO
espec��fico</uicontrol> para especificar una v��a de acceso a la imagen
ISO.</li>
-<li>Pulse <uicontrol>Buscar m��s ISO</uicontrol> para buscar m��s
im��genes ISO.</li>
-</ul></li>
-</ul></p>
-</csbody>
-</cshelp>
-</cshelp>
-
-
-<!-- ENGL1SH_VERS10N 61085_5 DO NOT REMOVE OR CHANGE THIS LINE -->
-<!-- T9N_SRC_ID 229 -->
-<!-- T9N_SH1P_STR1NG KV211AAP001 1 -->
diff --git a/plugins/kimchi/ui/pages/help/fr_FR/Makefile.am
b/plugins/kimchi/ui/pages/help/fr_FR/Makefile.am
deleted file mode 100644
index 11ce394..0000000
--- a/plugins/kimchi/ui/pages/help/fr_FR/Makefile.am
+++ /dev/null
@@ -1,23 +0,0 @@
-# Copyright IBM Corp, 2014
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-
-fr_FR_helpdir = $(datadir)/wok/plugins/kimchi/ui/pages/help/fr_FR
-
-dist_fr_FR_help_DATA = $(wildcard *.html) $(NULL)
-
-EXTRA_DIST = $(wildcard *.dita)
-
-CLEANFILES = $(wildcard *.html)
diff --git a/plugins/kimchi/ui/pages/help/fr_FR/guests.dita
b/plugins/kimchi/ui/pages/help/fr_FR/guests.dita
deleted file mode 100644
index ad5b4e4..0000000
--- a/plugins/kimchi/ui/pages/help/fr_FR/guests.dita
+++ /dev/null
@@ -1,130 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--Arbortext, Inc., 1988-2011, v.4002-->
-<!DOCTYPE cshelp PUBLIC "-//IBM//DTD DITA CSHelp//EN"
- "..\dtd\cshelp.dtd">
-
-
-<!--This DITA specialized document type is not supported by the Authoring Tools
development team.
-For support please see:
-https://w3.opensource.ibm.com/projects/dita-cshelp/-->
-<cshelp id="kimhvirtm" xml:lang="fr-fr">
-<title>Invit��s</title>
-<shortdesc>La page <wintitle>Invit��s</wintitle> r��pertorie les
machines virtuelles KVM d��finies.</shortdesc>
-<csbody>
-<p>Pour chaque invit��, les informations suivantes sont affich��es
:<dl><dlentry>
-<dt>Nom</dt>
-<dd>Nom de la machine virtuelle.</dd>
-</dlentry><dlentry>
-<dt>UC</dt>
-<dd>Pourcentage d'utilisation du processeur sur la machine
virtuelle.</dd>
-</dlentry><dlentry>
-<dt>E-S r��seau</dt>
-<dd>Vitesse de transmission d'entr��e-sortie du r��seau, exprim��e en ko par
seconde.</dd>
-</dlentry><dlentry>
-<dt>E-S disque</dt>
-<dd>Vitesse de transmission d'entr��e-sortie du disque, exprim��e en ko par
seconde.</dd>
-</dlentry><dlentry>
-<dt>Livetile</dt>
-<dd>Etat de la console du syst��me d'exploitation de l'h��te, ou
-ic��ne repr��sentant la distribution <tm tmtype="tm"
trademark="Linux">Linux</tm>
-si l'invit�� n'est pas actif.</dd>
-</dlentry></dl></p>
-<p>Les ic��nes d'action suivantes sont affich��es pour chaque invit��
:<dl>
-<dlentry>
-<dt>R��initialiser</dt>
-<dd>Cliquez pour r��initialiser l'invit��. </dd>
-</dlentry><dlentry>
-<dt>Alimentation (D��marrer ou Arr��ter)</dt>
-<dd>Cliquez pour mettre sous ou hors tension l'invit��. Si l'ic��ne est
rouge,
-l'alimentation est d��marr��e ; si l'ic��ne est verte, l'alimentation est
arr��t��e.</dd>
-</dlentry></dl> </p>
-<p>Les actions suivantes peuvent ��tre s��lectionn��es pour chaque invit��
:<ul>
-<li>S��lectionnez <uicontrol>Connexion</uicontrol> pour vous connecter
�� la console
-distante du syst��me d'exploitation invit��.</li>
-<li>S��lectionnez <uicontrol>G��rer le support</uicontrol> pour
modifier le chemin
-d'acc��s au support d'installation.</li>
-<li>S��lectionnez <uicontrol>R��initialiser</uicontrol> pour
r��initialiser l'invit��.</li>
-<li>S��lectionnez <uicontrol>Editer</uicontrol> pour ��diter les
propri��t��s d'un invit�� existant. Les invit��s peuvent ��tre ��dit��s uniquement
lorsqu'ils sont �� l'arr��t.</li>
-<li>S��lectionnez <uicontrol>Supprimer</uicontrol> pour supprimer
l'invit��.</li>
-</ul>Pour cr��er un invit��, cliquez sur l'ic��ne <uicontrol>plus
(+)</uicontrol>
-dans le coin sup��rieur droit de la page.</p>
-</csbody>
-<cshelp id="kimhvirtmcrt" xml:lang="fr-fr">
-<title>Cr��er une machine virtuelle</title>
-<shortdesc>Cr��ez une machine virtuelle en utilisant un mod��le
existant.</shortdesc>
-<csbody>
-<p> <ol>
-<li>Entrez le nom �� utiliser pour identifier la machine virtuelle.</li>
-<li rev="rev1">S��lectionnez un mod��le. <ul>
-<li>Si des mod��les existent, faites un choix parmi les mod��les
affich��s.</li>
-<li>Si aucun mod��le n'existe, cliquez sur <uicontrol>Cr��er un
mod��le</uicontrol> pour cr��er un mod��le.</li>
-</ul></li>
-<li>Cliquez sur <uicontrol>Cr��er</uicontrol>.</li>
-</ol> </p>
-</csbody>
-</cshelp>
-<cshelp id="kimhvirtmedit" xml:lang="fr-fr">
-<title>Editer l'invit��</title>
-<shortdesc>Editez les propri��t��s d'une machine virtuelle existante. Certaines
propri��t��s
-peuvent ��tre ��dit��es uniquement lorsque l'invit�� est arr��t��. D'autres
seront appliqu��es �� l'amor��age suivant.</shortdesc>
-<csprolog><csmetadata></csmetadata></csprolog>
-<csbody>
-<p>Pour chaque invit��, les informations suivantes sont affich��es dans
l'onglet <wintitle>G��n��ral</wintitle> :<dl>
-<dlentry>
-<dt>Nom</dt>
-<dd>Nom de la machine virtuelle. (Ne peut ��tre ��dit�� que lorsque l'invit��
est arr��t��)</dd>
-</dlentry><dlentry>
-<dt>UC</dt>
-<dd>Nombre de processeurs. (Si l'invit�� est en cours d'ex��cution, la
nouvelle quantit�� sera appliqu��e �� l'amor��age suivant)</dd>
-</dlentry><dlentry>
-<dt>M��moire</dt>
-<dd>Quantit�� de m��moire en Mo. (Si l'invit�� est en cours d'ex��cution,
la nouvelle quantit�� sera appliqu��e �� l'amor��age suivant)</dd>
-</dlentry><dlentry>
-<dt>Ic��ne</dt>
-<dd>Image graphique repr��sentant la distribution Linux �� afficher �� la place
-du statut en cours (Livetile) lorsque l'invit�� n'est pas actif.</dd>
-</dlentry></dl></p>
-<p>Les informations suivantes sont affich��es dans l'onglet
<wintitle>Stockage</wintitle>.</p>
-<dl><dlentry>
-<dt>Stockage</dt>
-<dd>Affiche l'emplacement du fichier ISO utilis�� pour
l'installation.</dd>
-</dlentry></dl>
-<p> Les zones qui ne sont pas d��sactiv��es peuvent ��tre ��dit��es. Apr��s que
vous avez ��dit�� une zone, cliquez sur <uicontrol>Sauvegarder</uicontrol>.
</p>
-</csbody>
-</cshelp>
-<cshelp id="kimstoragedevice" xml:lang="fr-fr">
-<title>Ajoutez, remplacez ou d��tachez une unit�� de stockage</title>
-<shortdesc rev="rev1">Vous pouvez ajouter, remplacer ou d��tacher une
unit�� de stockage
-pour votre machine virtuelle. Seule une unit�� CD-ROM est prise en charge. Pour ��diter
vos unit��s de stockage, proc��dez comme suit :</shortdesc>
-<csbody>
-<ol>
-<li>Dans la fen��tre <wintitle>Editer l'invit��</wintitle>,
s��lectionnez <wintitle>Stockage</wintitle>.</li>
-<li>Pour remplacer une unit�� de stockage, cliquez sur la premi��re ic��ne avec la
<uicontrol>barre oblique (/) orange</uicontrol>. Entrez le chemin d'acc��s
au fichier ISO et cliquez sur <uicontrol>Remplacer</uicontrol>.</li>
-<li>Pour d��tacher une unit�� de stockage, cliquez sur la deuxi��me ic��ne avec le
<uicontrol>tiret (-) rouge</uicontrol>. Confirmer la suppression et cliquez
sur <uicontrol>OK</uicontrol>.</li>
-<li>Pour ajouter une unit�� de stockage, cliquez sur la troisi��me ic��ne avec le
<uicontrol>signe plus (+) vert</uicontrol>. Entrez un nom d'unit�� et un
chemin d'acc��s au fichier ISO puis cliquez sur
<uicontrol>Attacher</uicontrol>.</li>
-</ol>
-</csbody>
-</cshelp>
-<cshelp id="kimreplacemedia" xml:lang="fr-fr">
-<title>Remplacer l'unit�� CD-ROM d'une machine virtuelle</title>
-<shortdesc rev="rev1">Vous pouvez remplacer le contenu du CD-ROM pour
-une machine virtuelle une fois l'installation termin��e.</shortdesc>
-<csbody>
-<ol>
-<li>V��rifiez que la machine virtuelle est d��marr��e.</li>
-<li>Dans le menu Actions, s��lectionnez <uicontrol>G��rer le
support</uicontrol>.</li>
-<li>Pour modifier les donn��es actuellement charg��es dans l'unit�� de CD-ROM,
cliquez sur l'ic��ne
-<uicontrol>barre oblique (/) orange</uicontrol> en regard de la zone
hdc.</li>
-<li>Sur la page <wintitle>Remplacer une unit�� CD-ROM d'une machine
virtuelle</wintitle>,
-entrez le chemin d'acc��s au fichier ISO. Les deux autres zones sont en lecture
seule.</li>
-<li>Cliquez sur <uicontrol>Remplacer</uicontrol>.</li>
-</ol>
-</csbody>
-</cshelp>
-<?tm 1391540919 3?>
-</cshelp>
-
-
-<!-- ENGL1SH_VERS10N 45645_6 DO NOT REMOVE OR CHANGE THIS LINE -->
-<!-- T9N_SRC_ID 231 -->
-<!-- T9N_SH1P_STR1NG KV211AAP001 1 -->
diff --git a/plugins/kimchi/ui/pages/help/fr_FR/host.dita
b/plugins/kimchi/ui/pages/help/fr_FR/host.dita
deleted file mode 100644
index f4c330b..0000000
--- a/plugins/kimchi/ui/pages/help/fr_FR/host.dita
+++ /dev/null
@@ -1,68 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--Arbortext, Inc., 1988-2011, v.4002-->
-<!DOCTYPE cshelp PUBLIC "-//IBM//DTD DITA CSHelp//EN"
- "..\dtd\cshelp.dtd">
-
-
-<!--This DITA specialized document type is not supported by the Authoring Tools
development team.
-For support please see:
-https://w3.opensource.ibm.com/projects/dita-cshelp/-->
-<cshelp id="kimhhost" xml:lang="fr-fr">
-<title>H��te</title>
-<shortdesc>La page <wintitle>H��te</wintitle> affiche des informations
-sur le syst��me h��te et vous permet d'arr��ter, de red��marrer et de vous
-connecter �� l'h��te.</shortdesc>
-<csbody>
-<p>Vous pouvez effectuer les actions suivantes sur l'h��te :<ul>
-<li>S��lectionnez <uicontrol>Arr��ter</uicontrol> pour arr��ter le
syst��me h��te.</li>
-<li>S��lectionnez <uicontrol>Red��marrer</uicontrol> pour red��marrer
le syst��me h��te.</li>
-<li>S��lectionnez <uicontrol>Connexion</uicontrol> pour ouvrir une
connexion VNC
-au syst��me h��te, si celui-ci n'est pas d��j�� connect��.</li>
-</ul></p>
-<p>Cliquez sur les sections suivantes pour afficher des informations sur
l'h��te :<dl>
-<dlentry>
-<dt>Informations de base</dt>
-<dd>Cette section affiche la distribution, la version et le nom de code
-du syst��me d'exploitation h��te, ainsi que le type de processeur et la quantit��
-de m��moire en Go.</dd>
-</dlentry><dlentry>
-<dt>Statistiques syst��me</dt>
-<dd>Cette section affiche les graphiques des statistiques pour l'UC, m��moire,
ainsi que
-les E-S disque et E-S r��seau pour l'h��te. S��lectionnez <uicontrol>Collecte
des donn��es une fois la page quitt��e</uicontrol>
-pour continuer la collecte de donn��es lorsque l'onglet h��te n'est plus
visible.</dd>
-</dlentry><dlentry>
-<dt>Mises �� jour logicielles</dt>
-<dd>Cette section affiche des informations pour tous les modules qui
-disposent de mises �� jour disponibles, y compris le nom de module, la version,
l'architecture
-et le r��f��rentiel. Vous pouvez mettre �� jour toutes les modules r��pertori��s en
s��lectionnant <uicontrol>Tout
-mettre �� jour</uicontrol>. Vous ne pouvez pas s��lectionner des modules
individuels pour les mises �� jour.</dd>
-</dlentry><dlentry>
-<dt>R��f��rentiels</dt>
-<dd>Cette section affiche les r��f��rentiels associ��s au syst��me h��te. Vous
pouvez ajouter, activer, ��diter ou retirer des r��f��rentiels. L'ajout d'un
r��f��rentiel associe celui-ci au syst��me h��te,
-tandis que l'activation d'un r��f��rentiel permet �� l'h��te d'y
acc��der. Si votre syst��me est Red Hat Enterprise Linux ou Fedora,
-vous pouvez ajouter des r��f��rentiels <filepath>yum</filepath>.
-Si votre syst��me est de type Ubuntu ou Debian, ajoutez des r��f��rentiels
-<filepath>deb</filepath>.<p>Si vous travaillez avec des r��f��rentiels
yum, vous pouvez ajouter un contr��le GPG
-afin de v��rifier qu'un module provenant de ce r��f��rentiel n'a pas ��t��
endommag��.
-S��lectionnez un r��f��rentiel puis cliquez sur
<uicontrol>Editer</uicontrol>. S��lectionnez
<uicontrol>Oui</uicontrol> pour activer le contr��le GPG,
-puis entrez une URL pour le fichier de cl��s GPG du r��f��rentiel.</p></dd>
-</dlentry><dlentry>
-<dt>Rapports de d��bogage</dt>
-<dd>Cette section affiche les rapports de d��bogage, y compris le nom et le chemin
du fichier.
-Vous pouvez faire un choix parmi les options afin de g��n��rer un nouveau rapport, ou
renommer, supprimer,
-ou t��l��charger un rapport existant.<p>Le rapport de d��bogage est g��n��r�� ��
-l'aide de la commande <cmdname>sosreport</cmdname>. Cette option est
disponible pour les distributions
-Red Hat Enterprise <tm tmtype="tm"
trademark="Linux">Linux</tm>, Fedora et Ubuntu. La commande g��n��re un
fichier .tar contenant la configuration et des informations de diagnostic,
-telles que la version du noyau d'ex��cution, les modules charg��s, ainsi que les
fichiers de configuration
-du syst��me et de la maintenance.
-La commande ex��cute ��galement des programmes externes pour collecter des informations
-suppl��mentaires et stocke cette sortie dans l'archive r��sultante.</p>
</dd>
-</dlentry></dl></p>
-</csbody>
-<?tm 1392659967 1?>
-</cshelp>
-
-
-<!-- ENGL1SH_VERS10N 47930_4 DO NOT REMOVE OR CHANGE THIS LINE -->
-<!-- T9N_SRC_ID 232 -->
-<!-- T9N_SH1P_STR1NG KVM21AAP001 3 -->
diff --git a/plugins/kimchi/ui/pages/help/fr_FR/network.dita
b/plugins/kimchi/ui/pages/help/fr_FR/network.dita
deleted file mode 100644
index 5c2e9dd..0000000
--- a/plugins/kimchi/ui/pages/help/fr_FR/network.dita
+++ /dev/null
@@ -1,67 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--Arbortext, Inc., 1988-2011, v.4002-->
-<!DOCTYPE cshelp PUBLIC "-//IBM//DTD DITA CSHelp//EN"
- "..\dtd\cshelp.dtd">
-
-
-<!--This DITA specialized document type is not supported by the Authoring Tools
development team.
-For support please see:
-https://w3.opensource.ibm.com/projects/dita-cshelp/-->
-<cshelp id="kimhnetw" xml:lang="fr-fr">
-<title>R��seau</title>
-<shortdesc>La page <wintitle>R��seau</wintitle> affiche des
informations sur la connexion r��seau.</shortdesc>
-<csbody>
-<p><dl><dlentry>
-<dt>Nom du r��seau</dt>
-<dd>Nom du r��seau, ou <uicontrol>par d��faut</uicontrol>.</dd>
-</dlentry><dlentry>
-<dt>Etat</dt>
-<dd>Etat du r��seau, actif (vert) ou inactif (rouge). </dd>
-</dlentry><dlentry>
-<dt>Type de r��seau</dt>
-<dd>Type du r��seau, par exemple <uicontrol>NAT</uicontrol> (conversion
d'adresses r��seau).</dd>
-</dlentry><dlentry>
-<dt>Interface</dt>
-<dd>Interface r��seau, par exemple <uicontrol>virbr0</uicontrol> (par
d��faut).</dd>
-</dlentry><dlentry>
-<dt>Espace adresse</dt>
-<dd>Adresse IP.</dd>
-</dlentry></dl></p>
-<p>Les actions suivantes peuvent ��tre s��lectionn��es :<ul>
-<li rev="rev1">S��lectionnez <uicontrol>D��marrer</uicontrol>
pour d��marrer la connexion au r��seau.</li>
-<li>S��lectionnez <uicontrol>Arr��ter</uicontrol> pour mettre fin �� la
connexion au r��seau.</li>
-<li>S��lectionnez <uicontrol>Supprimer</uicontrol> pour supprimer les
informations de connexion.</li>
-</ul>Pour cr��er un r��seau, cliquez sur l'ic��ne <uicontrol>plus
(+)</uicontrol>
-dans le coin sup��rieur droit de l'��cran.</p>
-</csbody>
-<cshelp id="kimhnetwcrt" xml:lang="fr-fr">
-<title>Cr��er un r��seau</title>
-<shortdesc>Cr��ez un r��seau.</shortdesc>
-<csbody>
-<p> <ol>
-<li>Entrez le nom du r��seau.</li>
-<li>Cliquez pour s��lectionner le type de r��seau. <dl
rev="rev1"><dlentry>
-<dt><uicontrol>Isol��</uicontrol></dt>
-<dd>Mode isol��. Les invit��s ne peuvent pas envoyer ni recevoir de communication
avec des syst��mes externes.</dd>
-</dlentry><dlentry>
-<dt><uicontrol>NAT</uicontrol></dt>
-<dd>Mode de conversion d'adresses r��seau. La communication �� partir
d'invit��s
-vers des syst��mes externes utilise l'adresse IP h��te. Les syst��mes externes ne
-peuvent pas initier de communication vers les invit��s.</dd>
-</dlentry><dlentry>
-<dt><uicontrol>Rout��</uicontrol></dt>
-<dd>Mode rout��. Les invit��s peuvent communiquer avec des syst��mes externes et
-��tre contact��s par des syst��mes externes comme s'il s'agissait de syst��mes
physiques
-sur le r��seau. Pour le mode rout��, vous devez sp��cifier des informations
suppl��mentaires
-sur la destination et le r��seau local virtuel.</dd>
-</dlentry></dl></li>
-<li>Cliquez sur <uicontrol>Cr��er</uicontrol>.</li>
-</ol> </p>
-</csbody>
-</cshelp>
-</cshelp>
-
-
-<!-- ENGL1SH_VERS10N 47050_3 DO NOT REMOVE OR CHANGE THIS LINE -->
-<!-- T9N_SRC_ID 230 -->
-<!-- T9N_SH1P_STR1NG KVM21AAP001 3 -->
diff --git a/plugins/kimchi/ui/pages/help/fr_FR/storage.dita
b/plugins/kimchi/ui/pages/help/fr_FR/storage.dita
deleted file mode 100644
index eebf2bb..0000000
--- a/plugins/kimchi/ui/pages/help/fr_FR/storage.dita
+++ /dev/null
@@ -1,93 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--Arbortext, Inc., 1988-2011, v.4002-->
-<!DOCTYPE cshelp PUBLIC "-//IBM//DTD DITA CSHelp//EN"
- "..\dtd\cshelp.dtd">
-
-
-<!--This DITA specialized document type is not supported by the Authoring Tools
development team.
-For support please see:
-https://w3.opensource.ibm.com/projects/dita-cshelp/-->
-<cshelp id="kimhstor" xml:lang="fr-fr">
-<title>Stockage</title>
-<shortdesc>La page <wintitle>Stockage</wintitle> r��pertorie les pools
de stockage disponibles,
-y compris les pools de stockage 'default' et 'ISO' pr��ts ��
l'emploi.
-Si vous souhaitez utiliser votre propre pool de stockage ISO, ajoutez-le dans le chemin
du pool de stockage 'ISO'.</shortdesc>
-<csbody>
-<p>Pour chaque pool de stockage, les informations suivantes sont affich��es
:<dl>
-<dlentry>
-<dt>Nom</dt>
-<dd>Nom du pool de stockage et pourcentage d'utilisation.</dd>
-</dlentry><dlentry>
-<dt>Etat</dt>
-<dd>Etat du pool de stockage, actif (vert) ou inactif (rouge). </dd>
-</dlentry><dlentry>
-<dt>Emplacement</dt>
-<dd>chemin d'acc��s au fichier pour l'emplacement du pool de
stockage.</dd>
-</dlentry><dlentry>
-<dt>Type</dt>
-<dd>Type de pool de stockage, par exemple
<uicontrol>dir</uicontrol>.</dd>
-</dlentry><dlentry>
-<dt>Capacit��</dt>
-<dd>Quantit�� d'espace dans le pool de stockage.</dd>
-</dlentry><dlentry>
-<dt>Allou��</dt>
-<dd>Quantit�� d'espace d��j�� allou��e dans le pool de stockage.</dd>
-</dlentry></dl></p>
-<p>Les actions suivantes peuvent ��tre s��lectionn��es pour chaque pool de
stockage :<ul>
-<li>S��lectionnez <uicontrol>Activer</uicontrol> pour activer le pool
de stockage pour utilisation.</li>
-<li>S��lectionnez <uicontrol>D��sactiver</uicontrol> pour d��sactiver
un pool de stockage actif.</li>
-<li>S��lectionnez <uicontrol>Annuler d��finition</uicontrol> pour
retirer un pool de stockage inactif.</li>
-</ul></p>
-<p>Pour afficher les d��tails de volume de stockage pour un pool de stockage,
cliquez sur la
-fl��che situ��e �� droite de la ligne du pool de stockage. D��tails inclus
:<dl><dlentry>
-<dt>Type</dt>
-<dd>Type de volume, par exemple
<uicontrol>file</uicontrol>.</dd>
-</dlentry><dlentry>
-<dt>Format</dt>
-<dd>Format, variable selon le type.</dd>
-</dlentry><dlentry>
-<dt>Capacit��</dt>
-<dd>Taille du volume de stockage.</dd>
-</dlentry><dlentry>
-<dt>Allocation</dt>
-<dd>Quantit�� d'espace d��j�� allou��e dans le pool de stockage.</dd>
-</dlentry></dl>Pour d��finir un pool de stockage, cliquez sur l'ic��ne
<uicontrol>plus (+)</uicontrol>
-dans le coin sup��rieur droit de l'��cran.</p>
-</csbody>
-<cshelp id="kimhdefstor" xml:lang="fr-fr">
-<title>D��finir un pool de stockage</title>
-<shortdesc> D��finissez un pool de stockage.</shortdesc>
-<csbody>
-<p> <ol>
-<li>Dans la zone <uicontrol>Nom du pool de stockage</uicontrol>, entrez
le nom �� utiliser pour identifier le pool de stockage.</li>
-<li>Dans la zone <uicontrol>Type de pool de stockage</uicontrol>,
s��lectionnez le type : <dl><dlentry>
-<dt><uicontrol>DIR</uicontrol></dt>
-<dd>Indique un pool de r��pertoires. Lorsque vous s��lectionnez
<uicontrol>DIR</uicontrol>,
-indiquez le <uicontrol>Chemin de stockage</uicontrol> (chemin d'acc��s au
fichier
-du pool de stockage).</dd>
-</dlentry><dlentry>
-<dt><uicontrol>NFS</uicontrol></dt>
-<dd>indique un pool de syst��mes de fichiers r��seau. Lorsque vous s��lectionnez
<uicontrol>NFS</uicontrol>,
-indiquez l'adresse <uicontrol>IP du serveur NFS</uicontrol> et le
<uicontrol>Chemin NFS</uicontrol> (chemin d'acc��s au r��pertoire
d'exportation).</dd>
-</dlentry><dlentry>
-<dt><uicontrol>iSCSI</uicontrol></dt>
-<dd>Indique un pool bas�� sur une cible allou��e sur un serveur iSCSI.
-Lorsque vous s��lectionnez <uicontrol>iSCSI</uicontrol>, indiquez
l'adresse IP du <uicontrol>Serveur iSCSI</uicontrol>
-et la <uicontrol>Cible</uicontrol> sur le serveur iSCSI. Vous avez la
possibilit�� d'ajouter l'authentification iSCSI.</dd>
-</dlentry><dlentry>
-<dt><uicontrol>Logique</uicontrol></dt>
-<dd>Indique un pool de stockage de volumes logiques. S��lectionnez
l'emplacement de l'unit�� dans <uicontrol>Chemin
d'unit��</uicontrol>.</dd>
-</dlentry><dlentry>
-<dt><uicontrol>Fibre Channel SCSI</uicontrol></dt>
-<dd>Indique un pool bas��e sur une connexion Fibre Channel SCSI. S��lectionnez
l'adaptateur SCSI �� utiliser.</dd>
-</dlentry></dl></li>
-<li>Cliquez sur <uicontrol>Cr��er</uicontrol>.</li>
-</ol> </p>
-</csbody>
-</cshelp>
-</cshelp>
-
-
-<!-- ENGL1SH_VERS10N 22336_4 DO NOT REMOVE OR CHANGE THIS LINE -->
-<!-- T9N_SRC_ID 233 -->
-<!-- T9N_SH1P_STR1NG KV211AAP001 1 -->
diff --git a/plugins/kimchi/ui/pages/help/fr_FR/templates.dita
b/plugins/kimchi/ui/pages/help/fr_FR/templates.dita
deleted file mode 100644
index a517e33..0000000
--- a/plugins/kimchi/ui/pages/help/fr_FR/templates.dita
+++ /dev/null
@@ -1,120 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--Arbortext, Inc., 1988-2011, v.4002-->
-<!DOCTYPE cshelp PUBLIC "-//IBM//DTD DITA CSHelp//EN"
- "..\dtd\cshelp.dtd">
-
-
-<!--This DITA specialized document type is not supported by the Authoring Tools
development team.
-For support please see:
-https://w3.opensource.ibm.com/projects/dita-cshelp/-->
-<cshelp id="kimhtempl" xml:lang="fr-fr">
-<title>Mod��les</title>
-<shortdesc>La page <wintitle>Mod��les</wintitle> affiche les mod��les
de machine virtuelle d��finis
-pouvant ��tre utilis��s pour cr��er des h��tes KVM.</shortdesc>
-<csbody>
-<p>Pour chaque mod��le, les informations suivantes sont affich��es :<dl>
-<dlentry>
-<dt>SE</dt>
-<dd>Nom du syst��me d'exploitation ou de la distribution.</dd>
-</dlentry><dlentry>
-<dt>Version</dt>
-<dd>Version du syst��me d'exploitation ou de la distribution.</dd>
-</dlentry><dlentry>
-<dt>UC</dt>
-<dd>Nombre de processeurs d��finis pour le mod��le.</dd>
-</dlentry><dlentry>
-<dt>M��moire</dt>
-<dd>Quantit�� de m��moire vive �� allouer, en Mo.</dd>
-</dlentry></dl></p>
-<p>Les actions suivantes peuvent ��tre s��lectionn��es pour chaque mod��le
:<ul>
-<li>S��lectionnez <uicontrol>Editer</uicontrol> pour ��diter le
mod��le.</li>
-<li>S��lectionnez <uicontrol>Supprimer</uicontrol> pour supprimer le
mod��le.</li>
-</ul>Pour ajouter un mod��le, cliquez sur l'ic��ne <uicontrol>plus
(+)</uicontrol>
-dans le coin sup��rieur droit de l'��cran.</p>
-</csbody>
-<cshelp id="kimhedittempl" xml:lang="fr-fr">
-<title>Editer un mod��le</title>
-<shortdesc>Editez un mod��le existant.</shortdesc>
-<csbody>
-<p>Pour chaque mod��le, les informations suivantes sont affich��es : <dl>
-<dlentry>
-<dt>Nom</dt>
-<dd>Nom du mod��le.</dd>
-</dlentry><dlentry>
-<dt>Fournisseur</dt>
-<dd>Nom de la soci��t�� qui a cr���� le syst��me d'exploitation ou la
distribution
-pour lequel/laquelle le mod��le est configur��.</dd>
-</dlentry><dlentry>
-<dt>Version</dt>
-<dd>Version du syst��me d'exploitation ou de la distribution
-pour lequel/laquelle le mod��le est configur��.</dd>
-</dlentry><dlentry>
-<dt>Nombre d'UC</dt>
-<dd>Nombre de processeurs d��finis pour le mod��le.</dd>
-</dlentry><dlentry>
-<dt>M��moire</dt>
-<dd>Quantit�� de m��moire en Mo �� allouer �� la machine virtuelle.</dd>
-</dlentry><dlentry>
-<dt>Disque</dt>
-<dd>Taille du disque en Go.</dd>
-</dlentry><dlentry>
-<dt>CD-ROM</dt>
-<dd>chemin d'acc��s au fichier pour l'emplacement du fichier ISO utilis��
pour l'installation de l'invit�� KVM.</dd>
-</dlentry><dlentry>
-<dt>Pool de stockage</dt>
-<dd>Pool de stockage sp��cifique ou pool de stockage par d��faut.</dd>
-</dlentry><dlentry>
-<dt>R��seau</dt>
-<dd>Interfaces r��seau par d��faut disponibles pour l'invit�� KVM. Vous pouvez
-s��lectionner plusieurs r��seaux.</dd>
-</dlentry></dl> Les zones qui ne sont pas d��sactiv��es peuvent ��tre
��dit��es. Apr��s que vous avez ��dit�� une zone, cliquez sur
<uicontrol>Sauvegarder</uicontrol>. </p>
-</csbody>
-</cshelp>
-<cshelp id="kimhaddtempl">
-<title>Ajouter un mod��le</title>
-<shortdesc>Ajoutez un mod��le �� partir du support source.
-Vous pouvez ajouter votre propre image ISO au pool de stockage 'ISO' pour la
reconnaissance suivante.</shortdesc>
-<csbody>
-<p>S��lectionnez l'emplacement du support source �� partir des options
suivantes :<dl>
-<dlentry>
-<dt>Image ISO locale</dt>
-<dd>S��lectionnez cette option pour rechercher dans les pools de stockage
l'image d'installation ISO disponible sur le syst��me.</dd>
-</dlentry><dlentry>
-<dt>Image ISO distante</dt>
-<dd>S��lectionnez cette option pour indiquer un emplacement distant pour une image
d'installation ISO.</dd>
-</dlentry></dl></p>
-</csbody>
-</cshelp>
-<cshelp id="kimhaddloct">
-<title>Ajouter un mod��le - Image ISO locale</title>
-<shortdesc>Ajoutez un mod��le �� partir d'une image ISO
locale.</shortdesc>
-<csbody>
-<p>Les images ISO disponibles sur le syst��me sont
affich��es.<dl><dlentry>
-<dt>SE</dt>
-<dd>Nom du syst��me d'exploitation ou de la distribution.</dd>
-</dlentry><dlentry>
-<dt>Version</dt>
-<dd>Version du syst��me d'exploitation ou de la distribution.</dd>
-</dlentry><dlentry>
-<dt>Taille</dt>
-<dd>Taille de l'image ISO.</dd>
-</dlentry></dl></p>
-<p>Pour cr��er un mod��le �� partir d'une image ISO, choisissez parmi les
options suivantes :<ul>
-<li>S��lectionnez une image ISO �� partir de laquelle cr��er un mod��le, puis
cliquez sur <uicontrol>Cr��er des mod��les �� partir de l'ISO s��lectionn��
</uicontrol>.</li>
-<li>S��lectionnez <uicontrol>Tout</uicontrol> pour cr��er un mod��le ��
partir de chaque
-image ISO r��pertori��e, puis cliquez sur <uicontrol>Cr��er des mod��les �� partir
de l'ISO s��lectionn��</uicontrol>.</li>
-<li>Si l'image ISO que vous souhaitez utiliser ne figure pas dans les
r��sultats
-d'analyse, vous pouvez faire un choix parmi les options suivantes :<ul>
-<li>S��lectionnez <uicontrol>Je souhaite utiliser un fichier ISO
sp��cifique</uicontrol> pour
-sp��cifier un chemin d'acc��s �� l'image ISO.</li>
-<li>Cliquez sur <uicontrol>Rechercher d'autres images
ISO</uicontrol> pour rechercher des images ISO suppl��mentaires.</li>
-</ul></li>
-</ul></p>
-</csbody>
-</cshelp>
-</cshelp>
-
-
-<!-- ENGL1SH_VERS10N 61085_5 DO NOT REMOVE OR CHANGE THIS LINE -->
-<!-- T9N_SRC_ID 229 -->
-<!-- T9N_SH1P_STR1NG KV211AAP001 1 -->
diff --git a/plugins/kimchi/ui/pages/help/it_IT/Makefile.am
b/plugins/kimchi/ui/pages/help/it_IT/Makefile.am
deleted file mode 100644
index 62e2f29..0000000
--- a/plugins/kimchi/ui/pages/help/it_IT/Makefile.am
+++ /dev/null
@@ -1,23 +0,0 @@
-# Copyright IBM Corp, 2014
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-
-it_IT_helpdir = $(datadir)/wok/plugins/kimchi/ui/pages/help/it_IT
-
-dist_it_IT_help_DATA = $(wildcard *.html) $(NULL)
-
-EXTRA_DIST = $(wildcard *.dita)
-
-CLEANFILES = $(wildcard *.html)
diff --git a/plugins/kimchi/ui/pages/help/it_IT/guests.dita
b/plugins/kimchi/ui/pages/help/it_IT/guests.dita
deleted file mode 100644
index e05db7e..0000000
--- a/plugins/kimchi/ui/pages/help/it_IT/guests.dita
+++ /dev/null
@@ -1,123 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--Arbortext, Inc., 1988-2011, v.4002-->
-<!DOCTYPE cshelp PUBLIC "-//IBM//DTD DITA CSHelp//EN"
- "..\dtd\cshelp.dtd">
-
-
-<!--This DITA specialized document type is not supported by the Authoring Tools
development team.
-For support please see:
-https://w3.opensource.ibm.com/projects/dita-cshelp/-->
-<cshelp id="kimhvirtm" xml:lang="it-it">
-<title>Guest</title>
-<shortdesc>La pagina <wintitle>Guest</wintitle> elenca le macchine
virtuali
-KVM definite.</shortdesc>
-<csbody>
-<p>Per ciascuna macchina guest vengono visualizzate le seguenti
informazioni:<dl><dlentry>
-<dt>Nome</dt>
-<dd>Il nome della macchina virtuale.</dd>
-</dlentry><dlentry>
-<dt>CPU</dt>
-<dd>La percentuale di utilizzo del processore nella macchina virtuale.</dd>
-</dlentry><dlentry>
-<dt>I/O di rete</dt>
-<dd>La velocit�� di trasmissione dell'input/output di rete in KB al
secondo.</dd>
-</dlentry><dlentry>
-<dt>I/O disco</dt>
-<dd>La velocit�� di trasmissione dell'input/output disco in KB al
secondo.</dd>
-</dlentry><dlentry>
-<dt>Riquadro animato</dt>
-<dd>Lo stato della console del sistema operativo della macchina guest o
un'icona che rappresenta la distribuzione <tm tmtype="tm"
trademark="Linux">Linux</tm> se la macchina guest non ��
attiva.</dd>
-</dlentry></dl></p>
-<p>Per ciascuna macchina guest vengono visualizzate le icone di azioni indicate di
seguito:<dl>
-<dlentry>
-<dt>Reimposta</dt>
-<dd>Fare clic qui per reimpostare la macchina guest. </dd>
-</dlentry><dlentry>
-<dt>Alimentazione (Avvia o Arresta)</dt>
-<dd>Fare clic qui per accendere o spegnere la macchina guest. Se l'icona ��
rossa, la macchina �� spenta, se �� verde �� accesa.</dd>
-</dlentry></dl> </p>
-<p>Per ciascuna macchina guest �� possibile selezionare le azioni indicate di
seguito:<ul>
-<li>Selezionare <uicontrol>Connetti</uicontrol> per effettuare la
connessione alla console remota per il sistema operativo della macchina guest.</li>
-<li>Selezionare <uicontrol>Gestisci supporti</uicontrol> per modificare
il percorso al supporto di installazione.</li>
-<li>Selezionare <uicontrol>Reimposta</uicontrol> per reimpostare la
macchina guest.</li>
-<li>Selezionare <uicontrol>Modifica</uicontrol> per modificare le
propriet����di una macchina guest esistente. �� possibile modificare le macchine guest
solo se sono arrestate.</li>
-<li>Selezionare <uicontrol>Elimina</uicontrol> per eliminare la
macchina guest.</li>
-</ul>Per creare una macchina guest, o macchina virtuale, fare clic sull'icona
<uicontrol>pi��
-(+)</uicontrol> nella parte in alto a destra della pagina.</p>
-</csbody>
-<cshelp id="kimhvirtmcrt" xml:lang="it-it">
-<title>Creare una macchina virtuale</title>
-<shortdesc>Creare una macchina virtuale utilizzando un modello
esistente.</shortdesc>
-<csbody>
-<p> <ol>
-<li>Immettere il nome da utilizzare per identificare la macchina
virtuale.</li>
-<li rev="rev1">Selezionare un modello. <ul>
-<li>Se il modello esiste, selezionarlo dai modelli visualizzati.</li>
-<li>Se non esiste alcun modello, fare clic su <uicontrol>Crea un
modello</uicontrol> per crearne uno.</li>
-</ul></li>
-<li>Fare clic su <uicontrol>Crea</uicontrol>.</li>
-</ol> </p>
-</csbody>
-</cshelp>
-<cshelp id="kimhvirtmedit" xml:lang="it-it">
-<title>Modifica macchina guest</title>
-<shortdesc>Modificare le propriet�� di una macchina virtuale esistente. Alcune
propriet�� possono essere
-modificate solo mentre la macchina guest �� arrestata. Altre diventeranno effettive al
prossimo avvio.</shortdesc>
-<csprolog><csmetadata></csmetadata></csprolog>
-<csbody>
-<p>Per ciascuna macchina guest vengono visualizzate le seguenti informazioni sulla
scheda <wintitle>Generale</wintitle>:<dl>
-<dlentry>
-<dt>Nome</dt>
-<dd>Il nome della macchina virtuale. (Pu�� essere modificato solo mentre la
macchina guest �� arrestata)</dd>
-</dlentry><dlentry>
-<dt>CPU</dt>
-<dd>Il numero di processori. (Se la macchina guest �� in esecuzione, la nuova
quantit�� diventer�� effettiva
-al prossimo avvio)</dd>
-</dlentry><dlentry>
-<dt>Memoria</dt>
-<dd>La quantit�� di memoria in MB. (Se la macchina guest �� in esecuzione, la nuova
quantit�� diventer�� effettiva
-al prossimo avvio)</dd>
-</dlentry><dlentry>
-<dt>Icona</dt>
-<dd>L'immagine grafica che rappresenta la distribuzione Linux da visualizzare
al posto dello stato corrente (Riquadro animato) quando la macchina guest non ��
attiva.</dd>
-</dlentry></dl></p>
-<p>Sulla scheda <wintitle>Memoria</wintitle> vengono visualizzate le
seguenti informazioni.</p>
-<dl><dlentry>
-<dt>Memoria</dt>
-<dd>Visualizza l'ubicazione del file ISO utilizzato per
l'installazione.</dd>
-</dlentry></dl>
-<p> I campi non disabilitati possono essere modificati. Dopo aver modificato un
campo, fare clic su <uicontrol>Salva</uicontrol>. </p>
-</csbody>
-</cshelp>
-<cshelp id="kimstoragedevice" xml:lang="it-it">
-<title>Aggiungere, sostituire o scollegare un dispositivo di
memoria.</title>
-<shortdesc rev="rev1">�� possibile aggiungere, sostituire o scollegare un
dispositivo di memoria per la macchina virtuale. L'unico dispositivo supportato ��
CDROM. Per modificare i dispositivi di memoria, attenersi alla seguente
procedura:</shortdesc>
-<csbody>
-<ol>
-<li>Nella finestra <wintitle>Modifica macchina guest</wintitle>,
selezionare <wintitle>Memoria</wintitle>.</li>
-<li>Per sostituire un dispositivo di memoria, fare clic sulla prima icona con la
<uicontrol>barra (/) arancione</uicontrol>. Immettere il percorso del file ISO
e fare clic su <uicontrol>Sostituisci</uicontrol>.</li>
-<li>Per scollegare un dispositivo di memoria, fare clic sulla seconda icona con il
<uicontrol>trattino (-) rosso</uicontrol>. Confermare l'eliminazione
facendo clic su <uicontrol>OK</uicontrol>.</li>
-<li>Per aggiungere un dispositivo di memoria, fare clic sulla terza icona con il
<uicontrol>segno pi�� (+)</uicontrol> verde. Immettere un nome dispositivo e
percorso file ISO e fare clic su <uicontrol>Collega</uicontrol>.</li>
-</ol>
-</csbody>
-</cshelp>
-<cshelp id="kimreplacemedia" xml:lang="it-it">
-<title>Sostituisci un CDROM della macchina virtuale</title>
-<shortdesc rev="rev1">�� possibile sostituire il contenuto del CDROM per
una macchina virtuale dopo il completamento dell'installazione.</shortdesc>
-<csbody>
-<ol>
-<li>Assicurarsi che la macchina virtuale sia avviata.</li>
-<li>Dal menu Azioni, selezionare <uicontrol>Gestisci
supporti</uicontrol>.</li>
-<li>Per modificare il contenuto correntemente caricato sul CDROM, fare clic
sull'icona della <uicontrol>barra (/) arancione</uicontrol> accanto al
campo hdc.</li>
-<li>Sulla pagina <wintitle>Sostituisci un CDROM della macchina
virtuale</wintitle>, immettere il percorso del file ISO. Gli altri due campi sono di
sola lettura.</li>
-<li>Fare clic su <uicontrol>Sostituisci</uicontrol>.</li>
-</ol>
-</csbody>
-</cshelp>
-<?tm 1391540919 3?>
-</cshelp>
-
-
-<!-- ENGL1SH_VERS10N 45645_6 DO NOT REMOVE OR CHANGE THIS LINE -->
-<!-- T9N_SRC_ID 231 -->
-<!-- T9N_SH1P_STR1NG KV211AAP001 1 -->
diff --git a/plugins/kimchi/ui/pages/help/it_IT/host.dita
b/plugins/kimchi/ui/pages/help/it_IT/host.dita
deleted file mode 100644
index 63d3367..0000000
--- a/plugins/kimchi/ui/pages/help/it_IT/host.dita
+++ /dev/null
@@ -1,51 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--Arbortext, Inc., 1988-2011, v.4002-->
-<!DOCTYPE cshelp PUBLIC "-//IBM//DTD DITA CSHelp//EN"
- "..\dtd\cshelp.dtd">
-
-
-<!--This DITA specialized document type is not supported by the Authoring Tools
development team.
-For support please see:
-https://w3.opensource.ibm.com/projects/dita-cshelp/-->
-<cshelp id="kimhhost" xml:lang="it-it">
-<title>Host</title>
-<shortdesc>La pagina <wintitle>Host</wintitle> visualizza le
informazioni sul sistema host e consente di arrestarlo, riavviarlo e connettersi ad
esso.</shortdesc>
-<csbody>
-<p>�� possibile effettuare le seguenti operazioni sull'host:<ul>
-<li>Selezionare <uicontrol>Arresta</uicontrol> per arrestare il sistema
host.</li>
-<li>Selezionare <uicontrol>Riavvia</uicontrol> per riavviare il sistema
host.</li>
-<li>Selezionare <uicontrol>Connetti</uicontrol> per aprire una
connessione VNC al sistema host, se non �� gi�� connesso.</li>
-</ul></p>
-<p>Fare clic sulle seguenti sezioni per visualizzare le informazioni
sull'host:<dl>
-<dlentry>
-<dt>Informazioni di base</dt>
-<dd>Questa sezione visualizza il nome codice, la versione e la distribuzione del
sistema operativo, come pure il tipo di processore e la quantit�� di memoria in
GB.</dd>
-</dlentry><dlentry>
-<dt>Statistiche di sistema</dt>
-<dd>Questa sezione visualizza i grafici che mostrano le statistiche per la CPU, la
memoria, l'I/O disco e di rete per l'host. Selezionare <uicontrol>Raccolta
dati all'uscita dalla pagina</uicontrol> per continuare la raccolta dei dati
quando la scheda host non �� pi�� visibile.</dd>
-</dlentry><dlentry>
-<dt>Aggiornamenti del software</dt>
-<dd>Questa sezione visualizza le informazioni per tutti i pacchetti per cui sono
disponibili gli aggiornamenti, incluso il nome, la versione, l'architettura e il
repository del pacchetto. �� possibile aggiornare tutti i pacchetti elencati, selezionando
<uicontrol>Aggiorna tutto</uicontrol>. Non �� possibile selezionare singoli
pacchetti per gli aggiornamenti.</dd>
-</dlentry><dlentry>
-<dt>Repository</dt>
-<dd>Questa sezione visualizza i repository associati al sistema host. �� possibile
aggiungere, abilitare, modificare o rimuovere i repository. L'aggiunta di un
repository lo associa al sistema host, mentre l'abilitazione di un repository
-consente all'host di accedervi. Se il sistema �� Red Hat Enterprise
-Linux o Fedora, �� possibile aggiungere i repository
<filepath>yum</filepath>.
-Se il sistema �� Ubuntu o Debian, aggiungere i repository
<filepath>deb</filepath>.<p>Se si stanno utilizzando i repository yum,
�� possibile aggiungere un controllo GPG per verificare che un pacchetto da questo
repository non sia stato corrotto.
-Selezionare un repository, quindi <uicontrol>Modifica</uicontrol>.
Selezionare <uicontrol>S��</uicontrol> per abilitare il controllo GPG, quindi
immettere un URL al file di chiavi GPG per il
-repository.</p></dd>
-</dlentry><dlentry>
-<dt>Report di debug</dt>
-<dd>Questa sezione visualizza i report di debug, incluso il nome e il percorso
file.
-Le opzioni disponibili consentono di generare un nuovo report oppure ridenominare,
rimuovere o scaricare un report esistente.<p>Il report di debug viene generato
utilizzando il comando <cmdname>sosreport</cmdname>. �� disponibile per le
distribuzioni Red
-Hat Enterprise <tm tmtype="tm"
trademark="Linux">Linux</tm>, Fedora e Ubuntu. Il comando genera un
file .tar che contiene informazioni di diagnostica e configurazione, come la versione del
kernel in esecuzione, i moduli caricati e i file di configurazione del servizio e del
sistema.
-Il comando esegue anche programmi esterni per raccogliere ulteriori informazioni e
memorizza l'output nell'archivio risultante.</p> </dd>
-</dlentry></dl></p>
-</csbody>
-<?tm 1392659967 1?>
-</cshelp>
-
-
-<!-- ENGL1SH_VERS10N 47930_4 DO NOT REMOVE OR CHANGE THIS LINE -->
-<!-- T9N_SRC_ID 232 -->
-<!-- T9N_SH1P_STR1NG KVM21AAP001 3 -->
diff --git a/plugins/kimchi/ui/pages/help/it_IT/network.dita
b/plugins/kimchi/ui/pages/help/it_IT/network.dita
deleted file mode 100644
index a396d58..0000000
--- a/plugins/kimchi/ui/pages/help/it_IT/network.dita
+++ /dev/null
@@ -1,63 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--Arbortext, Inc., 1988-2011, v.4002-->
-<!DOCTYPE cshelp PUBLIC "-//IBM//DTD DITA CSHelp//EN"
- "..\dtd\cshelp.dtd">
-
-
-<!--This DITA specialized document type is not supported by the Authoring Tools
development team.
-For support please see:
-https://w3.opensource.ibm.com/projects/dita-cshelp/-->
-<cshelp id="kimhnetw" xml:lang="it-it">
-<title>Rete</title>
-<shortdesc>La pagina <wintitle>Rete</wintitle> visualizza le
informazioni sulla connessione di rete.</shortdesc>
-<csbody>
-<p><dl><dlentry>
-<dt>Nome rete</dt>
-<dd>Il nome della rete o il <uicontrol>valore
predefinito</uicontrol>.</dd>
-</dlentry><dlentry>
-<dt>Stato</dt>
-<dd>Lo stato della rete, attivo (verde) o non attivo (rosso). </dd>
-</dlentry><dlentry>
-<dt>Tipo di rete</dt>
-<dd>I tipo di rete, ad esempio, <uicontrol>NAT</uicontrol> (network
-address translation).</dd>
-</dlentry><dlentry>
-<dt>Interfaccia</dt>
-<dd>L'interfaccia di rete, ad esempio,
<uicontrol>virbr0</uicontrol> (valore predefinito).</dd>
-</dlentry><dlentry>
-<dt>Spazio indirizzo</dt>
-<dd>L'indirizzo IP.</dd>
-</dlentry></dl></p>
-<p>�� possibile selezionare le seguenti azioni:<ul>
-<li rev="rev1">Selezionare <uicontrol>Avvia</uicontrol> per
iniziare la connessione di rete.</li>
-<li>Selezionare <uicontrol>Arresta</uicontrol> per terminare la
connessione di rete.</li>
-<li>Selezionare <uicontrol>Elimina</uicontrol> per eliminare le
informazioni di connessione.</li>
-</ul>Per creare una rete fare clic sull'icona <uicontrol>pi��
-(+)</uicontrol> nella parte in alto a destra del pannello.</p>
-</csbody>
-<cshelp id="kimhnetwcrt" xml:lang="it-it">
-<title>Crea una rete</title>
-<shortdesc>Creare una rete.</shortdesc>
-<csbody>
-<p> <ol>
-<li>Immettere il nome della rete.</li>
-<li>Fare clic per selezionare il tipo di rete. <dl
rev="rev1"><dlentry>
-<dt><uicontrol>Isolata</uicontrol></dt>
-<dd>La modalit�� isolata. Le macchine guest non possono inviare o ricevere
comunicazioni verso o da i sistemi esterni.</dd>
-</dlentry><dlentry>
-<dt><uicontrol>NAT</uicontrol></dt>
-<dd>La modalit�� NAT (Network Address Translation). La comunicazione dalle macchine
guest ai sistemi esterni utilizza l'indirizzo IP host. I sistemi esterni non possono
iniziare la comunicazione con le macchine guest.</dd>
-</dlentry><dlentry>
-<dt><uicontrol>Con bridge</uicontrol></dt>
-<dd>La modalit�� con bridge. Le macchine guest possono comunicare con i sistemi
esterni ed essere contattate dai sistemi esterni come se fossero sistemi fisici sulla
rete. Per la modalit�� con bridge, �� necessario specificare informazioni aggiuntive su
destinazione e VLAN.</dd>
-</dlentry></dl></li>
-<li>Fare clic su <uicontrol>Crea</uicontrol>.</li>
-</ol> </p>
-</csbody>
-</cshelp>
-</cshelp>
-
-
-<!-- ENGL1SH_VERS10N 47050_3 DO NOT REMOVE OR CHANGE THIS LINE -->
-<!-- T9N_SRC_ID 230 -->
-<!-- T9N_SH1P_STR1NG KVM21AAP001 3 -->
diff --git a/plugins/kimchi/ui/pages/help/it_IT/storage.dita
b/plugins/kimchi/ui/pages/help/it_IT/storage.dita
deleted file mode 100644
index 5a9bc25..0000000
--- a/plugins/kimchi/ui/pages/help/it_IT/storage.dita
+++ /dev/null
@@ -1,91 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--Arbortext, Inc., 1988-2011, v.4002-->
-<!DOCTYPE cshelp PUBLIC "-//IBM//DTD DITA CSHelp//EN"
- "..\dtd\cshelp.dtd">
-
-
-<!--This DITA specialized document type is not supported by the Authoring Tools
development team.
-For support please see:
-https://w3.opensource.ibm.com/projects/dita-cshelp/-->
-<cshelp id="kimhstor" xml:lang="it-it">
-<title>Memoria</title>
-<shortdesc>La pagina <wintitle>Memoria</wintitle> elenca i pool di
memoria
-disponibili, compresi i pool di memoria pronti per l'uso 'default' e
'ISO'.
-Se si desidera utilizzare un proprio ISO, aggiungerlo al percorso del pool di memoria
'ISO'.</shortdesc>
-<csbody>
-<p>Per ciascun pool di memoria vengono visualizzate le seguenti
informazioni:<dl>
-<dlentry>
-<dt>Nome</dt>
-<dd>Il nome del pool di memoria e la percentuale utilizzata.</dd>
-</dlentry><dlentry>
-<dt>Stato</dt>
-<dd>Lo stato del pool di memoria, attivo (verde) o non attivo (rosso). </dd>
-</dlentry><dlentry>
-<dt>Ubicazione</dt>
-<dd>Il percorso file all'ubicazione del pool di memoria.</dd>
-</dlentry><dlentry>
-<dt>Tipo</dt>
-<dd>Il tipo di pool di memoria, ad esempio,
<uicontrol>dir</uicontrol>.</dd>
-</dlentry><dlentry>
-<dt>Capacit��</dt>
-<dd>La quantit�� di spazio nel pool di memoria.</dd>
-</dlentry><dlentry>
-<dt>Assegnato</dt>
-<dd>La quantit�� di spazio gi�� assegnato nel pool di memoria.</dd>
-</dlentry></dl></p>
-<p>Per ciascun pool di memoria �� possibile selezionare le azioni indicate di
seguito:<ul>
-<li>Selezionare <uicontrol>Attiva</uicontrol> per attivare il pool di
memoria in modo da poterlo utilizzare.</li>
-<li>Selezionare <uicontrol>Disattiva</uicontrol> per disattivare un
pool di memoria attivo.</li>
-<li>Selezionare <uicontrol>Rimuovi definizione</uicontrol> per
rimuovere un pool di memoria non attivo.</li>
-</ul></p>
-<p>Per visualizzare i dettagli del volume di memoria per un pool di memoria, fare
clic sulla freccia sul lato destro della riga del pool di memoria. I dettagli
includono:<dl><dlentry>
-<dt>Tipo</dt>
-<dd>Il tipo di volume, ad esempio,
<uicontrol>file</uicontrol>.</dd>
-</dlentry><dlentry>
-<dt>Formato</dt>
-<dd>Il formato, che varia in base al tipo.</dd>
-</dlentry><dlentry>
-<dt>Capacit��</dt>
-<dd>La dimensione del volume di memoria.</dd>
-</dlentry><dlentry>
-<dt>Assegnazione</dt>
-<dd>La quantit�� di spazio gi�� assegnato nel pool di memoria.</dd>
-</dlentry></dl>Per definire un pool di memoria fare clic sull'icona
<uicontrol>pi��
-(+)</uicontrol> nella parte in alto a destra del pannello.</p>
-</csbody>
-<cshelp id="kimhdefstor" xml:lang="it-it">
-<title>Definire un pool di memoria</title>
-<shortdesc> Definire un pool di memoria.</shortdesc>
-<csbody>
-<p> <ol>
-<li>Nel campo <uicontrol>Nome pool di memoria</uicontrol>, immettere i
l nome da utilizzare per definire il pool di memoria.</li>
-<li>Nell'elenco <uicontrol>Tipo pool di memoria</uicontrol>,
selezionare il tipo: <dl><dlentry>
-<dt><uicontrol>DIR</uicontrol></dt>
-<dd>Specifica un pool directory. Quando si seleziona
<uicontrol>DIR</uicontrol>,
-immettere il <uicontrol>Percorso di memoria</uicontrol> (percorso file al
pool di memoria).</dd>
-</dlentry><dlentry>
-<dt><uicontrol>NFS</uicontrol></dt>
-<dd>Specifica un pool NFS (Network File System). Quando si seleziona
<uicontrol>NFS</uicontrol>,
-immettere l'indirizzo <uicontrol>IP del server NFS</uicontrol> e il
<uicontrol>Percorso NFS</uicontrol> (percorso alla directory
esportata).</dd>
-</dlentry><dlentry>
-<dt><uicontrol>iSCSI</uicontrol></dt>
-<dd>Specifica un pool basato su una destinazione assegnata su un server iSCSI.
-Quando si seleziona <uicontrol>iSCSI</uicontrol>, immettere l'indirizzo
IP del <uicontrol>Server iSCSI</uicontrol> e la
<uicontrol>Destinazione</uicontrol> sul server iSCSI. �� possibile,
facoltativamente, selezionare di aggiungere l'autenticazione iSCSI.</dd>
-</dlentry><dlentry>
-<dt><uicontrol>Logico</uicontrol></dt>
-<dd>Specifica un pool di memoria di tipo volume logico. Selezionare
l'ubicazione del dispositivo in <uicontrol>Percorso
dispositivo</uicontrol>.</dd>
-</dlentry><dlentry>
-<dt><uicontrol>Canale a fibre ottiche SCSI</uicontrol></dt>
-<dd>Specifica un pool basato su un canale a fibre ottiche SCSI. Selezionare quale
adattatore
-SCSI utilizzare.</dd>
-</dlentry></dl></li>
-<li>Fare clic su <uicontrol>Crea</uicontrol>.</li>
-</ol> </p>
-</csbody>
-</cshelp>
-</cshelp>
-
-
-<!-- ENGL1SH_VERS10N 22336_4 DO NOT REMOVE OR CHANGE THIS LINE -->
-<!-- T9N_SRC_ID 233 -->
-<!-- T9N_SH1P_STR1NG KV211AAP001 1 -->
diff --git a/plugins/kimchi/ui/pages/help/it_IT/templates.dita
b/plugins/kimchi/ui/pages/help/it_IT/templates.dita
deleted file mode 100644
index 9b84b16..0000000
--- a/plugins/kimchi/ui/pages/help/it_IT/templates.dita
+++ /dev/null
@@ -1,115 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--Arbortext, Inc., 1988-2011, v.4002-->
-<!DOCTYPE cshelp PUBLIC "-//IBM//DTD DITA CSHelp//EN"
- "..\dtd\cshelp.dtd">
-
-
-<!--This DITA specialized document type is not supported by the Authoring Tools
development team.
-For support please see:
-https://w3.opensource.ibm.com/projects/dita-cshelp/-->
-<cshelp id="kimhtempl" xml:lang="it-it">
-<title>Modelli</title>
-<shortdesc>La pagina <wintitle>Modelli</wintitle> visualizza i modelli
di macchina virtuale definiti che �� possibile utilizzare per creare macchine guest
KVM.</shortdesc>
-<csbody>
-<p>Per ciascun modello vengono visualizzate le seguenti informazioni:<dl>
-<dlentry>
-<dt>SO</dt>
-<dd>Il nome del sistema operativo o della distribuzione.</dd>
-</dlentry><dlentry>
-<dt>Versione</dt>
-<dd>La versione del sistema operativo o della distribuzione.</dd>
-</dlentry><dlentry>
-<dt>CPU</dt>
-<dd>Il numero di processori definiti per il modello.</dd>
-</dlentry><dlentry>
-<dt>Memoria</dt>
-<dd>La quantit�� di memoria ad accesso casuale da assegnare, in MB.</dd>
-</dlentry></dl></p>
-<p>Per ciascun modello �� possibile selezionare le azioni indicate di
seguito:<ul>
-<li>Selezionare <uicontrol>Modifica</uicontrol> per modificare il
modello.</li>
-<li>Selezionare <uicontrol>Elimina</uicontrol> per eliminare il
modello.</li>
-</ul>Per aggiungere un modello fare clic sull'icona <uicontrol>pi��
-(+)</uicontrol> nella parte in alto a destra del pannello.</p>
-</csbody>
-<cshelp id="kimhedittempl" xml:lang="it-it">
-<title>Modifica modello</title>
-<shortdesc>Modificare un modello esistente.</shortdesc>
-<csbody>
-<p>Per ciascun modello vengono visualizzate le seguenti informazioni: <dl>
-<dlentry>
-<dt>Nome</dt>
-<dd>Il nome del modello.</dd>
-</dlentry><dlentry>
-<dt>Fornitore</dt>
-<dd>Il nome della societ�� che ha creato il sistema operativo o la distribuzione
per il cui utilizzo �� configurato il modello.</dd>
-</dlentry><dlentry>
-<dt>Versione</dt>
-<dd>La versione del sistema operativo o della distribuzione per il cui utilizzo ��
configurato il modello.</dd>
-</dlentry><dlentry>
-<dt>Numero CPU</dt>
-<dd>Il numero di processori definiti per il modello.</dd>
-</dlentry><dlentry>
-<dt>Memoria</dt>
-<dd>La quantit�� di memoria in MB da assegnare alla macchina virtuale.</dd>
-</dlentry><dlentry>
-<dt>Disco</dt>
-<dd>La dimensione del disco in GB.</dd>
-</dlentry><dlentry>
-<dt>CDROM</dt>
-<dd>Il percorso file all'ubicazione del file ISO utilizzato per installare la
macchina guest
-KVM.</dd>
-</dlentry><dlentry>
-<dt>Pool di memoria</dt>
-<dd>Un pool di memoria specifico o quello predefinito.</dd>
-</dlentry><dlentry>
-<dt>Rete</dt>
-<dd>Le interfacce di rete predefinite disponibili per la macchina guest KVM. ��
possibile selezionare pi�� reti.</dd>
-</dlentry></dl> I campi non disabilitati possono essere modificati. Dopo aver
modificato un campo, fare clic su <uicontrol>Salva</uicontrol>. </p>
-</csbody>
-</cshelp>
-<cshelp id="kimhaddtempl">
-<title>Aggiungi modello</title>
-<shortdesc>Aggiungere un modello dal supporto di origine.
-�� possibile aggiungere una propria immagine ISO al pool di memoria 'ISO' per la
seguente individuazione.</shortdesc>
-<csbody>
-<p>Selezionare l'ubicazione del supporto di origine dalle seguenti
opzioni:<dl>
-<dlentry>
-<dt>Immagine ISO locale</dt>
-<dd>Selezionare questa opzione per eseguire la scansione dei pool di memoria alla
ricerca di immagini ISO di installazione disponibili sul sistema.</dd>
-</dlentry><dlentry>
-<dt>Immagine ISO remota</dt>
-<dd>Selezionare questa opzione per specificare un'ubicazione remota per
un'immagine ISO di installazione.</dd>
-</dlentry></dl></p>
-</csbody>
-</cshelp>
-<cshelp id="kimhaddloct">
-<title>Aggiungi modello - Immagine ISO locale</title>
-<shortdesc>Aggiungere un modello da un'immagine ISO locale.</shortdesc>
-<csbody>
-<p>Vengono visualizzate le immagini ISO disponibili sul
sistema.<dl><dlentry>
-<dt>SO</dt>
-<dd>Il nome del sistema operativo o della distribuzione.</dd>
-</dlentry><dlentry>
-<dt>Versione</dt>
-<dd>La versione del sistema operativo o della distribuzione.</dd>
-</dlentry><dlentry>
-<dt>Dimensione</dt>
-<dd>La dimensione dell'immagine ISO.</dd>
-</dlentry></dl></p>
-<p>Per creare un modello da un'immagine ISO scegliere tra le seguenti
opzioni:<ul>
-<li>Selezionare un'immagine ISO da cui creare un modello, quindi fare clic su
<uicontrol>Crea modelli da ISO selezionato</uicontrol>.</li>
-<li>Selezionare <uicontrol>Tutti</uicontrol> per creare un modello da
ciascuna immagine ISO elencata, quindi fare clic su <uicontrol>Crea modelli da ISO
selezionato</uicontrol>.</li>
-<li>Se nei risultati della scansione non viene visualizzata l'immagine ISO che
si desidera utilizzare, �� possibile selezionare dalle seguenti opzioni:<ul>
-<li>Selezionare <uicontrol>Utilizzare un file ISO specifico</uicontrol>
per specificare un percorso all'immagine ISO.</li>
-<li>Fare clic su <uicontrol>Ricerca pi�� ISO</uicontrol> per ricercare
pi�� immagini
-ISO.</li>
-</ul></li>
-</ul></p>
-</csbody>
-</cshelp>
-</cshelp>
-
-
-<!-- ENGL1SH_VERS10N 61085_5 DO NOT REMOVE OR CHANGE THIS LINE -->
-<!-- T9N_SRC_ID 229 -->
-<!-- T9N_SH1P_STR1NG KV211AAP001 1 -->
diff --git a/plugins/kimchi/ui/pages/help/ja_JP/Makefile.am
b/plugins/kimchi/ui/pages/help/ja_JP/Makefile.am
deleted file mode 100644
index f9c2f33..0000000
--- a/plugins/kimchi/ui/pages/help/ja_JP/Makefile.am
+++ /dev/null
@@ -1,23 +0,0 @@
-# Copyright IBM Corp, 2014
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-
-ja_JP_helpdir = $(datadir)/wok/plugins/kimchi/ui/pages/help/ja_JP
-
-dist_ja_JP_help_DATA = $(wildcard *.html) $(NULL)
-
-EXTRA_DIST = $(wildcard *.dita)
-
-CLEANFILES = $(wildcard *.html)
diff --git a/plugins/kimchi/ui/pages/help/ja_JP/guests.dita
b/plugins/kimchi/ui/pages/help/ja_JP/guests.dita
deleted file mode 100644
index 5dade49..0000000
--- a/plugins/kimchi/ui/pages/help/ja_JP/guests.dita
+++ /dev/null
@@ -1,172 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--Arbortext, Inc., 1988-2011, v.4002-->
-<!DOCTYPE cshelp PUBLIC "-//IBM//DTD DITA CSHelp//EN"
- "..\dtd\cshelp.dtd">
-
-
-<!--This DITA specialized document type is not supported by the Authoring Tools
development team.
-For support please see:
-https://w3.opensource.ibm.com/projects/dita-cshelp/-->
-<cshelp id="kimhvirtm" xml:lang="ja-jp">
-<title>���������</title>
-<shortdesc><wintitle>���������������</wintitle>������������������������������
KVM ������������������������������������������
-</shortdesc>
-<csbody>
-<p>������������������������������������������������������������
-<dl><dlentry>
-<dt>������</dt>
-<dd>���������������������������
-</dd>
-</dlentry><dlentry>
-<dt>CPU</dt>
-<dd>���������������������������������������������������������
-</dd>
-</dlentry><dlentry>
-<dt>���������������������������</dt>
-<dd>������������������������������������ (KB/���)���
-</dd>
-</dlentry><dlentry>
-<dt>���������������������</dt>
-<dd>������������������������������ (KB/���)���
-</dd>
-</dlentry><dlentry>
-<dt>������������������</dt>
-<dd>������������������������������������������������������������������������������������������������������������������������������������������<tm
tmtype="tm" trademark="Linux">Linux</tm>
-���������������������������������������������������������
-</dd>
-</dlentry></dl></p>
-<p>������������������������������������������������������������������������������������
-<dl>
-<dlentry>
-<dt>������������</dt>
-<dd>������������������������������������������������������
-</dd>
-</dlentry><dlentry>
-<dt>������ (���������������������)</dt>
-<dd>���������������������������������������������������������������������������
-������������������������������������������������������������������������������������������������������������������������
-</dd>
-</dlentry></dl> </p>
-<p>���������������������������������������������������������������������
-<ul>
-<li>������������������������������������������������������������������������������������������������������������<uicontrol>������������</uicontrol>���������������������
-</li>
-<li>������������������������������������������������������������������<uicontrol>���������������������������</uicontrol>���������������������
-</li>
-<li>������������������������������������<uicontrol>������������������</uicontrol>���������������������
-</li>
-<li>���������������������������������������������������������������<uicontrol>������������</uicontrol>���������������������
-���������������������������������������������������������������
-</li>
-<li>������������������������������<uicontrol>������������</uicontrol>���������������������
-</li>
-</ul>��������� (���������������)
���������������������������������������������������<uicontrol>���������
(+)</uicontrol> ������������������������������������������������
-</p>
-</csbody>
-<cshelp id="kimhvirtmcrt" xml:lang="ja-jp">
-<title>������������������������</title>
-<shortdesc>���������������������������������������������������������������������������������������������������
-</shortdesc>
-<csbody>
-<p> <ol>
-<li>������������������������������������������������������������������
-</li>
-<li rev="rev1">���������������������������������������
-<ul>
-<li>������������������������������������������������������������������������������������������������������������
-</li>
-<li>������������������������������������������������<uicontrol>���������������������������������</uicontrol>������������������������������������������������������������
-</li>
-</ul></li>
-<li><uicontrol>������������</uicontrol>������������������������������������
-</li>
-</ol> </p>
-</csbody>
-</cshelp>
-<cshelp id="kimhvirtmedit" xml:lang="ja-jp">
-<title>������������������</title>
-<shortdesc>������������������������������������������������������������������
-������������������������������������������������������������������������������������������������
-������������������������������������������������������������������������������������������</shortdesc>
-<csprolog><csmetadata></csmetadata></csprolog>
-<csbody>
-<p>���������������������������������������<wintitle>������������</wintitle>������������������������������
-<dl>
-<dlentry>
-<dt>������</dt>
-<dd>���������������������������
-(������������������������������������������������������)</dd>
-</dlentry><dlentry>
-<dt>CPU</dt>
-<dd>���������������������������
-(���������������������������������������������������������������������������������������)</dd>
-</dlentry><dlentry>
-<dt>������������</dt>
-<dd>������������������ (MB ������)���
-(���������������������������������������������������������������������������������������)</dd>
-</dlentry><dlentry>
-<dt>������������</dt>
-<dd>���������������������������������������������������������������
(������������������) ���������������������������Linux
������������������������������������������������������������������������������
-</dd>
-</dlentry></dl></p>
-<p>���������������<wintitle>���������������������</wintitle>������������������������������
-</p>
-<dl><dlentry>
-<dt>���������������</dt>
-<dd>������������������������������������ ISO
������������������������������������������������������
-</dd>
-</dlentry></dl>
-<p> ������������������������������������������������������������������������
-������������������������������������<uicontrol>������������</uicontrol>������������������������������������
-</p>
-</csbody>
-</cshelp>
-<cshelp id="kimstoragedevice" xml:lang="ja-jp">
-<title>������������������������������������������������������������������������</title>
-<shortdesc
rev="rev1">������������������������������������������������������������������������������������������������������������������������������������������������������
-������������������������������������������ CDROM ���������������
-������������������������������������������������������������������������������������������������
-</shortdesc>
-<csbody>
-<ol>
-<li><wintitle>������������������������</wintitle>������������������<wintitle>���������������������</wintitle>���������������������
-</li>
-<li>������������������������������������������������������<uicontrol>������������������������������
(/)</uicontrol>
���������������������������������������������������������������������
-ISO
������������������������������������<uicontrol>������������</uicontrol>���������������������������
-</li>
-<li>������������������������������������������������������<uicontrol>������������������
(-)</uicontrol> ������������ 2
���������������������������������������������������������
-���������������������<uicontrol>���OK���</uicontrol>���������������������������
-</li>
-<li>������������������������������������������������������<uicontrol>���������������
(+)</uicontrol> ������������ 3
���������������������������������������������������������
-������������������ ISO
������������������������������������<uicontrol>������������</uicontrol>���������������������������
-</li>
-</ol>
-</csbody>
-</cshelp>
-<cshelp id="kimreplacemedia" xml:lang="ja-jp">
-<title>VM ��� CDROM ���������</title>
-<shortdesc
rev="rev1">������������������������������������������������������������ CDROM
������������������������������������������������
-</shortdesc>
-<csbody>
-<ol>
-<li>���������������������������������������������������������������
-</li>
-<li>���������������������������������������<uicontrol>���������������������������</uicontrol>���������������������
-</li>
-<li>CDROM ���������������������������������������������������������hdc
������������������������������<uicontrol>������������������������������
(/)</uicontrol> ���������������������������������������
-</li>
-<li><wintitle>���VM ��� CDROM ������������</wintitle>���������������ISO
������������������������������������������
-��������������� 2 ���������������������������������������������������
-</li>
-<li><uicontrol>������������</uicontrol>������������������������������������
-</li>
-</ol>
-</csbody>
-</cshelp>
-<?tm 1391540919 3?>
-</cshelp>
-
-
-<!-- ENGL1SH_VERS10N 45645_6 DO NOT REMOVE OR CHANGE THIS LINE -->
-<!-- T9N_SRC_ID 231 -->
-<!-- T9N_SH1P_STR1NG KV211AAP001 1 -->
diff --git a/plugins/kimchi/ui/pages/help/ja_JP/host.dita
b/plugins/kimchi/ui/pages/help/ja_JP/host.dita
deleted file mode 100644
index 3a0141c..0000000
--- a/plugins/kimchi/ui/pages/help/ja_JP/host.dita
+++ /dev/null
@@ -1,70 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--Arbortext, Inc., 1988-2011, v.4002-->
-<!DOCTYPE cshelp PUBLIC "-//IBM//DTD DITA CSHelp//EN"
- "..\dtd\cshelp.dtd">
-
-
-<!--This DITA specialized document type is not supported by the Authoring Tools
development team.
-For support please see:
-https://w3.opensource.ibm.com/projects/dita-cshelp/-->
-<cshelp id="kimhhost" xml:lang="ja-jp">
-<title>���������</title>
-<shortdesc><wintitle>���������������</wintitle>������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������
-</shortdesc>
-<csbody>
-<p>���������������������������������������������������������������������
-<ul>
-<li>������������������������������������������������������������<uicontrol>���������������������������</uicontrol>���������������������
-</li>
-<li>������������������������������������������������<uicontrol>���������������</uicontrol>���������������������
-</li>
-<li>������������������������������ VNC ���������
(���������������������������������������)
���������������������������<uicontrol>������������</uicontrol>���������������������
-</li>
-</ul></p>
-<p>������������������������������������������������������������������������������������������������������������
-<dl>
-<dlentry>
-<dt>������������</dt>
-<dd>������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������
(GB ������) ������������������������
-</dd>
-</dlentry><dlentry>
-<dt>������������������������</dt>
-<dd>������������������������������������������
CPU���������������������������������������������������������������������������������������������������������������������������������������
-���������������������������������������������������������������������������������<uicontrol>���������������������������������������������������������������</uicontrol>������������������������������
-</dd>
-</dlentry><dlentry>
-<dt>������������������������</dt>
-<dd>���������������������������������������������������������������������������������������������
-(������������������������������������������������������������������������������������������)
������������������������
-<uicontrol>���������������������</uicontrol>���������������������������������������������������������������������������������������������
-���������������������������������������������������������������������������������������������
-</dd>
-</dlentry><dlentry>
-<dt>������������������</dt>
-<dd>������������������������������������������������������������������������������������������������������������������������������
-������������������������������������������������������������������������������������������������������������������
-������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������
-��������������� Red Hat Enterprise Linux ��������� Fedora
���������������<filepath>yum</filepath>
������������������������������������������
-��������������� Ubuntu ��������� Debian
���������������<filepath>deb</filepath>
������������������������������������������������
-<p>yum
������������������������������������������������������������������������������������������������������������������������������������������������������������GPG
������������������������������������
-���������������������������������<uicontrol>������������</uicontrol>������������������������������������
-<uicontrol>������������</uicontrol>��������������� GPG
������������������������������������������������������������������ GPG ������������������
URL ������������������������������
-</p></dd>
-</dlentry><dlentry>
-<dt>���������������������������</dt>
-<dd>���������������������������������������������������������
(������������������������������������) ������������������������
-������������������������������������������������������������������������������������������������������������������������������������������������������������������
-<p>���������������������������������<cmdname>sosreport</cmdname>
������������������������������������
-������������Red Hat Enterprise <tm tmtype="tm"
trademark="Linux">Linux</tm>���Fedora������������ Ubuntu
���������������������������������������������������������������
-���������������������������������������������������
(������������������������������������������������������������������������������������������������������������������������������������������������)
������������ .tar ���������������������������������
-������������������������������������������������������������������������������������������������������������������������������������������������������������
-</p> </dd>
-</dlentry></dl></p>
-</csbody>
-<?tm 1392659967 1?>
-</cshelp>
-
-
-<!-- ENGL1SH_VERS10N 47930_4 DO NOT REMOVE OR CHANGE THIS LINE -->
-<!-- T9N_SRC_ID 227 -->
-<!-- T9N_SH1P_STR1NG KVM21AAP001 1 -->
diff --git a/plugins/kimchi/ui/pages/help/ja_JP/network.dita
b/plugins/kimchi/ui/pages/help/ja_JP/network.dita
deleted file mode 100644
index 5d9ce05..0000000
--- a/plugins/kimchi/ui/pages/help/ja_JP/network.dita
+++ /dev/null
@@ -1,83 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--Arbortext, Inc., 1988-2011, v.4002-->
-<!DOCTYPE cshelp PUBLIC "-//IBM//DTD DITA CSHelp//EN"
- "..\dtd\cshelp.dtd">
-
-
-<!--This DITA specialized document type is not supported by the Authoring Tools
development team.
-For support please see:
-https://w3.opensource.ibm.com/projects/dita-cshelp/-->
-<cshelp id="kimhnetw" xml:lang="ja-jp">
-<title> ������������������</title>
-<shortdesc><wintitle>������������������������</wintitle>������������������������������������������������������������������������������������
-</shortdesc>
-<csbody>
-<p><dl><dlentry>
-<dt>���������������������</dt>
-<dd>��������������������������� (���������
<uicontrol>default</uicontrol>) ���������
-</dd>
-</dlentry><dlentry>
-<dt>������</dt>
-<dd>������������������������������������������������ (���)
��������������������������� (���) ���������
-</dd>
-</dlentry><dlentry>
-<dt>������������������������������</dt>
-<dd>���������������������������������������������
<uicontrol>NAT</uicontrol> (���������������������������������������)
���������
-</dd>
-</dlentry><dlentry>
-<dt>������������������������</dt>
-<dd>������������������������������������������������������������
<uicontrol>virbr0</uicontrol> (���������������) ���������
-</dd>
-</dlentry><dlentry>
-<dt>���������������������������</dt>
-<dd>IP ���������������</dd>
-</dlentry></dl></p>
-<p>������������������������������������������������
-<ul>
-<li
rev="rev1">���������������������������������������������<uicontrol>������������</uicontrol>���������������������
-</li>
-<li>���������������������������������������������<uicontrol>������������</uicontrol>���������������������
-</li>
-<li>���������������������������������<uicontrol>������������</uicontrol>���������������������
-</li>
-</ul>������������������������������������������������������������������<uicontrol>���������
(+)</uicontrol> ������������������������������������������������
-</p>
-</csbody>
-<cshelp id="kimhnetwcrt" xml:lang="ja-jp">
-<title>���������������������������</title>
-<shortdesc>���������������������������������������
-</shortdesc>
-<csbody>
-<p> <ol>
-<li>������������������������������������������������
-</li>
-<li>���������������������������������������������������������������������
-<dl rev="rev1"><dlentry>
-<dt><uicontrol>������</uicontrol></dt>
-<dd>������������������
-���������������������������������������������������������������������������������������
-</dd>
-</dlentry><dlentry>
-<dt><uicontrol>NAT</uicontrol></dt>
-<dd>���������������������������������������������������
-������������������������������������������������������������ IP
������������������������������������
-������������������������������������������������������������������������
-</dd>
-</dlentry><dlentry>
-<dt><uicontrol>������������</uicontrol></dt>
-<dd>���������������������������
-������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������
-������������������������������������������������ VLAN
������������������������������������������������������
-</dd>
-</dlentry></dl></li>
-<li><uicontrol>������������</uicontrol>������������������������������������
-</li>
-</ol> </p>
-</csbody>
-</cshelp>
-</cshelp>
-
-
-<!-- ENGL1SH_VERS10N 47050_3 DO NOT REMOVE OR CHANGE THIS LINE -->
-<!-- T9N_SRC_ID 230 -->
-<!-- T9N_SH1P_STR1NG KVM21AAP001 3 -->
diff --git a/plugins/kimchi/ui/pages/help/ja_JP/storage.dita
b/plugins/kimchi/ui/pages/help/ja_JP/storage.dita
deleted file mode 100644
index f975e7a..0000000
--- a/plugins/kimchi/ui/pages/help/ja_JP/storage.dita
+++ /dev/null
@@ -1,120 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--Arbortext, Inc., 1988-2011, v.4002-->
-<!DOCTYPE cshelp PUBLIC "-//IBM//DTD DITA CSHelp//EN"
- "..\dtd\cshelp.dtd">
-
-
-<!--This DITA specialized document type is not supported by the Authoring Tools
development team.
-For support please see:
-https://w3.opensource.ibm.com/projects/dita-cshelp/-->
-<cshelp id="kimhstor" xml:lang="ja-jp">
-<title>���������������</title>
-<shortdesc><wintitle>���������������������</wintitle>���������������������������������
-���������������������������
(������������������������default������������������������������������ISO���������������������������������������)
���������������������������
-��������� ISO
���������������������������������������ISO���������������������������������������������������������������������</shortdesc>
-<csbody>
-<p>������������������������������������������������������������������������������
-<dl>
-<dlentry>
-<dt>������</dt>
-<dd>���������������������������������������������������������
-</dd>
-</dlentry><dlentry>
-<dt>������</dt>
-<dd>��������������������������������������������������������� (���)
��������������������������� (���) ���������
-</dd>
-</dlentry><dlentry>
-<dt>������������������</dt>
-<dd>���������������������������������������������������������������������������
-</dd>
-</dlentry><dlentry>
-<dt>���������</dt>
-<dd>������������������������������������������������������
<uicontrol>dir</uicontrol> ���������
-</dd>
-</dlentry><dlentry>
-<dt>������</dt>
-<dd>������������������������������������������������������������
-</dd>
-</dlentry><dlentry>
-<dt>������������������</dt>
-<dd>������������������������������������������������������������������������������������
-</dd>
-</dlentry></dl></p>
-<p>���������������������������������������������������������������������������������������
-<ul>
-<li>������������������������������������������������������������������������������������<uicontrol>������������������������������</uicontrol>���������������������
-</li>
-<li>������������������������������������������������������������������������������������<uicontrol>���������������������������������</uicontrol>���������������������
-</li>
-<li>������������������������������������������������������������������������<uicontrol>���������������������������</uicontrol>���������������������
-</li>
-</ul></p>
-<p>���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������
-������������������������������������
-<dl><dlentry>
-<dt>���������</dt>
-<dd>������������������������������������������
<uicontrol>file</uicontrol> ���������
-</dd>
-</dlentry><dlentry>
-<dt>������������������</dt>
-<dd>���������������������������������������������������
-</dd>
-</dlentry><dlentry>
-<dt>������</dt>
-<dd>������������������������������������������������
-</dd>
-</dlentry><dlentry>
-<dt>������������</dt>
-<dd>������������������������������������������������������������������������������������
-</dd>
-</dlentry></dl>���������������������������������������������������������������������������<uicontrol>���������
(+)</uicontrol> ������������������������������������������������
-</p>
-</csbody>
-<cshelp id="kimhdefstor" xml:lang="ja-jp">
-<title>������������������������������������</title>
-<shortdesc> ������������������������������������������������
-</shortdesc>
-<csbody>
-<p> <ol>
-<li><uicontrol>������������������������������������</uicontrol>���������������������������������������������������������������������������������������������������
-</li>
-<li><uicontrol>���������������������������������������������</uicontrol>���������������������������������������������������������
-<dl><dlentry>
-<dt><uicontrol>DIR</uicontrol></dt>
-<dd>������������������������������������������������������
-<uicontrol>DIR</uicontrol>
������������������������<uicontrol>������������������������</uicontrol>
(���������������������������������������������������) ������������������������������
-</dd>
-</dlentry><dlentry>
-<dt><uicontrol>NFS</uicontrol></dt>
-<dd>������������������������������������������������������������������������������
-<uicontrol>NFS</uicontrol> ������������������������<uicontrol>NFS
������������ IP</uicontrol> ��������������������� <uicontrol>NFS
������</uicontrol>
-(���������������������������������������������������������)
������������������������������
-</dd>
-</dlentry><dlentry>
-<dt><uicontrol>iSCSI</uicontrol></dt>
-<dd>iSCSI
���������������������������������������������������������������������������������������������������������
-<uicontrol>iSCSI</uicontrol> ������������������������<uicontrol>iSCSI
������������</uicontrol> IP ������������������������ iSCSI
������������������<uicontrol>���������������</uicontrol>������������������������������
-���������������������iSCSI ������������������������������������������������
-</dd>
-</dlentry><dlentry>
-<dt><uicontrol>������</uicontrol></dt>
-<dd>������������������������������������������������������������������������
-������������������������������������<uicontrol>���������������������������</uicontrol>������������������������������
-</dd>
-</dlentry><dlentry>
-<dt><uicontrol>SCSI
������������������������������</uicontrol></dt>
-<dd>SCSI
���������������������������������������������������������������������������
-������������ SCSI ���������������������������������������������
-</dd>
-</dlentry></dl></li>
-<li><uicontrol>������������</uicontrol>������������������������������������
-</li>
-</ol> </p>
-</csbody>
-</cshelp>
-</cshelp>
-
-
-<!-- ENGL1SH_VERS10N 22336_4 DO NOT REMOVE OR CHANGE THIS LINE -->
-<!-- T9N_SRC_ID 233 -->
-<!-- T9N_SH1P_STR1NG KV211AAP001 1 -->
diff --git a/plugins/kimchi/ui/pages/help/ja_JP/templates.dita
b/plugins/kimchi/ui/pages/help/ja_JP/templates.dita
deleted file mode 100644
index 24dc2ab..0000000
--- a/plugins/kimchi/ui/pages/help/ja_JP/templates.dita
+++ /dev/null
@@ -1,150 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--Arbortext, Inc., 1988-2011, v.4002-->
-<!DOCTYPE cshelp PUBLIC "-//IBM//DTD DITA CSHelp//EN"
- "..\dtd\cshelp.dtd">
-
-
-<!--This DITA specialized document type is not supported by the Authoring Tools
development team.
-For support please see:
-https://w3.opensource.ibm.com/projects/dita-cshelp/-->
-<cshelp id="kimhtempl" xml:lang="ja-jp">
-<title>������������������</title>
-<shortdesc><wintitle>������������������������</wintitle>������������������KVM
���������������������������������������������������������������������������������������������������������������������������
-</shortdesc>
-<csbody>
-<p>���������������������������������������������������������������������
-<dl>
-<dlentry>
-<dt>OS</dt>
-<dd>���������������������������������������������������������������������������������������������
-</dd>
-</dlentry><dlentry>
-<dt>���������������</dt>
-<dd>������������������������������������������������������������������������������������������������������
-</dd>
-</dlentry><dlentry>
-<dt>CPU</dt>
-<dd>���������������������������������������������������������������������
-</dd>
-</dlentry><dlentry>
-<dt>������������</dt>
-<dd>��������������������������������������������������������������������� (MB
������)���
-</dd>
-</dlentry></dl></p>
-<p>������������������������������������������������������������������������������
-<ul>
-<li>���������������������������������������<uicontrol>������������</uicontrol>���������������������
-</li>
-<li>���������������������������������������<uicontrol>������������</uicontrol>���������������������
-</li>
-</ul>������������������������������������������������������������������<uicontrol>���������
(+)</uicontrol> ������������������������������������������������
-</p>
-</csbody>
-<cshelp id="kimhedittempl" xml:lang="ja-jp">
-<title>���������������������������</title>
-<shortdesc>������������������������������������������������
-</shortdesc>
-<csbody>
-<p>���������������������������������������������������������������������
-<dl>
-<dlentry>
-<dt>������</dt>
-<dd>������������������������������
-</dd>
-</dlentry><dlentry>
-<dt>������������</dt>
-<dd>������������������������������������������������������������������������������������������������������������������������������������������������������������������������������
-</dd>
-</dlentry><dlentry>
-<dt>���������������</dt>
-<dd>������������������������������������������������������������������������������������������������������������������������������������������������������������������
-</dd>
-</dlentry><dlentry>
-<dt>CPU ���</dt>
-<dd>���������������������������������������������������������������������
-</dd>
-</dlentry><dlentry>
-<dt>������������</dt>
-<dd>��������������������������������������������������������� (MB ������)���
-</dd>
-</dlentry><dlentry>
-<dt>������������</dt>
-<dd>������������������������ (GB ������)���
-</dd>
-</dlentry><dlentry>
-<dt>CDROM</dt>
-<dd>KVM ������������������������������������������������������������ ISO
������������������������������������������������������������
-</dd>
-</dlentry><dlentry>
-<dt>���������������������������</dt>
-<dd>������������������������������������������������������������������������������������������������
-</dd>
-</dlentry><dlentry>
-<dt> ������������������</dt>
-<dd>KVM
���������������������������������������������������������������������������������������������
-������������������������������������������������������������������
-</dd>
-</dlentry></dl>
������������������������������������������������������������������������
-������������������������������������<uicontrol>������������</uicontrol>������������������������������������
-</p>
-</csbody>
-</cshelp>
-<cshelp id="kimhaddtempl">
-<title>���������������������������</title>
-<shortdesc>���������������������������������������������������������������������
-������������������������������������������������������ ISO
������������������ISO������������������������������������������������������</shortdesc>
-<csbody>
-<p>���������������������������������������������������������������������������������������������������������
-<dl>
-<dlentry>
-<dt>������������ ISO ������������</dt>
-<dd>������������������������������������������������������������������������ ISO
������������������������������������������������������������������������
-</dd>
-</dlentry><dlentry>
-<dt>������������ ISO ������������</dt>
-<dd>������������������������������������������ ISO
���������������������������������������������������������������������
-</dd>
-</dlentry></dl></p>
-</csbody>
-</cshelp>
-<cshelp id="kimhaddloct">
-<title>��������������������������� - ������������ ISO ������������</title>
-<shortdesc>��������������������������������� ISO
������������������������������������
-</shortdesc>
-<csbody>
-<p>������������������������������ ISO ������������������������������������
-<dl><dlentry>
-<dt>OS</dt>
-<dd>���������������������������������������������������������������������������������������������
-</dd>
-</dlentry><dlentry>
-<dt>���������������</dt>
-<dd>������������������������������������������������������������������������������������������������������
-</dd>
-</dlentry><dlentry>
-<dt>���������</dt>
-<dd>ISO ���������������������������
-</dd>
-</dlentry></dl></p>
-<p>��������������������� ISO
���������������������������������������������������������������������������������������������
-<ul>
-<li>��������������������������������������������� ISO
������������������������������<uicontrol>��������������� ISO
������������������������������������</uicontrol>���������������������������
-</li>
-<li>������������������������ ISO
������������������������������������������������������������������������<uicontrol>���������������</uicontrol>���������������������<uicontrol>���������������
ISO ������������������������������������</uicontrol>���������������������������
-</li>
-<li>��������������� ISO
���������������������������������������������������������������������������������������������������������������
-<ul>
-<li>ISO ���������������������������������������������<uicontrol>������������
ISO ������������������������������</uicontrol>���������������������
-</li>
-<li>��������������� ISO ������������������������������������<uicontrol>���ISO
���������������������</uicontrol>���������������������������
-</li>
-</ul></li>
-</ul></p>
-</csbody>
-</cshelp>
-</cshelp>
-
-
-<!-- ENGL1SH_VERS10N 61085_5 DO NOT REMOVE OR CHANGE THIS LINE -->
-<!-- T9N_SRC_ID 229 -->
-<!-- T9N_SH1P_STR1NG KV211AAP001 1 -->
diff --git a/plugins/kimchi/ui/pages/help/kimchi.css
b/plugins/kimchi/ui/pages/help/kimchi.css
deleted file mode 100644
index 32fae4a..0000000
--- a/plugins/kimchi/ui/pages/help/kimchi.css
+++ /dev/null
@@ -1,208 +0,0 @@
-/*
- * Project Kimchi
- *
- * Copyright IBM, Corp. 2014
- *
- * 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.
- */
-BODY {
- background: #FFFFFF;
- margin-bottom: 1em;
- margin-left: .5em;
-}
-
-bold {
- font-weight: bold;
-}
-
-boldItalic {
- font-weight: bold;
- font-style: italic;
-}
-
-italic {
- font-style: italic;
-}
-
-underlined {
- text-decoration: underline;
-}
-
-uicontrol {
- font-weight: bold;
-}
-
-filepath {
- font-family: monospace, monospace;
-}.option {
- font-family: monospace, monospace;
-}
-
-cmdname {
- font-weight: bold;
- font-family: monospace, monospace;
-}
-
-.defparmname {
- font-weight: bold;
- text-decoration: underline;
- font-family: monospace, monospace;
-}
-
-.kwd {
- font-weight: bold;
-}
-
-.defkwd {
- font-weight: bold;
- text-decoration: underline;
-}
-
-var {
- font-style : italic;
-}
-
-strongwintitle {
- font-weight : bold;
-}
-
-parmname {
- font-weight: bold;
- font-family: monospace, monospace;
- white-space: nowrap;
-}
-
-code {
- font-family: monospace, monospace;
-}
-
-pre {
- font-family: monospace, monospace;
-}
-
-CITE {
- font-style: italic;
-}
-
-EM {
- font-style: italic;
-}
-
-STRONG {
- font-weight: bold;
-}
-
-VAR {
- font-style: italic;
-}
-
-dt {
- font-weight: bold;
-}
-
-/***********************************************************
- * Basic fonts
- ***********************************************************/
-body,
-td,
-th,
-caption {
- font-family: Verdana, Arial, Helvetica, sans-serif;
- font-size: 10pt;
-}
-
-pre, code {
- font-family: MS Courier New, Courier, monospace;
-}
-
-h1, h2, h3 {
- font-size: 12pt;
- font-weight: bold;
- color: #336699;
-}
-
-h4 {
- font-size: 10pt;
- font-weight: bold;
- color: #336699;
-}
-
-/***********************************************************
- * Basic indents, padding, and margin
- ***********************************************************/
-body {
- color: black;
- background-color: white;
- margin: 0;
- padding-top: 0.2em;
- padding-left: 0.6em;
- padding-right: 0.2em;
- padding-bottom: 1em;
-}
-
-h1,
-h2,
-h3,
-h4,
-h5,
-h6 {
- padding: 0;
- margin-top: 1em;
- margin-bottom: 0.75em;
- margin-left: 0;
- margin-right: 0;
-}
-
-address,
-dl,
-li,
-p {
- padding: 0;
- margin-top: 0.75em;
- margin-bottom: 0.75em;
- margin-left: 0;
- margin-right: 0;
- line-height: 125%;
-}
-
-td dl {
- margin-left: 2em;
-}
-
-pre {
- padding: 0;
- margin-top: 0.75em;
- margin-bottom: 0.75em;
- margin-left: 2em;
- margin-right: 0;
-}
-
-ol,
-ul {
- padding: 0;
- margin-top: 0.75em;
- margin-bottom: 0.75em;
- margin-left: 2.00em;
- margin-right: 0;
-}
-
-dd {
- margin-left: 3.00em;
- margin-top: 0.75em;
- margin-bottom: 0.75em;
-}
-
-dt {
- margin-left: 1.00em;
- margin-top: 0.75em;
-}
diff --git a/plugins/kimchi/ui/pages/help/ko_KR/Makefile.am
b/plugins/kimchi/ui/pages/help/ko_KR/Makefile.am
deleted file mode 100644
index e441955..0000000
--- a/plugins/kimchi/ui/pages/help/ko_KR/Makefile.am
+++ /dev/null
@@ -1,23 +0,0 @@
-# Copyright IBM Corp, 2014
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-
-ko_KR_helpdir = $(datadir)/wok/plugins/kimchi/ui/pages/help/ko_KR
-
-dist_ko_KR_help_DATA = $(wildcard *.html) $(NULL)
-
-EXTRA_DIST = $(wildcard *.dita)
-
-CLEANFILES = $(wildcard *.html)
diff --git a/plugins/kimchi/ui/pages/help/ko_KR/guests.dita
b/plugins/kimchi/ui/pages/help/ko_KR/guests.dita
deleted file mode 100644
index 2d9f32b..0000000
--- a/plugins/kimchi/ui/pages/help/ko_KR/guests.dita
+++ /dev/null
@@ -1,119 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--Arbortext, Inc., 1988-2011, v.4002-->
-<!DOCTYPE cshelp PUBLIC "-//IBM//DTD DITA CSHelp//EN"
- "..\dtd\cshelp.dtd">
-
-
-<!--This DITA specialized document type is not supported by the Authoring Tools
development team.
-For support please see:
-https://w3.opensource.ibm.com/projects/dita-cshelp/-->
-<cshelp id="kimhvirtm" xml:lang="ko-kr">
-<title>���������</title>
-<shortdesc><wintitle>���������</wintitle> ��������������� ��������� KVM
������ ��������� ���������������.</shortdesc>
-<csbody>
-<p>��� ������������ ������ ������ ���������
���������������.<dl><dlentry>
-<dt>������</dt>
-<dd>������ ��������� ���������������.</dd>
-</dlentry><dlentry>
-<dt>CPU</dt>
-<dd>������ ��������� ������������ ������������������.</dd>
-</dlentry><dlentry>
-<dt>������������ I/O</dt>
-<dd>������ ������������ ���/������(I/O) ������ ������(KB)���������.</dd>
-</dlentry><dlentry>
-<dt>��������� I/O</dt>
-<dd>������ ��������� ���/������(I/O) ������ ������(KB)���������.</dd>
-</dlentry><dlentry>
-<dt>���������������</dt>
-<dd>��������� ������ ��������� ���������������, ������������ ��������� ������
������ <tm tmtype="tm" trademark="Linux">Linux</tm>
��������� ������������ ������������������.</dd>
-</dlentry></dl></p>
-<p>������ ������ ������������ ��� ��������������� ���������������.<dl>
-<dlentry>
-<dt>������ ������</dt>
-<dd>������������ ������ ��������������� ���������������. </dd>
-</dlentry><dlentry>
-<dt>������(������ ������ ������)</dt>
-<dd>������������ ��������� ��������� ��������� ���������������. ������������
��������������� ��������� ������ ��������� ������������ ������������ ��������� ������
������������.</dd>
-</dlentry></dl> </p>
-<p>��� ��������������� ������ ��������� ��������� ��� ������������.<ul>
-<li>��������� ������ ��������� ������ ��������� ���������������
<uicontrol>������</uicontrol>��� ���������������.</li>
-<li>��������� ������ ��������� ��������������� <uicontrol>������
������</uicontrol>��� ���������������.</li>
-<li>������������ ������ ��������������� <uicontrol>������
������</uicontrol>��� ���������������.</li>
-<li>������ ������������ ��������� ���������������
<uicontrol>������</uicontrol>��� ���������������. ������������ ������
��������� ������ ��������� ��� ������������.</li>
-<li>������������ ��������������� <uicontrol>������</uicontrol>���
���������������.</li>
-</ul>��������� ������ ������ ��������� ��������������� ��������� ���������
��������� ������ <uicontrol>���������(+)</uicontrol> ������������
���������������.</p>
-</csbody>
-<cshelp id="kimhvirtmcrt" xml:lang="ko-kr">
-<title>������ ������ ������</title>
-<shortdesc>������ ��������������� ������������ ������ ���������
���������������.</shortdesc>
-<csbody>
-<p> <ol>
-<li>������ ��������� ������������ ��� ��������� ���������
������������������.</li>
-<li rev="rev1">��������������� ������������������. <ul>
-<li>��������������� ������������ ������, ��������� ������������ ���������
������������������.</li>
-<li>��������������� ������ ������, <uicontrol>������������
������</uicontrol>��� ������������ ��������������� ������������������.</li>
-</ul></li>
-<li><uicontrol>������</uicontrol>��� ������������������.</li>
-</ol> </p>
-</csbody>
-</cshelp>
-<cshelp id="kimhvirtmedit" xml:lang="ko-kr">
-<title>��������� ������</title>
-<shortdesc>������ ������ ��������� ��������� ���������������. ������ ���������
������������ ��������� ������������ ��������� ��� ������������.
-������ ��������� ������ ������������ ���������������. </shortdesc>
-<csprolog><csmetadata></csmetadata></csprolog>
-<csbody>
-<p>��� ������������ ������ ������ ��������� <wintitle>������</wintitle>
������ ���������������.<dl>
-<dlentry>
-<dt>������</dt>
-<dd>������ ��������� ���������������(������������ ��������� ������������ ���������
��� ������).</dd>
-</dlentry><dlentry>
-<dt>CPU</dt>
-<dd>������������ ������������(������������ ������ ������ ������ ��� ���������
������ ������������ ���������).</dd>
-</dlentry><dlentry>
-<dt>���������</dt>
-<dd>��������� ������(MB)���������(������������ ������ ������ ������ ��� ���������
������ ������������ ���������).</dd>
-</dlentry><dlentry>
-<dt>���������</dt>
-<dd>������������ ��������� ������ ��� ������ ������(���������������) ���������
��������� Linux ��������� ������������ ��������� ������������������.</dd>
-</dlentry></dl></p>
-<p>������ ��������� <wintitle>������������</wintitle> ������
���������������.</p>
-<dl><dlentry>
-<dt>������������</dt>
-<dd>��������� ��������� ISO ��������� ��������� ���������������.</dd>
-</dlentry></dl>
-<p> ������ ������������ ������������ ������ ��������� ��������� ��� ������������.
��������� ��������� ������ <uicontrol>������</uicontrol>��� ���������������.
</p>
-</csbody>
-</cshelp>
-<cshelp id="kimstoragedevice" xml:lang="ko-kr">
-<title>������������ ������ ������, ������ ������ ������</title>
-<shortdesc rev="rev1">������ ��������� ������ ������������ ���������
������, ������ ������ ��������� ��� ������������. ������������ ���������
CDROM������������. ������������ ��������� ��������������� ������ ���������
������������������.</shortdesc>
-<csbody>
-<ol>
-<li><wintitle>��������� ������</wintitle> ���������
<wintitle>������������</wintitle>��� ������������������.</li>
-<li>������������ ��������� ��������������� <uicontrol>���������
���������(/)</uicontrol>��� ������ ��� ������ ������������ ������������������. ISO
������ ��������� ������������ <uicontrol>������</uicontrol>���
������������������.</li>
-<li>������������ ��������� ��������������� <uicontrol>���������
������(-)</uicontrol>��� ������ ��� ������ ������������ ������������������. ������
��������� ������������ <uicontrol>������</uicontrol>���
������������������.</li>
-<li>������������ ��������� ��������������� ������ <uicontrol>���������
������(+)</uicontrol>��� ������ ��� ������ ������������ ������������������. ������
������ ��� ISO ������ ��������� ������������ <uicontrol>������</uicontrol>���
������������������.</li>
-</ol>
-</csbody>
-</cshelp>
-<cshelp id="kimreplacemedia" xml:lang="ko-kr">
-<title>VM��� CDROM ������</title>
-<shortdesc rev="rev1">��������� ��������� ������ ������ ��������� ������
CDROM��� ������������ ������ ��� ������������.</shortdesc>
-<csbody>
-<ol>
-<li>������ ��������� ������������������ ������������������.</li>
-<li>������ ������������ <uicontrol>������ ������</uicontrol>���
������������������.</li>
-<li>CDROM��� ������ ��������� ��������� ������������ ������ hdc ������ ������
������ <uicontrol>��������� ���������(/)</uicontrol> ������������
������������������.</li>
-<li><wintitle>VM��� CDROM ������</wintitle> ��������������� ISO ������
��������� ������������������. ������ ��� ��������� ������ ���������������.</li>
-<li><uicontrol>������</uicontrol>��� ������������������.</li>
-</ol>
-</csbody>
-</cshelp>
-<?tm 1391540919 3?>
-</cshelp>
-
-
-<!-- ENGL1SH_VERS10N 45645_6 DO NOT REMOVE OR CHANGE THIS LINE -->
-<!-- T9N_SRC_ID 231 -->
-<!-- T9N_SH1P_STR1NG KV211AAP001 1 -->
diff --git a/plugins/kimchi/ui/pages/help/ko_KR/host.dita
b/plugins/kimchi/ui/pages/help/ko_KR/host.dita
deleted file mode 100644
index ee4a9c3..0000000
--- a/plugins/kimchi/ui/pages/help/ko_KR/host.dita
+++ /dev/null
@@ -1,47 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--Arbortext, Inc., 1988-2011, v.4002-->
-<!DOCTYPE cshelp PUBLIC "-//IBM//DTD DITA CSHelp//EN"
- "..\dtd\cshelp.dtd">
-
-
-<!--This DITA specialized document type is not supported by the Authoring Tools
development team.
-For support please see:
-https://w3.opensource.ibm.com/projects/dita-cshelp/-->
-<cshelp id="kimhhost" xml:lang="ko-kr">
-<title>���������</title>
-<shortdesc><wintitle>���������</wintitle> ��������������� ���������
������������ ������ ��������� ������������ ��� ������������ ������������ ������������
������ ��� ������ ��������������� ������������ ��������� ���
������������.</shortdesc>
-<csbody>
-<p>������������ ������ ������ ��������� ��������� ��� ������������.<ul>
-<li>��������� ������������ ��������������� <uicontrol>���������
������</uicontrol>��� ���������������.</li>
-<li>��������� ������������ ������ ��������������� <uicontrol>������
������</uicontrol>��� ���������������.</li>
-<li>������ ������������ ������ ������ ������, ��������� ������������ ������ VNC
��������� ��������������� <uicontrol>������</uicontrol>���
���������������.</li>
-</ul></p>
-<p>������������ ������ ��������� ��������������� ������ ���������
������������������.<dl>
-<dlentry>
-<dt>������ ������</dt>
-<dd>��� ������������ ��������� ������ ������ ������, ������, ������ ������,
������������ ������, ��������� ������(GB) ������ ���������������.</dd>
-</dlentry><dlentry>
-<dt>��������� ������</dt>
-<dd>��� ������������ ������������ CPU, ���������, ��������� I/O, ������������
I/O��� ������ ��������� ������������ ������������ ���������������. ��������� ������
��������� ��� ��������� ��������� ��������������� <uicontrol>��� ������������ ������
������ ��������� ������</uicontrol>��� ���������������.</dd>
-</dlentry><dlentry>
-<dt>��������������� ������������</dt>
-<dd>��� ������������ ��������� ������, ������, ������������, ������������
������������ ������ ��������� ��������������� ������ ������ ������������ ������ ���������
���������������. <uicontrol>������ ������������</uicontrol>��� ������������
��������� ������ ������������ ��������������� ��� ������������. ��������������� ������
������ ������������ ��������� ������ ������������.</dd>
-</dlentry><dlentry>
-<dt>���������</dt>
-<dd>��� ������������ ��������� ������������ ��������� ������������ ���������������.
������������ ���������������, ������������ ���������������, ���������������, ��������� ���
������������. ������������ ������������ ������������ ��������� ������������ ������������,
������������ ������������ ������������ ������������ ������������ ������������ ���
������������. ������ ������������ Red Hat Enterprise Linux ������ Fedora��� ������,
<filepath>yum</filepath> ������������ ��������� ��� ������������.
-������ ������������ Ubuntu ������ Debian��� ������, <filepath>deb</filepath>
������������ ������������������.<p>yum ������������ ������������ ������, GPG
��������� ������������ ��� ������������ ������������ ������������ ������������ ���������
��� ������������.
-������������ ��������� ��� <uicontrol>������</uicontrol>���
������������������. <uicontrol>���</uicontrol>��� ������������ GPG ���������
������������ ��������� ��� ������������ ������ GPG ��� ��������� URL���
������������������.</p></dd>
-</dlentry><dlentry>
-<dt>��������� ���������</dt>
-<dd>��� ������������ ������ ��� ������ ��������� ��������� ��������� ������������
���������������.
-��� ��������� ������, ������ ��������� ������ ���������, ������, ������������ ������
������ ��������� ��������� ��� ������������.<p>��������� ������������
<cmdname>sosreport</cmdname> ��������� ������������ ���������������. ������
Red Hat Enterprise <tm tmtype="tm"
trademark="Linux">Linux</tm>, Fedora ��� Ubuntu ������������ ������
���������������. ��� ��������� ������ ��� ������ ������(���: ������ ������ ������ ������,
��������� ������, ��������� ��� ��������� ������ ������)��� ������������ .tar ���������
���������������.
-������ ��� ��������� ������ ��������������� ������������ ������ ��������� ������������
������ ��������������� ��� ��������� ���������������.</p> </dd>
-</dlentry></dl></p>
-</csbody>
-<?tm 1392659967 1?>
-</cshelp>
-
-
-<!-- ENGL1SH_VERS10N 47930_4 DO NOT REMOVE OR CHANGE THIS LINE -->
-<!-- T9N_SRC_ID 232 -->
-<!-- T9N_SH1P_STR1NG KVM21AAP001 3 -->
diff --git a/plugins/kimchi/ui/pages/help/ko_KR/network.dita
b/plugins/kimchi/ui/pages/help/ko_KR/network.dita
deleted file mode 100644
index 451510f..0000000
--- a/plugins/kimchi/ui/pages/help/ko_KR/network.dita
+++ /dev/null
@@ -1,61 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--Arbortext, Inc., 1988-2011, v.4002-->
-<!DOCTYPE cshelp PUBLIC "-//IBM//DTD DITA CSHelp//EN"
- "..\dtd\cshelp.dtd">
-
-
-<!--This DITA specialized document type is not supported by the Authoring Tools
development team.
-For support please see:
-https://w3.opensource.ibm.com/projects/dita-cshelp/-->
-<cshelp id="kimhnetw" xml:lang="ko-kr">
-<title>������������</title>
-<shortdesc><wintitle>������������</wintitle> ���������������
������������ ��������� ������ ��������� ���������������.</shortdesc>
-<csbody>
-<p><dl><dlentry>
-<dt>������������ ������</dt>
-<dd>��������������� ������ ������
<uicontrol>���������</uicontrol>���������.</dd>
-</dlentry><dlentry>
-<dt>������</dt>
-<dd>��������������� ������(��������� ������ ������, ������������ ������
���������)���������. </dd>
-</dlentry><dlentry>
-<dt>������������ ������</dt>
-<dd>������������ ���������������. ���:
<uicontrol>NAT</uicontrol>(Network Address Translation)</dd>
-</dlentry><dlentry>
-<dt>���������������</dt>
-<dd>������������ ������������������������. ���:
<uicontrol>virbr0</uicontrol>(���������)</dd>
-</dlentry><dlentry>
-<dt>������ ������</dt>
-<dd>IP ���������������.</dd>
-</dlentry></dl></p>
-<p>������ ��������� ��������� ��� ������������.<ul>
-<li rev="rev1">������������ ��������� ���������������
<uicontrol>������</uicontrol>��� ���������������.</li>
-<li>������������ ��������� ���������������
<uicontrol>������</uicontrol>��� ���������������.</li>
-<li>������ ��������� ��������������� <uicontrol>������</uicontrol>���
���������������.</li>
-</ul>��������������� ��������������� ������ ��������� ��������� ������
<uicontrol>���������(+)</uicontrol> ������������ ���������������.</p>
-</csbody>
-<cshelp id="kimhnetwcrt" xml:lang="ko-kr">
-<title>������������ ������</title>
-<shortdesc>��������������� ���������������.</shortdesc>
-<csbody>
-<p> <ol>
-<li>��������������� ��������� ������������������.</li>
-<li>������������ ��������� ��������������� ������������������. <dl
rev="rev1"><dlentry>
-<dt><uicontrol>���������</uicontrol></dt>
-<dd>������ ���������������. ������������ ������ ������������ ������ ���������
������������ ������ ��� ������������.</dd>
-</dlentry><dlentry>
-<dt><uicontrol>NAT</uicontrol></dt>
-<dd>Network Address Translation ���������������. ������������ ������
��������������� ��������� ������������ ��������� IP ��������� ���������������. ������
������������ ��������������� ��������� ��������� ��� ������������.</dd>
-</dlentry><dlentry>
-<dt><uicontrol>������������</uicontrol></dt>
-<dd>��������� ���������������. ������������ ������ ������������ ��������� ���
������ ������ ������������ ������������������ ��������� ��������������� ������������
��������� ��� ������������. ��������� ��������� ������, ������ ��������� ��� VLAN
��������� ������������ ���������.</dd>
-</dlentry></dl></li>
-<li><uicontrol>������</uicontrol>��� ������������������.</li>
-</ol> </p>
-</csbody>
-</cshelp>
-</cshelp>
-
-
-<!-- ENGL1SH_VERS10N 47050_3 DO NOT REMOVE OR CHANGE THIS LINE -->
-<!-- T9N_SRC_ID 230 -->
-<!-- T9N_SH1P_STR1NG KVM21AAP001 3 -->
diff --git a/plugins/kimchi/ui/pages/help/ko_KR/storage.dita
b/plugins/kimchi/ui/pages/help/ko_KR/storage.dita
deleted file mode 100644
index 2e6f5e8..0000000
--- a/plugins/kimchi/ui/pages/help/ko_KR/storage.dita
+++ /dev/null
@@ -1,86 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--Arbortext, Inc., 1988-2011, v.4002-->
-<!DOCTYPE cshelp PUBLIC "-//IBM//DTD DITA CSHelp//EN"
- "..\dtd\cshelp.dtd">
-
-
-<!--This DITA specialized document type is not supported by the Authoring Tools
development team.
-For support please see:
-https://w3.opensource.ibm.com/projects/dita-cshelp/-->
-<cshelp id="kimhstor" xml:lang="ko-kr">
-<title>������������</title>
-<shortdesc><wintitle>������������</wintitle> ��������������� ������
��������� ��� ������ '������' ��� 'ISO' ������������ ������ ������������
������ ��������� ������������ ������ ���������������.
-��������� ������ ISO��� ��������������� ������ 'ISO' ������������ ��� ���������
������������������.</shortdesc>
-<csbody>
-<p>��� ������������ ������ ������ ������ ��������� ���������������.<dl>
-<dlentry>
-<dt>������</dt>
-<dd>������������ ������ ������ ��� ������������������.</dd>
-</dlentry><dlentry>
-<dt>������</dt>
-<dd>������������ ������ ������(��������� ������ ������, ������������ ������
���������)���������. </dd>
-</dlentry><dlentry>
-<dt>������</dt>
-<dd>������������ ������ ��������� ������ ������ ���������������.</dd>
-</dlentry><dlentry>
-<dt>������</dt>
-<dd>������������ ������ ���������������. ���:
<uicontrol>dir</uicontrol></dd>
-</dlentry><dlentry>
-<dt>������</dt>
-<dd>������������ ��������� ��������� ������������.</dd>
-</dlentry><dlentry>
-<dt>���������</dt>
-<dd>������������ ������ ������ ��������� ��������� ������������.</dd>
-</dlentry></dl></p>
-<p>��� ������������ ��������� ������ ��������� ��������� ���
������������.<ul>
-<li>������ ��������������� ������������ ������ ������������������
<uicontrol>���������</uicontrol>��� ���������������.</li>
-<li>������������ ������ ���������������������
<uicontrol>������������</uicontrol>��� ���������������.</li>
-<li>��������� ������������ ������ ��������������� <uicontrol>������
������</uicontrol>��� ���������������.</li>
-</ul></p>
-<p>������������ ������ ������ ������������ ������ ��������������� ���������������
������������ ��� ������ ������������ ������ ������������ ������������������.
������������������ ��������� ���������������.<dl><dlentry>
-<dt>������</dt>
-<dd>��������� ���������������. ���:
<uicontrol>������</uicontrol></dd>
-</dlentry><dlentry>
-<dt>������</dt>
-<dd>��������� ��������� ������ ���������������.</dd>
-</dlentry><dlentry>
-<dt>������</dt>
-<dd>������������ ��������� ���������������.</dd>
-</dlentry><dlentry>
-<dt>������</dt>
-<dd>������������ ������ ������ ��������� ��������� ������������.</dd>
-</dlentry></dl>������������ ������ ��������������� ������ ��������� ���������
������ <uicontrol>���������(+)</uicontrol> ������������
���������������.</p>
-</csbody>
-<cshelp id="kimhdefstor" xml:lang="ko-kr">
-<title>������������ ��� ������</title>
-<shortdesc> ������������ ������ ���������������.</shortdesc>
-<csbody>
-<p> <ol>
-<li><uicontrol>������������ ��� ������</uicontrol> ������������,
������������ ������ ������������ ��� ��������� ��������� ������������������.</li>
-<li><uicontrol>������������ ��� ������</uicontrol> ������������ ������
��������� ������������������. <dl><dlentry>
-<dt><uicontrol>DIR</uicontrol></dt>
-<dd>������������ ������ ���������������. <uicontrol>DIR</uicontrol>
��������� ��������� ������, <uicontrol>������������
������</uicontrol>(������������ ������ ������ ������)���
���������������.</dd>
-</dlentry><dlentry>
-<dt><uicontrol>NFS</uicontrol></dt>
-<dd>������������ ������ ��������� ������ ���������������.
<uicontrol>NFS</uicontrol>��� ��������� ������, <uicontrol>NFS ������ IP
������</uicontrol> ��� <uicontrol>NFS ������</uicontrol>(������
��������������� ������)��� ���������������.</dd>
-</dlentry><dlentry>
-<dt><uicontrol>iSCSI</uicontrol></dt>
-<dd>iSCSI ��������� ��������� ��������� ������������ ������ ���������������.
-<uicontrol>iSCSI</uicontrol>��� ��������� ������, iSCSI ��������� ������
<uicontrol>iSCSI ������ IP ������</uicontrol> ���
<uicontrol>������</uicontrol>��� ���������������. ���������������, iSCSI
��������� ��������������� ��������� ��� ������������.</dd>
-</dlentry><dlentry>
-<dt><uicontrol>���������</uicontrol></dt>
-<dd>��������� ������ ������������ ������ ���������������. <uicontrol>������
������</uicontrol>������ ��������� ������ ��������� ���������������.</dd>
-</dlentry><dlentry>
-<dt><uicontrol>SCSI ��������� ������</uicontrol></dt>
-<dd>SCSI ��������� ��������� ������������ ������ ���������������. ��������� SCSI
������������ ���������������.</dd>
-</dlentry></dl></li>
-<li><uicontrol>������</uicontrol>��� ������������������.</li>
-</ol> </p>
-</csbody>
-</cshelp>
-</cshelp>
-
-
-<!-- ENGL1SH_VERS10N 22336_4 DO NOT REMOVE OR CHANGE THIS LINE -->
-<!-- T9N_SRC_ID 233 -->
-<!-- T9N_SH1P_STR1NG KV211AAP001 1 -->
diff --git a/plugins/kimchi/ui/pages/help/ko_KR/templates.dita
b/plugins/kimchi/ui/pages/help/ko_KR/templates.dita
deleted file mode 100644
index de16d6e..0000000
--- a/plugins/kimchi/ui/pages/help/ko_KR/templates.dita
+++ /dev/null
@@ -1,111 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--Arbortext, Inc., 1988-2011, v.4002-->
-<!DOCTYPE cshelp PUBLIC "-//IBM//DTD DITA CSHelp//EN"
- "..\dtd\cshelp.dtd">
-
-
-<!--This DITA specialized document type is not supported by the Authoring Tools
development team.
-For support please see:
-https://w3.opensource.ibm.com/projects/dita-cshelp/-->
-<cshelp id="kimhtempl" xml:lang="ko-kr">
-<title>������������</title>
-<shortdesc><wintitle>������������</wintitle> ��������������� KVM
������������ ������������ ��� ��������� ��� ������ ��������� ������ ������ ���������������
���������������.</shortdesc>
-<csbody>
-<p>��� ��������������� ������ ������ ��������� ���������������.<dl>
-<dlentry>
-<dt>OS</dt>
-<dd>������ ������ ������ ��������� ���������������.</dd>
-</dlentry><dlentry>
-<dt>������</dt>
-<dd>������ ������ ������ ��������� ���������������.</dd>
-</dlentry><dlentry>
-<dt>CPU</dt>
-<dd>��������������� ������ ��������� ��������������� ������������.</dd>
-</dlentry><dlentry>
-<dt>���������</dt>
-<dd>��������� RAM(Random Access Memory)��� ���(MB)���������.</dd>
-</dlentry></dl></p>
-<p>��� ������������������ ������ ��������� ��������� ��� ������������.<ul>
-<li>��������������� ��������������� <uicontrol>������</uicontrol>���
���������������.</li>
-<li>��������������� ��������������� <uicontrol>������</uicontrol>���
���������������.</li>
-</ul>��������������� ��������������� ������ ��������� ��������� ������
<uicontrol>���������(+)</uicontrol> ������������ ���������������.</p>
-</csbody>
-<cshelp id="kimhedittempl" xml:lang="ko-kr">
-<title>������������ ������</title>
-<shortdesc>������ ��������������� ���������������.</shortdesc>
-<csbody>
-<p>��� ��������������� ������ ������ ��������� ���������������. <dl>
-<dlentry>
-<dt>������</dt>
-<dd>��������������� ���������������.</dd>
-</dlentry><dlentry>
-<dt>������������</dt>
-<dd>��������������� ��������������� ��������� ������ ������ ������ ���������
��������� ��������� ���������������.</dd>
-</dlentry><dlentry>
-<dt>������</dt>
-<dd>��������������� ��������������� ��������� ������ ������ ������ ���������
���������������.</dd>
-</dlentry><dlentry>
-<dt>CPU ���</dt>
-<dd>��������������� ������ ��������� ��������������� ������������.</dd>
-</dlentry><dlentry>
-<dt>���������</dt>
-<dd>������ ��������� ��������� ��������� ������(MB)���������.</dd>
-</dlentry><dlentry>
-<dt>���������</dt>
-<dd>��������� ������(GB)���������.</dd>
-</dlentry><dlentry>
-<dt>CDROM</dt>
-<dd>KVM ������������ ������������ ��� ��������� ISO ��������� ��������� ������
������ ���������������.</dd>
-</dlentry><dlentry>
-<dt>������������ ���</dt>
-<dd>������ ������������ ��� ������ ������ ������������ ������������.</dd>
-</dlentry><dlentry>
-<dt>������������</dt>
-<dd>KVM ������������ ������ ��������� ������ ������������ ������������������������.
������ ��������������� ��������� ��� ������������.</dd>
-</dlentry></dl> ������ ������������ ������������ ������ ��������� ���������
��� ������������. ��������� ��������� ������ <uicontrol>������</uicontrol>���
���������������. </p>
-</csbody>
-</cshelp>
-<cshelp id="kimhaddtempl">
-<title>������������ ������</title>
-<shortdesc>������ ��������������� ��������������� ���������������. ������ ���������
������ 'ISO' ������������ ������ ��������� ������ ISO ������������ ��������� ���
������������. </shortdesc>
-<csbody>
-<p>������ ������ ��������� ������ ��������� ���������
������������������.<dl>
-<dlentry>
-<dt>������ ISO ���������</dt>
-<dd>��������������� ������ ��������� ������ ISO ������������ ������������ ������
��������������� ���������������.</dd>
-</dlentry><dlentry>
-<dt>������ ISO ���������</dt>
-<dd>������ ISO ������������ ������ ��������� ���������������
���������������.</dd>
-</dlentry></dl></p>
-</csbody>
-</cshelp>
-<cshelp id="kimhaddloct">
-<title>������������ ������ - ������ ISO ���������</title>
-<shortdesc>������ ISO ������������������ ���������������
���������������.</shortdesc>
-<csbody>
-<p>��������������� ������ ��������� ISO ������������
���������������.<dl><dlentry>
-<dt>OS</dt>
-<dd>������ ������ ������ ��������� ���������������.</dd>
-</dlentry><dlentry>
-<dt>������</dt>
-<dd>������ ������ ������ ��������� ���������������.</dd>
-</dlentry><dlentry>
-<dt>������</dt>
-<dd>ISO ������������ ���������������.</dd>
-</dlentry></dl></p>
-<p>ISO ������������������ ��������������� ��������������� ������ ������ ���������
������������������.<ul>
-<li>��������������� ������������ ������ ISO ������������ ��������� ���
<uicontrol>��������� ISO��������� ������������ ������</uicontrol>���
���������������.</li>
-<li>��������� ��� ISO ������������������ ��������������� ���������������
<uicontrol>������</uicontrol>��� ��������� ��� <uicontrol>���������
ISO��������� ������������ ������</uicontrol>��� ���������������.</li>
-<li>��������������� ISO ������������ ������ ��������� ������������ ������ ������,
������ ������ ��������� ��������� ��� ������������.<ul>
-<li>ISO ������������ ��������� ��������������� <uicontrol>������ ISO
��������� ��������������� ���������.</uicontrol>��� ���������������.</li>
-<li>������ ISO ������������ ��������������� <uicontrol>������ ISO
������</uicontrol>��� ���������������.</li>
-</ul></li>
-</ul></p>
-</csbody>
-</cshelp>
-</cshelp>
-
-
-<!-- ENGL1SH_VERS10N 61085_5 DO NOT REMOVE OR CHANGE THIS LINE -->
-<!-- T9N_SRC_ID 229 -->
-<!-- T9N_SH1P_STR1NG KV211AAP001 1 -->
diff --git a/plugins/kimchi/ui/pages/help/pt_BR/Makefile.am
b/plugins/kimchi/ui/pages/help/pt_BR/Makefile.am
deleted file mode 100644
index 7fc2cb0..0000000
--- a/plugins/kimchi/ui/pages/help/pt_BR/Makefile.am
+++ /dev/null
@@ -1,23 +0,0 @@
-# Copyright IBM Corp, 2014
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-
-pt_BR_helpdir = $(datadir)/wok/plugins/kimchi/ui/pages/help/pt_BR
-
-dist_pt_BR_help_DATA = $(wildcard *.html) $(NULL)
-
-EXTRA_DIST = $(wildcard *.dita)
-
-CLEANFILES = $(wildcard *.html)
diff --git a/plugins/kimchi/ui/pages/help/pt_BR/guests.dita
b/plugins/kimchi/ui/pages/help/pt_BR/guests.dita
deleted file mode 100644
index ac58d5c..0000000
--- a/plugins/kimchi/ui/pages/help/pt_BR/guests.dita
+++ /dev/null
@@ -1,137 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--Arbortext, Inc., 1988-2011, v.4002-->
-<!DOCTYPE cshelp PUBLIC "-//IBM//DTD DITA CSHelp//EN"
- "..\dtd\cshelp.dtd">
-
-
-<!--This DITA specialized document type is not supported by the Authoring Tools
development team.
-For support please see:
-https://w3.opensource.ibm.com/projects/dita-cshelp/-->
-<cshelp id="kimhvirtm" xml:lang="pt-br">
-<title>M��quinas Virtuais</title>
-<shortdesc>A p��gina <wintitle>M��quinas Virtuais</wintitle> lista as
m��quinas virtuais
-KVM definidas.</shortdesc>
-<csbody>
-<p>Para cada convidado, as informa����es a seguir s��o
exibidas:<dl><dlentry>
-<dt>Nome</dt>
-<dd>Nome da m��quina virtual.</dd>
-</dlentry><dlentry>
-<dt>CPU</dt>
-<dd>Porcentagem de utiliza����o do processador na m��quina virtual.</dd>
-</dlentry><dlentry>
-<dt>E/S de rede</dt>
-<dd>Taxa de transmiss��o de entrada/sa��da de rede em KB por segundo.</dd>
-</dlentry><dlentry>
-<dt>E/S de disco</dt>
-<dd>Taxa de transmiss��o de entrada/sa��da de disco em KB por segundo.</dd>
-</dlentry><dlentry>
-<dt>Livetile</dt>
-<dd>Estado do console do sistema operacional guest ou um ��cone que representa
-a distribui����o <tm tmtype="tm"
trademark="Linux">Linux</tm> se o
-convidado n��o estiver ativo.</dd>
-</dlentry></dl></p>
-<p>Os ��cones de a����es a seguir s��o exibidos para cada convidado:<dl>
-<dlentry>
-<dt>Reiniciar</dt>
-<dd>Clique para Reiniciar o convidado. </dd>
-</dlentry><dlentry>
-<dt>Energia (iniciar ou parar)</dt>
-<dd>Clique para ligar ou desligar o convidado. Se o ��cone estiver vermelho,
-a energia est�� desligada; se o ��cone estiver verde, a energia est�� ligada.</dd>
-</dlentry></dl> </p>
-<p>As a����es a seguir podem ser selecionadas para cada convidado:<ul>
-<li>Selecione <uicontrol>Conectar</uicontrol> para conectar-se ao
console
-remoto para o sistema operacional guest.</li>
-<li>Selecione <uicontrol>Gerenciar m��dia</uicontrol> para alterar o
caminho
-para a m��dia de instala����o.</li>
-<li>Selecione <uicontrol>Reiniciar</uicontrol> para Reiniciar o
convidado.</li>
-<li>Selecione <uicontrol>Editar</uicontrol> para editar as propriedades
de um
-convidado existente. Os M��quinas Virtuais podem ser editados somente quando
interrompidos.</li>
-<li>Selecione <uicontrol>Excluir</uicontrol> para excluir o
convidado.</li>
-</ul>Para criar um convidado, ou m��quina virtual, clique no ��cone
<uicontrol>mais
-(+)</uicontrol> na parte superior direita da p��gina.</p>
-</csbody>
-<cshelp id="kimhvirtmcrt" xml:lang="en-us">
-<title>Criar m��quina virtual</title>
-<shortdesc>Crie uma m��quina virtual usando um modelo existente.</shortdesc>
-<csbody>
-<p> <ol>
-<li>Digite o nome a ser usado para identificar a m��quina virtual.</li>
-<li rev="rev1">Selecione um modelo. <ul>
-<li>Se existirem modelos, selecione a partir dos modelos exibidos.</li>
-<li>Se n��o existir nenhum modelo, clique em <uicontrol>Criar um
modelo</uicontrol> para
-criar um modelo.</li>
-</ul></li>
-<li>Clique em <uicontrol>Criar</uicontrol>.</li>
-</ol> </p>
-</csbody>
-</cshelp>
-<cshelp id="kimhvirtmedit" xml:lang="en-us">
-<title>Editar convidado</title>
-<shortdesc>Edite as propriedades de uma m��quina virtual existente. Algumas
propriedades podem ser editadas enquanto o convidado est�� interrompido. Outras entrar��o
em vigor na pr��xima inicializa����o.</shortdesc>
-<csprolog><csmetadata></csmetadata></csprolog>
-<csbody>
-<p>Para cada convidado, as informa����es a seguir s��o exibidas na guia
<wintitle>Geral</wintitle>:<dl>
-<dlentry>
-<dt>Nome</dt>
-<dd>Nome da m��quina virtual. (somente pode ser editado enquanto o convidado est��
interrompido)</dd>
-</dlentry><dlentry>
-<dt>CPUs</dt>
-<dd>N��mero de processadores. (se o convidado estiver em execu����o, uma nova
quantia entrar�� em vigor na pr��xima inicializa����o)</dd>
-</dlentry><dlentry>
-<dt>Mem��ria</dt>
-<dd>Quantia de mem��ria em MB. (se o convidado estiver em execu����o, uma nova
quantia entrar�� em vigor na pr��xima inicializa����o)</dd>
-</dlentry><dlentry>
-<dt>��cone</dt>
-<dd>Imagem gr��fica representando a distribui����o Linux a ser exibida
-no lugar do status atual (Livetile) quando o convidado n��o est�� ativo.</dd>
-</dlentry></dl></p>
-<p>As informa����es a seguir s��o exibidas na guia
<wintitle>Armazenamento</wintitle>.</p>
-<dl><dlentry>
-<dt>Armazenamento</dt>
-<dd>Exibe o local do arquivo ISO usado para instala����o.</dd>
-</dlentry></dl>
-<p> Os campos que n��o est��o desativados podem ser editados. Depois de editar um
campo,
-clique em <uicontrol>Salvar</uicontrol>. </p>
-</csbody>
-</cshelp>
-<cshelp id="kimstoragedevice" xml:lang="en-us">
-<title>Incluir, substituir ou remover um dispositivo de
armazenamento</title>
-<shortdesc rev="rev1">�� poss��vel incluir, substituir ou remover um
dispositivo de armazenamento
-para sua m��quina virtual. O ��nico dispositivo suportado �� CD-ROM. Para editar
-seus dispositivos de armazenamento, siga estas etapas:</shortdesc>
-<csbody>
-<ol>
-<li>Na janela <wintitle>Editar convidado</wintitle>, selecione
<wintitle>Armazenamento</wintitle>.</li>
-<li>Para substituir um dispositivo de armazenamento, clique no primeiro ��cone com
a <uicontrol>barra
-laranja (/)</uicontrol>. Insira o caminho do arquivo ISO e clique em
<uicontrol>Substituir</uicontrol>.</li>
-<li>Para remover um dispositivo de armazenamento, clique no segundo ��cone com o
<uicontrol>tra��o
-vermelho (-)</uicontrol>. Confirme a exclus��o e clique em
<uicontrol>OK</uicontrol>.</li>
-<li>Para incluir um dispositivo de armazenamento, clique no terceiro ��cone com o
<uicontrol>sinal de
-mais (+)</uicontrol> verde. Insira um nome de dispositivo e um caminho de arquivo
ISO e clique em <uicontrol>Conectar</uicontrol>.</li>
-</ol>
-</csbody>
-</cshelp>
-<cshelp id="kimreplacemedia" xml:lang="en-us">
-<title>Substituir um CD-ROM da VM</title>
-<shortdesc rev="rev1">�� poss��vel substituir o conte��do do CD-ROM para
-uma m��quina virtual ap��s a instala����o ser conclu��da.</shortdesc>
-<csbody>
-<ol>
-<li>Assegure-se de que a m��quina virtual esteja iniciada.</li>
-<li>No menu A����es, selecione <uicontrol>Gerenciar
m��dia</uicontrol>.</li>
-<li>Para alterar o que est�� atualmente carregado no CD-ROM, clique no ��cone
<uicontrol>barra
-laranja (/)</uicontrol> pr��ximo ao campo hdc.</li>
-<li>Na p��gina <wintitle>Substituir um CD-ROM da VM</wintitle>, insira
-o caminho do arquivo ISO. Os outros dois campos s��o somente leitura.</li>
-<li>Clique em <uicontrol>Substituir</uicontrol>.</li>
-</ol>
-</csbody>
-</cshelp>
-<?tm 1391540919 3?>
-</cshelp>
-
-
-<!-- ENGL1SH_VERS10N 45645_6 DO NOT REMOVE OR CHANGE THIS LINE -->
-<!-- T9N_SRC_ID 231 -->
-<!-- T9N_SH1P_STR1NG KV211AAP001 1 -->
diff --git a/plugins/kimchi/ui/pages/help/pt_BR/host.dita
b/plugins/kimchi/ui/pages/help/pt_BR/host.dita
deleted file mode 100644
index 88f7eb2..0000000
--- a/plugins/kimchi/ui/pages/help/pt_BR/host.dita
+++ /dev/null
@@ -1,74 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--Arbortext, Inc., 1988-2011, v.4002-->
-<!DOCTYPE cshelp PUBLIC "-//IBM//DTD DITA CSHelp//EN"
- "..\dtd\cshelp.dtd">
-
-
-<!--This DITA specialized document type is not supported by the Authoring Tools
development team.
-For support please see:
-https://w3.opensource.ibm.com/projects/dita-cshelp/-->
-<cshelp id="kimhhost" xml:lang="pt-br">
-<title>Host</title>
-<shortdesc>A p��gina <wintitle>Host</wintitle> mostra informa����es
sobre
-o sistema host e permite encerrar, reiniciar e conectar
-ao host.</shortdesc>
-<csbody>
-<p>�� poss��vel executar as a����es a segur no host:<ul>
-<li>Selecione <uicontrol>Encerrar</uicontrol> para encerrar o sistema
-host.</li>
-<li>Selecione <uicontrol>Reiniciar</uicontrol> para reiniciar o sistema
host.</li>
-<li>Selecione <uicontrol>Conectar</uicontrol> para abrir uma conex��o
VNC
-para o sistema host, se ele j�� n��o estiver conectado.</li>
-</ul></p>
-<p>Clique nas se����es a seguir para exibir informa����es sobre o host:<dl>
-<dlentry>
-<dt>Informa����es b��sicas</dt>
-<dd>Esta se����o exibe a distribui����o do sistema operacional do host,
-a vers��o e o nome do c��digo, bem como o tipo de processador e quantia de
-mem��ria em GB.</dd>
-</dlentry><dlentry>
-<dt>Estat��sticas do sistema</dt>
-<dd>Esta se����o exibe gr��ficos para mostrar estat��sticas para CPU, mem��ria,
-E/S de disco e E/S de rede para o host. Selecione <uicontrol>Coletando
-dados depois de sair desta p��gina</uicontrol> para continuar a coletar dados
-quando a guia do host estiver fora de visualiza����o.</dd>
-</dlentry><dlentry>
-<dt>Atualiza����es de software</dt>
-<dd>Esta se����o exibe informa����es de todos os pacotes que
-possuem atualiza����es dispon��veis, incluindo nome do pacote, vers��o, arquitetura
-e reposit��rio. �� poss��vel atualizar todos os pacotes listados selecionando
<uicontrol>Atualizar
-todos</uicontrol>. N��o �� poss��vel selecionar pacotes individuais para
atualiza����es.</dd>
-</dlentry><dlentry>
-<dt>Reposit��rios</dt>
-<dd>Esta se����o exibe reposit��rios que est��o associados ao
-sistema host. �� poss��vel incluir, ativar, editar ou remover reposit��rios. Incluir
-um reposit��rio o associa com o sistema host enquanto ativar um reposit��rio
-permite que o host o acesse. Se o seu sistema for Red Hat Enterprise
-Linux ou Fedora, ser�� poss��vel incluir reposit��rios
<filepath>yum</filepath>.
-Se o seu sistema for Ubuntu ou Debian, inclua reposit��rios
<filepath>deb</filepath>.<p>Se
-voc�� estiver trabalhando com reposit��rios yum, ser�� poss��vel incluir uma
verifica����o de GPG para
-verificar se um pacote desse reposit��rio n��o foi corrompido.
-Selecione um reposit��rio e, em seguida, <uicontrol>Editar</uicontrol>.
Selecione <uicontrol>Sim</uicontrol> para
-ativar a Verifica����o de GPG e, em seguida, insira uma URL no arquivo-chave de GPG para
o
-reposit��rio.</p></dd>
-</dlentry><dlentry>
-<dt>Relat��rios de depura����o</dt>
-<dd>Esta se����o exibe relat��rios de depura����o, incluindo nome e caminho do
arquivo.
-�� poss��vel selecionar a partir das op����es para gerar um novo relat��rio ou renomear,
remover
-ou fazer o download de um relat��rio existente.<p>O relat��rio de depura����o ��
gerado usando
-o comando <cmdname>sosreport</cmdname>. Ele est�� dispon��vel para
distribui����es
-Red Hat Enterprise <tm tmtype="tm"
trademark="Linux">Linux</tm>, Fedora
-e Ubuntu. O comando gera um arquivo .tar que cont��m
-informa����es de configura����o e de diagn��stico, como vers��o do kernel
-em execu����o, m��dulos carregados e arquivos de configura����o de sistema e de
servi��o.
-O comando tamb��m executa programas externos para coletar informa����es adicionais
-e armazena essa sa��da no archive resultante.</p> </dd>
-</dlentry></dl></p>
-</csbody>
-<?tm 1392659967 1?>
-</cshelp>
-
-
-<!-- ENGL1SH_VERS10N 47930_4 DO NOT REMOVE OR CHANGE THIS LINE -->
-<!-- T9N_SRC_ID 232 -->
-<!-- T9N_SH1P_STR1NG KVM21AAP001 3 -->
diff --git a/plugins/kimchi/ui/pages/help/pt_BR/network.dita
b/plugins/kimchi/ui/pages/help/pt_BR/network.dita
deleted file mode 100644
index 1585298..0000000
--- a/plugins/kimchi/ui/pages/help/pt_BR/network.dita
+++ /dev/null
@@ -1,72 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--Arbortext, Inc., 1988-2011, v.4002-->
-<!DOCTYPE cshelp PUBLIC "-//IBM//DTD DITA CSHelp//EN"
- "..\dtd\cshelp.dtd">
-
-
-<!--This DITA specialized document type is not supported by the Authoring Tools
development team.
-For support please see:
-https://w3.opensource.ibm.com/projects/dita-cshelp/-->
-<cshelp id="kimhnetw" xml:lang="pt-br">
-<title>Rede</title>
-<shortdesc>A p��gina <wintitle>Rede</wintitle> exibe informa����es
-sobre a conex��o de rede.</shortdesc>
-<csbody>
-<p><dl><dlentry>
-<dt>Nome da rede</dt>
-<dd>Nome da rede ou <uicontrol>padr��o</uicontrol>.</dd>
-</dlentry><dlentry>
-<dt>Estado</dt>
-<dd>Estado da rede, ativo (verde) ou inativo (vermelho). </dd>
-</dlentry><dlentry>
-<dt>Tipo de rede</dt>
-<dd>Tipo de rede, por exemplo, <uicontrol>NAT</uicontrol> (convers��o
-de endere��o de rede).</dd>
-</dlentry><dlentry>
-<dt>Interface</dt>
-<dd>Interface de rede, por exemplo, <uicontrol>virbr0</uicontrol>
(padr��o).</dd>
-</dlentry><dlentry>
-<dt>Espa��o de endere��o</dt>
-<dd>Endere��o IP.</dd>
-</dlentry></dl></p>
-<p>As a����es a seguir podem ser selecionadas:<ul>
-<li rev="rev1">Selecione <uicontrol>Iniciar</uicontrol> para
iniciar a conex��o
-de rede.</li>
-<li>Selecione <uicontrol>Parar</uicontrol> para terminar a conex��o de
rede.</li>
-<li>Selecione <uicontrol>Excluir</uicontrol> para excluir as
informa����es
-de conex��o.</li>
-</ul>Para criar uma rede, clique no ��cone <uicontrol>mais
(+)</uicontrol> na
-parte superior direita da exibi����o.</p>
-</csbody>
-<cshelp id="kimhnetwcrt" xml:lang="en-us">
-<title>Criar uma rede</title>
-<shortdesc>Crie uma rede.</shortdesc>
-<csbody>
-<p> <ol>
-<li>Digite o nome da rede.</li>
-<li>Clique para selecionar o tipo de rede. <dl
rev="rev1"><dlentry>
-<dt><uicontrol>Isolado</uicontrol></dt>
-<dd>Modo isolado. Os M��quinas Virtuais n��o podem enviar ou receber comunica����o
para
-ou de sistemas externos.</dd>
-</dlentry><dlentry>
-<dt><uicontrol>NAT</uicontrol></dt>
-<dd>Modo de Convers��o de Endere��o de Rede. A comunica����o de M��quinas Virtuais
com
-sistemas externos usa o endere��o IP do host. Os sistemas externos n��o podem
-iniciar a comunica����o com os M��quinas Virtuais.</dd>
-</dlentry><dlentry>
-<dt><uicontrol>bridged</uicontrol></dt>
-<dd>Modo bridged. Os M��quinas Virtuais podem se comunicar com os sistemas externos
e
-ser contatados por sistemas externos como se fossem sistemas f��sicos
-na rede. Para o modo bridged, devem-se especificar informa����es adicionais
-de destino e de VLAN.</dd>
-</dlentry></dl></li>
-<li>Clique em <uicontrol>Criar</uicontrol>.</li>
-</ol> </p>
-</csbody>
-</cshelp>
-</cshelp>
-
-
-<!-- ENGL1SH_VERS10N 47050_3 DO NOT REMOVE OR CHANGE THIS LINE -->
-<!-- T9N_SRC_ID 230 -->
-<!-- T9N_SH1P_STR1NG KVM21AAP001 3 -->
diff --git a/plugins/kimchi/ui/pages/help/pt_BR/storage.dita
b/plugins/kimchi/ui/pages/help/pt_BR/storage.dita
deleted file mode 100644
index 03c8cab..0000000
--- a/plugins/kimchi/ui/pages/help/pt_BR/storage.dita
+++ /dev/null
@@ -1,102 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--Arbortext, Inc., 1988-2011, v.4002-->
-<!DOCTYPE cshelp PUBLIC "-//IBM//DTD DITA CSHelp//EN"
- "..\dtd\cshelp.dtd">
-
-
-<!--This DITA specialized document type is not supported by the Authoring Tools
development team.
-For support please see:
-https://w3.opensource.ibm.com/projects/dita-cshelp/-->
-<cshelp id="kimhstor" xml:lang="pt-br">
-<title>Armazenamento</title>
-<shortdesc>A p��gina <wintitle>Armazenamento</wintitle> lista os
conjuntos de armazenamentos dispon��veis, inclusive o conjunto de armazenamentos
'padr��o' e 'ISO' integrado.
-Se desejar usar seu pr��prio ISO, inclua-o em seu caminho do conjunto de armazenamentos
'ISO'.</shortdesc>
-<csbody>
-<p>Para cada storage pool, as informa����es a seguir s��o exibidas:<dl>
-<dlentry>
-<dt>Nome</dt>
-<dd>Nome do storage pool e porcentagem usada.</dd>
-</dlentry><dlentry>
-<dt>Estado</dt>
-<dd>Estado do storage pool, ativo (verde) ou inativo (vermelho). </dd>
-</dlentry><dlentry>
-<dt>Local</dt>
-<dd>Caminho do arquivo para o local do storage pool.</dd>
-</dlentry><dlentry>
-<dt>Tipo</dt>
-<dd>Tipo de storage pool, por exemplo,
<uicontrol>dir</uicontrol>.</dd>
-</dlentry><dlentry>
-<dt>Capacidade</dt>
-<dd>Quantia de espa��o no storage pool.</dd>
-</dlentry><dlentry>
-<dt>Alocado</dt>
-<dd>Quantia de espa��o j�� alocado no storage pool.</dd>
-</dlentry></dl></p>
-<p>As a����es a seguir podem ser selecionadas para cada storage pool:<ul>
-<li>Selecione <uicontrol>Ativar</uicontrol> para ativar o storage pool
-para que ele possa ser usado.</li>
-<li>Selecione <uicontrol>Desativar</uicontrol> para desativar um
storage pool
-ativo.</li>
-<li>Selecione <uicontrol>Indefinir</uicontrol> para remover um storage
pool
-inativo.</li>
-</ul></p>
-<p>Para exibir detalhes do volume de armazenamento para um storage pool, clique na
-seta no lado direito da linha do storage pool. Os detalhes incluem
-os seguintes:<dl><dlentry>
-<dt>Tipo</dt>
-<dd>O tipo de volume, por exemplo,
<uicontrol>arquivo</uicontrol>.</dd>
-</dlentry><dlentry>
-<dt>Formato</dt>
-<dd>O formato, que varia dependendo do tipo.</dd>
-</dlentry><dlentry>
-<dt>Capacidade</dt>
-<dd>Tamanho do volume de armazenamento.</dd>
-</dlentry><dlentry>
-<dt>Aloca����o</dt>
-<dd>Quantia de espa��o j�� alocado no storage pool.</dd>
-</dlentry></dl>Para definir um storage pool, clique no ��cone
<uicontrol>mais
-(+)</uicontrol> na parte superior direita da exibi����o.</p>
-</csbody>
-<cshelp id="kimhdefstor" xml:lang="en-us">
-<title>Definir um storage pool</title>
-<shortdesc> Defina um storage pool.</shortdesc>
-<csbody>
-<p> <ol>
-<li>No campo <uicontrol>Nome do storage pool</uicontrol>, digite o
-nome a ser usado para identificar o storage pool.</li>
-<li>Na lista <uicontrol>Tipo de storage pool</uicontrol>, selecione o
-tipo: <dl><dlentry>
-<dt><uicontrol>DIR</uicontrol></dt>
-<dd>Especifica um conjunto de diret��rios. Ao selecionar
<uicontrol>DIR</uicontrol>,
-digite o <uicontrol>Caminho do armazenamento</uicontrol> (caminho do arquivo
para o
-storage pool).</dd>
-</dlentry><dlentry>
-<dt><uicontrol>NFS</uicontrol></dt>
-<dd>Especifica um conjunto de sistema de arquivos de rede. Ao selecionar
<uicontrol>NFS</uicontrol>,
-digite o endere��o <uicontrol>IP do servidor NFS</uicontrol> e o
<uicontrol>Caminho
-do NFS</uicontrol> (caminho do diret��rio exportado).</dd>
-</dlentry><dlentry>
-<dt><uicontrol>iSCSI</uicontrol></dt>
-<dd>Especifica um conjunto com base em um destino alocado em um servidor iSCSI.
-Ao selecionar <uicontrol>iSCSI</uicontrol>, digite o endere��o IP do
<uicontrol>Servidor
-iSCSI</uicontrol> e o <uicontrol>Destino</uicontrol> no
-servidor iSCSI. Opcionalmente, �� poss��vel selecionar para incluir a autentica����o
iSCSI.</dd>
-</dlentry><dlentry>
-<dt><uicontrol>L��gico</uicontrol></dt>
-<dd>Especifica um storage pool do volume l��gico. Selecione o local para
-o dispositivo em <uicontrol>Caminho do dispositivo</uicontrol>.</dd>
-</dlentry><dlentry>
-<dt><uicontrol>Fibre Channel SCSI</uicontrol></dt>
-<dd>Especifica um conjunto com base em um Fibre Channel SCSI. Selecione qual
-adaptador SCSI deve ser usado.</dd>
-</dlentry></dl></li>
-<li>Clique em <uicontrol>Criar</uicontrol>.</li>
-</ol> </p>
-</csbody>
-</cshelp>
-</cshelp>
-
-
-<!-- ENGL1SH_VERS10N 22336_4 DO NOT REMOVE OR CHANGE THIS LINE -->
-<!-- T9N_SRC_ID 233 -->
-<!-- T9N_SH1P_STR1NG KV211AAP001 1 -->
diff --git a/plugins/kimchi/ui/pages/help/pt_BR/templates.dita
b/plugins/kimchi/ui/pages/help/pt_BR/templates.dita
deleted file mode 100644
index f3c6515..0000000
--- a/plugins/kimchi/ui/pages/help/pt_BR/templates.dita
+++ /dev/null
@@ -1,127 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--Arbortext, Inc., 1988-2011, v.4002-->
-<!DOCTYPE cshelp PUBLIC "-//IBM//DTD DITA CSHelp//EN"
- "..\dtd\cshelp.dtd">
-
-
-<!--This DITA specialized document type is not supported by the Authoring Tools
development team.
-For support please see:
-https://w3.opensource.ibm.com/projects/dita-cshelp/-->
-<cshelp id="kimhtempl" xml:lang="pt-br">
-<title>Modelos</title>
-<shortdesc>A p��gina <wintitle>Modelos</wintitle> mostra os modelos de
-m��quina virtual definidos que podem ser usados para criar M��quinas Virtuais do
KVM.</shortdesc>
-<csbody>
-<p>Para cada modelo, as informa����es a seguir s��o exibidas:<dl>
-<dlentry>
-<dt>S.O.</dt>
-<dd>Nome do sistema operacional ou distribui����o.</dd>
-</dlentry><dlentry>
-<dt>Vers��o</dt>
-<dd>Vers��o do sistema operacional ou distribui����o.</dd>
-</dlentry><dlentry>
-<dt>CPUs</dt>
-<dd>N��mero de processadores que est��o definidos para o modelo.</dd>
-</dlentry><dlentry>
-<dt>Mem��ria</dt>
-<dd>Quantia de mem��ria de acesso aleat��rio a ser alocada, em MB.</dd>
-</dlentry></dl></p>
-<p>As a����es a seguir podem ser selecionadas para cada modelo:<ul>
-<li>Selecione <uicontrol>Editar</uicontrol> para editar o
modelo.</li>
-<li>Selecione <uicontrol>Excluir</uicontrol> para excluir o
modelo.</li>
-</ul>Para incluir um modelo, clique no ��cone <uicontrol>mais
(+)</uicontrol> na
-parte superior direita da exibi����o.</p>
-</csbody>
-<cshelp id="kimhedittempl" xml:lang="en-us">
-<title>Editar modelo</title>
-<shortdesc>Edite um modelo existente.</shortdesc>
-<csbody>
-<p>Para cada modelo, as informa����es a seguir s��o exibidas: <dl>
-<dlentry>
-<dt>Nome</dt>
-<dd>Nome do modelo.</dd>
-</dlentry><dlentry>
-<dt>Fornecedor</dt>
-<dd>O nome da empresa que criou o sistema operacional ou a distribui����o
-que o modelo est�� configurado para usar.</dd>
-</dlentry><dlentry>
-<dt>Vers��o</dt>
-<dd>A vers��o do sistema operacional ou distribui����o que o modelo
-est�� configurado para usar.</dd>
-</dlentry><dlentry>
-<dt>N��mero de CPU</dt>
-<dd>N��mero de processadores que est��o definidos para o modelo.</dd>
-</dlentry><dlentry>
-<dt>Mem��ria</dt>
-<dd>Quantia de mem��ria em MB a ser alocada para a m��quina virtual.</dd>
-</dlentry><dlentry>
-<dt>Disco</dt>
-<dd>O tamanho do disco em GB.</dd>
-</dlentry><dlentry>
-<dt>CD-ROM</dt>
-<dd>O caminho do arquivo para o local do arquivo ISO usado para instalar o
-convidado do KVM.</dd>
-</dlentry><dlentry>
-<dt>storage pool</dt>
-<dd>storage pool espec��fico ou storage pool padr��o.</dd>
-</dlentry><dlentry>
-<dt>Rede</dt>
-<dd>As interfaces de rede padr��o dispon��veis para o convidado do KVM. ��
poss��vel
-selecionar diversas redes.</dd>
-</dlentry></dl> Os campos que n��o est��o desativados podem ser editados.
Depois
-de editar um campo, clique em <uicontrol>Salvar</uicontrol>. </p>
-</csbody>
-</cshelp>
-<cshelp id="kimhaddtempl">
-<title>Incluir modelo</title>
-<shortdesc>Inclua um modelo a partir da m��dia de origem.
-�� poss��vel incluir sua pr��pria imagem ISO em seu conjunto de armazenamentos
'ISO' para a descoberta a seguir.</shortdesc>
-<csbody>
-<p>Selecione o local da m��dia de origem a partir das op����es a seguir:<dl>
-<dlentry>
-<dt>Imagem ISO local</dt>
-<dd>Selecione para varrer conjuntos de armazenamentos para imagens ISO de
instala����o dispon��veis
-no sistema.</dd>
-</dlentry><dlentry>
-<dt>Imagem ISO remota</dt>
-<dd>Selecione para especificar um local remoto para uma imagem ISO de
instala����o.</dd>
-</dlentry></dl></p>
-</csbody>
-</cshelp>
-<cshelp id="kimhaddloct">
-<title>Incluir modelo - imagem ISO local</title>
-<shortdesc>Inclua um modelo a partir de uma imagem ISO local.</shortdesc>
-<csbody>
-<p>As imagens ISO dispon��veis no sistema s��o exibidas.<dl><dlentry>
-<dt>S.O.</dt>
-<dd>Nome do sistema operacional ou distribui����o.</dd>
-</dlentry><dlentry>
-<dt>Vers��o</dt>
-<dd>Vers��o do sistema operacional ou distribui����o.</dd>
-</dlentry><dlentry>
-<dt>Tamanho</dt>
-<dd>Tamanho da imagem ISO.</dd>
-</dlentry></dl></p>
-<p>Para criar um modelo a partir de uma imagem ISO, escolha a partir das op����es
-a seguir:<ul>
-<li>Selecione uma imagem ISO para criar um modelo a partir dela, em seguida, clique
em <uicontrol>Criar
-modelos a partir do ISO selecionado</uicontrol>.</li>
-<li>Selecione <uicontrol>Todos</uicontrol> para criar um modelo a
partir de cada
-imagem ISO listada, em seguida, clique em <uicontrol>Criar modelos a partir do
-ISO selecionado</uicontrol>.</li>
-<li>Se a imagem ISO que voc�� deseja usar n��o aparecer nos resultados de
-varredura, ser�� poss��vel selecionar a partir das op����es a seguir:<ul>
-<li>Selecione <uicontrol>Eu desejo usar um arquivo ISO
espec��fico</uicontrol> para
-especificar um caminho para a imagem ISO.</li>
-<li>Clique em <uicontrol>Procurar mais ISOs</uicontrol> para procurar
mais
-imagens ISO.</li>
-</ul></li>
-</ul></p>
-</csbody>
-</cshelp>
-</cshelp>
-
-
-<!-- ENGL1SH_VERS10N 61085_5 DO NOT REMOVE OR CHANGE THIS LINE -->
-<!-- T9N_SRC_ID 229 -->
-<!-- T9N_SH1P_STR1NG KV211AAP001 1 -->
diff --git a/plugins/kimchi/ui/pages/help/ru_RU/Makefile.am
b/plugins/kimchi/ui/pages/help/ru_RU/Makefile.am
deleted file mode 100644
index 85ca27a..0000000
--- a/plugins/kimchi/ui/pages/help/ru_RU/Makefile.am
+++ /dev/null
@@ -1,23 +0,0 @@
-# Copyright IBM Corp, 2014
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-
-ru_RU_helpdir = $(datadir)/wok/plugins/kimchi/ui/pages/help/ru_RU
-
-dist_ru_RU_help_DATA = $(wildcard *.html) $(NULL)
-
-EXTRA_DIST = $(wildcard *.dita)
-
-CLEANFILES = $(wildcard *.html)
diff --git a/plugins/kimchi/ui/pages/help/ru_RU/guests.dita
b/plugins/kimchi/ui/pages/help/ru_RU/guests.dita
deleted file mode 100644
index 701dd7e..0000000
--- a/plugins/kimchi/ui/pages/help/ru_RU/guests.dita
+++ /dev/null
@@ -1,122 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--Arbortext, Inc., 1988-2011, v.4002-->
-<!DOCTYPE cshelp PUBLIC "-//IBM//DTD DITA CSHelp//EN"
- "..\dtd\cshelp.dtd">
-
-
-<!--This DITA specialized document type is not supported by the Authoring Tools
development team.
-For support please see:
-https://w3.opensource.ibm.com/projects/dita-cshelp/-->
-<cshelp id="kimhvirtm" xml:lang="ru-ru">
-<title>���������������� ��������������</title>
-<shortdesc>���� ���������������� <wintitle>����������������
��������������</wintitle> ������������������������ ������������ ������������������
���������������������� ���������� KVM.</shortdesc>
-<csbody>
-<p>������ ������������ ���������������� �������������� ������������������������
������������������ ��������������������:<dl><dlentry>
-<dt>������</dt>
-<dd>������ ���������������������� ������������.</dd>
-</dlentry><dlentry>
-<dt>������������������</dt>
-<dd>�������������� �������������������������� �������������������� ��
���������������������� ������������.</dd>
-</dlentry><dlentry>
-<dt>�������������� ��������-����������</dt>
-<dd>���������������� ���������������� ����������-������������ ��
����/��.</dd>
-</dlentry><dlentry>
-<dt>���������������� ��������-����������</dt>
-<dd>���������������� ������������������ ����������-������������ ��
����/��.</dd>
-</dlentry><dlentry>
-<dt>Livetile</dt>
-<dd>������������������ �������������� ���������������� ������������������������
�������������� ������ ������������, ���������������������������� �������������� ����
<tm tmtype="tm" trademark="Linux">Linux</tm>, ��������
���������������� �������������� ���� ��������������.</dd>
-</dlentry></dl></p>
-<p>������ ������������ ���������������� �������������� ������������������������
������������������ ������������ ����������������:<dl>
-<dlentry>
-<dt>����������</dt>
-<dd>���������� ���������������� ��������������. </dd>
-</dlentry><dlentry>
-<dt>�������������� (������������/������������������)</dt>
-<dd>������������������/�������������������� �������������� ����������������
��������������. �������� ������������ ��������������, �������������� ������������������.
�������� ������������ ��������������, �������������� ����������������.</dd>
-</dlentry></dl> </p>
-<p>������ ������������ ���������������� �������������� ����������������
������������������ ����������������:<ul>
-<li><uicontrol>������������������������</uicontrol> -
������������������������ �� ������������������ �������������� ����������������
������������������������ ��������������.</li>
-<li><uicontrol>�������������������� ��������������������</uicontrol> -
������������������ �������� �� �������������������������� ����������������.</li>
-<li><uicontrol>����������</uicontrol> - ���������� ����������������
��������������.</li>
-<li><uicontrol>����������������</uicontrol> - ������������������
�������������� ���������������� ��������������. ���������������� ����������������
�������������� ���������� ����������������, ������������ ���������� ��������������
����������������������.</li>
-<li><uicontrol>��������������</uicontrol> - ��������������
���������������� ��������������.</li>
-</ul>������ ���������������� ���������������� ��������������
(���������������������� ������������) ���������������� ���� ������������
<uicontrol>��������
-(+)</uicontrol> �� ������������ �������������� ��������
����������������.</p>
-</csbody>
-<cshelp id="kimhvirtmcrt" xml:lang="ru-ru">
-<title>���������������� ���������������������� ������������</title>
-<shortdesc>���������������� ���������������������� ������������ �� ��������������
��������������.</shortdesc>
-<csbody>
-<p> <ol>
-<li>�������������� ������ ������ �������������������������� ����������������������
������������.</li>
-<li rev="rev1">���������������� ������������. <ul>
-<li>�������� �������� ��������������, ���������������� ������������ ��
������������.</li>
-<li>�������� ���������������� ������, ���������������� ����
<uicontrol>�������������� ������������</uicontrol>, ���������� ��������������
������������.</li>
-</ul></li>
-<li>���������������� ����
<uicontrol>��������������</uicontrol>.</li>
-</ol> </p>
-</csbody>
-</cshelp>
-<cshelp id="kimhvirtmedit" xml:lang="ru-ru">
-<title>������������������ ���������������� ��������������</title>
-<shortdesc>������������������ �������������� ������������������������
���������������������� ������������. ������������������ ���������������� ����������
���������������� ������������ �������� ���������������������� ���������������� ����������.
������������ ���������������� �� �������� ���������� ������������������
������������������������.</shortdesc>
-<csprolog><csmetadata></csmetadata></csprolog>
-<csbody>
-<p>������ ������������ ���������������� �������������� ������������������������
������������������ �������������������� ���� ��������������
<wintitle>����������</wintitle>:<dl>
-<dlentry>
-<dt>������</dt>
-<dd>������ ���������������������� ������������. (����������
�������������������������� �������� ���������������������� ����������������
����������)</dd>
-</dlentry><dlentry>
-<dt>��������������������</dt>
-<dd>���������� ����������������������. (�������� ���������������� ����������
����������������, ���������� ���������� �������������� �� �������� ����������
������������������������)</dd>
-</dlentry><dlentry>
-<dt>������������</dt>
-<dd>���������� ������������ �� ����. (�������� ���������������� ����������
����������������, ���������� ���������� �������������� �� �������� ����������
������������������������)</dd>
-</dlentry><dlentry>
-<dt>������������</dt>
-<dd>���������������������� ����������������������, ����������������������������
�������������� ���� Linux. ������ ������������������������ ������������ ����������������
������������������
-(Livetile), ���������� ���������������� �������������� ���� ��������������.</dd>
-</dlentry></dl></p>
-<p>���� �������������� <wintitle>����������������
������������</wintitle> ������������������������ ������������������
��������������������.</p>
-<dl><dlentry>
-<dt>���������������� ������������</dt>
-<dd>�������������������� ������������������������ ���������� ISO ������
������������������.</dd>
-</dlentry></dl>
-<p> ���������������� �������� ���������� ����������������. ����������
������������������ �������� ���������������� ����
<uicontrol>������������������</uicontrol>. </p>
-</csbody>
-</cshelp>
-<cshelp id="kimstoragedevice" xml:lang="ru-ru">
-<title>��������������������, ������������ �� ��������������������
������������������ ����������������</title>
-<shortdesc rev="rev1">�� ���������������������� ������������ ����������
������������������, ���������������� �� ������������������ ��������������������
����������������. ������������������������ ����������������������������
�������������������� - CDROM. ������ ������������������ ������������������
���������������� ������������������ ������������������
����������������:</shortdesc>
-<csbody>
-<ol>
-<li>�� �������� <wintitle>���������������� ����������������
��������������</wintitle> ���������������� <wintitle>����������������
������������</wintitle>.</li>
-<li>������ ������������ �������������������� ���������������� ���������������� ����
������������ ������������ �� <uicontrol>������������������ ���������� ������������
(/)</uicontrol>. �������������� �������� �� ���������� ISO �� ���������������� ����
<uicontrol>����������������</uicontrol>.</li>
-<li>������ �������������������� �������������������� ����������������
���������������� ���� ������������ ������������ �� <uicontrol>��������������
���������������������������� ������������ (-)</uicontrol>. ����������������������
���������������� �� �������������� ������������
<uicontrol>OK</uicontrol>.</li>
-<li>������ �������������������� �������������������� ����������������
���������������� ���� �������������� ������������ �� <uicontrol>��������������
������������
-(+)</uicontrol>. �������������� ������ �������������������� �� �������� ��
���������� ISO �� ���������������� ����
<uicontrol>��������������������</uicontrol>.</li>
-</ol>
-</csbody>
-</cshelp>
-<cshelp id="kimreplacemedia" xml:lang="ru-ru">
-<title>������������ CDROM ���������������������� ������������</title>
-<shortdesc rev="rev1">���� ������������������ ������������������
���������� ���������������� �������������������� CDROM ������ ����������������������
������������.</shortdesc>
-<csbody>
-<ol>
-<li>������������������ ���������������������� ������������.</li>
-<li>�� �������� ���������������� ����������������
<uicontrol>�������������������� ��������������������</uicontrol>.</li>
-<li>������ ������������ ����������������, ������������������������ �� CDROM,
���������������� ���� ������������ �� <uicontrol>������������������ ����������
������������
-(/)</uicontrol> ���������� �� ���������� hdc.</li>
-<li>���� ���������������� <wintitle>������������ CDROM ����������������������
������������</wintitle> �������������� �������� �� ���������� ISO. ������
������������ �������� ���������������� ������������ ������ ������������.</li>
-<li>���������������� ����������
<uicontrol>����������������</uicontrol>.</li>
-</ol>
-</csbody>
-</cshelp>
-<?tm 1391540919 3?>
-</cshelp>
-
-
-<!-- ENGL1SH_VERS10N 45645_6 DO NOT REMOVE OR CHANGE THIS LINE -->
-<!-- T9N_SRC_ID 231 -->
-<!-- T9N_SH1P_STR1NG KV211AAP001 1 -->
diff --git a/plugins/kimchi/ui/pages/help/ru_RU/host.dita
b/plugins/kimchi/ui/pages/help/ru_RU/host.dita
deleted file mode 100644
index fb72c21..0000000
--- a/plugins/kimchi/ui/pages/help/ru_RU/host.dita
+++ /dev/null
@@ -1,48 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--Arbortext, Inc., 1988-2011, v.4002-->
-<!DOCTYPE cshelp PUBLIC "-//IBM//DTD DITA CSHelp//EN"
- "..\dtd\cshelp.dtd">
-
-
-<!--This DITA specialized document type is not supported by the Authoring Tools
development team.
-For support please see:
-https://w3.opensource.ibm.com/projects/dita-cshelp/-->
-<cshelp id="kimhhost" xml:lang="ru-ru">
-<title>��������</title>
-<shortdesc>���������������� <wintitle>��������</wintitle>
�������������������� �������������������� �� �������������� ���������� ��
������������������ �������������������������� ��������, ��������������������������
�������� �� ������������������������ �� ��������.</shortdesc>
-<csbody>
-<p>���� ���������� ���������� ������������������ ������������������
����������������:<ul>
-<li><uicontrol>������������������ ������������</uicontrol> -
�������������������� �������������� ����������.</li>
-<li><uicontrol>��������������������������</uicontrol> -
�������������������������� �������������� ����������.</li>
-<li><uicontrol>������������������������</uicontrol> - ��������������
�������������������� VNC �� ���������������� ����������, �������� ������ ������ ����
����������������������.</li>
-</ul></p>
-<p>���������������� ���� ������������������ ���������������� ������
������������������ �������������������� �� ����������:<dl>
-<dlentry>
-<dt>�������������� ��������������������</dt>
-<dd>�� �������� �������������� ������������������������ ��������������
������������������������ ��������������, ������ ������������ �� �������������� ������, ��
���������� ������ �������������������� �� ���������� ������������ �� ����.</dd>
-</dlentry><dlentry>
-<dt>������������������ ��������������������</dt>
-<dd>�� �������� �������������� ������������������������ ��������������,
�������������������� ���������������������������� �������������������� ��
��������������������, ������������, ���������������� ����������-������������ ��
�������������� ����������-������������ ������ ����������. ����������������
<uicontrol>�������� ������������ ���������� ���������������� ��������
����������������</uicontrol>, ���������� �������� ������������
���������������������� ���������� ���������������� �������������� ��������.</dd>
-</dlentry><dlentry>
-<dt>�������������������� ������������������������
����������������������</dt>
-<dd>�� �������� �������������� ������������������������ �������������������� ������
�������� ��������������, ������ �������������� ���������������� ��������������������,
�������������� ������ ������������, ������������, ���������������������� ��
������������������. ���������� ���������������� ������ ������������ �� ������������
�������������� ���� <uicontrol>���������������� ������</uicontrol>.
������������������ ������������ ������ �������������������� ��������������
������������.</dd>
-</dlentry><dlentry>
-<dt>������������������</dt>
-<dd>�� �������� �������������� ������������������������ ������������������,
������������������ �� ���������������� ����������. ������������������ ����������
������������������, ������������������������, ���������������� �� ��������������. ������
�������������������� ������������������ ���������������������� �� ����������������
����������, ������ ������������������ ������������������ ��������������������
������������������ ������ ����������. �������� �������������� - Red Hat Enterprise Linux
������ Fedora, ���������� ���������������� ������������������
<filepath>yum</filepath>.
-�������� �������������� - Ubuntu ������ Debian, ���������������� ������������������
<filepath>deb</filepath>.<p>������ ������������ ��
���������������������� yum ���������� ���������������� ���������������� GPG ������
���������������� ���������������������� �������������� ���� ��������������
������������������.
-���������������� ������������������ �� ���������������� ����
<uicontrol>����������������</uicontrol>. ����������������
<uicontrol>����</uicontrol>, ���������� ���������������� ���������������� GPG,
�� �������������� URL ���������� ������������ GPG ������
������������������.</p></dd>
-</dlentry><dlentry>
-<dt>�������������������� ������������</dt>
-<dd>�� �������� �������������� ������������������������ ��������������������
������������, �������������� ������ �� ��������.
-���������������� �������������� ������ ����������������, ����������������������������,
���������������� �� ���������������� ��������������.<p>��������������������
���������� ������������������ ���������������� <cmdname>sosreport</cmdname>.
���� ���������������� ������ Red
-Hat Enterprise <tm tmtype="tm"
trademark="Linux">Linux</tm>, Fedora �� Ubuntu. ��������������
�������������� �������� .tar �� �������������������������������� ��
������������������������������ ����������������������, ���������� ������ ������������
��������, ���������������������� ������������ �� ���������� ������������������������
�������������� �� ����������.
-�������������� ���������� ������������������ �������������� ������������������ ������
���������� ���������������������������� �������������������� �� ������������������ ����
���������� �� ���������������������������� ������������.</p> </dd>
-</dlentry></dl></p>
-</csbody>
-<?tm 1392659967 1?>
-</cshelp>
-
-
-<!-- ENGL1SH_VERS10N 47930_4 DO NOT REMOVE OR CHANGE THIS LINE -->
-<!-- T9N_SRC_ID 232 -->
-<!-- T9N_SH1P_STR1NG KVM21AAP001 3 -->
diff --git a/plugins/kimchi/ui/pages/help/ru_RU/network.dita
b/plugins/kimchi/ui/pages/help/ru_RU/network.dita
deleted file mode 100644
index 9cdcdd1..0000000
--- a/plugins/kimchi/ui/pages/help/ru_RU/network.dita
+++ /dev/null
@@ -1,61 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--Arbortext, Inc., 1988-2011, v.4002-->
-<!DOCTYPE cshelp PUBLIC "-//IBM//DTD DITA CSHelp//EN"
- "..\dtd\cshelp.dtd">
-
-
-<!--This DITA specialized document type is not supported by the Authoring Tools
development team.
-For support please see:
-https://w3.opensource.ibm.com/projects/dita-cshelp/-->
-<cshelp id="kimhnetw" xml:lang="ru-ru">
-<title>��������</title>
-<shortdesc>���� ���������������� <wintitle>��������</wintitle>
������������������������ �������������������� �� ��������������
��������������������.</shortdesc>
-<csbody>
-<p><dl><dlentry>
-<dt>������ ��������</dt>
-<dd>������ �������� ������ <uicontrol>����
������������������</uicontrol>.</dd>
-</dlentry><dlentry>
-<dt>������������������</dt>
-<dd>������������������ �������� - ���������������� (��������������) ������
�������������������� (��������������). </dd>
-</dlentry><dlentry>
-<dt>������ ��������</dt>
-<dd>������ ��������, ���������������� <uicontrol>NAT</uicontrol>
(���������������������������� �������������� ��������������).</dd>
-</dlentry><dlentry>
-<dt>������������������</dt>
-<dd>�������������� ������������������, ����������������
<uicontrol>virbr0</uicontrol> (���� ������������������).</dd>
-</dlentry><dlentry>
-<dt>���������������� ������������������������</dt>
-<dd>IP-����������.</dd>
-</dlentry></dl></p>
-<p>���������������� ������������������ ����������������:<ul>
-<li rev="rev1"><uicontrol>������������������</uicontrol> -
�������������� �������������� ��������������������.</li>
-<li><uicontrol>��������������������</uicontrol> - ��������������
�������������� ��������������������.</li>
-<li><uicontrol>��������������</uicontrol> - ��������������
�������������������� �� ��������������������.</li>
-</ul>������ ���������������� �������� ���������������� ���� ������������
<uicontrol>���������� (+)</uicontrol> �� ������������ �������������� ��������
����������������.</p>
-</csbody>
-<cshelp id="kimhnetwcrt" xml:lang="ru-ru">
-<title>���������������� ��������</title>
-<shortdesc>���������������� ��������.</shortdesc>
-<csbody>
-<p> <ol>
-<li>�������������� ������ ��������.</li>
-<li>���������������� ������ ��������. <dl
rev="rev1"><dlentry>
-<dt><uicontrol>��������������������������</uicontrol></dt>
-<dd>�������������������������� ����������. ���������������� �������������� ����
���������� ������������������������ �������������� �� ����������������
������������������.</dd>
-</dlentry><dlentry>
-<dt><uicontrol>NAT</uicontrol></dt>
-<dd>���������� ���������������������������� �������������� ��������������.
���������� �������������� ���������� ������������������ �� ����������������
������������������ ���������������������������� ���������� IP-���������� ����������.
�������������� �������������� ���� ���������� ������������������������ ��
����������������.</dd>
-</dlentry><dlentry>
-<dt><uicontrol>���������� ��������</uicontrol></dt>
-<dd>���������� ������������ ���������� ��������. ���������������� ��������������
���������� ������������������������ �������������� �� ���������������� ������������������,
�� �������������� �������������� ���������� ������������������������ �� ����������������,
������ �������� ���� ���� �������� ���������������������� ������������������ �� ��������.
�� ������������ ������������ ���������� �������� �������������������� ��������������
���������������������������� �������������������� �� ��������������
������������������������ �� VLAN.</dd>
-</dlentry></dl></li>
-<li>���������������� ����
<uicontrol>��������������</uicontrol>.</li>
-</ol> </p>
-</csbody>
-</cshelp>
-</cshelp>
-
-
-<!-- ENGL1SH_VERS10N 47050_3 DO NOT REMOVE OR CHANGE THIS LINE -->
-<!-- T9N_SRC_ID 230 -->
-<!-- T9N_SH1P_STR1NG KVM21AAP001 3 -->
diff --git a/plugins/kimchi/ui/pages/help/ru_RU/storage.dita
b/plugins/kimchi/ui/pages/help/ru_RU/storage.dita
deleted file mode 100644
index fa37edc..0000000
--- a/plugins/kimchi/ui/pages/help/ru_RU/storage.dita
+++ /dev/null
@@ -1,88 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--Arbortext, Inc., 1988-2011, v.4002-->
-<!DOCTYPE cshelp PUBLIC "-//IBM//DTD DITA CSHelp//EN"
- "..\dtd\cshelp.dtd">
-
-
-<!--This DITA specialized document type is not supported by the Authoring Tools
development team.
-For support please see:
-https://w3.opensource.ibm.com/projects/dita-cshelp/-->
-<cshelp id="kimhstor" xml:lang="ru-ru">
-<title>���������������� ������������</title>
-<shortdesc>���� ���������������� <wintitle>����������������
������������</wintitle> ������������������������ ������������ ������������������
���������� ������������, �������������� �������� ������������ '����
������������������' �� 'ISO'.
-�������� ���� ������������ ������������������������ ���������������������� ISO,
���������������� ������ �� �������� ���������������� ������������
'ISO'.</shortdesc>
-<csbody>
-<p>������ �������������� �������� ������������ ������������������������
������������������ ��������������������:<dl>
-<dlentry>
-<dt>������</dt>
-<dd>������ �������� ������������ �� ��������������
��������������������������.</dd>
-</dlentry><dlentry>
-<dt>������������������</dt>
-<dd>������������������ �������� ������������ - ���������������� (��������������)
������ �������������������� (��������������). </dd>
-</dlentry><dlentry>
-<dt>������������������������</dt>
-<dd>�������� �� ������������������������ �������� ������������.</dd>
-</dlentry><dlentry>
-<dt>������</dt>
-<dd>������ �������� ������������, ����������������
<uicontrol>��������������</uicontrol>.</dd>
-</dlentry><dlentry>
-<dt>��������������</dt>
-<dd>���������� �������� ������������.</dd>
-</dlentry><dlentry>
-<dt>����������������</dt>
-<dd>���������� �������������������� ������������ �� ��������.</dd>
-</dlentry></dl></p>
-<p>������ �������������� �������� ������������ ���������� ����������������
������������������ ����������������:<ul>
-<li><uicontrol>������������������������</uicontrol> -
������������������������ ������ ������������, ���������� ������ ���������� ��������
������������������������.</li>
-<li><uicontrol>����������������������������</uicontrol> -
���������������������������� ���������������� ������ ������������.</li>
-<li><uicontrol>��������������</uicontrol> - ��������������
�������������������� ������ ������������.</li>
-</ul></p>
-<p>������ ������������������ ���������������� �� ���������� �������� ������������
���������������� ���� �������������� �� ������������ ���������� ������������ ��������
������������. ���������������� ����������������:<dl><dlentry>
-<dt>������</dt>
-<dd>������ ��������, ����������������
<uicontrol>��������</uicontrol>.</dd>
-</dlentry><dlentry>
-<dt>������������</dt>
-<dd>������������ (�������������� ���� ��������).</dd>
-</dlentry><dlentry>
-<dt>��������������</dt>
-<dd>������������ ��������.</dd>
-</dlentry><dlentry>
-<dt>������������������</dt>
-<dd>���������� �������������������� ������������ �� ��������.</dd>
-</dlentry></dl>������ ���������������� �������� ������������ ����������������
���� ������������ <uicontrol>���������� (+)</uicontrol> �� ������������
�������������� �������� ����������������.</p>
-</csbody>
-<cshelp id="kimhdefstor" xml:lang="ru-ru">
-<title>���������������� �������� ������������</title>
-<shortdesc> ���������������� �������� ������������.</shortdesc>
-<csbody>
-<p> <ol>
-<li>�� �������� <uicontrol>������ �������� ������������</uicontrol>
�������������� ������ ������ �������������������������� �������� ������������.</li>
-<li>�� ������������ <uicontrol>������ �������� ������������</uicontrol>
���������������� ������: <dl><dlentry>
-<dt><uicontrol>��������������</uicontrol></dt>
-<dd>������������ ������-��������������. ������ ������������ ��������
<uicontrol>��������������</uicontrol> ������������������ ��������
-<uicontrol>�������� �� �������� ������������</uicontrol> (�������� ��
�������� ������������ �� ���������������� ��������������).</dd>
-</dlentry><dlentry>
-<dt><uicontrol>NFS</uicontrol></dt>
-<dd>������������ ������ ���� ������������ �������������� ����������������
��������������. ������ ������������ <uicontrol>NFS</uicontrol> ��������������
���������� ��
-�������� <uicontrol>IP-���������� �������������� NFS</uicontrol> �� ��������
�� ���������������������������������� ���������������� �� ��������
<uicontrol>�������� NFS</uicontrol>.</dd>
-</dlentry><dlentry>
-<dt><uicontrol>iSCSI</uicontrol></dt>
-<dd>������������ ������ ���� ������������ ���������������� ��������������,
���������������������� ���� �������������� iSCSI.
-������ ������������ �������� <uicontrol>iSCSI</uicontrol> ��������������
IP-���������� �� �������� <uicontrol>������������ iSCSI</uicontrol> ��
�������������� ������������ ���� �������������� iSCSI �� ��������
<uicontrol>�������������� ������������</uicontrol>. ���������� ����������
���������������� �������������������������� iSCSI.</dd>
-</dlentry><dlentry>
-<dt><uicontrol>��������������������</uicontrol></dt>
-<dd>������������ ������ ������������ ���� ������������ ����������������������
��������. ���������������� ������������������������ �������������������� �� ��������
<uicontrol>�������� �� ��������������������</uicontrol>.</dd>
-</dlentry><dlentry>
-<dt><uicontrol>SCSI Fibre Channel</uicontrol></dt>
-<dd>������������ ������ ���� ������������ SCSI Fibre Channel. ����������������
�������������� SCSI.</dd>
-</dlentry></dl></li>
-<li>���������������� ����
<uicontrol>��������������</uicontrol>.</li>
-</ol> </p>
-</csbody>
-</cshelp>
-</cshelp>
-
-
-<!-- ENGL1SH_VERS10N 22336_4 DO NOT REMOVE OR CHANGE THIS LINE -->
-<!-- T9N_SRC_ID 233 -->
-<!-- T9N_SH1P_STR1NG KV211AAP001 1 -->
diff --git a/plugins/kimchi/ui/pages/help/ru_RU/templates.dita
b/plugins/kimchi/ui/pages/help/ru_RU/templates.dita
deleted file mode 100644
index 27ce4ae..0000000
--- a/plugins/kimchi/ui/pages/help/ru_RU/templates.dita
+++ /dev/null
@@ -1,111 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--Arbortext, Inc., 1988-2011, v.4002-->
-<!DOCTYPE cshelp PUBLIC "-//IBM//DTD DITA CSHelp//EN"
- "..\dtd\cshelp.dtd">
-
-
-<!--This DITA specialized document type is not supported by the Authoring Tools
development team.
-For support please see:
-https://w3.opensource.ibm.com/projects/dita-cshelp/-->
-<cshelp id="kimhtempl" xml:lang="ru-ru">
-<title>��������������</title>
-<shortdesc>���� ���������������� <wintitle>��������������</wintitle>
������������������������ ������������������ �������������� ����������������������
����������, �������������� ���������� ������������������������ ������ ����������������
���������������� ������������ KVM.</shortdesc>
-<csbody>
-<p>������ �������������� �������������� ������������������������ ������������������
��������������������:<dl>
-<dlentry>
-<dt>����</dt>
-<dd>������ ������������������������ �������������� ������ ����������������
������������������������ ��������������.</dd>
-</dlentry><dlentry>
-<dt>������������</dt>
-<dd>������������ ������������������������ �������������� ������ ����������������
������������������������ ��������������.</dd>
-</dlentry><dlentry>
-<dt>��������������������</dt>
-<dd>�������������������� ���������������������� ������ ��������������.</dd>
-</dlentry><dlentry>
-<dt>������������</dt>
-<dd>�������������������� ���������� ���������������������� ������������ ��
����.</dd>
-</dlentry></dl></p>
-<p>������ �������������� �������������� ���������� ����������������
������������������ ����������������:<ul>
-<li><uicontrol>����������������</uicontrol> - ����������������
������������.</li>
-<li><uicontrol>��������������</uicontrol> - ��������������
������������.</li>
-</ul>������ �������������������� �������������� ���������������� ���� ������������
<uicontrol>���������� (+)</uicontrol> �� ������������ �������������� ��������
����������������.</p>
-</csbody>
-<cshelp id="kimhedittempl" xml:lang="ru-ru">
-<title>���������������� ������������</title>
-<shortdesc>���������������� ������������������������
������������.</shortdesc>
-<csbody>
-<p>������ �������������� �������������� ������������������������ ������������������
��������������������: <dl>
-<dlentry>
-<dt>������</dt>
-<dd>������ ��������������.</dd>
-</dlentry><dlentry>
-<dt>������������</dt>
-<dd>������ ����������������, ������������������ ������������������������
�������������� ������ �������������� ������������������������ ��������������, ������
�������������������������� �������������� ��������������������������
������������.</dd>
-</dlentry><dlentry>
-<dt>������������</dt>
-<dd>������������ ������������������������ �������������� ������ ����������������
������������������������ ��������������, ������ �������������������������� ��������������
�������������������������� ������������.</dd>
-</dlentry><dlentry>
-<dt>�������������������� ����������������������</dt>
-<dd>�������������������� ���������������������� ������ ��������������.</dd>
-</dlentry><dlentry>
-<dt>������������</dt>
-<dd>���������� ������������ �� ����, �������������������� ����������������������
������������.</dd>
-</dlentry><dlentry>
-<dt>��������</dt>
-<dd>������������ ���������� �� ����.</dd>
-</dlentry><dlentry>
-<dt>CDROM</dt>
-<dd>�������� �� ���������� ISO ������ ������������������ ����������������
�������������� KVM.</dd>
-</dlentry><dlentry>
-<dt>������ ������������</dt>
-<dd>������������������������ ������ ������������ ������ ������ ������������ ����
������������������.</dd>
-</dlentry><dlentry>
-<dt>��������</dt>
-<dd>�������������� �������������������� ���� ������������������, ������������������
������ ���������������� �������������� KVM. ���������� �������������� ������������������
����������.</dd>
-</dlentry></dl> ���������������� �������� ���������� ����������������.
���������� ������������������ �������� ���������������� ����
<uicontrol>������������������</uicontrol>. </p>
-</csbody>
-</cshelp>
-<cshelp id="kimhaddtempl">
-<title>�������������������� ��������������</title>
-<shortdesc>�������������������� �������������� �� ������������������
����������������. ���������������� ���������������������� ���������� ISO ��
���������������� ������������ ISO ������ ����������������������
������������.</shortdesc>
-<csbody>
-<p>���������������� �������� ���� ������������������ ������������������
������������������������ ������������������ ����������������:<dl>
-<dlentry>
-<dt>������������������ ���������� ISO</dt>
-<dd>���������������� �������� �������������� ������ ������������
������������������������ �������������� ISO �� ������������������ ���������� ������������
��������������.</dd>
-</dlentry><dlentry>
-<dt>������������������ ���������� ISO</dt>
-<dd>���������������� �������� ��������������, ���������� ��������������
������������������ ������������������������ �������������������������� ������������
ISO.</dd>
-</dlentry></dl></p>
-</csbody>
-</cshelp>
-<cshelp id="kimhaddloct">
-<title>�������������������� �������������� (������������������ ����������
ISO)</title>
-<shortdesc>�������������������� �������������� ���� ��������������������
������������ ISO.</shortdesc>
-<csbody>
-<p>���������� ���������������� ������������ ISO, ������������������ ��
��������������.<dl><dlentry>
-<dt>����</dt>
-<dd>������ ������������������������ �������������� ������ ����������������
������������������������ ��������������.</dd>
-</dlentry><dlentry>
-<dt>������������</dt>
-<dd>������������ ������������������������ �������������� ������ ����������������
������������������������ ��������������.</dd>
-</dlentry><dlentry>
-<dt>������������</dt>
-<dd>������������ ������������ ISO.</dd>
-</dlentry></dl></p>
-<p>������ ���������������� �������������� ���� ������������ ISO ����������������
�������� ���� ������������������ ������������������:<ul>
-<li>���������������� ���������� ISO, ���� ���������������� ����������
�������������� ������������, ���������� ���������������� ����
<uicontrol>�������������� �������������� ���� ������������������ ��������������
ISO</uicontrol>.</li>
-<li>���������������� <uicontrol>������</uicontrol>, ����������
�������������� ������������ ���� �������������� ������������ ISO �� ������������,
���������� ���������������� ���� <uicontrol>�������������� �������������� ����
������������������ �������������� ISO</uicontrol>.</li>
-<li>�������� ������������������ ���������� ISO ���������������������� ��
���������������������� ������������, ���������������� �������� ���� ������������������
������������������:<ul>
-<li>���������������� <uicontrol>������������������������ ��������������������
�������� ISO</uicontrol>, ���������� �������������� �������� �� ������������
ISO.</li>
-<li>���������������� ���� <uicontrol>���������� ����������������������������
�������������� ISO</uicontrol> ������ ������������ ����������������������������
�������������� ISO.</li>
-</ul></li>
-</ul></p>
-</csbody>
-</cshelp>
-</cshelp>
-
-
-<!-- ENGL1SH_VERS10N 61085_5 DO NOT REMOVE OR CHANGE THIS LINE -->
-<!-- T9N_SRC_ID 229 -->
-<!-- T9N_SH1P_STR1NG KV211AAP001 1 -->
diff --git a/plugins/kimchi/ui/pages/help/zh_CN/Makefile.am
b/plugins/kimchi/ui/pages/help/zh_CN/Makefile.am
deleted file mode 100644
index e785048..0000000
--- a/plugins/kimchi/ui/pages/help/zh_CN/Makefile.am
+++ /dev/null
@@ -1,23 +0,0 @@
-# Copyright IBM Corp, 2014
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-
-zh_CN_helpdir = $(datadir)/wok/plugins/kimchi/ui/pages/help/zh_CN
-
-dist_zh_CN_help_DATA = $(wildcard *.html) $(NULL)
-
-EXTRA_DIST = $(wildcard *.dita)
-
-CLEANFILES = $(wildcard *.html)
diff --git a/plugins/kimchi/ui/pages/help/zh_CN/guests.dita
b/plugins/kimchi/ui/pages/help/zh_CN/guests.dita
deleted file mode 100644
index d684af2..0000000
--- a/plugins/kimchi/ui/pages/help/zh_CN/guests.dita
+++ /dev/null
@@ -1,118 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--Arbortext, Inc., 1988-2011, v.4002-->
-<!DOCTYPE cshelp PUBLIC "-//IBM//DTD DITA CSHelp//EN"
- "..\dtd\cshelp.dtd">
-
-
-<!--This DITA specialized document type is not supported by the Authoring Tools
development team.
-For support please see:
-https://w3.opensource.ibm.com/projects/dita-cshelp/-->
-<cshelp id="kimhvirtm" xml:lang="zh-cn">
-<title>������</title>
-<shortdesc>���<wintitle>������</wintitle>���������������������������
KVM ������������</shortdesc>
-<csbody>
-<p>���������������������������������������������<dl><dlentry>
-<dt>������</dt>
-<dd>���������������������</dd>
-</dlentry><dlentry>
-<dt>CPU</dt>
-<dd>���������������������������������������</dd>
-</dlentry><dlentry>
-<dt>������ I/O</dt>
-<dd>������������/������������������������ KB/������������</dd>
-</dlentry><dlentry>
-<dt>������ I/O</dt>
-<dd>������������/������������������������ KB/������������</dd>
-</dlentry><dlentry>
-<dt>Livetile</dt>
-<dd>������������������������������������������������������������������������������������
<tm tmtype="tm" trademark="Linux">Linux</tm>
���������������������</dd>
-</dlentry></dl></p>
-<p>���������������������������������������������<dl>
-<dlentry>
-<dt>������</dt>
-<dd>������������������������������</dd>
-</dlentry><dlentry>
-<dt>���������������������������</dt>
-<dd>������������������������������������������������������������������������������������������������������������������������������������������������������</dd>
-</dlentry></dl> </p>
-<p>���������������������������������������<ul>
-<li>������<uicontrol>������</uicontrol>���������������������������������������������������</li>
-<li>������<uicontrol>������������</uicontrol>���������������������������������</li>
-<li>������<uicontrol>������</uicontrol>������������������</li>
-<li>������<uicontrol>������</uicontrol>���������������������������������������������������������������������</li>
-<li>������<uicontrol>������</uicontrol>������������������</li>
-</ul>���������������������������������������������������������<uicontrol>���������
(+) </uicontrol> ���������</p>
-</csbody>
-<cshelp id="kimhvirtmcrt" xml:lang="zh-cn">
-<title>���������������</title>
-<shortdesc>������������������������������������������</shortdesc>
-<csbody>
-<p> <ol>
-<li>���������������������������������������</li>
-<li rev="rev1">���������������<ul>
-<li>���������������������������������������������������������������</li>
-<li>���������������������������������������<uicontrol>������������</uicontrol>������������������</li>
-</ul></li>
-<li>������<uicontrol>������</uicontrol>���</li>
-</ol> </p>
-</csbody>
-</cshelp>
-<cshelp id="kimhvirtmedit" xml:lang="zh-cn">
-<title>������������</title>
-<shortdesc>���������������������������������������������������������������������������������������������������������������������������������������</shortdesc>
-<csprolog><csmetadata></csmetadata></csprolog>
-<csbody>
-<p>������������������������������<wintitle>������</wintitle>������������������������������������<dl>
-<dlentry>
-<dt>������</dt>
-<dd>���������������������������������������������������������������������</dd>
-</dlentry><dlentry>
-<dt>CPU ���</dt>
-<dd>���������������������������������������������������������������������������������������������</dd>
-</dlentry><dlentry>
-<dt>������</dt>
-<dd>��������������� MB
���������������������������������������������������������������������������������</dd>
-</dlentry><dlentry>
-<dt>������</dt>
-<dd>��������������������������������������������������� Linux
������������������������������ (Livetile) ������������������</dd>
-</dlentry></dl></p>
-<p>���������<wintitle>���������</wintitle>������������������������������������</p>
-<dl><dlentry>
-<dt>���������</dt>
-<dd>��������������������� ISO ������������������������</dd>
-</dlentry></dl>
-<p>
���������������������������������������������������������������������<uicontrol>������</uicontrol>���</p>
-</csbody>
-</cshelp>
-<cshelp id="kimstoragedevice" xml:lang="zh-cn">
-<title>������������������������������������</title>
-<shortdesc
rev="rev1">���������������������������������������������������������������������������������������
CDROM���������������������������������������������������</shortdesc>
-<csbody>
-<ol>
-<li>������<wintitle>������������</wintitle>������������������������<wintitle>���������</wintitle>������</li>
-<li>���������������������������������������������������������<uicontrol>������������
(/)</uicontrol>��������� ISO
���������������������<uicontrol>������</uicontrol>���</li>
-<li>���������������������������������������������������������<uicontrol>���������������
(-)</uicontrol>������������������������������������<uicontrol>������</uicontrol>���</li>
-<li>���������������������������������������������������������<uicontrol>���������������
(+)</uicontrol>��������������������� ISO
���������������������<uicontrol>������</uicontrol>���</li>
-</ol>
-</csbody>
-</cshelp>
-<cshelp id="kimreplacemedia" xml:lang="zh-cn">
-<title>������ VM ��� CDROM</title>
-<shortdesc rev="rev1">������������������������������������������������
CDROM ������������</shortdesc>
-<csbody>
-<ol>
-<li>������������������������������</li>
-<li>���������������������������������<uicontrol>������������</uicontrol>���</li>
-<li>������������������������ CDROM ������������������������ hdc
���������������<uicontrol>������������ (/)</uicontrol> ���������</li>
-<li>������<wintitle>������ VM ��� CDROM</wintitle>���������������������
ISO ���������������������������������������������</li>
-<li>������<uicontrol>������</uicontrol>���</li>
-</ol>
-</csbody>
-</cshelp>
-<?tm 1391540919 3?>
-</cshelp>
-
-
-<!-- ENGL1SH_VERS10N 45645_6 DO NOT REMOVE OR CHANGE THIS LINE -->
-<!-- T9N_SRC_ID 231 -->
-<!-- T9N_SH1P_STR1NG KV211AAP001 1 -->
diff --git a/plugins/kimchi/ui/pages/help/zh_CN/host.dita
b/plugins/kimchi/ui/pages/help/zh_CN/host.dita
deleted file mode 100644
index 78a89c3..0000000
--- a/plugins/kimchi/ui/pages/help/zh_CN/host.dita
+++ /dev/null
@@ -1,45 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--Arbortext, Inc., 1988-2011, v.4002-->
-<!DOCTYPE cshelp PUBLIC "-//IBM//DTD DITA CSHelp//EN"
- "..\dtd\cshelp.dtd">
-
-
-<!--This DITA specialized document type is not supported by the Authoring Tools
development team.
-For support please see:
-https://w3.opensource.ibm.com/projects/dita-cshelp/-->
-<cshelp id="kimhhost" xml:lang="zh-cn">
-<title>������</title>
-<shortdesc>���<wintitle>������</wintitle>������������������������������������������������������������������������������������������������������</shortdesc>
-<csbody>
-<p>���������������������������������<ul>
-<li>������<uicontrol>������</uicontrol>������������������������</li>
-<li>������<uicontrol>������������</uicontrol>������������������������������</li>
-<li>������<uicontrol>������</uicontrol>��������������������������� VNC
���������������������������������</li>
-</ul></p>
-<p>���������������������������������������������������<dl>
-<dlentry>
-<dt>������������</dt>
-<dd>���������������������������������������������������������������������������������������������������������
GB ���������</dd>
-</dlentry><dlentry>
-<dt>������������������</dt>
-<dd>��������������������������������������������� CPU������������������ I/O
��������� I/O
������������������������<uicontrol>���������������������������������</uicontrol>������������������������������������������������������������</dd>
-</dlentry><dlentry>
-<dt>������������</dt>
-<dd>���������������������������������������������������������������������������������������������������������������������������������������������<uicontrol>������������</uicontrol>���������������������������������������������������������������������������������</dd>
-</dlentry><dlentry>
-<dt>���������</dt>
-<dd>���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������
Red Hat Enterprise Linux ��� Fedora������������������ <filepath>yum</filepath>
��������������������������������� Ubuntu ��� Debian������������������
<filepath>deb</filepath> ������������<p>��������������� Yum
��������������������������� GPG
������������������������������������������������������������������������������������������������<uicontrol>������</uicontrol>���������<uicontrol>���</uicontrol>���������
GPG ��������������������������������� GPG ��������������� URL���</p></dd>
-</dlentry><dlentry>
-<dt>������������</dt>
-<dd>���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<p>���������������������
-<cmdname>sosreport</cmdname> ��������������������������������� Red
-Hat Enterprise <tm tmtype="tm"
trademark="Linux">Linux</tm>���Fedora ��� Ubuntu
������������������������������������������������������������ .tar
���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������</p>
</dd>
-</dlentry></dl></p>
-</csbody>
-<?tm 1392659967 1?>
-</cshelp>
-
-
-<!-- ENGL1SH_VERS10N 47930_4 DO NOT REMOVE OR CHANGE THIS LINE -->
-<!-- T9N_SRC_ID 232 -->
-<!-- T9N_SH1P_STR1NG KVM21AAP001 3 -->
diff --git a/plugins/kimchi/ui/pages/help/zh_CN/network.dita
b/plugins/kimchi/ui/pages/help/zh_CN/network.dita
deleted file mode 100644
index f6aa532..0000000
--- a/plugins/kimchi/ui/pages/help/zh_CN/network.dita
+++ /dev/null
@@ -1,61 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--Arbortext, Inc., 1988-2011, v.4002-->
-<!DOCTYPE cshelp PUBLIC "-//IBM//DTD DITA CSHelp//EN"
- "..\dtd\cshelp.dtd">
-
-
-<!--This DITA specialized document type is not supported by the Authoring Tools
development team.
-For support please see:
-https://w3.opensource.ibm.com/projects/dita-cshelp/-->
-<cshelp id="kimhnetw" xml:lang="zh-cn">
-<title>������</title>
-<shortdesc>���<wintitle>������</wintitle>���������������������������������������������</shortdesc>
-<csbody>
-<p><dl><dlentry>
-<dt>���������</dt>
-<dd>������������������<uicontrol>���������</uicontrol>���</dd>
-</dlentry><dlentry>
-<dt>������</dt>
-<dd>���������������������������������������������������������������</dd>
-</dlentry><dlentry>
-<dt>������������</dt>
-<dd>������������������������<uicontrol>NAT</uicontrol>���������������������������</dd>
-</dlentry><dlentry>
-<dt>������</dt>
-<dd>������������������������<uicontrol>virbr0</uicontrol>������������������</dd>
-</dlentry><dlentry>
-<dt>������������</dt>
-<dd>IP ���������</dd>
-</dlentry></dl></p>
-<p>���������������������������<ul>
-<li
rev="rev1">������<uicontrol>������</uicontrol>������������������������</li>
-<li>������<uicontrol>������</uicontrol>������������������������</li>
-<li>������<uicontrol>������</uicontrol>������������������������</li>
-</ul>������������������������������������������������<uicontrol>���������
(+)</uicontrol> ���������</p>
-</csbody>
-<cshelp id="kimhnetwcrt" xml:lang="zh-cn">
-<title>������������</title>
-<shortdesc>���������������</shortdesc>
-<csbody>
-<p> <ol>
-<li>������������������������</li>
-<li>������������������������������������<dl
rev="rev1"><dlentry>
-<dt><uicontrol>������</uicontrol></dt>
-<dd>������������������������������������������������������������������������������</dd>
-</dlentry><dlentry>
-<dt><uicontrol>NAT</uicontrol></dt>
-<dd>��������������������������������������������������������������������������� IP
������������������������������������������������������</dd>
-</dlentry><dlentry>
-<dt><uicontrol>������</uicontrol></dt>
-<dd>������������������������������������������������������������������������������������������������������������������������������������������������������������������
VLAN ���������</dd>
-</dlentry></dl></li>
-<li>������<uicontrol>������</uicontrol>���</li>
-</ol> </p>
-</csbody>
-</cshelp>
-</cshelp>
-
-
-<!-- ENGL1SH_VERS10N 47050_3 DO NOT REMOVE OR CHANGE THIS LINE -->
-<!-- T9N_SRC_ID 230 -->
-<!-- T9N_SH1P_STR1NG KVM21AAP001 3 -->
diff --git a/plugins/kimchi/ui/pages/help/zh_CN/storage.dita
b/plugins/kimchi/ui/pages/help/zh_CN/storage.dita
deleted file mode 100644
index cfb09f5..0000000
--- a/plugins/kimchi/ui/pages/help/zh_CN/storage.dita
+++ /dev/null
@@ -1,84 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--Arbortext, Inc., 1988-2011, v.4002-->
-<!DOCTYPE cshelp PUBLIC "-//IBM//DTD DITA CSHelp//EN"
- "..\dtd\cshelp.dtd">
-
-
-<!--This DITA specialized document type is not supported by the Authoring Tools
development team.
-For support please see:
-https://w3.opensource.ibm.com/projects/dita-cshelp/-->
-<cshelp id="kimhstor" xml:lang="zh-cn">
-<title>���������</title>
-<shortdesc>���<wintitle>���������</wintitle>���������������������������������������������������������������������ISO���������������������������������������������
ISO������������������������ISO���������������������</shortdesc>
-<csbody>
-<p>������������������������������������������������<dl>
-<dlentry>
-<dt>������</dt>
-<dd>������������������������������������������</dd>
-</dlentry><dlentry>
-<dt>������</dt>
-<dd>������������������������������������������������������������������</dd>
-</dlentry><dlentry>
-<dt>������ </dt>
-<dd>���������������������������������������</dd>
-</dlentry><dlentry>
-<dt>������</dt>
-<dd>������������������������������<uicontrol>dir</uicontrol>���</dd>
-</dlentry><dlentry>
-<dt>������</dt>
-<dd>���������������������������</dd>
-</dlentry><dlentry>
-<dt>���������</dt>
-<dd>������������������������������������</dd>
-</dlentry></dl></p>
-<p>������������������������������������������<ul>
-<li>������<uicontrol>������</uicontrol>���������������������������������������</li>
-<li>������<uicontrol>������������</uicontrol>���������������������������������</li>
-<li>������<uicontrol>������������</uicontrol>������������������������������</li>
-</ul></p>
-<p>���������������������������������������������������������������������������������������������������������������������<dl><dlentry>
-<dt>������</dt>
-<dd>������������������������<uicontrol>������</uicontrol>���</dd>
-</dlentry><dlentry>
-<dt>������</dt>
-<dd>���������������������������������</dd>
-</dlentry><dlentry>
-<dt>������</dt>
-<dd>���������������������</dd>
-</dlentry><dlentry>
-<dt>������</dt>
-<dd>������������������������������������</dd>
-</dlentry></dl>���������������������������������������������������<uicontrol>���������
(+)</uicontrol> ���������</p>
-</csbody>
-<cshelp id="kimhdefstor" xml:lang="zh-cn">
-<title>���������������</title>
-<shortdesc> ������������������</shortdesc>
-<csbody>
-<p> <ol>
-<li>���<uicontrol>���������������</uicontrol>���������������������������������������������������</li>
-<li>���<uicontrol>���������������</uicontrol>���������������������������<dl><dlentry>
-<dt><uicontrol>DIR</uicontrol></dt>
-<dd>��������������������������� <uicontrol>DIR</uicontrol>
������������<uicontrol>������������</uicontrol>���������������������������������</dd>
-</dlentry><dlentry>
-<dt><uicontrol>NFS</uicontrol></dt>
-<dd>��������������������������������������� <uicontrol>NFS</uicontrol>
������������ <uicontrol>NFS ��������� IP ������</uicontrol>���
<uicontrol>NFS ������</uicontrol>���������������������������������</dd>
-</dlentry><dlentry>
-<dt><uicontrol>iSCSI</uicontrol></dt>
-<dd>������ iSCSI ������������������������������������������������
<uicontrol>iSCSI</uicontrol> ��������� iSCSI ������������������
<uicontrol>iSCSI ��������� IP
������</uicontrol>���<uicontrol>������</uicontrol>������������������������������������
iSCSI ���������</dd>
-</dlentry><dlentry>
-<dt><uicontrol>������</uicontrol></dt>
-<dd>������������������������������<uicontrol>������������</uicontrol>���������������������������</dd>
-</dlentry><dlentry>
-<dt><uicontrol>SCSI ������������</uicontrol></dt>
-<dd>������ SCSI ������������������������������������������ SCSI
������������</dd>
-</dlentry></dl></li>
-<li>������<uicontrol>������</uicontrol>���</li>
-</ol> </p>
-</csbody>
-</cshelp>
-</cshelp>
-
-
-<!-- ENGL1SH_VERS10N 22336_4 DO NOT REMOVE OR CHANGE THIS LINE -->
-<!-- T9N_SRC_ID 233 -->
-<!-- T9N_SH1P_STR1NG KV211AAP001 1 -->
diff --git a/plugins/kimchi/ui/pages/help/zh_CN/templates.dita
b/plugins/kimchi/ui/pages/help/zh_CN/templates.dita
deleted file mode 100644
index ca50119..0000000
--- a/plugins/kimchi/ui/pages/help/zh_CN/templates.dita
+++ /dev/null
@@ -1,111 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--Arbortext, Inc., 1988-2011, v.4002-->
-<!DOCTYPE cshelp PUBLIC "-//IBM//DTD DITA CSHelp//EN"
- "..\dtd\cshelp.dtd">
-
-
-<!--This DITA specialized document type is not supported by the Authoring Tools
development team.
-For support please see:
-https://w3.opensource.ibm.com/projects/dita-cshelp/-->
-<cshelp id="kimhtempl" xml:lang="zh-cn">
-<title>������</title>
-<shortdesc>���<wintitle>������</wintitle>������������������������������
KVM ������������������������������������</shortdesc>
-<csbody>
-<p>���������������������������������������������<dl>
-<dlentry>
-<dt>������������</dt>
-<dd>������������������������������������</dd>
-</dlentry><dlentry>
-<dt>������</dt>
-<dd>������������������������������������</dd>
-</dlentry><dlentry>
-<dt>CPU ���</dt>
-<dd>���������������������������������</dd>
-</dlentry><dlentry>
-<dt>������</dt>
-<dd>��������������������������������������� MB ���������</dd>
-</dlentry></dl></p>
-<p>���������������������������������������<ul>
-<li>������<uicontrol>������</uicontrol>������������������</li>
-<li>������<uicontrol>������</uicontrol>������������������</li>
-</ul>������������������������������������������������<uicontrol>���������
(+)</uicontrol> ���������</p>
-</csbody>
-<cshelp id="kimhedittempl" xml:lang="zh-cn">
-<title>������������</title>
-<shortdesc>���������������������</shortdesc>
-<csbody>
-<p>���������������������������������������������<dl>
-<dlentry>
-<dt>������</dt>
-<dd>������������������</dd>
-</dlentry><dlentry>
-<dt>���������</dt>
-<dd>������������������������������������������������������������������������������������</dd>
-</dlentry><dlentry>
-<dt>������</dt>
-<dd>������������������������������������������������������������</dd>
-</dlentry><dlentry>
-<dt>CPU ������</dt>
-<dd>���������������������������������</dd>
-</dlentry><dlentry>
-<dt>������</dt>
-<dd>��������������������������������������� MB ���������</dd>
-</dlentry><dlentry>
-<dt>������</dt>
-<dd>������������������ GB ���������</dd>
-</dlentry><dlentry>
-<dt>CDROM</dt>
-<dd>������������ KVM ��������� ISO ������������������������������������</dd>
-</dlentry><dlentry>
-<dt>���������</dt>
-<dd>������������������������������������</dd>
-</dlentry><dlentry>
-<dt>������</dt>
-<dd>������ KVM
������������������������������������������������������������������</dd>
-</dlentry></dl>
���������������������������������������������������������������������<uicontrol>������</uicontrol>���</p>
-</csbody>
-</cshelp>
-<cshelp id="kimhaddtempl">
-<title>������������</title>
-<shortdesc>������������������������������������������������������ ISO
������������������ISO������������������������������������</shortdesc>
-<csbody>
-<p>������������������������������������������������<dl>
-<dlentry>
-<dt>������ ISO ������</dt>
-<dd>������������������������������������������ ISO
���������������������������������</dd>
-</dlentry><dlentry>
-<dt>������ ISO ������</dt>
-<dd>��������������������������� ISO ������������������������</dd>
-</dlentry></dl></p>
-</csbody>
-</cshelp>
-<cshelp id="kimhaddloct">
-<title>������������ - ������ ISO ������</title>
-<shortdesc>��������� ISO ���������������������</shortdesc>
-<csbody>
-<p>��������������������������� ISO ���������<dl><dlentry>
-<dt>������������</dt>
-<dd>������������������������������������</dd>
-</dlentry><dlentry>
-<dt>������</dt>
-<dd>������������������������������������</dd>
-</dlentry><dlentry>
-<dt>������</dt>
-<dd>ISO ������������������</dd>
-</dlentry></dl></p>
-<p>������ ISO ���������������������������������������������������<ul>
-<li>������������������������������ ISO
���������������������<uicontrol>��������� ISO
������������</uicontrol>���</li>
-<li>������<uicontrol>������</uicontrol>������������������������ ISO
���������������������������������<uicontrol>��������� ISO
������������</uicontrol>���</li>
-<li>��������������������� ISO
������������������������������������������������������������������������<ul>
-<li>������<uicontrol>������������������ ISO ������</uicontrol>���������
ISO ������������������</li>
-<li>������<uicontrol>������������ ISO</uicontrol> ��������������� ISO
���������</li>
-</ul></li>
-</ul></p>
-</csbody>
-</cshelp>
-</cshelp>
-
-
-<!-- ENGL1SH_VERS10N 61085_5 DO NOT REMOVE OR CHANGE THIS LINE -->
-<!-- T9N_SRC_ID 229 -->
-<!-- T9N_SH1P_STR1NG KV211AAP001 1 -->
diff --git a/plugins/kimchi/ui/pages/help/zh_TW/Makefile.am
b/plugins/kimchi/ui/pages/help/zh_TW/Makefile.am
deleted file mode 100644
index 9c8ac26..0000000
--- a/plugins/kimchi/ui/pages/help/zh_TW/Makefile.am
+++ /dev/null
@@ -1,23 +0,0 @@
-# Copyright IBM Corp, 2014
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-
-zh_TW_helpdir = $(datadir)/wok/plugins/kimchi/ui/pages/help/zh_TW
-
-dist_zh_TW_help_DATA = $(wildcard *.html) $(NULL)
-
-EXTRA_DIST = $(wildcard *.dita)
-
-CLEANFILES = $(wildcard *.html)
diff --git a/plugins/kimchi/ui/pages/help/zh_TW/guests.dita
b/plugins/kimchi/ui/pages/help/zh_TW/guests.dita
deleted file mode 100644
index cf73785..0000000
--- a/plugins/kimchi/ui/pages/help/zh_TW/guests.dita
+++ /dev/null
@@ -1,120 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--Arbortext, Inc., 1988-2011, v.4002-->
-<!DOCTYPE cshelp PUBLIC "-//IBM//DTD DITA CSHelp//EN"
- "..\dtd\cshelp.dtd">
-
-
-<!--This DITA specialized document type is not supported by the Authoring Tools
development team.
-For support please see:
-https://w3.opensource.ibm.com/projects/dita-cshelp/-->
-<cshelp id="kimhvirtm" xml:lang="zh-tw">
-<title>������</title>
-<shortdesc>���<wintitle>������</wintitle>������������������������������
KVM ���������������</shortdesc>
-<csbody>
-<p>���������������������������������������������������<dl><dlentry>
-<dt>������</dt>
-<dd>������������������������</dd>
-</dlentry><dlentry>
-<dt>CPU</dt>
-<dd>������������������������������������������������</dd>
-</dlentry><dlentry>
-<dt>������ I/O</dt>
-<dd>������������/������������������ (KB/s)���</dd>
-</dlentry><dlentry>
-<dt>������ I/O</dt>
-<dd>������������/������������������ (KB/s)���</dd>
-</dlentry><dlentry>
-<dt>Livetile</dt>
-<dd>��������������������������������������������������� <tm
tmtype="tm" trademark="Linux">Linux</tm>
������������������������������������������������������������������</dd>
-</dlentry></dl></p>
-<p>���������������������������������������������������������<dl>
-<dlentry>
-<dt>������</dt>
-<dd>���������������������������</dd>
-</dlentry><dlentry>
-<dt>���������������������������</dt>
-<dd>���������������������������������������������������������������������������������������������������������������������������������������������������</dd>
-</dlentry></dl> </p>
-<p>���������������������������������������������<ul>
-<li>������<uicontrol>������</uicontrol>���������������������������������������������������</li>
-<li>������<uicontrol>������������</uicontrol>���������������������������������</li>
-<li>������<uicontrol>������</uicontrol>������������������</li>
-<li>������<uicontrol>������</uicontrol>������������������������������������������������������������������������</li>
-<li>������<uicontrol>������</uicontrol>������������������</li>
-</ul>������������������������������������������������������������������������<uicontrol>������
(+)</uicontrol> ���������</p>
-</csbody>
-<cshelp id="kimhvirtmcrt" xml:lang="zh-tw">
-<title>������������������</title>
-<shortdesc>���������������������������������������</shortdesc>
-<csbody>
-<p> <ol>
-<li>������������������������������������������</li>
-<li rev="rev1">���������������<ul>
-<li>������������������������������������������������������</li>
-<li>���������������������������������<uicontrol>������������</uicontrol>������������������</li>
-</ul></li>
-<li>���������<uicontrol>������</uicontrol>���</li>
-</ol> </p>
-</csbody>
-</cshelp>
-<cshelp id="kimhvirtmedit" xml:lang="zh-tw">
-<title>������������</title>
-<shortdesc>������������������������������������������������������������������������������������������������������������������������������������</shortdesc>
-<csprolog><csmetadata></csmetadata></csprolog>
-<csbody>
-<p>������������������������������������<wintitle>������</wintitle>���������������������������������<dl>
-<dlentry>
-<dt>������</dt>
-<dd>������������������������������������������������������������������</dd>
-</dlentry><dlentry>
-<dt>CPU</dt>
-<dd>���������������������������������������������������������������������������������������������</dd>
-</dlentry><dlentry>
-<dt>���������</dt>
-<dd>���������������
(MB)������������������������������������������������������������������������������</dd>
-</dlentry><dlentry>
-<dt>������</dt>
-<dd>������������������������������������������������������������ (Livetile)
��������������� Linux ������������������������������</dd>
-</dlentry></dl></p>
-<p>���������������������������<wintitle>������</wintitle>���������������</p>
-<dl><dlentry>
-<dt>���������</dt>
-<dd>��������������������� ISO ������������������</dd>
-</dlentry></dl>
-<p>
���������������������������������������������������������������<uicontrol>������</uicontrol>���</p>
-</csbody>
-</cshelp>
-<cshelp id="kimstoragedevice" xml:lang="zh-tw">
-<title>������������������������������������</title>
-<shortdesc
rev="rev1">������������������������������������������������������������������������������������������
CDROM������������������������������������������������������</shortdesc>
-<csbody>
-<ol>
-<li>������<wintitle>������������</wintitle>������������������������<wintitle>���������</wintitle>������</li>
-<li>���������������������������������������������<uicontrol>������������
(/)</uicontrol> ���������������������������
-ISO
������������������������������<uicontrol>������</uicontrol>���</li>
-<li>���������������������������������������������<uicontrol>������������
(/)</uicontrol>
���������������������������������������������������<uicontrol>������</uicontrol>���</li>
-<li>���������������������������������������������������<uicontrol>������
(+)</uicontrol> ������������������������������������������
-ISO
������������������������������<uicontrol>������</uicontrol>���</li>
-</ol>
-</csbody>
-</cshelp>
-<cshelp id="kimreplacemedia" xml:lang="zh-tw">
-<title>��������������������� CDROM</title>
-<shortdesc rev="rev1">���������������������������������������������������
CDROM ������������</shortdesc>
-<csbody>
-<ol>
-<li>������������������������������</li>
-<li>������������������������������������<uicontrol>������������</uicontrol>���</li>
-<li>��������������������� CDROM ��������������������������������� hdc
���������������<uicontrol>������������ (/)</uicontrol> ���������</li>
-<li>������<wintitle>���������������������
CDROM</wintitle>��������������������� ISO
������������������������������������������������</li>
-<li>���������<uicontrol>������</uicontrol>���</li>
-</ol>
-</csbody>
-</cshelp>
-<?tm 1391540919 3?>
-</cshelp>
-
-
-<!-- ENGL1SH_VERS10N 45645_6 DO NOT REMOVE OR CHANGE THIS LINE -->
-<!-- T9N_SRC_ID 231 -->
-<!-- T9N_SH1P_STR1NG KV211AAP001 1 -->
diff --git a/plugins/kimchi/ui/pages/help/zh_TW/host.dita
b/plugins/kimchi/ui/pages/help/zh_TW/host.dita
deleted file mode 100644
index a55aae4..0000000
--- a/plugins/kimchi/ui/pages/help/zh_TW/host.dita
+++ /dev/null
@@ -1,50 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--Arbortext, Inc., 1988-2011, v.4002-->
-<!DOCTYPE cshelp PUBLIC "-//IBM//DTD DITA CSHelp//EN"
- "..\dtd\cshelp.dtd">
-
-
-<!--This DITA specialized document type is not supported by the Authoring Tools
development team.
-For support please see:
-https://w3.opensource.ibm.com/projects/dita-cshelp/-->
-<cshelp id="kimhhost" xml:lang="zh-tw">
-<title>������</title>
-<shortdesc>���<wintitle>������</wintitle>���������������������������������������������������������������������������������������������������������</shortdesc>
-<csbody>
-<p>������������������������������������������<ul>
-<li>������<uicontrol>������</uicontrol>������������������������</li>
-<li>������<uicontrol>������������</uicontrol>������������������������������</li>
-<li>������<uicontrol>������</uicontrol>��������������������������� VNC
������������������������������������������������</li>
-</ul></p>
-<p>������������������������������������������������������<dl>
-<dlentry>
-<dt>������������</dt>
-<dd>������������������������������������������������������������������������������������������������������������������
(GB)���</dd>
-</dlentry><dlentry>
-<dt>������������������</dt>
-<dd>��������������������������������������������������� CPU���������������������
I/O ��������� I/O
������������������������<uicontrol>���������������������������������</uicontrol>���������������������������������������������������������������</dd>
-</dlentry><dlentry>
-<dt>������������</dt>
-<dd>���������������������������������������������������������������������������������������������������������������������������������������������<uicontrol>������������</uicontrol>���������������������������������������������������������������������������</dd>
-</dlentry><dlentry>
-<dt>���������</dt>
-<dd>������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������
-Red Hat Enterprise Linux ��� Fedora������������������
<filepath>yum</filepath> ���������������������������������
-Ubuntu ��� Debian������������������ <filepath>deb</filepath>
������������<p>���������������������
-yum ��������������������������� GPG
���������������������������������������������������������������������������������������������<uicontrol>������</uicontrol>���������<uicontrol>���</uicontrol>���������
-GPG ��������������������������������� GPG ������������ URL���</p></dd>
-</dlentry><dlentry>
-<dt>������������</dt>
-<dd>���������������������������������������������������������������������������������������������������������������������������������������������������������<p>���������������������
-<cmdname>sosreport</cmdname> ������������������������������������ Red
-Hat Enterprise <tm tmtype="tm"
trademark="Linux">Linux</tm>���Fedora
-��� Ubuntu ��������������������������������� .tar
������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������</p>
</dd>
-</dlentry></dl></p>
-</csbody>
-<?tm 1392659967 1?>
-</cshelp>
-
-
-<!-- ENGL1SH_VERS10N 47930_4 DO NOT REMOVE OR CHANGE THIS LINE -->
-<!-- T9N_SRC_ID 232 -->
-<!-- T9N_SH1P_STR1NG KVM21AAP001 3 -->
diff --git a/plugins/kimchi/ui/pages/help/zh_TW/network.dita
b/plugins/kimchi/ui/pages/help/zh_TW/network.dita
deleted file mode 100644
index f392060..0000000
--- a/plugins/kimchi/ui/pages/help/zh_TW/network.dita
+++ /dev/null
@@ -1,61 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--Arbortext, Inc., 1988-2011, v.4002-->
-<!DOCTYPE cshelp PUBLIC "-//IBM//DTD DITA CSHelp//EN"
- "..\dtd\cshelp.dtd">
-
-
-<!--This DITA specialized document type is not supported by the Authoring Tools
development team.
-For support please see:
-https://w3.opensource.ibm.com/projects/dita-cshelp/-->
-<cshelp id="kimhnetw" xml:lang="zh-tw">
-<title>������</title>
-<shortdesc>���<wintitle>������</wintitle>������������������������������������������������</shortdesc>
-<csbody>
-<p><dl><dlentry>
-<dt>������������</dt>
-<dd>������������������������<uicontrol>���������</uicontrol>���</dd>
-</dlentry><dlentry>
-<dt>������</dt>
-<dd>���������������������������������������������������������������������</dd>
-</dlentry><dlentry>
-<dt>������������</dt>
-<dd>������������������������<uicontrol>NAT</uicontrol>���������������������</dd>
-</dlentry><dlentry>
-<dt>������</dt>
-<dd>������������������������<uicontrol>virbr0</uicontrol>������������������</dd>
-</dlentry><dlentry>
-<dt>������������</dt>
-<dd>IP ���������</dd>
-</dlentry></dl></p>
-<p>������������������������<ul>
-<li
rev="rev1">������<uicontrol>������</uicontrol>������������������������</li>
-<li>������<uicontrol>������</uicontrol>������������������������</li>
-<li>������<uicontrol>������</uicontrol>������������������������</li>
-</ul>���������������������������������������������������������<uicontrol>������
(+)</uicontrol> ���������</p>
-</csbody>
-<cshelp id="kimhnetwcrt" xml:lang="zh-tw">
-<title>������������</title>
-<shortdesc>������������</shortdesc>
-<csbody>
-<p> <ol>
-<li>������������������������</li>
-<li>���������������������������������<dl
rev="rev1"><dlentry>
-<dt><uicontrol>���������</uicontrol></dt>
-<dd>������������������������������������������������������������������������������������������������������������</dd>
-</dlentry><dlentry>
-<dt><uicontrol>NAT</uicontrol></dt>
-<dd>������������������������������������������������������������������ IP
������������������������������������������������������������</dd>
-</dlentry><dlentry>
-<dt><uicontrol>���������</uicontrol></dt>
-<dd>���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������
VLAN ���������</dd>
-</dlentry></dl></li>
-<li>���������<uicontrol>������</uicontrol>���</li>
-</ol> </p>
-</csbody>
-</cshelp>
-</cshelp>
-
-
-<!-- ENGL1SH_VERS10N 47050_3 DO NOT REMOVE OR CHANGE THIS LINE -->
-<!-- T9N_SRC_ID 230 -->
-<!-- T9N_SH1P_STR1NG KVM21AAP001 3 -->
diff --git a/plugins/kimchi/ui/pages/help/zh_TW/storage.dita
b/plugins/kimchi/ui/pages/help/zh_TW/storage.dita
deleted file mode 100644
index 971619c..0000000
--- a/plugins/kimchi/ui/pages/help/zh_TW/storage.dita
+++ /dev/null
@@ -1,88 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--Arbortext, Inc., 1988-2011, v.4002-->
-<!DOCTYPE cshelp PUBLIC "-//IBM//DTD DITA CSHelp//EN"
- "..\dtd\cshelp.dtd">
-
-
-<!--This DITA specialized document type is not supported by the Authoring Tools
development team.
-For support please see:
-https://w3.opensource.ibm.com/projects/dita-cshelp/-->
-<cshelp id="kimhstor" xml:lang="zh-tw">
-<title>���������</title>
-<shortdesc>���<wintitle>���������</wintitle>������������������������������������������������������������������������������������
'ISO' ��������������������������������������� ISO���������������������
'ISO' ������������������</shortdesc>
-<csbody>
-<p>������������������������������������������������������<dl>
-<dlentry>
-<dt>������</dt>
-<dd>������������������������������������������</dd>
-</dlentry><dlentry>
-<dt>������</dt>
-<dd>������������������������������������������������������������������������</dd>
-</dlentry><dlentry>
-<dt>������</dt>
-<dd>���������������������������������</dd>
-</dlentry><dlentry>
-<dt>������</dt>
-<dd>������������������������������<uicontrol>dir</uicontrol>���</dd>
-</dlentry><dlentry>
-<dt>������</dt>
-<dd>������������������������������</dd>
-</dlentry><dlentry>
-<dt>���������</dt>
-<dd>���������������������������������������</dd>
-</dlentry></dl></p>
-<p>������������������������������������������������<ul>
-<li>������<uicontrol>������</uicontrol>������������������������������������������</li>
-<li>������<uicontrol>������������</uicontrol>���������������������������������������</li>
-<li>������<uicontrol>������������</uicontrol>������������������������������������</li>
-</ul></p>
-<p>������������������������������������������������������������������������������������������������������������������������������<dl><dlentry>
-<dt>������</dt>
-<dd>���������������������������<uicontrol>������</uicontrol>���</dd>
-</dlentry><dlentry>
-<dt>������</dt>
-<dd>���������������������������</dd>
-</dlentry><dlentry>
-<dt>������</dt>
-<dd>������������������������</dd>
-</dlentry><dlentry>
-<dt>������</dt>
-<dd>���������������������������������������</dd>
-</dlentry></dl>������������������������������������������������������������<uicontrol>������
(+)</uicontrol> ���������</p>
-</csbody>
-<cshelp id="kimhdefstor" xml:lang="zh-tw">
-<title>���������������</title>
-<shortdesc> ������������������</shortdesc>
-<csbody>
-<p> <ol>
-<li>���<uicontrol>���������������</uicontrol>���������������������������������������������������</li>
-<li>���<uicontrol>���������������</uicontrol>���������������������������<dl><dlentry>
-<dt><uicontrol>DIR</uicontrol></dt>
-<dd>��������������������������������� <uicontrol>DIR</uicontrol>
���������������<uicontrol>���������������</uicontrol>���������������������������</dd>
-</dlentry><dlentry>
-<dt><uicontrol>NFS</uicontrol></dt>
-<dd>���������������������������������������������
<uicontrol>NFS</uicontrol> ���������������
-<uicontrol>NFS ��������� IP</uicontrol> ��������� <uicontrol>NFS
-������</uicontrol>���������������������������������</dd>
-</dlentry><dlentry>
-<dt><uicontrol>iSCSI</uicontrol></dt>
-<dd>��������� iSCSI ���������������������������������������������������������
-<uicontrol>iSCSI</uicontrol> ��������������� <uicontrol>iSCSI
-���������</uicontrol> IP ��������� iSCSI
���������������<uicontrol>������</uicontrol>������������������������������������
iSCSI ���������</dd>
-</dlentry><dlentry>
-<dt><uicontrol>������</uicontrol></dt>
-<dd>���������������������������������<uicontrol>������������</uicontrol>���������������������������</dd>
-</dlentry><dlentry>
-<dt><uicontrol>SCSI ������������</uicontrol></dt>
-<dd>������ SCSI ������������������������������������������������ SCSI
������������</dd>
-</dlentry></dl></li>
-<li>���������<uicontrol>������</uicontrol>���</li>
-</ol> </p>
-</csbody>
-</cshelp>
-</cshelp>
-
-
-<!-- ENGL1SH_VERS10N 22336_4 DO NOT REMOVE OR CHANGE THIS LINE -->
-<!-- T9N_SRC_ID 233 -->
-<!-- T9N_SH1P_STR1NG KV211AAP001 1 -->
diff --git a/plugins/kimchi/ui/pages/help/zh_TW/templates.dita
b/plugins/kimchi/ui/pages/help/zh_TW/templates.dita
deleted file mode 100644
index 4b3a6a6..0000000
--- a/plugins/kimchi/ui/pages/help/zh_TW/templates.dita
+++ /dev/null
@@ -1,112 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--Arbortext, Inc., 1988-2011, v.4002-->
-<!DOCTYPE cshelp PUBLIC "-//IBM//DTD DITA CSHelp//EN"
- "..\dtd\cshelp.dtd">
-
-
-<!--This DITA specialized document type is not supported by the Authoring Tools
development team.
-For support please see:
-https://w3.opensource.ibm.com/projects/dita-cshelp/-->
-<cshelp id="kimhtempl" xml:lang="zh-tw">
-<title>������</title>
-<shortdesc>���<wintitle>������</wintitle>���������������������������������
-KVM ���������������������������������������</shortdesc>
-<csbody>
-<p>���������������������������������������������������<dl>
-<dlentry>
-<dt>OS</dt>
-<dd>������������������������������������������������</dd>
-</dlentry><dlentry>
-<dt>������</dt>
-<dd>������������������������������������������������</dd>
-</dlentry><dlentry>
-<dt>CPU</dt>
-<dd>������������������������������������</dd>
-</dlentry><dlentry>
-<dt>���������</dt>
-<dd>��������������������������������������� (MB)���</dd>
-</dlentry></dl></p>
-<p>���������������������������������������������<ul>
-<li>������<uicontrol>������</uicontrol>������������������</li>
-<li>������<uicontrol>������</uicontrol>������������������</li>
-</ul>���������������������������������������������������������<uicontrol>������
(+)</uicontrol> ���������</p>
-</csbody>
-<cshelp id="kimhedittempl" xml:lang="zh-tw">
-<title>������������</title>
-<shortdesc>���������������������</shortdesc>
-<csbody>
-<p>���������������������������������������������������<dl>
-<dlentry>
-<dt>������</dt>
-<dd>������������������</dd>
-</dlentry><dlentry>
-<dt>���������</dt>
-<dd>������������������������������������������������������������������������������</dd>
-</dlentry><dlentry>
-<dt>������</dt>
-<dd>���������������������������������������������������������������</dd>
-</dlentry><dlentry>
-<dt>CPU ������</dt>
-<dd>������������������������������������</dd>
-</dlentry><dlentry>
-<dt>���������</dt>
-<dd>������������������������������������������ (MB)���</dd>
-</dlentry><dlentry>
-<dt>������</dt>
-<dd>������������ (GB)���</dd>
-</dlentry><dlentry>
-<dt>CDROM</dt>
-<dd>������������ KVM ��������� ISO ������������������������������</dd>
-</dlentry><dlentry>
-<dt>���������</dt>
-<dd>������������������������������������</dd>
-</dlentry><dlentry>
-<dt>������</dt>
-<dd>KVM
���������������������������������������������������������������������</dd>
-</dlentry></dl>
���������������������������������������������������������������<uicontrol>������</uicontrol>���</p>
-</csbody>
-</cshelp>
-<cshelp id="kimhaddtempl">
-<title>������������</title>
-<shortdesc>������������������������������������������������������ ISO
������������������ 'ISO' ������������������������������������</shortdesc>
-<csbody>
-<p>������������������������������������������������<dl>
-<dlentry>
-<dt>������ ISO ���������</dt>
-<dd>��������������������������������������������������������������� ISO
������������</dd>
-</dlentry><dlentry>
-<dt>������ ISO ���������</dt>
-<dd>��������������������������� ISO ���������������������������</dd>
-</dlentry></dl></p>
-</csbody>
-</cshelp>
-<cshelp id="kimhaddloct">
-<title>������������ - ������ ISO ���������</title>
-<shortdesc>��������� ISO ������������������������</shortdesc>
-<csbody>
-<p>������������������������������ ISO ������������<dl><dlentry>
-<dt>OS</dt>
-<dd>������������������������������������������������</dd>
-</dlentry><dlentry>
-<dt>������</dt>
-<dd>������������������������������������������������</dd>
-</dlentry><dlentry>
-<dt>������</dt>
-<dd>ISO ���������������������</dd>
-</dlentry></dl></p>
-<p>��������� ISO ������������������������������������������������������<ul>
-<li>������������������������������ ISO
���������������������������<uicontrol>��������� ISO
������������</uicontrol>���</li>
-<li>������<uicontrol>������</uicontrol>������������������������ ISO
���������������������������������������<uicontrol>��������� ISO
������������</uicontrol>���</li>
-<li>������������������ ISO
���������������������������������������������������������������������������<ul>
-<li>������<uicontrol>��������������������� ISO
������</uicontrol>��������� ISO ���������������������</li>
-<li>���������<uicontrol>������������ ISO</uicontrol> ���������������
ISO ������������</li>
-</ul></li>
-</ul></p>
-</csbody>
-</cshelp>
-</cshelp>
-
-
-<!-- ENGL1SH_VERS10N 61085_5 DO NOT REMOVE OR CHANGE THIS LINE -->
-<!-- T9N_SRC_ID 229 -->
-<!-- T9N_SH1P_STR1NG KV211AAP001 1 -->
diff --git a/plugins/kimchi/ui/pages/host.html.tmpl
b/plugins/kimchi/ui/pages/host.html.tmpl
deleted file mode 100644
index d87debc..0000000
--- a/plugins/kimchi/ui/pages/host.html.tmpl
+++ /dev/null
@@ -1,177 +0,0 @@
-#*
- * Project Kimchi
- *
- * Copyright IBM, Corp. 2013-2015
- *
- * 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.
- *#
-
-#unicode UTF-8
-#import gettext
-#from wok.cachebust import href
-#silent t = gettext.translation($lang.domain, $lang.localedir, languages=$lang.lang,
fallback=True)
-#silent _ = t.gettext
-#silent _t = t.gettext
-<!DOCTYPE html>
-<html>
-<head>
-<link rel="stylesheet"
href="plugins/kimchi/css/theme-default.min.css">
-<script src="plugins/kimchi/js/kimchi.min.js"></script>
-</head>
-<body>
-<div id="host-root-container">
- <div class="toolbar">
- <div class="tools">
- </div>
- </div>
- <div id="host-content-container"
class="empty-when-logged-off"></div>
-</div>
-
-<script id="host-tmpl" type="kimchi/template">
- <div class="host-panel">
- <div class="logo-container">
- <div class="logo" style="background-image:
url({logo});"></div>
- </div>
- <div id="host-info-container" class="info-container">
- <h2 class="hostname">{hostname}</h2>
- <div class="action-panel">
- <button id="host-button-shutdown" class="btn-normal-1
stop">
- <div class="button-icon
action-icon-stop"></div>
- $_("Shut down")
- </button>
- <button id="host-button-restart" class="btn-normal-1
restart">
- <div class="button-icon
action-icon-restart"></div>
- $_("Restart")
- </button>
- <button class="btn-normal-1 connect"
disabled="disabled">
- <div class="button-icon
action-icon-connect"></div>
- $_("Connect")
- </button>
- </div>
- <div class="host-section">
- <h3 class="section-header"
- aria-expanded="false"
- aria-controls="content-sys-info">
- $_("Basic Information")
- </h3>
- <div id="content-sys-info"
class="section-content">
- <div class="section-row">
- <div class="section-label">$_("OS
Distro")</div>
- <div
class="section-value">{os_distro}</div>
- </div>
- <div class="section-row">
- <div class="section-label">$_("OS
Version")</div>
- <div
class="section-value">{os_version}</div>
- </div>
- <div class="section-row">
- <div class="section-label">$_("OS Code
Name")</div>
- <div
class="section-value">{os_codename}</div>
- </div>
- <div class="section-row">
- <div
class="section-label">$_("Processor")</div>
- <div
class="section-value">{cpu_model}</div>
- </div>
- <div class="section-row">
- <div
class="section-label">$_("CPU(s)")</div>
- <div class="section-value">{cpus}</div>
- </div>
- <div class="section-row">
- <div
class="section-label">$_("Memory")</div>
- <div class="section-value">{memory}</div>
- </div>
- </div>
- </div>
- <div class="host-section">
- <h3 class="section-header"
- aria-controls="content-sys-statistics">
- $_("System Statistics")
- </h3>
- <div id="content-sys-statistics"
class="section-content">
- <div class="section-row">
- <div
class="section-label">$_("CPU")</div>
- <div class="section-value">
- <div id="container-chart-cpu"
class="inline-block"></div>
- </div>
- </div>
- <div class="section-row">
- <div
class="section-label">$_("Memory")</div>
- <div class="section-value">
- <div id="container-chart-memory"
class="inline-block"></div>
- </div>
- </div>
- <div class="section-row">
- <div class="section-label">$_("Disk
I/O")</div>
- <div class="section-value">
- <div id="container-chart-disk-io"
class="inline-block"></div>
- </div>
- </div>
- <div class="section-row">
- <div class="section-label">$_("Network
I/O")</div>
- <div class="section-value">
- <div id="container-chart-network-io"
class="inline-block"></div>
- </div>
- </div>
- </div>
- </div>
- <div id="software-update-section" class="host-section
hidden">
- <h3 class="section-header"
- aria-controls="content-software-update">
- $_("Software Updates")
- </h3>
- <div id="content-software-update"
class="section-content">
- <div class="section-row">
- <div class="section-value">
- <div
id="software-updates-grid-container"></div>
- <div id="software-updates-progress-container"
class="hidden">
- <label
for="software-updates-progress-textarea">$_("Update
Progress")</label>
- <textarea
id="software-updates-progress-textarea" readonly></textarea>
- </div>
- </div>
- </div>
- </div>
- </div>
- <div id="repositories-section" class="host-section
hidden">
- <h3 class="section-header"
- aria-controls="content-repositories">
- $_("Repositories")
- </h3>
- <div id="content-repositories"
class="section-content">
- <div class="section-row">
- <div class="section-value">
- <div
id="repositories-grid-container"></div>
- </div>
- </div>
- </div>
- </div>
- <div id="debug-report-section" class="host-section
hidden">
- <h3 class="section-header"
- aria-controls="content-sys-reports">
- $_("Debug Reports")
- </h3>
- <div id="content-sys-reports"
class="section-content">
- <div class="section-row">
- <div class="section-value">
- <div
id="available-reports-grid-container"></div>
- </div>
- </div>
- </div>
- </div>
- </div>
- </div>
-</script>
-
-<script type="text/javascript">
- kimchi.host_main();
-</script>
-</body>
-</html>
diff --git a/plugins/kimchi/ui/pages/i18n.json.tmpl
b/plugins/kimchi/ui/pages/i18n.json.tmpl
deleted file mode 100644
index cd320e0..0000000
--- a/plugins/kimchi/ui/pages/i18n.json.tmpl
+++ /dev/null
@@ -1,187 +0,0 @@
-#*
- * Project Kimchi
- *
- * Copyright IBM, Corp. 2014-2015
- *
- * 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.
- *#
-#unicode UTF-8
-#import gettext
-#from wok.cachebust import href
-#silent t = gettext.translation($lang.domain, $lang.localedir, languages=$lang.lang,
fallback=True)
-#silent _ = t.gettext
-#silent _t = t.gettext
-{
- "KCHAUTH6001E": "$_("The username or password you entered is
incorrect. Please try again.")",
- "KCHAUTH6002E": "$_("This field is required.")",
-
- "KCHAUTH6001M": "$_("Log in")",
- "KCHAUTH6002M": "$_("Logging in...")",
-
- "Host": "$_("Host")",
- "Guests": "$_("Guests")",
- "Templates": "$_("Templates")",
- "Storage": "$_("Storage")",
- "Network": "$_("Network")",
-
- "KCHAPI6002E": "$_("Failed to get application
configuration")",
- "KCHAPI6003E": "$_("This is not a valid Linux path")",
- "KCHAPI6004E": "$_("This is not a valid URL.")",
- "KCHAPI6005E": "$_("No such data available.")",
- "KCHAPI6007E": "$_("Can not contact the host system. Verify the
host system is up and that you have network connectivity to it. HTTP request response %1.
")",
- "KCHAPI6008E": "$_("Unable to read file.")",
- "KCHAPI6009E": "$_("Error while uploading file.")",
-
- "KCHAPI6001M": "$_("Delete Confirmation")",
- "KCHAPI6002M": "$_("OK")",
- "KCHAPI6003M": "$_("Cancel")",
- "KCHAPI6004M": "$_("Confirm")",
- "KCHAPI6005M": "$_("Create")",
- "KCHAPI6006M": "$_("Warning")",
- "KCHAPI6007M": "$_("Save")",
- "KCHAPI6008M": "$_("Creating...")",
- "KCHAPI6009M": "$_("Cloning...")",
-
- "KCHGRD6001M": "$_("Loading...")",
- "KCHGRD6002M": "$_("An error occurred while retrieving system
information.")",
- "KCHGRD6003M": "$_("Retry")",
- "KCHGRD6004M": "$_("Detailed message:")",
-
- "KCHTMPL6001W": "$_("No ISO found")",
-
- "KCHTMPL6002E": "$_("This is not a valid ISO file.")",
-
- "KCHTMPL6002M": "$_("This may take a long time. Do you want to
continue?")",
- "KCHTMPL6003M": "$_("This will permanently delete the template.
Would you like to continue?")",
-
- "KCHHOST6001E": "$_("Unable to shut down system as there are some
virtual machines running!")",
-
- "KCHHOST6001M": "$_("Max:")",
- "KCHHOST6002M": "$_("Utilization")",
- "KCHHOST6003M": "$_("Available")",
- "KCHHOST6004M": "$_("Read Rate")",
- "KCHHOST6005M": "$_("Write Rate")",
- "KCHHOST6006M": "$_("Received")",
- "KCHHOST6007M": "$_("Sent")",
- "KCHHOST6008M": "$_("Shutting down or restarting host will cause
unsaved work lost. Continue to shut down/restarting?")",
-
-
- "KCHREPO6001M": "$_("Confirm")",
- "KCHREPO6002M": "$_("Repository will be removed permanently and
can't be recovered. Do you want to continue?")",
- "KCHREPO6003M": "$_("Repositories")",
- "KCHREPO6004M": "$_("ID")",
- "KCHREPO6005M": "$_("Name")",
- "KCHREPO6006M": "$_("Base URL")",
- "KCHREPO6007M": "$_("Is Mirror")",
- "KCHREPO6008M": "$_("URL Args")",
- "KCHREPO6009M": "$_("Enabled")",
- "KCHREPO6010M": "$_("GPG Check")",
- "KCHREPO6011M": "$_("GPG Key")",
- "KCHREPO6012M": "$_("Add")",
- "KCHREPO6013M": "$_("Edit")",
- "KCHREPO6014M": "$_("Remove")",
- "KCHREPO6016M": "$_("Enable")",
- "KCHREPO6017M": "$_("Disable")",
-
-
- "KCHUPD6001M": "$_("Software Updates")",
- "KCHUPD6002M": "$_("Package Name")",
- "KCHUPD6003M": "$_("Version")",
- "KCHUPD6004M": "$_("Architecture")",
- "KCHUPD6005M": "$_("Repository")",
- "KCHUPD6006M": "$_("Update All")",
- "KCHUPD6007M": "$_("Updating...")",
- "KCHUPD6008M": "$_("Failed to retrieve packages update
information.")",
- "KCHUPD6009M": "$_("Failed to update package(s).")",
-
-
- "KCHDR6001M": "$_("Debug report will be removed permanently and
can't be recovered. Do you want to continue?")",
- "KCHDR6002M": "$_("Debug Reports")",
- "KCHDR6003M": "$_("Name")",
- "KCHDR6005M": "$_("Generated Time")",
- "KCHDR6006M": "$_("Generate")",
- "KCHDR6007M": "$_("Generating...")",
- "KCHDR6008M": "$_("Rename")",
- "KCHDR6009M": "$_("Remove")",
- "KCHDR6010M": "$_("Download")",
- "KCHDR6011M": "$_("Report name should contain only letters,
digits, underscore ('_') and/or hyphen ('-').")",
- "KCHDR6012M": "$_("Pending...")",
- "KCHDR6013M": "$_("Report name is the same as the original
one.")",
-
- "KCHVM6001M": "$_("This will delete the virtual machine and its
virtual disks. This operation cannot be undone. Would you like to continue?")",
- "KCHVM6002M": "$_("Power off Confirmation")",
- "KCHVM6003M": "$_("This action may produce undesirable results,
"
- "for example unflushed disk cache in the guest. "
- "Would you like to continue?")",
- "KCHVM6004M": "$_("Reset Confirmation")",
- "KCHVM6005M": "$_("There is a risk of data loss caused by reset
without"
- " the guest OS shutdown. Would you like to
continue?")",
- "KCHVM6006M": "$_("Shut Down Confirmation")",
- "KCHVM6007M": "$_("Note the guest OS may ignore this request.
Would you like to continue?")",
- "KCHVM6008M": "$_("Virtual Machine delete
Confirmation")",
- "KCHVM6009M": "$_("This virtual machine is not persistent. Power
Off will delete it. Continue?")",
- "KCHVM6010M": "$_("When the target guest has SCSI or iSCSI
volumes, they will be cloned on default storage pool. The same will happen when the target
pool does not have enough space to clone the volumes. Do you want to
continue?")",
-
- "KCHVMCD6001M": "$_("This CDROM will be detached permanently and
you can re-attach it. Continue to detach it?")",
- "KCHVMCD6002M": "$_("Attach")",
- "KCHVMCD6003M": "$_("Attaching...")",
- "KCHVMCD6004M": "$_("Replace")",
- "KCHVMCD6005M": "$_("Replacing...")",
- "KCHVMCD6006M": "$_("Successfully attached!")",
- "KCHVMCD6007M": "$_("Successfully replaced!")",
- "KCHVMCD6008M": "$_("Successfully detached!")",
- "KCHVMCD6009M": "$_("This disk will be detached permanently and
you can re-attach it. Continue to detach it?")",
-
- "KCHVMED6001M": "$_("interface:")",
- "KCHVMED6002M": "$_("address:")",
- "KCHVMED6003M": "$_("link_type:")",
- "KCHVMED6004M": "$_("block:")",
- "KCHVMED6005M": "$_("drive_type:")",
- "KCHVMED6006M": "$_("model:")",
- "KCHVMED6007M": "$_("Affected devices:")",
-
- "KCHNET6001E": "$_("The VLAN id must be between 1 and
4094.")",
-
- "KCHNET6001M": "$_("unavailable")",
- "KCHNET6002M": "$_("This action will interrupt network
connectivity for any virtual machine that depend on this network.")",
- "KCHNET6003M": "$_("Create a network")",
- "KCHNET6004M": "$_("This network is not persistent. Instead of
stop, this action will permanently delete it. Would you like to continue?")",
- "KCHNET6001W": "$_("The bridged VLAN tag may not work well with
NetworkManager enabled. You should consider disabling it.")",
-
- "KCHPOOL6001M": "$_("This will permanently delete the storage
pool. Would you like to continue?")",
- "KCHPOOL6002M": "$_("This storage pool is empty.")",
- "KCHPOOL6003M": "$_("It will format your disk and you will loose
any data in there, are you sure to continue? ")",
- "KCHPOOL6004M": "$_("SCSI Fibre Channel")",
- "KCHPOOL6005M": "$_("No SCSI adapters found.")",
- "KCHPOOL6006M": "$_("Loading iSCSI targets...")",
- "KCHPOOL6007M": "$_("No iSCSI found. Please input
one.")",
- "KCHPOOL6008M": "$_("Failed to load iSCSI targets.")",
-
- "KCHPOOL6001E": "$_("The storage pool name can not be
blank.")",
- "KCHPOOL6002E": "$_("The storage pool path can not be
blank.")",
- "KCHPOOL6003E": "$_("NFS server mount path can not be
blank.")",
- "KCHPOOL6005E": "$_("Invalid NFS mount path.")",
- "KCHPOOL6006E": "$_("No logical device selected.")",
- "KCHPOOL6007E": "$_("The iSCSI target can not be
blank.")",
- "KCHPOOL6008E": "$_("Server name can not be blank.")",
- "KCHPOOL6009E": "$_("This is not a valid Server Name or IP.
Please, modify it.")",
- "KCHPOOL6010M": "$_("Looking for available partitions
...")",
- "KCHPOOL6011M": "$_("No available partitions
found.")",
- "KCHPOOL6012M": "$_("This storage pool is not persistent. Instead
of deactivate, this action will permanently delete it. Would you like to
continue?")",
- "KCHPOOL6013M": "$_("Unable to retrieve partitions
information.")",
- "KCHPOOL6014M": "$_("In progress...")",
- "KCHPOOL6015M": "$_("Failed!")",
-
- "KCHVMSTOR0001E": "$_("CDROM path needs to be a valid
local/remote path and cannot be blank.")",
- "KCHVMSTOR0002E": "$_("Disk pool or volume cannot be
blank.")"
-}
diff --git a/plugins/kimchi/ui/pages/network.html.tmpl
b/plugins/kimchi/ui/pages/network.html.tmpl
deleted file mode 100644
index 915feac..0000000
--- a/plugins/kimchi/ui/pages/network.html.tmpl
+++ /dev/null
@@ -1,133 +0,0 @@
-#*
- * Project Kimchi
- *
- * Copyright IBM, Corp. 2013-2015
- *
- * 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.
- *#
-
-#unicode UTF-8
-#import gettext
-#from wok.cachebust import href
-#silent t = gettext.translation($lang.domain, $lang.localedir, languages=$lang.lang,
fallback=True)
-#silent _ = t.gettext
-#silent _t = t.gettext
-<!DOCTYPE html>
-<html>
-<head>
-<link rel="stylesheet"
href="plugins/kimchi/css/theme-default.min.css">
-<script src="plugins/kimchi/js/kimchi.min.js"></script>
-</head>
-<body>
-<div class="toolbar">
- <div class="tools" style="display:none">
- <a id="networkAdd" class="btn-tool"
href="javascript:void(0);"><span class="icon
add">+</span></a>
- </div>
-</div>
-<div id="network-content" class="network">
- <div class="grid-control"><input type="text"
class="filter" placeholder="$_("Filter")"></div>
- <div id="networkGrid" class="list">
- <div>
- <span class="column-name">$_("Network
Name")</span><!--
- --><span
class="column-state">$_("State")</span><!--
- --><span class="column-type">$_("Network
Type")</span><!--
- --><span
class="column-interface">$_("Interface")</span><!--
- --><span class="column-space">$_("Address
Space")</span><!--
- --><span
style="display:none">$_("Actions")</span>
- </div>
- <div id="networkBody"
class="empty-when-logged-off"></div>
- </div>
- <div id="networkConfig" class="network-config">
- <div class="section-container">
- <div class="section-header">1. $_("Network
Name")</div>
- <div class="section-content">
- <input type="text" id="networkName" />
- <div class="input-hint">
- <span class="icon-info-circled light-grey c1
help-inline"></span>
- <span class="input-hint-text
help-inline">$_("Name should not contain '/' and
'\"'.")</span>
- </div>
- </div>
- </div>
- <div class="section-container">
- <div class="section-header">2. $_("Network
Type")</div>
- <div class="section-content">
- <div class="input-container">
- <input type="radio" id="networkTypeIso"
name="networkType" value="isolated" />
- <label for="networkTypeIso">$_("Isolated: no
external network connection")</label>
- </div>
- <div class="input-container">
- <input type="radio" id="networkTypeNat"
name="networkType" value="nat" />
- <label for="networkTypeNat">$_("NAT: outbound
physical network connection only")</label>
- </div>
- <div class="input-container">
- <div class="bridged-inline">
- <input type="radio" id="networkTypeBri"
name="networkType" value="bridged" />
- </div>
- <div class="bridged-inline">
- <label for="networkTypeBri">$_("Bridged:
Virtual machines are connected to physical network directly")</label><br
/>
- <label id="networkBriDisabledLabel"
style="display:none">$_("(No interfaces found)")</label>
- </div>
- </div>
- <div id="bridgeOptions">
- <div>
- <div class="bridge-option-column">
- <label
for="networkInterface">$_("Destination"): </label>
- </div>
- <div class="bridge-option-column">
- <div class="network-type-wrapper-controls">
- <div id ="networkDestinationID">
- <input id="networkDestinationInputId"
name="type" type="hidden"/>
- <span id="networkDestinationLabel"
type="text"></span><span class="arrow"></span>
- <div>
- <ul
id="networkInterface"></ul>
- </div>
- </div>
- </div>
- </div>
- </div>
- <div>
- <input id="enableVlan" type="checkbox"
value="" />
- <label for="enableVlan"
id="labelEnableVlan">$_("Enable VLAN") </label>
- </div>
- <label for="networkVlanID"
id="labelNetworkVlanID">$_("VLAN ID"): </label>
- <input type="text" id="networkVlanID"
class="network-label"/>
- </div>
- </div>
- </div>
- </div>
- </div>
-</div>
-<script id="networkItem" type="text/html">
- <div id='{name}' class='remove-when-logged-off'>
- <span class='column-name' title="{name}"
val="{name}">{name}</span><!--
- --><span class='column-state' val="{state}"><span
class='network-state {state}'></span></span><!--
- --><span class='column-type'
val="{type}">{type}</span><!--
- --><span class='column-interface'
val="{interface}">{interface}</span><!--
- --><span class='column-space'
val="{addrSpace}">{addrSpace}</span><!--
- --><span class='column-action' style="display:none">
- <span class="ui-button-secondary dropdown popable
action-button">
- $_("Actions")
- <ul class='popover actionsheet right-side menu-container'>
- <li nwAct="start" class='{startClass}'><a
class='button-big'>$_("Start")</a></li>
- <li nwAct="stop" class='{stopClass}'><a
{stopDisabled} class='button-big'>$_("Stop")</a></li>
- <li nwAct="delete" class='{deleteClass}'><a
{deleteDisabled} class='red'>$_("Delete")</a></li>
- </ul>
- </span>
- </span>
- </div>
-</script>
-<script>
- kimchi.initNetwork();
-</script>
-</body>
-</html>
diff --git a/plugins/kimchi/ui/pages/report-add.html.tmpl
b/plugins/kimchi/ui/pages/report-add.html.tmpl
deleted file mode 100644
index 25bf0a9..0000000
--- a/plugins/kimchi/ui/pages/report-add.html.tmpl
+++ /dev/null
@@ -1,56 +0,0 @@
-#*
- * Project Kimchi
- *
- * Copyright IBM, Corp. 2013-2015
- *
- * 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.
- *#
-#unicode UTF-8
-#import gettext
-#from wok.cachebust import href
-#silent t = gettext.translation($lang.domain, $lang.localedir, languages=$lang.lang,
fallback=True)
-#silent _ = t.gettext
-#silent _t = t.gettext
-<!DOCTYPE html>
-<div id="report-add-window" class="window">
- <header>
- <h1 class="title h1 grey">$_("Generate a New Debug
Report")</h1>
- </header>
- <div class="content">
- <form id="form-report-add">
- <section class="form-section">
- <h2>
- <label for="report-name-textbox">$_("Report
Name")</label>
- </h2>
- <div class="field">
- <input type="text" class="text"
id="report-name-textbox" name="name" />
- <span class="icon-info-circled light-grey
c1"></span>
- <span class="info-add-debug-report">
- $_("The name used to identify the report. If omitted, a name
will be chosen based on current time. Name can contain: letters, digits, underscore
(\"_\") and hyphen (\"-\").")
- </span>
- </div>
- </section>
- </form>
- </div>
- <footer>
- <div class="btn-group">
- <button id="button-report-add"
class="btn-normal"><span
class="text">$_("Generate")</span></button>
- <button id="button-report-cancel" class="btn-normal
close" type="button">
- <span calss="text">$_("Cancel")</span>
- </button>
- </div>
- </footer>
-</div>
-<script>
- kimchi.report_add_main();
-</script>
diff --git a/plugins/kimchi/ui/pages/report-rename.html.tmpl
b/plugins/kimchi/ui/pages/report-rename.html.tmpl
deleted file mode 100644
index 90a0a80..0000000
--- a/plugins/kimchi/ui/pages/report-rename.html.tmpl
+++ /dev/null
@@ -1,56 +0,0 @@
-#*
- * Project Kimchi
- *
- * Copyright IBM, Corp. 2014-2015
- *
- * 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.
- *#
-#unicode UTF-8
-#import gettext
-#from wok.cachebust import href
-#silent t = gettext.translation($lang.domain, $lang.localedir, languages=$lang.lang,
fallback=True)
-#silent _ = t.gettext
-#silent _t = t.gettext
-<!DOCTYPE html>
-<div id="report-rename-window" class="window">
- <header>
- <h1 class="title h1 grey">$_("Rename a Debug
Report")</h1>
- </header>
- <div class="content">
- <form id="form-report-rename">
- <section class="form-section">
- <h2>
- <label for="report-name-textbox">$_("Report
Name")</label>
- </h2>
- <div class="field">
- <input type="text" class="text"
id="report-name-textbox" name="name" />
- <span class="icon-info-circled light-grey
c1"></span>
- <span class="info-debug-report-rename">
- $_("The name used to identify the report. Name can contain:
letters, digits and hyphen (\"-\").")
- </span>
- </div>
- </section>
- </form>
- </div>
- <footer>
- <div class="btn-group">
- <button id="button-report-rename"
class="btn-normal"><span
class="text">$_("Submit")</span></button>
- <button id-"button-report-rename-cancel" class="btn-normal
close" type="button">
- <span class="text">$_("Cancel")</span>
- </button>
- </div>
- </footer>
-</div>
-<script>
- kimchi.report_rename_main();
-</script>
diff --git a/plugins/kimchi/ui/pages/repository-add.html.tmpl
b/plugins/kimchi/ui/pages/repository-add.html.tmpl
deleted file mode 100644
index 950252a..0000000
--- a/plugins/kimchi/ui/pages/repository-add.html.tmpl
+++ /dev/null
@@ -1,113 +0,0 @@
-#*
- * Project Kimchi
- *
- * Copyright IBM, Corp. 2014-2015
- *
- * 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.
- *#
-#unicode UTF-8
-#import gettext
-#from wok.cachebust import href
-#silent t = gettext.translation($lang.domain, $lang.localedir, languages=$lang.lang,
fallback=True)
-#silent _ = t.gettext
-#silent _t = t.gettext
-<div id="repository-add-window" class="window">
- <form id="form-repository-add">
- <header class="window-header">
- <h1 class="title h1 grey">$_("Add a
Repository")</h1>
- </header>
- <section>
- <div class="content">
- <div class="form-section yum">
- <h2>$_("Identifier")</h2>
- <div class="field">
- <div class="textbox-wrapper">
- <input type="text" class="text"
name="repo_id" />
- </div>
- <div class="icon-info-circled light-grey c1
help-inline"></div>
- <p class="text-help help-inline">
- $_("Single word, unique identifier for the
repository.")
- </p>
- </div>
- </div>
- <section class="form-section yum">
- <h2>$_("Name")</h2>
- <div class="field">
- <div class="textbox-wrapper">
- <input type="text" class="text"
name="config[repo_name]" />
- </div>
- <div class="icon-info-circled light-grey c1
help-inline"></div>
- <p class="text-help help-inline">
- $_("Textual name for the repository.")
- </p>
- </div>
- </section>
- <section class="form-section">
- <h2>$_("URL")<span class="required"
role="presentation" title='$_("Required
Field")'>*</span></h2>
- <div class="field">
- <div class="textbox-wrapper">
- <input type="text" class="text
required" name="baseurl" />
- </div>
- <div class="icon-info-circled light-grey c1
help-inline"></div>
- <p class="text-help help-inline">
- $_("URL to the repository. Supported protocols are http,
ftp, and file.")
- </p>
- </div>
- <div class="field yum">
- <p class="yum">
- <input type="checkbox" name="isMirror"
value="true" id="isMirror" />
- <label id="isMirrorLabel"
for="isMirror">$_("Repository is a mirror")</label>
- </p>
- </div>
- </section>
- <section class="form-section repository-dist deb">
- <h2>$_("Distribution")</h2>
- <div class="field">
- <div class="textbox-wrapper">
- <input type="text" class="text"
name="config[dist]" />
- </div>
- <div class="icon-info-circled light-grey c1
help-inline"></div>
- <p class="text-help help-inline">
- $_("Distribution of the DEB repository.")
- </p>
- </div>
- </section>
- <section class="form-section repository-comps deb">
- <h2>$_("Components")</h2>
- <div class="field">
- <div class="textbox-wrapper">
- <input type="text" class="text"
name="config[comps]" />
- </div>
- <div class="icon-info-circled light-grey c1
help-inline"></div>
- <p class="text-help help-inline">
- $_("List of components in DEB repository.")
- </p>
- </div>
- </section>
- </div>
- </section>
- <footer>
- <div class="btn-group">
- <button type="submit" id="button-repository-add"
class="btn-normal" disabled="disabled">
- <span class="text">$_("Add")</span>
- </button>
- <button type="button" id="button-repository-close"
class="btn-normal close">
- <span
class="text">$("Cancel")</span>
- </button>
- </div>
- </footer>
- </form>
-</div>
-<script>
- kimchi.repository_add_main();
-</script>
diff --git a/plugins/kimchi/ui/pages/repository-edit.html.tmpl
b/plugins/kimchi/ui/pages/repository-edit.html.tmpl
deleted file mode 100644
index e5a3cfb..0000000
--- a/plugins/kimchi/ui/pages/repository-edit.html.tmpl
+++ /dev/null
@@ -1,117 +0,0 @@
-#*
- * Project Kimchi
- *
- * Copyright IBM, Corp. 2014-2015
- *
- * 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.
- *#
-#unicode UTF-8
-#import gettext
-#from wok.cachebust import href
-#silent t = gettext.translation($lang.domain, $lang.localedir, languages=$lang.lang,
fallback=True)
-#silent _ = t.gettext
-#silent _t = t.gettext
-
-<div id="repository-edit-window" class="window">
- <form id="form-repository-edit">
- <header>
- <h1 class="title h1 grey">$_("Edit
Repository")</h1>
- </header>
- <div class="content">
- <section id="form-repository-edit">
- <fieldset class="repository-edit-fieldset">
- <div class="repository-id yum">
- <div class="repository-edit-wrapper-label">
- <label
for="repository-edit-id-textbox">$_("ID")</label>
- </div>
- <div class="repository-edit-wrapper-controls">
- <input id="repository-edit-id-textbox"
name="repo_id" type="text" disabled="disabled"
readonly="readonly"/>
- </div>
- </div>
- <div class="repository-name yum">
- <div class="repository-edit-wrapper-label">
- <label
for="repository-edit-name-textbox">$_("Name")</label>
- </div>
- <div class="repository-edit-wrapper-controls">
- <input id="repository-edit-name-textbox"
class="yum" name="config[repo_name]" type="text" />
- </div>
- </div>
- <div class="repository-url">
- <div class="repository-edit-wrapper-label">
- <label
for="repository-edit-baseurl-textbox">$_("URL")</label>
- </div>
- <div class="repository-edit-wrapper-controls">
- <input id="repository-edit-baseurl-textbox"
name="baseurl" type="text" />
- </div>
- </div>
- <div class="repository-dist deb">
- <div class="repository-edit-wrapper-label">
- <label
for="repository-edit-urlargs-textbox">$_("Distribution")</label>
- </div>
- <div class="repository-edit-wrapper-controls">
- <input id="repository-edit-urlargs-textbox"
class="deb" name="config[dist]" type="text" />
- </div>
- </div>
- <div class="repository-mirrorlist yum">
- <div class="repository-edit-wrapper-label">
- <label
for="repository-edit-urlargs-textbox">$_("Mirror List
URL")</label>
- </div>
- <div class="repository-edit-wrapper-controls">
- <input id="repository-edit-urlargs-textbox"
class="yum" name="config[mirrorlist]" type="text" />
- </div>
- </div>
- <div class="repository-comps deb">
- <div class="repository-edit-wrapper-label">
- <label
for="repository-edit-urlargs-textbox">$_("Components")</label>
- </div>
- <div class="repository-edit-wrapper-controls">
- <input id="repository-edit-urlargs-textbox"
class="deb" name="config[comps]" type="text" />
- </div>
- </div>
- <div class="repository-gpgkey yum">
- <div class="repository-edit-wrapper-label">
- <label
for="repository-edit-gpgkey-textbox">$_("GPG Key")</label>
- </div>
- <div class="repository-edit-wrapper-controls">
- <input id="repository-edit-gpgkey-textbox"
class="yum" name="config[gpgkey]" type="text" />
- </div>
- </div>
- <div class="repository-gpgcheck yum">
- <div class="repository-edit-wrapper-label">
- <label>$_("GPG Check")</label>
- </div>
- <div class="repository-edit-wrapper-controls">
- <input id="repository-edit-gpgcheck-radio-true"
class="yum" name="config[gpgcheck]" type="radio"
value="true" />
- <label
for="repository-edit-gpgcheck-radio-true">$_("Yes")</label>
- <input id="repository-edit-gpgcheck-radio-false"
class="yum" name="config[gpgcheck]" type="radio"
value="false" />
- <label
for="repository-edit-gpgcheck-radio-false">$_("No")</label>
- </div>
- </div>
- </fieldset>
- </section>
- </div>
- <footer>
- <div class="btn-group">
- <button type="submit"
id="repository-edit-button-save" class="btn-normal">
- <span class="text">$_("Save")</span>
- </button>
- <button type="button"
id="repository-edit-button-cancel" class="close btn-normal">
- <span
class="text">$_("Cancel")</span>
- </button>
- </div>
- </footer>
- </form>
-</div>
-<script type="text/javascript">
- kimchi.repository_edit_main();
-</script>
diff --git a/plugins/kimchi/ui/pages/storage.html.tmpl
b/plugins/kimchi/ui/pages/storage.html.tmpl
deleted file mode 100644
index 7b51a8b..0000000
--- a/plugins/kimchi/ui/pages/storage.html.tmpl
+++ /dev/null
@@ -1,143 +0,0 @@
-#*
- * Project Kimchi
- *
- * Copyright IBM, Corp. 2013-2015
- *
- * 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.
- *#
-
-#unicode UTF-8
-#import gettext
-#silent t = gettext.translation($lang.domain, $lang.localedir, languages=$lang.lang,
fallback=True)
-#silent _ = t.gettext
-#silent _t = t.gettext
-<!DOCTYPE html>
-<html>
-<head>
-<link rel="stylesheet"
href="plugins/kimchi/css/theme-default.min.css">
-<script src="plugins/kimchi/js/kimchi.min.js"></script>
-</head>
-<body>
-<div class="toolbar">
- <div class="tools" style="display:none">
- <a id="storage-pool-add" class="btn-tool"
href="javascript:void(0);"><span class="icon
add">+</span></a>
- </div>
-</div>
-<div class='storage'>
-<div class="grid-control"><input type="text"
class="filter" placeholder="$_("Filter")"></div>
-<div id='storageGrid'>
- <div>
- <span class="storage-name">$_("Name")</span>
- <span class="storage-state" >$_("State")</span>
- <span class="storage-type">$_("Type")</span>
- <span
class="storage-capacity">$_("Capacity")</span>
- <span
class="storage-allocate">$_("Allocated")</span>
- <span
class="storage-location">$_("Location")</span>
- </div>
- <div id="storagepoolsList" class="list-storage
empty-when-logged-off"></div>
-</div>
-</div>
-<div id="logicalPoolExtend" title="$_("Device
path")">
- <p id="loading-info" class="text-help">
- <img src = "plugins/kimchi/images/theme-default/loading.gif" />
- $_("Looking for available partitions ...")
- </p>
- <div class="host-partition">
- </div>
-</div>
-<script id="storageTmpl" type="html/text">
- <div id="{name}" class="storage-li in"
data-name="{name}" data-stat="{state}">
- <span class="storage-name" val="{name}{usage}%">
- <span title="{name}">{name}</span>
- <span class="usage">{usage}%</span>
- </span>
- <span class="storage-state">
- <div class="status-dot toolable active"
data-state="{state}">
- <label
class="tooltip">$_("active")</label>
- </div>
- <div class="status-dot toolable inactive"
data-state="{state}">
- <label
class="tooltip">$_("inactive")</label>
- </div>
- </span>
- <span class="storage-type" val="{type}">
- <div>{type}</div>
- </span>
- <span class="storage-capacity" val="{capacity}">
- <div data-type="{type}">{capacity}</div>
- </span>
- <span class="storage-allocate" val="{allocated}">
- <div data-type="{type}">{allocated}</div>
- </span>
- <span class="storage-location" val="{path}">
- <div>{path}</div>
- </span>
- <span class="bottom storage-button"
style="display:none">
- <div class="btn dropdown popable storage-action"
data-state="{state}" data-type="{type}"
data-name="{name}">
- <span
class="text">$_("Actions")</span><span
class="arrow"></span>
- <div class="popover actionsheet right-side"
style="width: 250px">
- <button class="button-big pool-deactivate"
data-stat="{state}" data-name="{name}"
data-persistent="{persistent}"><span
class="text">$_("Deactivate")</span></button>
- <button class="button-big pool-activate"
data-stat="{state}" data-name="{name}"><span
class="text">$_("Activate")</span></button>
- <button class="button-big pool-add-volume"
data-stat="{state}" data-name="{name}"
data-type="{type}"><span class="text">$_("Add
Volume")</span></button>
- <button class="button-big pool-extend {enableExt}"
data-stat="{state}" data-name="{name}"><span
class="text">$_("Extend")</span></button>
- <button class="button-big red pool-delete"
data-stat="{state}" data-name="{name}"><span
class="text">$_("Undefine")</span></button>
- </div>
- </div>
- </span>
- <span class="handle">
- <div class="arrow-down"></div>
- </span>
- <div class="volumes">
- <div id="volume{name}" class="volumeslist"
data-name="{name}" ></div>
- <div class="clear"></div>
- </div>
- </div>
-</script>
-<script id="volumeTmpl" type="html/text">
- <div class="volume-box white-box"
data-volume-name="{name}">
- <div class="storage-icon volume-default icon-{format} ">
- </div>
- <div class="volume-title">
- <div class="volume-name"
title="{name}">{name}</div>
- <div class="volume-progress hidden">
- <div class="progress-bar-outer">
- <div class="progress-bar-inner"></div>
- </div>
- <div class="progress-label">
- <span class="progress-status"></span>
- <span class="progress-transferred"></span>
- </div>
- </div>
- </div>
- <div class="volume-setting">
- </div>
- <div class="volume-type-position">
- <div title="{type}"
class="volume-text">$_("Type"): {type}</div>
- <div title="{format}"
class="volume-text">$_("Format"): {format}</div>
- </div>
- <div class="volume-quota-position">
- <div title="{capacity}"
class="volume-textquota">$_("Capacity"): {capacity}</div>
- <div
title="{allocation}"class="volume-textquota">$_("Allocation"):
{allocation}</div>
- </div>
- </div>
-</script>
-<script id="logicalPoolExtendTmpl" type="html/text">
- <div>
- <input type="checkbox" value="{path}"
name="devices">
- <label for="{name}">{path}</label>
- </div>
-</script>
-<script>
- kimchi.storage_main();
-</script>
-</body>
-</html>
diff --git a/plugins/kimchi/ui/pages/storagepool-add-volume.html.tmpl
b/plugins/kimchi/ui/pages/storagepool-add-volume.html.tmpl
deleted file mode 100644
index ab10939..0000000
--- a/plugins/kimchi/ui/pages/storagepool-add-volume.html.tmpl
+++ /dev/null
@@ -1,79 +0,0 @@
-#*
- * Project Kimchi
- *
- * Copyright IBM, Corp. 2014-2015
- *
- * 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.
- *#
-#unicode UTF-8
-#import gettext
-#from wok.cachebust import href
-#silent t = gettext.translation($lang.domain, $lang.localedir, languages=$lang.lang,
fallback=True)
-#silent _ = t.gettext
-#silent _t = t.gettext
-<div id="sp-add-volume-window" class="window">
- <form id="form-sp-add-volume">
- <header class="window-header">
- <h1 class="title h1 grey">$_("Add a Volume to Storage
Pool")</h1>
- </header>
- <section>
- <div class="content">
- <div class="form-section">
- <h2>
- <input type="radio"
id="volume-type-download" class="volume-type"
name="volumeType" value="download" checked="checked" />
- <label for="volume-type-download">
- $_("Fetch from remote URL")
- </label>
- </h2>
- <div class="field">
- <div class="textbox-wrapper">
- <input type="text"
id="volume-remote-url" class="text volume-input download"
name="volumeRemoteURL" />
- </div><br>
- <div class="icon-info-circled light-grey c1
help-inline"></div>
- <p class="text-help help-inline">
- $_("Enter the remote URL here.")
- </p>
- </div>
- </div>
- <div class="form-section">
- <h2>
- <input type="radio"
id="volume-type-upload" class="volume-type"
name="volumeType" value="upload"/>
- <label for="volume-type-upload">
- $_("Upload a file")
- </label>
- </h2>
- <div class="field">
- <div class="icon-info-circled light-grey c1
help-inline"></div>
- <p class="text-help help-inline">
- $_("Choose the file you want to upload.")
- </p>
- <div class="textbox-wrapper">
- <input type="file" class="volume-input
upload" id="volume-input-file" name="volumeLocalFile"
disabled="disabled" />
- </div>
- </div>
- </div>
- </div>
- </section>
- <footer>
- <div class="btn-group">
- <button type="submit" id="sp-add-volume-button"
class="btn-normal" disabled="disabled">
- <span class="text">$_("Add")</span>
- </button>
- <button type="button" class="btn-normal
close"><span
class="text">$_("Cancel")</span></button>
- </div>
- </footer>
- </form>
-</div>
-<script type="text/javascript">
- kimchi.sp_add_volume_main();
-</script>
diff --git a/plugins/kimchi/ui/pages/storagepool-add.html.tmpl
b/plugins/kimchi/ui/pages/storagepool-add.html.tmpl
deleted file mode 100644
index a697af5..0000000
--- a/plugins/kimchi/ui/pages/storagepool-add.html.tmpl
+++ /dev/null
@@ -1,186 +0,0 @@
-#*
- * Project Kimchi
- *
- * Copyright IBM, Corp. 2013-2015
- *
- * 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.
- *#
-#unicode UTF-8
-#import gettext
-#silent t = gettext.translation($lang.domain, $lang.localedir, languages=$lang.lang,
fallback=True)
-#silent _ = t.gettext
-#silent _t = t.gettext
-<!DOCTYPE html>
-<html>
-<body>
- <div class="window storage-window storage-admin">
- <header>
- <h1 class="title h1 grey">$_("Define a New Storage
Pool")</h1>
- </header>
- <div class="content">
- <form id="form-pool-add">
- <section class="form-section">
- <h2>1. $_("Storage Pool Name")</h2>
- <div class="field">
- <input id="poolId" required="required"
type="text" class="text storage-base-input-width"
name="name"><br>
- <div class="icon-info-circled light-grey c1
help-inline"></div>
- <p class="text-help help-inline">
- $_("The name used to identify the storage pools, and it
should not be empty.")
- </p>
- </div>
- </section>
- <section class="form-section">
- <h2>2. $_("Storage Pool Type")</h2>
- <div class="storage-type-wrapper-controls">
- <div id="poolTypeId">
- <input id="poolTypeInputId"
name="type" type="hidden" value="dir"/>
- <span id="pool-type-label"
class="text"></span><span class="arrow"></span>
- <div>
- <ul id="storagePool-list">
- </ul>
- </div>
- </div>
- </div>
- </section>
- <div class="path-section">
- <section class="form-section">
- <h2>3. $_("Storage Path")</h2>
- <div class="field">
- <input id="pathId" type="text"
class="text storage-base-input-width"><br>
- <div class="icon-info-circled light-grey c1
help-inline"></div>
- <p class="text-help help-inline">
- $_("The path of the Storage Pool. Each Storage Pool
must have a unique path.")</p><br>
- <div class="icon-info-circled light-grey c1
help-inline"></div>
- <p class="text-help help-inline">
- $_("Kimchi will try to create the directory when it
does not already exist in your system.")</p>
- </div>
- <div class="clear"></div>
- </section>
- </div>
- <div class="nfs-section tmpl-html">
- <section class="form-section">
- <h2>3. $_("NFS Server IP")</h2>
- <div class="field storage-field">
- <div id="serverComboboxId"
class="storage-add-input-width">
- <input id="nfsserverId"/>
- <div>
- <ul id="nfs-server-used">
- </ul>
- </div>
- </div><br>
- <div class="icon-info-circled light-grey c1
help-inline"></div>
- <p class="text-help help-inline">
- $_("NFS server IP or hostname. It can be input or
chosen from history.")</p>
- </div>
- </section>
- <section class="form-section">
- <h2>4. $_("NFS Path")</h2>
- <div class="field storage-field">
- <div id="targetFilterSelectId"
class="storage-add-input-width">
- <input id="nfspathId"
class="input" disabled/>
- <div>
- <ul id="nfs-server-target">
- </ul>
- </div>
- </div><br>
- <div class="icon-info-circled light-grey c1
help-inline"></div>
- <p class="text-help help-inline">$_("The
NFS exported path on NFS server.")</p>
- </div>
- </section>
- </div>
- <div class="logical-section tmpl-html">
- <section class="form-section storageType">
- <h2>3. $_("Device path")</h2>
- <div class="host-partition">
- <div class="icon-info-circled light-grey c1
help-inline"></div>
- <p class="text-help help-inline">
- $_("Looking for available partitions ...")
- <img src =
"plugins/kimchi/images/theme-default/loading.gif" />
- </p>
- </div>
- </section>
- </div>
- <div class="iscsi-section tmpl-html">
- <section class="form-section">
- <h2>3. $_("iSCSI Server")</h2>
- <div class="field">
- <span class="filter-select popable"
id="iSCSIServer">
- <input id="iscsiserverId"
type="text" placeholder="$_("Server")">
- <div class="popover"><ul
class="option select-list"></ul></div>
- </span>
- <input id="iscsiportId"
placeholder="$_("Port")" type="text" class="text
storage-port-width" maxlength="4"><br>
- <div class="icon-info-circled light-grey c1
help-inline"></div>
- <p class="text-help help-inline">
- $_("iSCSI server IP or hostname. It should not be
empty.")</p>
- </div>
- </section>
- <section class="form-section">
- <h2>4. $_("Target")</h2>
- <div class="field">
- <span class="filter-select popable"
id="iSCSITarget">
- <input id="iscsiTargetId"
type="text">
- <div class="popover"><ul
class="option select-list"></ul></div>
- </span><br>
- <div class="icon-info-circled light-grey c1
help-inline"></div>
- <p class="text-help help-inline">$_("The
iSCSI target on iSCSI server")</p>
- </div>
- </section>
- <section class="form-section">
- <div class="field">
- <input type="checkbox" id="authId"
name="authname">
- <label for="authId">$_("Add iSCSI
Authentication")</label>
- </div>
- </section>
- <section class="authenticationfield form-section
tmpl-html">
- <h2>5. $_("iSCSI Authentication")</h2>
- <div class="field">
- <input id="usernameId"
placeholder="$_("User Name")" type="text" class="text
storage-auth-width">
- <input id="passwordId"
placeholder="$_("Password")" type="password"
class="text storage-auth-width">
- </div>
- </section>
- </div>
- <div class="scsi-section tmpl-html">
- <section class="form-section">
- <h2>3. $_("SCSI Adapter")</h2>
- <div class="storage-type-wrapper-controls">
- <div id="scsiAdapter">
- <input type="hidden"/>
- <span class="text"></span><span
class="arrow"></span>
- <div><ul></ul></div>
- </div>
- </div>
- </section>
- </div>
- </form>
- </div>
- <footer>
- <div class="btn-group">
- <button id="pool-doAdd" class="btn-normal">
- <span
class="text">$_("Create")</span>
- </button>
- <button class="btn-normal" id="pool-loading"
style="display: none"><span class="text">$_("Please,
wait...")</span></button>
- <button class="btn-normal close"
type="button"><span
class="text">$_("Cancel")</span></button>
- </div>
- </footer>
- </div>
- <script>
- kimchi.storagepool_add_main();
- </script>
- <script id="partitionTmpl" type="html/text">
- <div>
- <input type="checkbox" id="{name}"
value="{path}" name="devices">
- <label for="{name}">{path}</label>
- </div>
- </script>
-</body>
-</html>
diff --git a/plugins/kimchi/ui/pages/template-add.html.tmpl
b/plugins/kimchi/ui/pages/template-add.html.tmpl
deleted file mode 100644
index b44db79..0000000
--- a/plugins/kimchi/ui/pages/template-add.html.tmpl
+++ /dev/null
@@ -1,233 +0,0 @@
-#*
- * Project Kimchi
- *
- * Copyright IBM, Corp. 2013-2015
- *
- * 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.
- *#
-#unicode UTF-8
-#import gettext
-#from wok.cachebust import href
-#silent t = gettext.translation($lang.domain, $lang.localedir, languages=$lang.lang,
fallback=True)
-#silent _ = t.gettext
-#silent _t = t.gettext
-<!DOCTYPE html>
-<html>
-<body>
-<div class="window" style="width: 992px;height: 660px;">
- <header>
- <h1 class="title h1 grey">$_("Add
Template")</h1>
- </header>
- <div class="content" style="margin-bottom: 0">
- <div class="page-list">
- <!-- 1 -->
- <div class="page" id="iso-type-box"
style="left:0">
- <h2 class="step-title">$_("Where is the source media
for this template? ")</h2>
- <ul class="step-choose">
- <li>
- <a id="iso-local"
class="local">$_("Local ISO Image")</a>
- </li>
- <li>
- <a id="vm-image-local"
class="local">$_("Local Image File")</a>
- </li>
- <li>
- <a id="iso-remote"
class="remote">$_("Remote ISO Image")</a>
- </li>
- </ul>
- </div>
-
- <!-- 1-1 -->
- <div class="page" id="iso-local-box">
- <header>
- <a class="back"
id="iso-local-box-back"></a>
- <h2 class="step-title">$_("Local ISO
Image")</h2>
- </header>
-
- <button class="btn-normal" id="iso-search"
style="display: none"><span class="text">$_("Search
ISOs")</span></button>
- <button class="btn-normal" id="iso-search-loading"
style="display: none"><span class="text">$_("Please,
wait...")</span></button>
- <!-- 1-1-1 -->
- <div id="local-iso-field" class="iso-field"
style="display: none;">
- <h3 class="step-subtitle">
- $_("The following ISOs are available:")
- </h3>
- <div class="toolbar">
- <label class="check-all">
- <input type="checkbox"
id="select-all-local-iso">$_("All")
- </label>
- </div>
- <div>
- <form id="form-local-iso">
- <ul id="list-local-iso"
class="list-iso">
- </ul>
- </form>
- <script id="tmpl-list-local-iso"
type="text/html">
- <li>
- <label>
- <input type="checkbox"
name="iso" value="{isoId}">
- <div class="box box-iso">
- <div class="iso-icon
{os_distro}">
- </div>
- <h3 class="iso-title"
title="{name}">
- {name}
- </h3>
- <div class="iso-info">
- <div class="iso-info-col">
- <div class="iso-info-item"
title="{os_distro}">
- $_("OS: "){os_distro}
- </div>
- <div class="iso-info-item"
title="{os_version}">
- $_("Version:
"){os_version}
- </div>
- </div>
- <div class="iso-info-col">
- <div class="iso-info-item"
title="{capacity}">
- $_("Size: "){capacity}
- </div>
- </div>
- </div>
- </div>
- </label>
- </li>
- </script>
- </div>
- <div class="button-field">
- <button class="btn-normal" id="iso-more"
style="display: none"><span class="text">$_("Search more
ISOs")</span></button>
- <button class="btn-normal"
id="iso-more-loading" style="display: none"><span
class="text">$_("Please, wait...")</span></button>
- <button class="btn-normal"
id="btn-template-local-iso-create" disabled="disabled"><span
class="text">$_("Create Templates from Selected
ISO")</span></button>
- </div>
- </div>
-
- <!-- 1-1-2 -->
- <div id="iso-file-field">
- <h3 class="step-subtitle">
- <label>
- <input type="checkbox"
id="iso-file-check">
- $_("I want to use a specific ISO file")
- </label>
- </h3>
- <div id="iso-file-box"
class="custom-iso-field">
- <div class="input-wrapper"><input
type="text" class="text" id="iso-file"
name="iso-file"></div>
- <button class="btn-normal"
id="btn-template-file-create" disabled="disabled"><span
class="text">$_("Create")</span></button>
- </div>
- </div>
-
- </div>
-
- <div class="page" id="vm-image-local-box">
- <header>
- <a class="back"
id="vm-image-local-box-back"></a>
- <h2 class="step-title">$_("Local Image
File")</h2>
- </header>
- <div class="body">
- <label for="vm-image-local-text">File
Path:</label>
- <input type="text" id="vm-image-local-text"
/>
- <button
class="ui-button-primary">$_("Create")</button>
- </div>
- </div>
-
- <!-- 1-2 -->
- <div class="page" id="iso-remote-box">
- <header>
- <a class="back"
id="iso-remote-box-back"></a>
- <h2 class="step-title">$_("Remote ISO
Image")</h2>
- </header>
-
- <!-- 1-2-0 -->
- <div id="load-remote-iso">
- <h3 class="step-subtitle">
- <label>
- <img src =
"plugins/kimchi/images/theme-default/loading.gif" />
- $_("Loading default remote ISOs ...")
- </label>
- </h3>
- </div>
-
- <!-- 1-2-1 -->
- <div id="remote-iso-field" class="iso-field"
style="display: none;">
- <h3 class="step-subtitle">
- $_("The following ISOs are available:")
- </h3>
- <div class="toolbar">
- <label class="check-all">
- <input type="checkbox"
id="select-all-remote-iso">$_("All")
- </label>
- </div>
- <div>
- <form id="form-remote-iso">
- <ul id="list-remote-iso"
class="list-iso">
- </ul>
- </form>
- <script id="tmpl-list-remote-iso"
type="text/html">
- <li>
- <label>
- <input type="checkbox"
name="iso" value="{isoId}">
- <div class="box box-iso">
- <div class="iso-icon
{os_distro}">
- </div>
- <h3 class="iso-title"
title="{name}">
- {name}
- </h3>
- <div class="iso-info">
- <div class="iso-info-col">
- <div class="iso-info-item"
title="{os_distro}">
- $_("OS: "){os_distro}
- </div>
- <div class="iso-info-item"
title="{os_version}">
- $_("Version:
"){os_version}
- </div>
-
- </div>
- <div class="iso-info-col">
- <div class="iso-info-item"
title="{os_arch}">
- $_("Arch: "){os_arch}
- </div>
- </div>
- </div>
- </div>
- </label>
- </li>
- </script>
- </div>
- <div class="button-field">
- <button class="btn-normal"
id="btn-template-remote-iso-create" disabled="disabled"><span
class="text">$_("Create Templates from Selected
ISO")</span></button>
- </div>
- </div>
-
- <!-- 1-2-2 -->
- <div id="iso-url-field" style="display:
none;">
- <h3 class="step-subtitle">
- <label>
- <input type="checkbox"
id="iso-url-check">
- $_("I want to use a custom URL")
- </label>
- </h3>
- <div id="iso-url-box"
class="custom-iso-field">
- <div class="input-wrapper"><input
type="text" class="text" id="iso-url"
name="iso-url"></div>
- <button class="btn-normal"
id="btn-template-url-create" disabled="disabled"><span
class="text">$_("Create")</span></button>
- </div>
- </div>
-
- </div>
- </div>
- </div>
- <footer>
- <div class="button-group">
- <button class="btn-normal close"
type="button"><span
type="text">$_("Cancel")</span></button>
- </div>
- </footer>
-</div>
-<script>
-kimchi.template_add_main();
-</script>
-</body>
-</html>
diff --git a/plugins/kimchi/ui/pages/template-edit.html.tmpl
b/plugins/kimchi/ui/pages/template-edit.html.tmpl
deleted file mode 100644
index 0588294..0000000
--- a/plugins/kimchi/ui/pages/template-edit.html.tmpl
+++ /dev/null
@@ -1,193 +0,0 @@
-#*
- * Project Kimchi
- *
- * Copyright IBM, Corp. 2013-2015
- *
- * 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.
- *#
-#unicode UTF-8
-#import gettext
-#from wok.cachebust import href
-#silent t = gettext.translation($lang.domain, $lang.localedir, languages=$lang.lang,
fallback=True)
-#silent _ = t.gettext
-#silent _t = t.gettext
-
-<div id="template-edit-window" class="window">
- <header>
- <h1 class="title h1 grey">$_("Edit
Template")</h1>
- </header>
- <div class="content">
- <div id="edit-template-tabs">
- <input type="hidden" id="template-name"
name="templateName" />
- <ul>
- <li>
- <a
href="#form-template-general">$_("General")</a>
- </li>
- <li>
- <a
href="#form-template-storage">$_("Storage")</a>
- </li>
- <li>
- <a
href="#form-template-interface">$_("Interface")</a>
- </li>
- <li>
- <a
href="#form-template-processor">$_("Processor")</a>
- </li>
- </ul>
- <form id="form-template-general">
- <div class="form-template-inline-wrapper">
- <div class="template-edit-wrapper-label">
- <label
for="template-edit-id-textbox">$_("Name")</label>
- </div>
- <div class="template-edit-wrapper-label">
- <label
for="template-edit-vendor-textbox">$_("Vendor")</label>
- </div>
- <div class="template-edit-wrapper-label">
- <label
for="template-edit-version-textbox">$_("Version")</label>
- </div>
- <div class="template-edit-wrapper-label">
- <label
for="template-edit-memory-textbox">$_("Memory (MB)")</label>
- </div>
- <div class="template-edit-wrapper-label
templ-edit-cdrom">
- <label
for="template-edit-cdrom-textbox">$_("CDROM")</label>
- </div>
- <div class="template-edit-wrapper-label templ-edit-vm-image
hide">
- <label
for="template-edit-vmimage-textbox">$_("Image File")</label>
- </div>
- <div class="template-edit-wrapper-label">
- <label>$_("Graphics")</label>
- </div>
- </div>
- <div class="form-template-inline-wrapper">
- <div class="template-edit-wrapper-controls">
- <input id="template-edit-id-textbox"
name="name" type="text" />
- </div>
- <div class="template-edit-wrapper-controls">
- <input id="template-edit-vendor-textbox"
name="os_distro" type="text" disabled="disabled" />
- </div>
- <div class="template-edit-wrapper-controls">
- <input id="template-edit-version-textbox"
name="os_version" type="text" disabled="disabled" />
- </div>
- <div class="template-edit-wrapper-controls">
- <input id="template-edit-memory-textbox"
name="memory" type="text" />
- </div>
- <div class="template-edit-wrapper-controls
templ-edit-cdrom">
- <input id="template-edit-cdrom-textbox"
name="cdrom" type="text" disabled="disabled" />
- </div>
- <div class="template-edit-wrapper-controls
templ-edit-vm-image hide">
- <input id="template-edit-vmimage-textbox"
name="vm-image" type="text" disabled="disabled" />
- </div>
- <div class="template-edit-wrapper-controls">
- <div class="btn dropdown popable">
- <input id="template-edit-graphics"
name="graphics" type="hidden" />
- <span class="text"
id="template-edit-graphics-label"></span><span
class="arrow"></span>
- <div class="popover" style="width:
100%">
- <ul class="select-list"
id="template-edit-graphics-list" data-target="template-edit-graphics"
data-label="template-edit-graphics-label">
- </ul>
- </div>
- </div>
- </div>
- </div>
- </form>
- <form id="form-template-storage">
- <div class="template-tab-header">
- <span class="template-storage-cell">$_("Storage
Pool")</span>
- <span
class="template-storage-cell">$_("Type")</span>
- <span
class="template-storage-cell">$_("Disk(GB)")</span>
- <span class="template-storage-cell">$_("Disk
Format")</span>
- <button type="button"
id="template-edit-storage-add-button"
class="action-area"></button>
- </div>
- <div class="template-tab-body">
- </div>
- </form>
- <form id="form-template-interface">
- <div class="template-tab-header">
- <span
class="template-interface-cell">$_("Network")</span>
- <span
class="template-interface-cell">$_("Type")</span>
- <button type="button"
id="template-edit-interface-add-button"
class="action-area"></button>
- </div>
- <div class="template-tab-body"></div>
- </form>
- <form id="form-template-processor">
- <div>
- <label for="cpus">$_("CPU
Number"):</label>
- <input type="text" value="1"
id="cpus" />
- </div>
- <div class="manual">
- <input type="checkbox" id="cpus-check" />
- <label for="cpus-check">$_("Manually set CPU
topology")</label>
- </div>
- <div class="topology hide">
- <div>
- <label
for="cores">$_("Cores"):</label>
- <input type="text" value="1"
id="cores" />
- </div>
- <div>
- <label
for="threads">$_("Threads"):</label>
- <select id="threads"></select>
- </div>
- </div>
- </form>
- </div>
- </div>
- <footer>
- <div class="btn-group">
- <a id="tmpl-edit-button-save" class="btn-normal"
href="javascript:void(0);"><span
class="text">$_("Save")</span></a>
- <button class="btn-normal close"
type="button"><span
class="text">$_("Cancel")</span></button>
- </div>
- </footer>
-</div>
-<script>
- kimchi.template_edit_main();
-</script>
-<script id="template-storage-pool-tmpl" type="text/html">
- <div class='item'>
- <span class="template-storage-cell">
- <input class="template-storage-name" value={storageName}
type="text" style="display:none" />
- <select id="selectStorageName"></select>
- </span>
- <span class="template-storage-cell">
- <input class="template-storage-type" value={storageType}
readonly=true type="text" />
- </span>
- <span class="template-storage-cell">
- <input class="template-storage-disk" value={storageDisk}
type="text" />
- </span>
- <span class="template-storage-cell">
- <input class="template-storage-disk-format"
value={storageDiskFormat} type="text" style="display:none" />
- <select id="diskFormat">
- <option value="qcow2">qcow2</option>
- <option value="raw">raw</option>
- <option value="bochs">bochs</option>
- <option value="cloop">cloop</option>
- <option value="cow">cow</option>
- <option value="dmg">dmg</option>
- <option value="qcow">qcow</option>
- <option value="qed">qed</option>
- <option value="vmdk">vmdk</option>
- <option value="vpc">vpc</option>
- </select>
- </span>
- </div>
-</script>
-<script id="template-interface-tmpl" type="text/html">
- <div class="item" id={networkID}>
- <span class="template-interface-cell">
- <select></select>
- </span>
- <span class="template-interface-cell">
- <input value={type} readonly=true type="text" />
- </span>
- <span class="action-area">
- <button class="delete"></button>
- </span>
- </div>
-</script>
diff --git a/plugins/kimchi/ui/pages/templates.html.tmpl
b/plugins/kimchi/ui/pages/templates.html.tmpl
deleted file mode 100644
index af1cf3f..0000000
--- a/plugins/kimchi/ui/pages/templates.html.tmpl
+++ /dev/null
@@ -1,77 +0,0 @@
-#*
- * Project Kimchi
- *
- * Copyright IBM, Corp. 2013-2014
- *
- * 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.
- *#
-#unicode UTF-8
-#import gettext
-#from wok.cachebust import href
-#silent t = gettext.translation($lang.domain, $lang.localedir, languages=$lang.lang,
fallback=True)
-#silent _ = t.gettext
-#silent _t = t.gettext
-<!DOCTYPE html>
-<html>
-<head>
-<link rel="stylesheet"
href="plugins/kimchi/css/theme-default.min.css">
-<script src="plugins/kimchi/js/kimchi.min.js"></script>
-</head>
-<body>
-<div class="toolbar">
- <div class="tools" style="display:none">
- <a id="template-add" class="btn-tool"
href="javascript:void(0);"><span class="icon
add">+</span></a>
- </div>
-</div>
-<div>
- <div id="noTemplates" class="list-no-result"
style="display: none;">
- $_("No templates found.")
- </div>
-
- <ul id="templateList"
class="empty-when-logged-off"></ul>
-
- <script id="templateTmpl" type="html/text">
-
- <div class="template-box white-box template-border">
- <div class="btn dropdown popable" style="width:
70px">
- <span
class="text">$_("Actions")</span><span
class="arrow"></span>
- <div class="popover actionsheet right-side"
style="width: 250px">
- <a class="button-big template-edit"
data-template='{name}'>$_("Edit")</a>
- <a class="button-big template-clone"
data-template='{name}'>$_("Clone")</a>
- <a class="button-big red template-delete"
data-template='{name}'>$_("Delete")</a>
- </div>
- </div>
-
- <div class="template-icon template-icon-position">
- <img alt="" src="{icon}">
- <img alt="" src="{location}"
class="template-type-icon-position">
- </div>
- <div class="template-general template-title
template-title-position">
- <h2 class="title"
title="{name}">{name}</h2>
- </div>
- <div class="template-os-position">
- <div class="template-text">$_("OS"):
{os_distro}</div>
- <div class="template-text">$_("Version"):
{os_version}</div>
- </div>
- <div class="template-cpu-position">
- <div class="template-text">$_("CPUs"):
{cpus}</div>
- <div class="template-text">$_("Memory"):
{memory}M</div>
- </div>
- </div>
- </script>
-</div>
-<script>
- kimchi.template_main();
-</script>
-</body>
-</html>
diff --git a/plugins/kimchi/ui/robots.txt b/plugins/kimchi/ui/robots.txt
deleted file mode 100644
index 1f53798..0000000
--- a/plugins/kimchi/ui/robots.txt
+++ /dev/null
@@ -1,2 +0,0 @@
-User-agent: *
-Disallow: /
diff --git a/plugins/kimchi/ui/spice-html5/Makefile.am
b/plugins/kimchi/ui/spice-html5/Makefile.am
deleted file mode 100644
index c43f1ef..0000000
--- a/plugins/kimchi/ui/spice-html5/Makefile.am
+++ /dev/null
@@ -1,25 +0,0 @@
-#
-# Kimchi
-#
-# Copyright IBM, Corp. 2014
-#
-# 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.
-
-SUBDIRS = pages
-
-if WITH_SPICE
-SUBDIRS += css thirdparty
-
-spicehtml5dir = $(datadir)/wok/plugins/kimchi/ui/spice-html5
-dist_spicehtml5_DATA = $(wildcard *.js) $(NULL)
-endif
diff --git a/plugins/kimchi/ui/spice-html5/atKeynames.js
b/plugins/kimchi/ui/spice-html5/atKeynames.js
deleted file mode 100644
index e1e27fd..0000000
--- a/plugins/kimchi/ui/spice-html5/atKeynames.js
+++ /dev/null
@@ -1,183 +0,0 @@
-"use strict";
-/*
- Copyright (C) 2012 by Aric Stewart <aric(a)codeweavers.com>
-
- This file is part of spice-html5.
-
- spice-html5 is free software: you can redistribute it and/or modify
- it under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- spice-html5 is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public License
- along with spice-html5. If not, see <
http://www.gnu.org/licenses/>.
-*/
-/*
- * Copyright 1990,91 by Thomas Roell, Dinkelscherben, Germany.
- *
- * Permission to use, copy, modify, distribute, and sell this software and its
- * documentation for any purpose is hereby granted without fee, provided that
- * the above copyright notice appear in all copies and that both that
- * copyright notice and this permission notice appear in supporting
- * documentation, and that the name of Thomas Roell not be used in
- * advertising or publicity pertaining to distribution of the software without
- * specific, written prior permission. Thomas Roell makes no representations
- * about the suitability of this software for any purpose. It is provided
- * "as is" without express or implied warranty.
- *
- * THOMAS ROELL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
- * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
- * EVENT SHALL THOMAS ROELL BE LIABLE FOR ANY SPECIAL, INDIRECT OR
- * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
- * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
- * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- *
- */
-/*
- * Copyright (c) 1994-2003 by The XFree86 Project, Inc.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- * OTHER DEALINGS IN THE SOFTWARE.
- *
- * Except as contained in this notice, the name of the copyright holder(s)
- * and author(s) shall not be used in advertising or otherwise to promote
- * the sale, use or other dealings in this Software without prior written
- * authorization from the copyright holder(s) and author(s).
- */
-
-/*
- * NOTE: The AT/MF keyboards can generate (via the 8042) two (MF: three)
- * sets of scancodes. Set3 can only be generated by a MF keyboard.
- * Set2 sends a makecode for keypress, and the same code prefixed by a
- * F0 for keyrelease. This is a little bit ugly to handle. Thus we use
- * here for X386 the PC/XT compatible Set1. This set uses 8bit scancodes.
- * Bit 7 ist set if the key is released. The code E0 switches to a
- * different meaning to add the new MF cursorkeys, while not breaking old
- * applications. E1 is another special prefix. Since I assume that there
- * will be further versions of PC/XT scancode compatible keyboards, we
- * may be in trouble one day.
- *
- * IDEA: 1) Use Set2 on AT84 keyboards and translate it to MF Set3.
- * 2) Use the keyboards native set and translate it to common keysyms.
- */
-
-/*
- * definition of the AT84/MF101/MF102 Keyboard:
- * ============================================================
- * Defined Key Cap Glyphs Pressed value
- * Key Name Main Also (hex) (dec)
- * ---------------- ---------- ------- ------ ------
- */
-
-var KEY_Escape =/* Escape 0x01 */ 1
-var KEY_1 =/* 1 ! 0x02 */ 2
-var KEY_2 =/* 2 @ 0x03 */ 3
-var KEY_3 =/* 3 # 0x04 */ 4
-var KEY_4 =/* 4 $ 0x05 */ 5
-var KEY_5 =/* 5 % 0x06 */ 6
-var KEY_6 =/* 6 ^ 0x07 */ 7
-var KEY_7 =/* 7 & 0x08 */ 8
-var KEY_8 =/* 8 * 0x09 */ 9
-var KEY_9 =/* 9 ( 0x0a */ 10
-var KEY_0 =/* 0 ) 0x0b */ 11
-var KEY_Minus =/* - (Minus) _ (Under) 0x0c */ 12
-var KEY_Equal =/* = (Equal) + 0x0d */ 13
-var KEY_BackSpace =/* Back Space 0x0e */ 14
-var KEY_Tab =/* Tab 0x0f */ 15
-var KEY_Q =/* Q 0x10 */ 16
-var KEY_W =/* W 0x11 */ 17
-var KEY_E =/* E 0x12 */ 18
-var KEY_R =/* R 0x13 */ 19
-var KEY_T =/* T 0x14 */ 20
-var KEY_Y =/* Y 0x15 */ 21
-var KEY_U =/* U 0x16 */ 22
-var KEY_I =/* I 0x17 */ 23
-var KEY_O =/* O 0x18 */ 24
-var KEY_P =/* P 0x19 */ 25
-var KEY_LBrace =/* [ { 0x1a */ 26
-var KEY_RBrace =/* ] } 0x1b */ 27
-var KEY_Enter =/* Enter 0x1c */ 28
-var KEY_LCtrl =/* Ctrl(left) 0x1d */ 29
-var KEY_A =/* A 0x1e */ 30
-var KEY_S =/* S 0x1f */ 31
-var KEY_D =/* D 0x20 */ 32
-var KEY_F =/* F 0x21 */ 33
-var KEY_G =/* G 0x22 */ 34
-var KEY_H =/* H 0x23 */ 35
-var KEY_J =/* J 0x24 */ 36
-var KEY_K =/* K 0x25 */ 37
-var KEY_L =/* L 0x26 */ 38
-var KEY_SemiColon =/* ;(SemiColon) :(Colon) 0x27 */ 39
-var KEY_Quote =/* ' (Apostr) " (Quote) 0x28 */ 40
-var KEY_Tilde =/* ` (Accent) ~ (Tilde) 0x29 */ 41
-var KEY_ShiftL =/* Shift(left) 0x2a */ 42
-var KEY_BSlash =/* \(BckSlash) |(VertBar)0x2b */ 43
-var KEY_Z =/* Z 0x2c */ 44
-var KEY_X =/* X 0x2d */ 45
-var KEY_C =/* C 0x2e */ 46
-var KEY_V =/* V 0x2f */ 47
-var KEY_B =/* B 0x30 */ 48
-var KEY_N =/* N 0x31 */ 49
-var KEY_M =/* M 0x32 */ 50
-var KEY_Comma =/* , (Comma) < (Less) 0x33 */ 51
-var KEY_Period =/* . (Period) >(Greater)0x34 */ 52
-var KEY_Slash =/* / (Slash) ? 0x35 */ 53
-var KEY_ShiftR =/* Shift(right) 0x36 */ 54
-var KEY_KP_Multiply =/* * 0x37 */ 55
-var KEY_Alt =/* Alt(left) 0x38 */ 56
-var KEY_Space =/* (SpaceBar) 0x39 */ 57
-var KEY_CapsLock =/* CapsLock 0x3a */ 58
-var KEY_F1 =/* F1 0x3b */ 59
-var KEY_F2 =/* F2 0x3c */ 60
-var KEY_F3 =/* F3 0x3d */ 61
-var KEY_F4 =/* F4 0x3e */ 62
-var KEY_F5 =/* F5 0x3f */ 63
-var KEY_F6 =/* F6 0x40 */ 64
-var KEY_F7 =/* F7 0x41 */ 65
-var KEY_F8 =/* F8 0x42 */ 66
-var KEY_F9 =/* F9 0x43 */ 67
-var KEY_F10 =/* F10 0x44 */ 68
-var KEY_NumLock =/* NumLock 0x45 */ 69
-var KEY_ScrollLock =/* ScrollLock 0x46 */ 70
-var KEY_KP_7 =/* 7 Home 0x47 */ 71
-var KEY_KP_8 =/* 8 Up 0x48 */ 72
-var KEY_KP_9 =/* 9 PgUp 0x49 */ 73
-var KEY_KP_Minus =/* - (Minus) 0x4a */ 74
-var KEY_KP_4 =/* 4 Left 0x4b */ 75
-var KEY_KP_5 =/* 5 0x4c */ 76
-var KEY_KP_6 =/* 6 Right 0x4d */ 77
-var KEY_KP_Plus =/* + (Plus) 0x4e */ 78
-var KEY_KP_1 =/* 1 End 0x4f */ 79
-var KEY_KP_2 =/* 2 Down 0x50 */ 80
-var KEY_KP_3 =/* 3 PgDown 0x51 */ 81
-var KEY_KP_0 =/* 0 Insert 0x52 */ 82
-var KEY_KP_Decimal =/* . (Decimal) Delete 0x53 */ 83
-var KEY_SysReqest =/* SysReqest 0x54 */ 84
- /* NOTUSED 0x55 */
-var KEY_Less =/* < (Less) >(Greater) 0x56 */ 86
-var KEY_F11 =/* F11 0x57 */ 87
-var KEY_F12 =/* F12 0x58 */ 88
-
-var KEY_Prefix0 =/* special 0x60 */ 96
-var KEY_Prefix1 =/* specail 0x61 */ 97
diff --git a/plugins/kimchi/ui/spice-html5/bitmap.js
b/plugins/kimchi/ui/spice-html5/bitmap.js
deleted file mode 100644
index 03f5127..0000000
--- a/plugins/kimchi/ui/spice-html5/bitmap.js
+++ /dev/null
@@ -1,51 +0,0 @@
-"use strict";
-/*
- Copyright (C) 2012 by Jeremy P. White <jwhite(a)codeweavers.com>
-
- This file is part of spice-html5.
-
- spice-html5 is free software: you can redistribute it and/or modify
- it under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- spice-html5 is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public License
- along with spice-html5. If not, see <
http://www.gnu.org/licenses/>.
-*/
-
-
-/*----------------------------------------------------------------------------
-** bitmap.js
-** Handle SPICE_IMAGE_TYPE_BITMAP
-**--------------------------------------------------------------------------*/
-function convert_spice_bitmap_to_web(context, spice_bitmap)
-{
- var ret;
- var offset, x;
- var u8 = new Uint8Array(spice_bitmap.data);
- if (spice_bitmap.format != SPICE_BITMAP_FMT_32BIT &&
- spice_bitmap.format != SPICE_BITMAP_FMT_RGBA)
- return undefined;
-
- ret = context.createImageData(spice_bitmap.x, spice_bitmap.y);
- for (offset = 0; offset < (spice_bitmap.y * spice_bitmap.stride); )
- for (x = 0; x < spice_bitmap.x; x++, offset += 4)
- {
- ret.data[offset + 0 ] = u8[offset + 2];
- ret.data[offset + 1 ] = u8[offset + 1];
- ret.data[offset + 2 ] = u8[offset + 0];
-
- // FIXME - We effectively treat all images as having
SPICE_IMAGE_FLAGS_HIGH_BITS_SET
- if (spice_bitmap.format == SPICE_BITMAP_FMT_32BIT)
- ret.data[offset + 3] = 255;
- else
- ret.data[offset + 3] = u8[offset];
- }
-
- return ret;
-}
diff --git a/plugins/kimchi/ui/spice-html5/css/Makefile.am
b/plugins/kimchi/ui/spice-html5/css/Makefile.am
deleted file mode 100644
index ed51972..0000000
--- a/plugins/kimchi/ui/spice-html5/css/Makefile.am
+++ /dev/null
@@ -1,20 +0,0 @@
-#
-# Kimchi
-#
-# Copyright IBM, Corp. 2014
-#
-# 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.
-
-spicecssdir = $(datadir)/wok/plugins/kimchi/ui/spice-html5
-
-dist_spicecss_DATA = $(wildcard *.css) $(NULL)
diff --git a/plugins/kimchi/ui/spice-html5/css/spice.css
b/plugins/kimchi/ui/spice-html5/css/spice.css
deleted file mode 100644
index 5d092ba..0000000
--- a/plugins/kimchi/ui/spice-html5/css/spice.css
+++ /dev/null
@@ -1,118 +0,0 @@
-body
-{
- background-color: #999999;
- color: #000000; margin: 0; padding: 0;
- font-family: "Lucida Grande", "Lucida Sans Unicode",
"Helvetica Neue", Helvetica, Arial, Verdana, sans-serif;
- font-size: 12pt;
- line-height: 1.5em;
-}
-
-* { margin: 0; }
-
-#login
-{
- width: 95%;
- margin-left: auto;
- margin-right: auto;
- border: 1px solid #999999;
- background: -webkit-gradient(linear, left top, left bottom, from(#fff),
to(#24414e));
- background: -moz-linear-gradient(top, #fff, #24414e);
- background-color: #24414e;
- -moz-border-radius: 10px;
- -webkit-border-radius: 10px;
- border-radius: 10px;
-}
-#login span.logo
-{
- display: inline-block;
- margin-right: 5px;
- padding: 2px 10px 2px 20px;
- border-right: 1px solid #999999;
- font-size: 20px;
- font-weight: bolder;
- text-shadow: #efefef 1px 1px 0px;
-}
-#login label { color: #ffffff; text-shadow: 1px 1px 0px rgba(175, 210, 220, 0.8); }
-#login input
-{
- padding: 5px;
- background-color: #fAfAfA;
- border: 1px inset #999999;
- outline: none;
- -moz-border-radius: 3px; -webkit-border-radius: 3px; border-radius: 3px;
- box-sizing: border-box;
- -moz-box-sizing: border-box;
- -webkit-box-sizing: border-box;
-}
-#login input#host { width: 200px; }
-#login input#port { width: 75px; }
-#login input#password { width: 100px; }
-#login button
-{
- padding: 5px 10px 5px 10px;
- margin-left: 5px;
- text-shadow: #efefef 1px 1px 0px;
- border: 1px outset #999999;
- cursor: pointer;
- -moz-border-radius: 5px; -webkit-border-radius: 5px; border-radius: 5px;
-}
-#login button:hover
-{
- background-color: #666666;
- color: #ffffff;
-}
-
-#spice-area
-{
- height: 100%;
- width: 95%;
- padding: 0;
- margin-left: auto;
- margin-right: auto;
- border: solid #222222 1px;
- -webkit-box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.2);
- -moz-box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.2);
- box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.2);
- -moz-border-radius: 10px;
- -webkit-border-radius: 10px;
- border-radius: 10px;
-}
-.spice-screen
-{
- min-height: 600px;
- height: 100%;
- margin: 10px;
- padding: 0;
- background-color: #333333;
-}
-.spice-message {
- width: 700px;
- height: 50px;
- overflow: auto;
- margin-top: 5px;
- margin-left: auto;
- margin-right: auto;
- padding: 10px;
- background-color: #efefef;
- border: solid #c3c3c3 2px;
- font-size: 8pt;
- line-height: 1.1em;
- font-family: 'Andale Mono', monospace;
- -moz-border-radius: 10px;
- -webkit-border-radius: 10px;
- border-radius: 10px;
- -webkit-box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.2);
- -moz-box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.2);
- box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.2);
-}
-.spice-message p {
- margin-bottom: 0em;
- margin-top: 0em;
-}
-.spice-message-warning {
- color: orange;
-}
-.spice-message-error {
- color: red;
-}
-
diff --git a/plugins/kimchi/ui/spice-html5/cursor.js
b/plugins/kimchi/ui/spice-html5/cursor.js
deleted file mode 100644
index 71e941d..0000000
--- a/plugins/kimchi/ui/spice-html5/cursor.js
+++ /dev/null
@@ -1,110 +0,0 @@
-"use strict";
-/*
- Copyright (C) 2012 by Jeremy P. White <jwhite(a)codeweavers.com>
-
- This file is part of spice-html5.
-
- spice-html5 is free software: you can redistribute it and/or modify
- it under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- spice-html5 is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public License
- along with spice-html5. If not, see <
http://www.gnu.org/licenses/>.
-*/
-
-
-/*----------------------------------------------------------------------------
-** SpiceCursorConn
-** Drive the Spice Cursor Channel
-**--------------------------------------------------------------------------*/
-function SpiceCursorConn()
-{
- SpiceConn.apply(this, arguments);
-}
-
-SpiceCursorConn.prototype = Object.create(SpiceConn.prototype);
-SpiceCursorConn.prototype.process_channel_message = function(msg)
-{
- if (msg.type == SPICE_MSG_CURSOR_INIT)
- {
- var cursor_init = new SpiceMsgCursorInit(msg.data);
- DEBUG > 1 && console.log("SpiceMsgCursorInit");
- if (this.parent && this.parent.inputs &&
- this.parent.inputs.mouse_mode == SPICE_MOUSE_MODE_SERVER)
- {
- // FIXME - this imagines that the server actually
- // provides the current cursor position,
- // instead of 0,0. As of May 11, 2012,
- // that assumption was false :-(.
- this.parent.inputs.mousex = cursor_init.position.x;
- this.parent.inputs.mousey = cursor_init.position.y;
- }
- // FIXME - We don't handle most of the parameters here...
- return true;
- }
-
- if (msg.type == SPICE_MSG_CURSOR_SET)
- {
- var cursor_set = new SpiceMsgCursorSet(msg.data);
- DEBUG > 1 && console.log("SpiceMsgCursorSet");
- if (cursor_set.flags & SPICE_CURSOR_FLAGS_NONE)
- {
- document.getElementById(this.parent.screen_id).style.cursor =
"none";
- return true;
- }
-
- if (cursor_set.flags > 0)
- this.log_warn("FIXME: No support for cursor flags " +
cursor_set.flags);
-
- if (cursor_set.cursor.header.type != SPICE_CURSOR_TYPE_ALPHA)
- {
- this.log_warn("FIXME: No support for cursor type " +
cursor_set.cursor.header.type);
- return false;
- }
-
- this.set_cursor(cursor_set.cursor);
-
- return true;
- }
-
- if (msg.type == SPICE_MSG_CURSOR_HIDE)
- {
- DEBUG > 1 && console.log("SpiceMsgCursorHide");
- document.getElementById(this.parent.screen_id).style.cursor = "none";
- return true;
- }
-
- if (msg.type == SPICE_MSG_CURSOR_RESET)
- {
- DEBUG > 1 && console.log("SpiceMsgCursorReset");
- document.getElementById(this.parent.screen_id).style.cursor = "auto";
- return true;
- }
-
- if (msg.type == SPICE_MSG_CURSOR_INVAL_ALL)
- {
- DEBUG > 1 && console.log("SpiceMsgCursorInvalAll");
- // FIXME - There may be something useful to do here...
- return true;
- }
-
- return false;
-}
-
-SpiceCursorConn.prototype.set_cursor = function(cursor)
-{
- var pngstr = create_rgba_png(cursor.header.height, cursor.header.width,
cursor.data);
- var curstr = 'url(data:image/png,' + pngstr + ') ' +
- cursor.header.hot_spot_x + ' ' + cursor.header.hot_spot_y + ",
default";
- var screen = document.getElementById(this.parent.screen_id);
- screen.style.cursor = 'auto';
- screen.style.cursor = curstr;
- if (window.getComputedStyle(screen, null).cursor == 'auto')
- SpiceSimulateCursor.simulate_cursor(this, cursor, screen, pngstr);
-}
diff --git a/plugins/kimchi/ui/spice-html5/display.js
b/plugins/kimchi/ui/spice-html5/display.js
deleted file mode 100644
index 2aa5985..0000000
--- a/plugins/kimchi/ui/spice-html5/display.js
+++ /dev/null
@@ -1,823 +0,0 @@
-"use strict";
-/*
- Copyright (C) 2012 by Jeremy P. White <jwhite(a)codeweavers.com>
-
- This file is part of spice-html5.
-
- spice-html5 is free software: you can redistribute it and/or modify
- it under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- spice-html5 is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public License
- along with spice-html5. If not, see <
http://www.gnu.org/licenses/>.
-*/
-
-
-/*----------------------------------------------------------------------------
-** FIXME: putImageData does not support Alpha blending
-** or compositing. So if we have data in an ImageData
-** format, we have to draw it onto a context,
-** and then use drawImage to put it onto the target,
-** as drawImage does alpha.
-**--------------------------------------------------------------------------*/
-function putImageDataWithAlpha(context, d, x, y)
-{
- var c = document.createElement("canvas");
- var t = c.getContext("2d");
- c.setAttribute('width', d.width);
- c.setAttribute('height', d.height);
- t.putImageData(d, 0, 0);
- context.drawImage(c, x, y, d.width, d.height);
-}
-
-/*----------------------------------------------------------------------------
-** FIXME: Spice will send an image with '0' alpha when it is intended to
-** go on a surface w/no alpha. So in that case, we have to strip
-** out the alpha. The test case for this was flux box; in a Xspice
-** server, right click on the desktop to get the menu; the top bar
-** doesn't paint/highlight correctly w/out this change.
-**--------------------------------------------------------------------------*/
-function stripAlpha(d)
-{
- var i;
- for (i = 0; i < (d.width * d.height * 4); i += 4)
- d.data[i + 3] = 255;
-}
-
-/*----------------------------------------------------------------------------
-** SpiceDisplayConn
-** Drive the Spice Display Channel
-**--------------------------------------------------------------------------*/
-function SpiceDisplayConn()
-{
- SpiceConn.apply(this, arguments);
-}
-
-SpiceDisplayConn.prototype = Object.create(SpiceConn.prototype);
-SpiceDisplayConn.prototype.process_channel_message = function(msg)
-{
- if (msg.type == SPICE_MSG_DISPLAY_MARK)
- {
- // FIXME - DISPLAY_MARK not implemented (may be hard or impossible)
- this.known_unimplemented(msg.type, "Display Mark");
- return true;
- }
-
- if (msg.type == SPICE_MSG_DISPLAY_RESET)
- {
- DEBUG > 2 && console.log("Display reset");
- this.surfaces[this.primary_surface].canvas.context.restore();
- return true;
- }
-
- if (msg.type == SPICE_MSG_DISPLAY_DRAW_COPY)
- {
- var draw_copy = new SpiceMsgDisplayDrawCopy(msg.data);
-
- DEBUG > 1 && this.log_draw("DrawCopy", draw_copy);
-
- if (! draw_copy.base.box.is_same_size(draw_copy.data.src_area))
- this.log_warn("FIXME: DrawCopy src_area is a different size than
base.box; we do not handle that yet.");
- if (draw_copy.base.clip.type != SPICE_CLIP_TYPE_NONE)
- this.log_warn("FIXME: DrawCopy we don't handle clipping yet");
- if (draw_copy.data.rop_descriptor != SPICE_ROPD_OP_PUT)
- this.log_warn("FIXME: DrawCopy we don't handle ropd type: " +
draw_copy.data.rop_descriptor);
- if (draw_copy.data.mask.flags)
- this.log_warn("FIXME: DrawCopy we don't handle mask flag: " +
draw_copy.data.mask.flags);
- if (draw_copy.data.mask.bitmap)
- this.log_warn("FIXME: DrawCopy we don't handle mask");
-
- if (draw_copy.data && draw_copy.data.src_bitmap)
- {
- if (draw_copy.data.src_bitmap.descriptor.flags &&
- draw_copy.data.src_bitmap.descriptor.flags != SPICE_IMAGE_FLAGS_CACHE_ME
&&
- draw_copy.data.src_bitmap.descriptor.flags !=
SPICE_IMAGE_FLAGS_HIGH_BITS_SET)
- {
- this.log_warn("FIXME: DrawCopy unhandled image flags: " +
draw_copy.data.src_bitmap.descriptor.flags);
- DEBUG <= 1 && this.log_draw("DrawCopy", draw_copy);
- }
-
- if (draw_copy.data.src_bitmap.descriptor.type == SPICE_IMAGE_TYPE_QUIC)
- {
- var canvas = this.surfaces[draw_copy.base.surface_id].canvas;
- if (! draw_copy.data.src_bitmap.quic)
- {
- this.log_warn("FIXME: DrawCopy could not handle this QUIC
file.");
- return false;
- }
- var source_img = convert_spice_quic_to_web(canvas.context,
- draw_copy.data.src_bitmap.quic);
-
- return this.draw_copy_helper(
- { base: draw_copy.base,
- src_area: draw_copy.data.src_area,
- image_data: source_img,
- tag: "copyquic." + draw_copy.data.src_bitmap.quic.type,
- has_alpha: (draw_copy.data.src_bitmap.quic.type ==
QUIC_IMAGE_TYPE_RGBA ? true : false) ,
- descriptor : draw_copy.data.src_bitmap.descriptor
- });
- }
- else if (draw_copy.data.src_bitmap.descriptor.type ==
SPICE_IMAGE_TYPE_FROM_CACHE ||
- draw_copy.data.src_bitmap.descriptor.type ==
SPICE_IMAGE_TYPE_FROM_CACHE_LOSSLESS)
- {
- if (! this.cache || !
this.cache[draw_copy.data.src_bitmap.descriptor.id])
- {
- this.log_warn("FIXME: DrawCopy did not find image id " +
draw_copy.data.src_bitmap.descriptor.id + " in cache.");
- return false;
- }
-
- return this.draw_copy_helper(
- { base: draw_copy.base,
- src_area: draw_copy.data.src_area,
- image_data: this.cache[draw_copy.data.src_bitmap.descriptor.id],
- tag: "copycache." +
draw_copy.data.src_bitmap.descriptor.id,
- has_alpha: true, /* FIXME - may want this to be false... */
- descriptor : draw_copy.data.src_bitmap.descriptor
- });
-
- /* FIXME - LOSSLESS CACHE ramifications not understood or handled */
- }
- else if (draw_copy.data.src_bitmap.descriptor.type ==
SPICE_IMAGE_TYPE_SURFACE)
- {
- var source_context =
this.surfaces[draw_copy.data.src_bitmap.surface_id].canvas.context;
- var target_context =
this.surfaces[draw_copy.base.surface_id].canvas.context;
-
- var source_img = source_context.getImageData(
- draw_copy.data.src_area.left, draw_copy.data.src_area.top,
- draw_copy.data.src_area.right - draw_copy.data.src_area.left,
- draw_copy.data.src_area.bottom - draw_copy.data.src_area.top);
- var computed_src_area = new SpiceRect;
- computed_src_area.top = computed_src_area.left = 0;
- computed_src_area.right = source_img.width;
- computed_src_area.bottom = source_img.height;
-
- /* FIXME - there is a potential optimization here.
- That is, if the surface is from 0,0, and
- both surfaces are alpha surfaces, you should
- be able to just do a drawImage, which should
- save time. */
-
- return this.draw_copy_helper(
- { base: draw_copy.base,
- src_area: computed_src_area,
- image_data: source_img,
- tag: "copysurf." + draw_copy.data.src_bitmap.surface_id,
- has_alpha:
this.surfaces[draw_copy.data.src_bitmap.surface_id].format == SPICE_SURFACE_FMT_32_xRGB ?
false : true,
- descriptor : draw_copy.data.src_bitmap.descriptor
- });
-
- return true;
- }
- else if (draw_copy.data.src_bitmap.descriptor.type == SPICE_IMAGE_TYPE_JPEG)
- {
- if (! draw_copy.data.src_bitmap.jpeg)
- {
- this.log_warn("FIXME: DrawCopy could not handle this JPEG
file.");
- return false;
- }
-
- // FIXME - how lame is this. Be have it in binary format, and we have
- // to put it into string to get it back into jpeg. Blech.
- var tmpstr = "data:image/jpeg,";
- var img = new Image;
- var i;
- var qdv = new Uint8Array(draw_copy.data.src_bitmap.jpeg.data);
- for (i = 0; i < qdv.length; i++)
- {
- tmpstr += '%';
- if (qdv[i] < 16)
- tmpstr += '0';
- tmpstr += qdv[i].toString(16);
- }
-
- img.o =
- { base: draw_copy.base,
- tag: "jpeg." + draw_copy.data.src_bitmap.surface_id,
- descriptor : draw_copy.data.src_bitmap.descriptor,
- sc : this,
- };
- img.onload = handle_draw_jpeg_onload;
- img.src = tmpstr;
-
- return true;
- }
- else if (draw_copy.data.src_bitmap.descriptor.type ==
SPICE_IMAGE_TYPE_JPEG_ALPHA)
- {
- if (! draw_copy.data.src_bitmap.jpeg_alpha)
- {
- this.log_warn("FIXME: DrawCopy could not handle this JPEG ALPHA
file.");
- return false;
- }
-
- // FIXME - how lame is this. Be have it in binary format, and we have
- // to put it into string to get it back into jpeg. Blech.
- var tmpstr = "data:image/jpeg,";
- var img = new Image;
- var i;
- var qdv = new Uint8Array(draw_copy.data.src_bitmap.jpeg_alpha.data);
- for (i = 0; i < qdv.length; i++)
- {
- tmpstr += '%';
- if (qdv[i] < 16)
- tmpstr += '0';
- tmpstr += qdv[i].toString(16);
- }
-
- img.o =
- { base: draw_copy.base,
- tag: "jpeg." + draw_copy.data.src_bitmap.surface_id,
- descriptor : draw_copy.data.src_bitmap.descriptor,
- sc : this,
- };
-
- if (this.surfaces[draw_copy.base.surface_id].format ==
SPICE_SURFACE_FMT_32_ARGB)
- {
-
- var canvas = this.surfaces[draw_copy.base.surface_id].canvas;
- img.alpha_img = convert_spice_lz_to_web(canvas.context,
- draw_copy.data.src_bitmap.jpeg_alpha.alpha);
- }
- img.onload = handle_draw_jpeg_onload;
- img.src = tmpstr;
-
- return true;
- }
- else if (draw_copy.data.src_bitmap.descriptor.type ==
SPICE_IMAGE_TYPE_BITMAP)
- {
- var canvas = this.surfaces[draw_copy.base.surface_id].canvas;
- if (! draw_copy.data.src_bitmap.bitmap)
- {
- this.log_err("null bitmap");
- return false;
- }
-
- var source_img = convert_spice_bitmap_to_web(canvas.context,
- draw_copy.data.src_bitmap.bitmap);
- if (! source_img)
- {
- this.log_warn("FIXME: Unable to interpret bitmap of format:
" +
- draw_copy.data.src_bitmap.bitmap.format);
- return false;
- }
-
- return this.draw_copy_helper(
- { base: draw_copy.base,
- src_area: draw_copy.data.src_area,
- image_data: source_img,
- tag: "bitmap." +
draw_copy.data.src_bitmap.bitmap.format,
- has_alpha: draw_copy.data.src_bitmap.bitmap ==
SPICE_BITMAP_FMT_32BIT ? false : true,
- descriptor : draw_copy.data.src_bitmap.descriptor
- });
- }
- else if (draw_copy.data.src_bitmap.descriptor.type ==
SPICE_IMAGE_TYPE_LZ_RGB)
- {
- var canvas = this.surfaces[draw_copy.base.surface_id].canvas;
- if (! draw_copy.data.src_bitmap.lz_rgb)
- {
- this.log_err("null lz_rgb ");
- return false;
- }
-
- if (draw_copy.data.src_bitmap.lz_rgb.top_down != 1)
- this.log_warn("FIXME: Implement non top down support for
lz_rgb");
-
- var source_img = convert_spice_lz_to_web(canvas.context,
- draw_copy.data.src_bitmap.lz_rgb);
- if (! source_img)
- {
- this.log_warn("FIXME: Unable to interpret bitmap of type: "
+
- draw_copy.data.src_bitmap.lz_rgb.type);
- return false;
- }
-
- return this.draw_copy_helper(
- { base: draw_copy.base,
- src_area: draw_copy.data.src_area,
- image_data: source_img,
- tag: "lz_rgb." + draw_copy.data.src_bitmap.lz_rgb.type,
- has_alpha: draw_copy.data.src_bitmap.lz_rgb.type ==
LZ_IMAGE_TYPE_RGBA ? true : false ,
- descriptor : draw_copy.data.src_bitmap.descriptor
- });
- }
- else
- {
- this.log_warn("FIXME: DrawCopy unhandled image type: " +
draw_copy.data.src_bitmap.descriptor.type);
- this.log_draw("DrawCopy", draw_copy);
- return false;
- }
- }
-
- this.log_warn("FIXME: DrawCopy no src_bitmap.");
- return false;
- }
-
- if (msg.type == SPICE_MSG_DISPLAY_DRAW_FILL)
- {
- var draw_fill = new SpiceMsgDisplayDrawFill(msg.data);
-
- DEBUG > 1 && this.log_draw("DrawFill", draw_fill);
-
- if (draw_fill.data.rop_descriptor != SPICE_ROPD_OP_PUT)
- this.log_warn("FIXME: DrawFill we don't handle ropd type: " +
draw_fill.data.rop_descriptor);
- if (draw_fill.data.mask.flags)
- this.log_warn("FIXME: DrawFill we don't handle mask flag: " +
draw_fill.data.mask.flags);
- if (draw_fill.data.mask.bitmap)
- this.log_warn("FIXME: DrawFill we don't handle mask");
-
- if (draw_fill.data.brush.type == SPICE_BRUSH_TYPE_SOLID)
- {
- // FIXME - do brushes ever have alpha?
- var color = draw_fill.data.brush.color & 0xffffff;
- var color_str = "rgb(" + (color >> 16) + ", " +
((color >> 8) & 0xff) + ", " + (color & 0xff) + ")";
- this.surfaces[draw_fill.base.surface_id].canvas.context.fillStyle =
color_str;
-
- this.surfaces[draw_fill.base.surface_id].canvas.context.fillRect(
- draw_fill.base.box.left, draw_fill.base.box.top,
- draw_fill.base.box.right - draw_fill.base.box.left,
- draw_fill.base.box.bottom - draw_fill.base.box.top);
-
- if (DUMP_DRAWS && this.parent.dump_id)
- {
- var debug_canvas = document.createElement("canvas");
- debug_canvas.setAttribute('width',
this.surfaces[draw_fill.base.surface_id].canvas.width);
- debug_canvas.setAttribute('height',
this.surfaces[draw_fill.base.surface_id].canvas.height);
- debug_canvas.setAttribute('id', "fillbrush." +
draw_fill.base.surface_id + "." +
this.surfaces[draw_fill.base.surface_id].draw_count);
- debug_canvas.getContext("2d").fillStyle = color_str;
- debug_canvas.getContext("2d").fillRect(
- draw_fill.base.box.left, draw_fill.base.box.top,
- draw_fill.base.box.right - draw_fill.base.box.left,
- draw_fill.base.box.bottom - draw_fill.base.box.top);
- document.getElementById(this.parent.dump_id).appendChild(debug_canvas);
- }
-
- this.surfaces[draw_fill.base.surface_id].draw_count++;
-
- }
- else
- {
- this.log_warn("FIXME: DrawFill can't handle brush type: " +
draw_fill.data.brush.type);
- }
- return true;
- }
-
- if (msg.type == SPICE_MSG_DISPLAY_COPY_BITS)
- {
- var copy_bits = new SpiceMsgDisplayCopyBits(msg.data);
-
- DEBUG > 1 && this.log_draw("CopyBits", copy_bits);
-
- var source_canvas = this.surfaces[copy_bits.base.surface_id].canvas;
- var source_context = source_canvas.context;
-
- var width = source_canvas.width - copy_bits.src_pos.x;
- var height = source_canvas.height - copy_bits.src_pos.y;
- if (width > (copy_bits.base.box.right - copy_bits.base.box.left))
- width = copy_bits.base.box.right - copy_bits.base.box.left;
- if (height > (copy_bits.base.box.bottom - copy_bits.base.box.top))
- height = copy_bits.base.box.bottom - copy_bits.base.box.top;
-
- var source_img = source_context.getImageData(
- copy_bits.src_pos.x, copy_bits.src_pos.y, width, height);
- //source_context.putImageData(source_img, copy_bits.base.box.left,
copy_bits.base.box.top);
- putImageDataWithAlpha(source_context, source_img, copy_bits.base.box.left,
copy_bits.base.box.top);
-
- if (DUMP_DRAWS && this.parent.dump_id)
- {
- var debug_canvas = document.createElement("canvas");
- debug_canvas.setAttribute('width', width);
- debug_canvas.setAttribute('height', height);
- debug_canvas.setAttribute('id', "copybits" +
copy_bits.base.surface_id + "." +
this.surfaces[copy_bits.base.surface_id].draw_count);
- debug_canvas.getContext("2d").putImageData(source_img, 0, 0);
- document.getElementById(this.parent.dump_id).appendChild(debug_canvas);
- }
-
-
- this.surfaces[copy_bits.base.surface_id].draw_count++;
- return true;
- }
-
- if (msg.type == SPICE_MSG_DISPLAY_INVAL_ALL_PALETTES)
- {
- this.known_unimplemented(msg.type, "Inval All Palettes");
- return true;
- }
-
- if (msg.type == SPICE_MSG_DISPLAY_SURFACE_CREATE)
- {
- if (! ("surfaces" in this))
- this.surfaces = [];
-
- var m = new SpiceMsgSurfaceCreate(msg.data);
- DEBUG > 1 && console.log(this.type + ": MsgSurfaceCreate id
" + m.surface.surface_id
- + "; " + m.surface.width + "x" +
m.surface.height
- + "; format " + m.surface.format
- + "; flags " + m.surface.flags);
- if (m.surface.format != SPICE_SURFACE_FMT_32_xRGB &&
- m.surface.format != SPICE_SURFACE_FMT_32_ARGB)
- {
- this.log_warn("FIXME: cannot handle surface format " +
m.surface.format + " yet.");
- return false;
- }
-
- var canvas = document.createElement("canvas");
- canvas.setAttribute('width', m.surface.width);
- canvas.setAttribute('height', m.surface.height);
- canvas.setAttribute('id', "spice_surface_" +
m.surface.surface_id);
- canvas.setAttribute('tabindex', m.surface.surface_id);
- canvas.context = canvas.getContext("2d");
-
- if (DUMP_CANVASES && this.parent.dump_id)
- document.getElementById(this.parent.dump_id).appendChild(canvas);
-
- m.surface.canvas = canvas;
- m.surface.draw_count = 0;
- this.surfaces[m.surface.surface_id] = m.surface;
-
- if (m.surface.flags & SPICE_SURFACE_FLAGS_PRIMARY)
- {
- this.primary_surface = m.surface.surface_id;
-
- /* This .save() is done entirely to enable SPICE_MSG_DISPLAY_RESET */
- canvas.context.save();
- document.getElementById(this.parent.screen_id).appendChild(canvas);
-
- /* We're going to leave width dynamic, but correctly set the height */
- document.getElementById(this.parent.screen_id).style.height =
m.surface.height + "px";
- this.hook_events();
- }
- return true;
- }
-
- if (msg.type == SPICE_MSG_DISPLAY_SURFACE_DESTROY)
- {
- var m = new SpiceMsgSurfaceDestroy(msg.data);
- DEBUG > 1 && console.log(this.type + ": MsgSurfaceDestroy id
" + m.surface_id);
- this.delete_surface(m.surface_id);
- return true;
- }
-
- if (msg.type == SPICE_MSG_DISPLAY_STREAM_CREATE)
- {
- var m = new SpiceMsgDisplayStreamCreate(msg.data);
- DEBUG > 1 && console.log(this.type + ": MsgStreamCreate id"
+ m.id);
- if (!this.streams)
- this.streams = new Array();
- if (this.streams[m.id])
- console.log("Stream already exists");
- else
- this.streams[m.id] = m;
- if (m.codec_type != SPICE_VIDEO_CODEC_TYPE_MJPEG)
- console.log("Unhandled stream codec: "+m.codec_type);
- return true;
- }
-
- if (msg.type == SPICE_MSG_DISPLAY_STREAM_DATA)
- {
- var m = new SpiceMsgDisplayStreamData(msg.data);
- if (!this.streams[m.base.id])
- {
- console.log("no stream for data");
- return false;
- }
- if (this.streams[m.base.id].codec_type === SPICE_VIDEO_CODEC_TYPE_MJPEG)
- {
- var tmpstr = "data:image/jpeg,";
- var img = new Image;
- var i;
- for (i = 0; i < m.data.length; i++)
- {
- tmpstr += '%';
- if (m.data[i] < 16)
- tmpstr += '0';
- tmpstr += m.data[i].toString(16);
- }
- var strm_base = new SpiceMsgDisplayBase();
- strm_base.surface_id = this.streams[m.base.id].surface_id;
- strm_base.box = this.streams[m.base.id].dest;
- strm_base.clip = this.streams[m.base.id].clip;
- img.o =
- { base: strm_base,
- tag: "mjpeg." + m.base.id,
- descriptor: null,
- sc : this,
- };
- img.onload = handle_draw_jpeg_onload;
- img.src = tmpstr;
- }
- return true;
- }
-
- if (msg.type == SPICE_MSG_DISPLAY_STREAM_CLIP)
- {
- var m = new SpiceMsgDisplayStreamClip(msg.data);
- DEBUG > 1 && console.log(this.type + ": MsgStreamClip id" +
m.id);
- this.streams[m.id].clip = m.clip;
- return true;
- }
-
- if (msg.type == SPICE_MSG_DISPLAY_STREAM_DESTROY)
- {
- var m = new SpiceMsgDisplayStreamDestroy(msg.data);
- DEBUG > 1 && console.log(this.type + ": MsgStreamDestroy id"
+ m.id);
- this.streams[m.id] = undefined;
- return true;
- }
- if (msg.type == SPICE_MSG_DISPLAY_INVAL_LIST)
- {
- var m = new SpiceMsgDisplayInvalList(msg.data);
- var i;
- DEBUG > 1 && console.log(this.type + ": MsgInvalList " +
m.count + " items");
- for (i = 0; i < m.count; i++)
- if (this.cache[m.resources[i].id] != undefined)
- delete this.cache[m.resources[i].id];
- return true;
- }
-
- return false;
-}
-
-SpiceDisplayConn.prototype.delete_surface = function(surface_id)
-{
- var canvas = document.getElementById("spice_surface_" + surface_id);
- if (DUMP_CANVASES && this.parent.dump_id)
- document.getElementById(this.parent.dump_id).removeChild(canvas);
- if (this.primary_surface == surface_id)
- {
- this.unhook_events();
- this.primary_surface = undefined;
- document.getElementById(this.parent.screen_id).removeChild(canvas);
- }
-
- delete this.surfaces[surface_id];
-}
-
-
-SpiceDisplayConn.prototype.draw_copy_helper = function(o)
-{
-
- var canvas = this.surfaces[o.base.surface_id].canvas;
- if (o.has_alpha)
- {
- /* FIXME - This is based on trial + error, not a serious thoughtful
- analysis of what Spice requires. See display.js for more. */
- if (this.surfaces[o.base.surface_id].format == SPICE_SURFACE_FMT_32_xRGB)
- {
- stripAlpha(o.image_data);
- canvas.context.putImageData(o.image_data, o.base.box.left, o.base.box.top);
- }
- else
- putImageDataWithAlpha(canvas.context, o.image_data,
- o.base.box.left, o.base.box.top);
- }
- else
- canvas.context.putImageData(o.image_data, o.base.box.left, o.base.box.top);
-
- if (o.src_area.left > 0 || o.src_area.top > 0)
- {
- this.log_warn("FIXME: DrawCopy not shifting draw copies just yet...");
- }
-
- if (o.descriptor && (o.descriptor.flags & SPICE_IMAGE_FLAGS_CACHE_ME))
- {
- if (! ("cache" in this))
- this.cache = {};
- this.cache[o.descriptor.id] = o.image_data;
- }
-
- if (DUMP_DRAWS && this.parent.dump_id)
- {
- var debug_canvas = document.createElement("canvas");
- debug_canvas.setAttribute('width', o.image_data.width);
- debug_canvas.setAttribute('height', o.image_data.height);
- debug_canvas.setAttribute('id', o.tag + "." +
- this.surfaces[o.base.surface_id].draw_count + "." +
- o.base.surface_id + "@" + o.base.box.left + "x" +
o.base.box.top);
- debug_canvas.getContext("2d").putImageData(o.image_data, 0, 0);
- document.getElementById(this.parent.dump_id).appendChild(debug_canvas);
- }
-
- this.surfaces[o.base.surface_id].draw_count++;
-
- return true;
-}
-
-
-SpiceDisplayConn.prototype.log_draw = function(prefix, draw)
-{
- var str = prefix + "." + draw.base.surface_id + "." +
this.surfaces[draw.base.surface_id].draw_count + ": ";
- str += "base.box " + draw.base.box.left + ", " +
draw.base.box.top + " to " +
- draw.base.box.right + ", " + draw.base.box.bottom;
- str += "; clip.type " + draw.base.clip.type;
-
- if (draw.data)
- {
- if (draw.data.src_area)
- str += "; src_area " + draw.data.src_area.left + ", " +
draw.data.src_area.top + " to "
- + draw.data.src_area.right + ", " +
draw.data.src_area.bottom;
-
- if (draw.data.src_bitmap && draw.data.src_bitmap != null)
- {
- str += "; src_bitmap id: " + draw.data.src_bitmap.descriptor.id;
- str += "; src_bitmap width " +
draw.data.src_bitmap.descriptor.width + ", height " +
draw.data.src_bitmap.descriptor.height;
- str += "; src_bitmap type " + draw.data.src_bitmap.descriptor.type
+ ", flags " + draw.data.src_bitmap.descriptor.flags;
- if (draw.data.src_bitmap.surface_id !== undefined)
- str += "; src_bitmap surface_id " +
draw.data.src_bitmap.surface_id;
- if (draw.data.src_bitmap.quic)
- str += "; QUIC type " + draw.data.src_bitmap.quic.type +
- "; width " + draw.data.src_bitmap.quic.width +
- "; height " + draw.data.src_bitmap.quic.height ;
- if (draw.data.src_bitmap.lz_rgb)
- str += "; LZ_RGB length " + draw.data.src_bitmap.lz_rgb.length
+
- "; magic " + draw.data.src_bitmap.lz_rgb.magic +
- "; version 0x" +
draw.data.src_bitmap.lz_rgb.version.toString(16) +
- "; type " + draw.data.src_bitmap.lz_rgb.type +
- "; width " + draw.data.src_bitmap.lz_rgb.width +
- "; height " + draw.data.src_bitmap.lz_rgb.height +
- "; stride " + draw.data.src_bitmap.lz_rgb.stride +
- "; top down " + draw.data.src_bitmap.lz_rgb.top_down;
- }
- else
- str += "; src_bitmap is null";
-
- if (draw.data.brush)
- {
- if (draw.data.brush.type == SPICE_BRUSH_TYPE_SOLID)
- str += "; brush.color 0x" +
draw.data.brush.color.toString(16);
- if (draw.data.brush.type == SPICE_BRUSH_TYPE_PATTERN)
- {
- str += "; brush.pat ";
- if (draw.data.brush.pattern.pat != null)
- str += "[SpiceImage]";
- else
- str += "[null]";
- str += " at " + draw.data.brush.pattern.pos.x + ", "
+ draw.data.brush.pattern.pos.y;
- }
- }
-
- str += "; rop_descriptor " + draw.data.rop_descriptor;
- if (draw.data.scale_mode !== undefined)
- str += "; scale_mode " + draw.data.scale_mode;
- str += "; mask.flags " + draw.data.mask.flags;
- str += "; mask.pos " + draw.data.mask.pos.x + ", " +
draw.data.mask.pos.y;
- if (draw.data.mask.bitmap != null)
- {
- str += "; mask.bitmap width " +
draw.data.mask.bitmap.descriptor.width + ", height " +
draw.data.mask.bitmap.descriptor.height;
- str += "; mask.bitmap type " +
draw.data.mask.bitmap.descriptor.type + ", flags " +
draw.data.mask.bitmap.descriptor.flags;
- }
- else
- str += "; mask.bitmap is null";
- }
-
- console.log(str);
-}
-
-SpiceDisplayConn.prototype.hook_events = function()
-{
- if (this.primary_surface !== undefined)
- {
- var canvas = this.surfaces[this.primary_surface].canvas;
- canvas.sc = this.parent;
- canvas.addEventListener('mousemove', handle_mousemove);
- canvas.addEventListener('mousedown', handle_mousedown);
- canvas.addEventListener('contextmenu', handle_contextmenu);
- canvas.addEventListener('mouseup', handle_mouseup);
- canvas.addEventListener('keydown', handle_keydown);
- canvas.addEventListener('keyup', handle_keyup);
- canvas.addEventListener('mouseout', handle_mouseout);
- canvas.addEventListener('mouseover', handle_mouseover);
- canvas.addEventListener('mousewheel', handle_mousewheel);
- canvas.focus();
- }
-}
-
-SpiceDisplayConn.prototype.unhook_events = function()
-{
- if (this.primary_surface !== undefined)
- {
- var canvas = this.surfaces[this.primary_surface].canvas;
- canvas.removeEventListener('mousemove', handle_mousemove);
- canvas.removeEventListener('mousedown', handle_mousedown);
- canvas.removeEventListener('contextmenu', handle_contextmenu);
- canvas.removeEventListener('mouseup', handle_mouseup);
- canvas.removeEventListener('keydown', handle_keydown);
- canvas.removeEventListener('keyup', handle_keyup);
- canvas.removeEventListener('mouseout', handle_mouseout);
- canvas.removeEventListener('mouseover', handle_mouseover);
- canvas.removeEventListener('mousewheel', handle_mousewheel);
- }
-}
-
-
-SpiceDisplayConn.prototype.destroy_surfaces = function()
-{
- for (var s in this.surfaces)
- {
- this.delete_surface(this.surfaces[s].surface_id);
- }
-
- this.surfaces = undefined;
-}
-
-
-function handle_mouseover(e)
-{
- this.focus();
-}
-
-function handle_mouseout(e)
-{
- if (this.sc && this.sc.cursor &&
this.sc.cursor.spice_simulated_cursor)
- this.sc.cursor.spice_simulated_cursor.style.display = 'none';
- this.blur();
-}
-
-function handle_draw_jpeg_onload()
-{
- var temp_canvas = null;
- var context;
-
- /*------------------------------------------------------------
- ** FIXME:
- ** The helper should be extended to be able to handle actual HtmlImageElements
- ** ...and the cache should be modified to do so as well
- **----------------------------------------------------------*/
- if (this.o.sc.surfaces[this.o.base.surface_id] === undefined)
- {
- // This can happen; if the jpeg image loads after our surface
- // has been destroyed (e.g. open a menu, close it quickly),
- // we'll find we have no surface.
- DEBUG > 2 && this.o.sc.log_info("Discarding jpeg; presumed lost
surface " + this.o.base.surface_id);
- temp_canvas = document.createElement("canvas");
- temp_canvas.setAttribute('width', this.o.base.box.right);
- temp_canvas.setAttribute('height', this.o.base.box.bottom);
- context = temp_canvas.getContext("2d");
- }
- else
- context = this.o.sc.surfaces[this.o.base.surface_id].canvas.context;
-
- if (this.alpha_img)
- {
- var c = document.createElement("canvas");
- var t = c.getContext("2d");
- c.setAttribute('width', this.alpha_img.width);
- c.setAttribute('height', this.alpha_img.height);
- t.putImageData(this.alpha_img, 0, 0);
- t.globalCompositeOperation = 'source-in';
- t.drawImage(this, 0, 0);
-
- context.drawImage(c, this.o.base.box.left, this.o.base.box.top);
-
- if (this.o.descriptor &&
- (this.o.descriptor.flags & SPICE_IMAGE_FLAGS_CACHE_ME))
- {
- if (! ("cache" in this.o.sc))
- this.o.sc.cache = {};
-
- this.o.sc.cache[this.o.descriptor.id] =
- t.getImageData(0, 0,
- this.alpha_img.width,
- this.alpha_img.height);
- }
- }
- else
- {
- context.drawImage(this, this.o.base.box.left, this.o.base.box.top);
-
- // Give the Garbage collector a clue to recycle this; avoids
- // fairly massive memory leaks during video playback
- this.src = null;
-
- if (this.o.descriptor &&
- (this.o.descriptor.flags & SPICE_IMAGE_FLAGS_CACHE_ME))
- {
- if (! ("cache" in this.o.sc))
- this.o.sc.cache = {};
-
- this.o.sc.cache[this.o.descriptor.id] =
- context.getImageData(this.o.base.box.left, this.o.base.box.top,
- this.o.base.box.right - this.o.base.box.left,
- this.o.base.box.bottom - this.o.base.box.top);
- }
- }
-
- if (temp_canvas == null)
- {
- if (DUMP_DRAWS && this.o.sc.parent.dump_id)
- {
- var debug_canvas = document.createElement("canvas");
- debug_canvas.setAttribute('id', this.o.tag + "." +
- this.o.sc.surfaces[this.o.base.surface_id].draw_count + "." +
- this.o.base.surface_id + "@" + this.o.base.box.left +
"x" + this.o.base.box.top);
- debug_canvas.getContext("2d").drawImage(this, 0, 0);
- document.getElementById(this.o.sc.parent.dump_id).appendChild(debug_canvas);
- }
-
- this.o.sc.surfaces[this.o.base.surface_id].draw_count++;
- }
-}
diff --git a/plugins/kimchi/ui/spice-html5/enums.js
b/plugins/kimchi/ui/spice-html5/enums.js
deleted file mode 100644
index d99b38e..0000000
--- a/plugins/kimchi/ui/spice-html5/enums.js
+++ /dev/null
@@ -1,324 +0,0 @@
-"use strict";
-/*
- Copyright (C) 2012 by Jeremy P. White <jwhite(a)codeweavers.com>
-
- This file is part of spice-html5.
-
- spice-html5 is free software: you can redistribute it and/or modify
- it under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- spice-html5 is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public License
- along with spice-html5. If not, see <
http://www.gnu.org/licenses/>.
-*/
-
-
-/*----------------------------------------------------------------------------
-** enums.js
-** 'constants' for Spice
-**--------------------------------------------------------------------------*/
-var SPICE_MAGIC = "REDQ";
-var SPICE_VERSION_MAJOR = 2;
-var SPICE_VERSION_MINOR = 2;
-
-var SPICE_CONNECT_TIMEOUT = (30 * 1000);
-
-var SPICE_COMMON_CAP_PROTOCOL_AUTH_SELECTION = 0;
-var SPICE_COMMON_CAP_AUTH_SPICE = 1;
-var SPICE_COMMON_CAP_AUTH_SASL = 2;
-var SPICE_COMMON_CAP_MINI_HEADER = 3;
-
-var SPICE_TICKET_KEY_PAIR_LENGTH = 1024;
-var SPICE_TICKET_PUBKEY_BYTES = (SPICE_TICKET_KEY_PAIR_LENGTH / 8 + 34);
-
-var SPICE_LINK_ERR_OK = 0,
- SPICE_LINK_ERR_ERROR = 1,
- SPICE_LINK_ERR_INVALID_MAGIC = 2,
- SPICE_LINK_ERR_INVALID_DATA = 3,
- SPICE_LINK_ERR_VERSION_MISMATCH = 4,
- SPICE_LINK_ERR_NEED_SECURED = 5,
- SPICE_LINK_ERR_NEED_UNSECURED = 6,
- SPICE_LINK_ERR_PERMISSION_DENIED = 7,
- SPICE_LINK_ERR_BAD_CONNECTION_ID = 8,
- SPICE_LINK_ERR_CHANNEL_NOT_AVAILABLE = 9;
-
-var SPICE_MSG_MIGRATE = 1;
-var SPICE_MSG_MIGRATE_DATA = 2;
-var SPICE_MSG_SET_ACK = 3;
-var SPICE_MSG_PING = 4;
-var SPICE_MSG_WAIT_FOR_CHANNELS = 5;
-var SPICE_MSG_DISCONNECTING = 6;
-var SPICE_MSG_NOTIFY = 7;
-var SPICE_MSG_LIST = 8;
-
-var SPICE_MSG_MAIN_MIGRATE_BEGIN = 101;
-var SPICE_MSG_MAIN_MIGRATE_CANCEL = 102;
-var SPICE_MSG_MAIN_INIT = 103;
-var SPICE_MSG_MAIN_CHANNELS_LIST = 104;
-var SPICE_MSG_MAIN_MOUSE_MODE = 105;
-var SPICE_MSG_MAIN_MULTI_MEDIA_TIME = 106;
-var SPICE_MSG_MAIN_AGENT_CONNECTED = 107;
-var SPICE_MSG_MAIN_AGENT_DISCONNECTED = 108;
-var SPICE_MSG_MAIN_AGENT_DATA = 109;
-var SPICE_MSG_MAIN_AGENT_TOKEN = 110;
-var SPICE_MSG_MAIN_MIGRATE_SWITCH_HOST = 111;
-var SPICE_MSG_MAIN_MIGRATE_END = 112;
-var SPICE_MSG_MAIN_NAME = 113;
-var SPICE_MSG_MAIN_UUID = 114;
-var SPICE_MSG_MAIN_AGENT_CONNECTED_TOKENS = 115;
-var SPICE_MSG_MAIN_MIGRATE_BEGIN_SEAMLESS = 116;
-var SPICE_MSG_MAIN_MIGRATE_DST_SEAMLESS_ACK = 117;
-var SPICE_MSG_MAIN_MIGRATE_DST_SEAMLESS_NACK = 118;
-var SPICE_MSG_END_MAIN = 119;
-
-
-
-var SPICE_MSGC_ACK_SYNC = 1;
-var SPICE_MSGC_ACK = 2;
-var SPICE_MSGC_PONG = 3;
-var SPICE_MSGC_MIGRATE_FLUSH_MARK = 4;
-var SPICE_MSGC_MIGRATE_DATA = 5;
-var SPICE_MSGC_DISCONNECTING = 6;
-
-
-var SPICE_MSGC_MAIN_CLIENT_INFO = 101;
-var SPICE_MSGC_MAIN_MIGRATE_CONNECTED = 102;
-var SPICE_MSGC_MAIN_MIGRATE_CONNECT_ERROR = 103;
-var SPICE_MSGC_MAIN_ATTACH_CHANNELS = 104;
-var SPICE_MSGC_MAIN_MOUSE_MODE_REQUEST = 105;
-var SPICE_MSGC_MAIN_AGENT_START = 106;
-var SPICE_MSGC_MAIN_AGENT_DATA = 107;
-var SPICE_MSGC_MAIN_AGENT_TOKEN = 108;
-var SPICE_MSGC_MAIN_MIGRATE_END = 109;
-var SPICE_MSGC_END_MAIN = 110;
-
-var SPICE_MSG_DISPLAY_MODE = 101;
-var SPICE_MSG_DISPLAY_MARK = 102;
-var SPICE_MSG_DISPLAY_RESET = 103;
-var SPICE_MSG_DISPLAY_COPY_BITS = 104;
-var SPICE_MSG_DISPLAY_INVAL_LIST = 105;
-var SPICE_MSG_DISPLAY_INVAL_ALL_PIXMAPS = 106;
-var SPICE_MSG_DISPLAY_INVAL_PALETTE = 107;
-var SPICE_MSG_DISPLAY_INVAL_ALL_PALETTES= 108;
-
-var SPICE_MSG_DISPLAY_STREAM_CREATE = 122;
-var SPICE_MSG_DISPLAY_STREAM_DATA = 123;
-var SPICE_MSG_DISPLAY_STREAM_CLIP = 124;
-var SPICE_MSG_DISPLAY_STREAM_DESTROY = 125;
-var SPICE_MSG_DISPLAY_STREAM_DESTROY_ALL= 126;
-
-var SPICE_MSG_DISPLAY_DRAW_FILL = 302;
-var SPICE_MSG_DISPLAY_DRAW_OPAQUE = 303;
-var SPICE_MSG_DISPLAY_DRAW_COPY = 304;
-var SPICE_MSG_DISPLAY_DRAW_BLEND = 305;
-var SPICE_MSG_DISPLAY_DRAW_BLACKNESS = 306;
-var SPICE_MSG_DISPLAY_DRAW_WHITENESS = 307;
-var SPICE_MSG_DISPLAY_DRAW_INVERS = 308;
-var SPICE_MSG_DISPLAY_DRAW_ROP3 = 309;
-var SPICE_MSG_DISPLAY_DRAW_STROKE = 310;
-var SPICE_MSG_DISPLAY_DRAW_TEXT = 311;
-var SPICE_MSG_DISPLAY_DRAW_TRANSPARENT = 312;
-var SPICE_MSG_DISPLAY_DRAW_ALPHA_BLEND = 313;
-var SPICE_MSG_DISPLAY_SURFACE_CREATE = 314;
-var SPICE_MSG_DISPLAY_SURFACE_DESTROY = 315;
-
-var SPICE_MSGC_DISPLAY_INIT = 101;
-
-var SPICE_MSG_INPUTS_INIT = 101;
-var SPICE_MSG_INPUTS_KEY_MODIFIERS = 102;
-
-var SPICE_MSG_INPUTS_MOUSE_MOTION_ACK = 111;
-
-var SPICE_MSGC_INPUTS_KEY_DOWN = 101;
-var SPICE_MSGC_INPUTS_KEY_UP = 102;
-var SPICE_MSGC_INPUTS_KEY_MODIFIERS = 103;
-
-var SPICE_MSGC_INPUTS_MOUSE_MOTION = 111;
-var SPICE_MSGC_INPUTS_MOUSE_POSITION = 112;
-var SPICE_MSGC_INPUTS_MOUSE_PRESS = 113;
-var SPICE_MSGC_INPUTS_MOUSE_RELEASE = 114;
-
-var SPICE_MSG_CURSOR_INIT = 101;
-var SPICE_MSG_CURSOR_RESET = 102;
-var SPICE_MSG_CURSOR_SET = 103;
-var SPICE_MSG_CURSOR_MOVE = 104;
-var SPICE_MSG_CURSOR_HIDE = 105;
-var SPICE_MSG_CURSOR_TRAIL = 106;
-var SPICE_MSG_CURSOR_INVAL_ONE = 107;
-var SPICE_MSG_CURSOR_INVAL_ALL = 108;
-
-var SPICE_MSG_PLAYBACK_DATA = 101;
-var SPICE_MSG_PLAYBACK_MODE = 102;
-var SPICE_MSG_PLAYBACK_START = 103;
-var SPICE_MSG_PLAYBACK_STOP = 104;
-var SPICE_MSG_PLAYBACK_VOLUME = 105;
-var SPICE_MSG_PLAYBACK_MUTE = 106;
-var SPICE_MSG_PLAYBACK_LATENCY = 107;
-
-var SPICE_PLAYBACK_CAP_CELT_0_5_1 = 0;
-var SPICE_PLAYBACK_CAP_VOLUME = 1;
-var SPICE_PLAYBACK_CAP_LATENCY = 2;
-var SPICE_PLAYBACK_CAP_OPUS = 3;
-
-var SPICE_AUDIO_DATA_MODE_INVALID = 0;
-var SPICE_AUDIO_DATA_MODE_RAW = 1;
-var SPICE_AUDIO_DATA_MODE_CELT_0_5_1 = 2;
-var SPICE_AUDIO_DATA_MODE_OPUS = 3;
-
-var SPICE_AUDIO_FMT_INVALID = 0;
-var SPICE_AUDIO_FMT_S16 = 1;
-
-var SPICE_CHANNEL_MAIN = 1;
-var SPICE_CHANNEL_DISPLAY = 2;
-var SPICE_CHANNEL_INPUTS = 3;
-var SPICE_CHANNEL_CURSOR = 4;
-var SPICE_CHANNEL_PLAYBACK = 5;
-var SPICE_CHANNEL_RECORD = 6;
-var SPICE_CHANNEL_TUNNEL = 7;
-var SPICE_CHANNEL_SMARTCARD = 8;
-var SPICE_CHANNEL_USBREDIR = 9;
-
-var SPICE_SURFACE_FLAGS_PRIMARY = (1 << 0);
-
-var SPICE_NOTIFY_SEVERITY_INFO = 0;
-var SPICE_NOTIFY_SEVERITY_WARN = 1;
-var SPICE_NOTIFY_SEVERITY_ERROR = 2;
-
-var SPICE_MOUSE_MODE_SERVER = (1 << 0),
- SPICE_MOUSE_MODE_CLIENT = (1 << 1),
- SPICE_MOUSE_MODE_MASK = 0x3;
-
-var SPICE_CLIP_TYPE_NONE = 0;
-var SPICE_CLIP_TYPE_RECTS = 1;
-
-var SPICE_IMAGE_TYPE_BITMAP = 0;
-var SPICE_IMAGE_TYPE_QUIC = 1;
-var SPICE_IMAGE_TYPE_RESERVED = 2;
-var SPICE_IMAGE_TYPE_LZ_PLT = 100;
-var SPICE_IMAGE_TYPE_LZ_RGB = 101;
-var SPICE_IMAGE_TYPE_GLZ_RGB = 102;
-var SPICE_IMAGE_TYPE_FROM_CACHE = 103;
-var SPICE_IMAGE_TYPE_SURFACE = 104;
-var SPICE_IMAGE_TYPE_JPEG = 105;
-var SPICE_IMAGE_TYPE_FROM_CACHE_LOSSLESS = 106;
-var SPICE_IMAGE_TYPE_ZLIB_GLZ_RGB = 107;
-var SPICE_IMAGE_TYPE_JPEG_ALPHA = 108;
-
-var SPICE_IMAGE_FLAGS_CACHE_ME = (1 << 0),
- SPICE_IMAGE_FLAGS_HIGH_BITS_SET = (1 << 1),
- SPICE_IMAGE_FLAGS_CACHE_REPLACE_ME = (1 << 2);
-
-var SPICE_BITMAP_FLAGS_PAL_CACHE_ME = (1 << 0),
- SPICE_BITMAP_FLAGS_PAL_FROM_CACHE = (1 << 1),
- SPICE_BITMAP_FLAGS_TOP_DOWN = (1 << 2),
- SPICE_BITMAP_FLAGS_MASK = 0x7;
-
-var SPICE_BITMAP_FMT_INVALID = 0,
- SPICE_BITMAP_FMT_1BIT_LE = 1,
- SPICE_BITMAP_FMT_1BIT_BE = 2,
- SPICE_BITMAP_FMT_4BIT_LE = 3,
- SPICE_BITMAP_FMT_4BIT_BE = 4,
- SPICE_BITMAP_FMT_8BIT = 5,
- SPICE_BITMAP_FMT_16BIT = 6,
- SPICE_BITMAP_FMT_24BIT = 7,
- SPICE_BITMAP_FMT_32BIT = 8,
- SPICE_BITMAP_FMT_RGBA = 9;
-
-
-var SPICE_CURSOR_FLAGS_NONE = (1 << 0),
- SPICE_CURSOR_FLAGS_CACHE_ME = (1 << 1),
- SPICE_CURSOR_FLAGS_FROM_CACHE = (1 << 2),
- SPICE_CURSOR_FLAGS_MASK = 0x7;
-
-var SPICE_MOUSE_BUTTON_MASK_LEFT = (1 << 0),
- SPICE_MOUSE_BUTTON_MASK_MIDDLE = (1 << 1),
- SPICE_MOUSE_BUTTON_MASK_RIGHT = (1 << 2),
- SPICE_MOUSE_BUTTON_MASK_MASK = 0x7;
-
-var SPICE_MOUSE_BUTTON_INVALID = 0;
-var SPICE_MOUSE_BUTTON_LEFT = 1;
-var SPICE_MOUSE_BUTTON_MIDDLE = 2;
-var SPICE_MOUSE_BUTTON_RIGHT = 3;
-var SPICE_MOUSE_BUTTON_UP = 4;
-var SPICE_MOUSE_BUTTON_DOWN = 5;
-
-var SPICE_BRUSH_TYPE_NONE = 0,
- SPICE_BRUSH_TYPE_SOLID = 1,
- SPICE_BRUSH_TYPE_PATTERN = 2;
-
-var SPICE_SURFACE_FMT_INVALID = 0,
- SPICE_SURFACE_FMT_1_A = 1,
- SPICE_SURFACE_FMT_8_A = 8,
- SPICE_SURFACE_FMT_16_555 = 16,
- SPICE_SURFACE_FMT_32_xRGB = 32,
- SPICE_SURFACE_FMT_16_565 = 80,
- SPICE_SURFACE_FMT_32_ARGB = 96;
-
-var SPICE_ROPD_INVERS_SRC = (1 << 0),
- SPICE_ROPD_INVERS_BRUSH = (1 << 1),
- SPICE_ROPD_INVERS_DEST = (1 << 2),
- SPICE_ROPD_OP_PUT = (1 << 3),
- SPICE_ROPD_OP_OR = (1 << 4),
- SPICE_ROPD_OP_AND = (1 << 5),
- SPICE_ROPD_OP_XOR = (1 << 6),
- SPICE_ROPD_OP_BLACKNESS = (1 << 7),
- SPICE_ROPD_OP_WHITENESS = (1 << 8),
- SPICE_ROPD_OP_INVERS = (1 << 9),
- SPICE_ROPD_INVERS_RES = (1 << 10),
- SPICE_ROPD_MASK = 0x7ff;
-
-var LZ_IMAGE_TYPE_INVALID = 0,
- LZ_IMAGE_TYPE_PLT1_LE = 1,
- LZ_IMAGE_TYPE_PLT1_BE = 2, // PLT stands for palette
- LZ_IMAGE_TYPE_PLT4_LE = 3,
- LZ_IMAGE_TYPE_PLT4_BE = 4,
- LZ_IMAGE_TYPE_PLT8 = 5,
- LZ_IMAGE_TYPE_RGB16 = 6,
- LZ_IMAGE_TYPE_RGB24 = 7,
- LZ_IMAGE_TYPE_RGB32 = 8,
- LZ_IMAGE_TYPE_RGBA = 9,
- LZ_IMAGE_TYPE_XXXA = 10;
-
-
-var QUIC_IMAGE_TYPE_INVALID = 0,
- QUIC_IMAGE_TYPE_GRAY = 1,
- QUIC_IMAGE_TYPE_RGB16 = 2,
- QUIC_IMAGE_TYPE_RGB24 = 3,
- QUIC_IMAGE_TYPE_RGB32 = 4,
- QUIC_IMAGE_TYPE_RGBA = 5;
-
-var SPICE_INPUT_MOTION_ACK_BUNCH = 4;
-
-
-var SPICE_CURSOR_TYPE_ALPHA = 0,
- SPICE_CURSOR_TYPE_MONO = 1,
- SPICE_CURSOR_TYPE_COLOR4 = 2,
- SPICE_CURSOR_TYPE_COLOR8 = 3,
- SPICE_CURSOR_TYPE_COLOR16 = 4,
- SPICE_CURSOR_TYPE_COLOR24 = 5,
- SPICE_CURSOR_TYPE_COLOR32 = 6;
-
-var SPICE_VIDEO_CODEC_TYPE_MJPEG = 1;
-
-var VD_AGENT_PROTOCOL = 1;
-
-var VD_AGENT_MOUSE_STATE = 1,
- VD_AGENT_MONITORS_CONFIG = 2,
- VD_AGENT_REPLY = 3,
- VD_AGENT_CLIPBOARD = 4,
- VD_AGENT_DISPLAY_CONFIG = 5,
- VD_AGENT_ANNOUNCE_CAPABILITIES = 6,
- VD_AGENT_CLIPBOARD_GRAB = 7,
- VD_AGENT_CLIPBOARD_REQUEST = 8,
- VD_AGENT_CLIPBOARD_RELEASE = 9,
- VD_AGENT_FILE_XFER_START =10,
- VD_AGENT_FILE_XFER_STATUS =11,
- VD_AGENT_FILE_XFER_DATA =12,
- VD_AGENT_CLIENT_DISCONNECTED =13,
- VD_AGENT_MAX_CLIPBOARD =14;
diff --git a/plugins/kimchi/ui/spice-html5/inputs.js
b/plugins/kimchi/ui/spice-html5/inputs.js
deleted file mode 100644
index c904eda..0000000
--- a/plugins/kimchi/ui/spice-html5/inputs.js
+++ /dev/null
@@ -1,280 +0,0 @@
-"use strict";
-/*
- Copyright (C) 2012 by Jeremy P. White <jwhite(a)codeweavers.com>
-
- This file is part of spice-html5.
-
- spice-html5 is free software: you can redistribute it and/or modify
- it under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- spice-html5 is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public License
- along with spice-html5. If not, see <
http://www.gnu.org/licenses/>.
-*/
-
-/*----------------------------------------------------------------------------
- ** Modifier Keystates
- ** These need to be tracked because focus in and out can get the keyboard
- ** out of sync.
- **------------------------------------------------------------------------*/
-var Shift_state = -1;
-var Ctrl_state = -1;
-var Alt_state = -1;
-var Meta_state = -1;
-
-/*----------------------------------------------------------------------------
-** SpiceInputsConn
-** Drive the Spice Inputs channel (e.g. mouse + keyboard)
-**--------------------------------------------------------------------------*/
-function SpiceInputsConn()
-{
- SpiceConn.apply(this, arguments);
-
- this.mousex = undefined;
- this.mousey = undefined;
- this.button_state = 0;
- this.waiting_for_ack = 0;
-}
-
-SpiceInputsConn.prototype = Object.create(SpiceConn.prototype);
-SpiceInputsConn.prototype.process_channel_message = function(msg)
-{
- if (msg.type == SPICE_MSG_INPUTS_INIT)
- {
- var inputs_init = new SpiceMsgInputsInit(msg.data);
- this.keyboard_modifiers = inputs_init.keyboard_modifiers;
- DEBUG > 1 && console.log("MsgInputsInit - modifier " +
this.keyboard_modifiers);
- // FIXME - We don't do anything with the keyboard modifiers...
- return true;
- }
- if (msg.type == SPICE_MSG_INPUTS_KEY_MODIFIERS)
- {
- var key = new SpiceMsgInputsKeyModifiers(msg.data);
- this.keyboard_modifiers = key.keyboard_modifiers;
- DEBUG > 1 && console.log("MsgInputsKeyModifiers - modifier "
+ this.keyboard_modifiers);
- // FIXME - We don't do anything with the keyboard modifiers...
- return true;
- }
- if (msg.type == SPICE_MSG_INPUTS_MOUSE_MOTION_ACK)
- {
- DEBUG > 1 && console.log("mouse motion ack");
- this.waiting_for_ack -= SPICE_INPUT_MOTION_ACK_BUNCH;
- return true;
- }
- return false;
-}
-
-
-
-function handle_mousemove(e)
-{
- var msg = new SpiceMiniData();
- var move;
- if (this.sc.mouse_mode == SPICE_MOUSE_MODE_CLIENT)
- {
- move = new SpiceMsgcMousePosition(this.sc, e)
- msg.build_msg(SPICE_MSGC_INPUTS_MOUSE_POSITION, move);
- }
- else
- {
- move = new SpiceMsgcMouseMotion(this.sc, e)
- msg.build_msg(SPICE_MSGC_INPUTS_MOUSE_MOTION, move);
- }
- if (this.sc && this.sc.inputs && this.sc.inputs.state ===
"ready")
- {
- if (this.sc.inputs.waiting_for_ack < (2 * SPICE_INPUT_MOTION_ACK_BUNCH))
- {
- this.sc.inputs.send_msg(msg);
- this.sc.inputs.waiting_for_ack++;
- }
- else
- {
- DEBUG > 0 && this.sc.log_info("Discarding mouse
motion");
- }
- }
-
- if (this.sc && this.sc.cursor &&
this.sc.cursor.spice_simulated_cursor)
- {
- this.sc.cursor.spice_simulated_cursor.style.display = 'block';
- this.sc.cursor.spice_simulated_cursor.style.left = e.pageX -
this.sc.cursor.spice_simulated_cursor.spice_hot_x + 'px';
- this.sc.cursor.spice_simulated_cursor.style.top = e.pageY -
this.sc.cursor.spice_simulated_cursor.spice_hot_y + 'px';
- e.preventDefault();
- }
-
-}
-
-function handle_mousedown(e)
-{
- var press = new SpiceMsgcMousePress(this.sc, e)
- var msg = new SpiceMiniData();
- msg.build_msg(SPICE_MSGC_INPUTS_MOUSE_PRESS, press);
- if (this.sc && this.sc.inputs && this.sc.inputs.state ===
"ready")
- this.sc.inputs.send_msg(msg);
-
- e.preventDefault();
-}
-
-function handle_contextmenu(e)
-{
- e.preventDefault();
- return false;
-}
-
-function handle_mouseup(e)
-{
- var release = new SpiceMsgcMouseRelease(this.sc, e)
- var msg = new SpiceMiniData();
- msg.build_msg(SPICE_MSGC_INPUTS_MOUSE_RELEASE, release);
- if (this.sc && this.sc.inputs && this.sc.inputs.state ===
"ready")
- this.sc.inputs.send_msg(msg);
-
- e.preventDefault();
-}
-
-function handle_mousewheel(e)
-{
- var press = new SpiceMsgcMousePress;
- var release = new SpiceMsgcMouseRelease;
- if (e.wheelDelta > 0)
- press.button = release.button = SPICE_MOUSE_BUTTON_UP;
- else
- press.button = release.button = SPICE_MOUSE_BUTTON_DOWN;
- press.buttons_state = 0;
- release.buttons_state = 0;
-
- var msg = new SpiceMiniData();
- msg.build_msg(SPICE_MSGC_INPUTS_MOUSE_PRESS, press);
- if (this.sc && this.sc.inputs && this.sc.inputs.state ===
"ready")
- this.sc.inputs.send_msg(msg);
-
- msg.build_msg(SPICE_MSGC_INPUTS_MOUSE_RELEASE, release);
- if (this.sc && this.sc.inputs && this.sc.inputs.state ===
"ready")
- this.sc.inputs.send_msg(msg);
-
- e.preventDefault();
-}
-
-function handle_keydown(e)
-{
- var key = new SpiceMsgcKeyDown(e)
- var msg = new SpiceMiniData();
- check_and_update_modifiers(e, key.code, this.sc);
- msg.build_msg(SPICE_MSGC_INPUTS_KEY_DOWN, key);
- if (this.sc && this.sc.inputs && this.sc.inputs.state ===
"ready")
- this.sc.inputs.send_msg(msg);
-
- e.preventDefault();
-}
-
-function handle_keyup(e)
-{
- var key = new SpiceMsgcKeyUp(e)
- var msg = new SpiceMiniData();
- check_and_update_modifiers(e, key.code, this.sc);
- msg.build_msg(SPICE_MSGC_INPUTS_KEY_UP, key);
- if (this.sc && this.sc.inputs && this.sc.inputs.state ===
"ready")
- this.sc.inputs.send_msg(msg);
-
- e.preventDefault();
-}
-
-function sendCtrlAltDel()
-{
- if (sc && sc.inputs && sc.inputs.state === "ready"){
- var key = new SpiceMsgcKeyDown();
- var msg = new SpiceMiniData();
-
- update_modifier(true, KEY_LCtrl, sc);
- update_modifier(true, KEY_Alt, sc);
-
- key.code = KEY_KP_Decimal;
- msg.build_msg(SPICE_MSGC_INPUTS_KEY_DOWN, key);
- sc.inputs.send_msg(msg);
- msg.build_msg(SPICE_MSGC_INPUTS_KEY_UP, key);
- sc.inputs.send_msg(msg);
-
- if(Ctrl_state == false) update_modifier(false, KEY_LCtrl, sc);
- if(Alt_state == false) update_modifier(false, KEY_Alt, sc);
- }
-}
-
-function update_modifier(state, code, sc)
-{
- var msg = new SpiceMiniData();
- if (!state)
- {
- var key = new SpiceMsgcKeyUp()
- key.code =(0x80|code);
- msg.build_msg(SPICE_MSGC_INPUTS_KEY_UP, key);
- }
- else
- {
- var key = new SpiceMsgcKeyDown()
- key.code = code;
- msg.build_msg(SPICE_MSGC_INPUTS_KEY_DOWN, key);
- }
-
- sc.inputs.send_msg(msg);
-}
-
-function check_and_update_modifiers(e, code, sc)
-{
- if (Shift_state === -1)
- {
- Shift_state = e.shiftKey;
- Ctrl_state = e.ctrlKey;
- Alt_state = e.altKey;
- Meta_state = e.metaKey;
- }
-
- if (code === KEY_ShiftL)
- Shift_state = true;
- else if (code === KEY_Alt)
- Alt_state = true;
- else if (code === KEY_LCtrl)
- Ctrl_state = true;
- else if (code === 0xE0B5)
- Meta_state = true;
- else if (code === (0x80|KEY_ShiftL))
- Shift_state = false;
- else if (code === (0x80|KEY_Alt))
- Alt_state = false;
- else if (code === (0x80|KEY_LCtrl))
- Ctrl_state = false;
- else if (code === (0x80|0xE0B5))
- Meta_state = false;
-
- if (sc && sc.inputs && sc.inputs.state === "ready")
- {
- if (Shift_state != e.shiftKey)
- {
- console.log("Shift state out of sync");
- update_modifier(e.shiftKey, KEY_ShiftL, sc);
- Shift_state = e.shiftKey;
- }
- if (Alt_state != e.altKey)
- {
- console.log("Alt state out of sync");
- update_modifier(e.altKey, KEY_Alt, sc);
- Alt_state = e.altKey;
- }
- if (Ctrl_state != e.ctrlKey)
- {
- console.log("Ctrl state out of sync");
- update_modifier(e.ctrlKey, KEY_LCtrl, sc);
- Ctrl_state = e.ctrlKey;
- }
- if (Meta_state != e.metaKey)
- {
- console.log("Meta state out of sync");
- update_modifier(e.metaKey, 0xE0B5, sc);
- Meta_state = e.metaKey;
- }
- }
-}
diff --git a/plugins/kimchi/ui/spice-html5/lz.js b/plugins/kimchi/ui/spice-html5/lz.js
deleted file mode 100644
index 4292eac..0000000
--- a/plugins/kimchi/ui/spice-html5/lz.js
+++ /dev/null
@@ -1,166 +0,0 @@
-"use strict";
-/*
- Copyright (C) 2012 by Jeremy P. White <jwhite(a)codeweavers.com>
-
- This file is part of spice-html5.
-
- spice-html5 is free software: you can redistribute it and/or modify
- it under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- spice-html5 is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public License
- along with spice-html5. If not, see <
http://www.gnu.org/licenses/>.
-*/
-
-
-/*----------------------------------------------------------------------------
-** lz.js
-** Functions for handling SPICE_IMAGE_TYPE_LZ_RGB
-** Adapted from lz.c .
-**--------------------------------------------------------------------------*/
-function lz_rgb32_decompress(in_buf, at, out_buf, type, default_alpha)
-{
- var encoder = at;
- var op = 0;
- var ctrl;
- var ctr = 0;
-
- for (ctrl = in_buf[encoder++]; (op * 4) < out_buf.length; ctrl =
in_buf[encoder++])
- {
- var ref = op;
- var len = ctrl >> 5;
- var ofs = (ctrl & 31) << 8;
-
-//if (type == LZ_IMAGE_TYPE_RGBA)
-//console.log(ctr++ + ": from " + (encoder + 28) + ", ctrl " + ctrl +
", len " + len + ", ofs " + ofs + ", op " + op);
- if (ctrl >= 32) {
-
- var code;
- len--;
-
- if (len == 7 - 1) {
- do {
- code = in_buf[encoder++];
- len += code;
- } while (code == 255);
- }
- code = in_buf[encoder++];
- ofs += code;
-
-
- if (code == 255) {
- if ((ofs - code) == (31 << 8)) {
- ofs = in_buf[encoder++] << 8;
- ofs += in_buf[encoder++];
- ofs += 8191;
- }
- }
- len += 1;
- if (type == LZ_IMAGE_TYPE_RGBA)
- len += 2;
-
- ofs += 1;
-
- ref -= ofs;
- if (ref == (op - 1)) {
- var b = ref;
-//if (type == LZ_IMAGE_TYPE_RGBA) console.log("alpha " + out_buf[(b*4)+3] +
" dupped into pixel " + op + " through pixel " + (op + len));
- for (; len; --len) {
- if (type == LZ_IMAGE_TYPE_RGBA)
- {
- out_buf[(op*4) + 3] = out_buf[(b*4)+3];
- }
- else
- {
- for (i = 0; i < 4; i++)
- out_buf[(op*4) + i] = out_buf[(b*4)+i];
- }
- op++;
- }
- } else {
-//if (type == LZ_IMAGE_TYPE_RGBA) console.log("alpha copied to pixel " + op +
" through " + (op + len) + " from " + ref);
- for (; len; --len) {
- if (type == LZ_IMAGE_TYPE_RGBA)
- {
- out_buf[(op*4) + 3] = out_buf[(ref*4)+3];
- }
- else
- {
- for (i = 0; i < 4; i++)
- out_buf[(op*4) + i] = out_buf[(ref*4)+i];
- }
- op++; ref++;
- }
- }
- } else {
- ctrl++;
-
- if (type == LZ_IMAGE_TYPE_RGBA)
- {
-//console.log("alpha " + in_buf[encoder] + " set into pixel " + op);
- out_buf[(op*4) + 3] = in_buf[encoder++];
- }
- else
- {
- out_buf[(op*4) + 0] = in_buf[encoder + 2];
- out_buf[(op*4) + 1] = in_buf[encoder + 1];
- out_buf[(op*4) + 2] = in_buf[encoder + 0];
- if (default_alpha)
- out_buf[(op*4) + 3] = 255;
- encoder += 3;
- }
- op++;
-
-
- for (--ctrl; ctrl; ctrl--) {
- if (type == LZ_IMAGE_TYPE_RGBA)
- {
-//console.log("alpha " + in_buf[encoder] + " set into pixel " + op);
- out_buf[(op*4) + 3] = in_buf[encoder++];
- }
- else
- {
- out_buf[(op*4) + 0] = in_buf[encoder + 2];
- out_buf[(op*4) + 1] = in_buf[encoder + 1];
- out_buf[(op*4) + 2] = in_buf[encoder + 0];
- if (default_alpha)
- out_buf[(op*4) + 3] = 255;
- encoder += 3;
- }
- op++;
- }
- }
-
- }
- return encoder - 1;
-}
-
-function convert_spice_lz_to_web(context, lz_image)
-{
- var at;
- if (lz_image.type === LZ_IMAGE_TYPE_RGB32 || lz_image.type === LZ_IMAGE_TYPE_RGBA)
- {
- var u8 = new Uint8Array(lz_image.data);
- var ret = context.createImageData(lz_image.width, lz_image.height);
-
- at = lz_rgb32_decompress(u8, 0, ret.data, LZ_IMAGE_TYPE_RGB32, lz_image.type !=
LZ_IMAGE_TYPE_RGBA);
- if (lz_image.type == LZ_IMAGE_TYPE_RGBA)
- lz_rgb32_decompress(u8, at, ret.data, LZ_IMAGE_TYPE_RGBA, false);
- }
- else if (lz_image.type === LZ_IMAGE_TYPE_XXXA)
- {
- var u8 = new Uint8Array(lz_image.data);
- var ret = context.createImageData(lz_image.width, lz_image.height);
- lz_rgb32_decompress(u8, 0, ret.data, LZ_IMAGE_TYPE_RGBA, false);
- }
- else
- return undefined;
-
- return ret;
-}
diff --git a/plugins/kimchi/ui/spice-html5/main.js
b/plugins/kimchi/ui/spice-html5/main.js
deleted file mode 100644
index 91f1963..0000000
--- a/plugins/kimchi/ui/spice-html5/main.js
+++ /dev/null
@@ -1,231 +0,0 @@
-"use strict";
-/*
- Copyright (C) 2012 by Jeremy P. White <jwhite(a)codeweavers.com>
-
- This file is part of spice-html5.
-
- spice-html5 is free software: you can redistribute it and/or modify
- it under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- spice-html5 is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public License
- along with spice-html5. If not, see <
http://www.gnu.org/licenses/>.
-*/
-
-/*----------------------------------------------------------------------------
-** SpiceMainConn
-** This is the master Javascript class for establishing and
-** managing a connection to a Spice Server.
-**
-** Invocation: You must pass an object with properties as follows:
-** uri (required) Uri of a WebSocket listener that is
-** connected to a spice server.
-** password (required) Password to send to the spice server
-** message_id (optional) Identifier of an element in the DOM
-** where SpiceConn will write messages.
-** It will use classes spice-messages-x,
-** where x is one of info, warning, or error.
-** screen_id (optional) Identifier of an element in the DOM
-** where SpiceConn will create any new
-** client screens. This is the main UI.
-** dump_id (optional) If given, an element to use for
-** dumping every single image + canvas drawn.
-** Sometimes useful for debugging.
-** onerror (optional) If given, a function to receive async
-** errors. Note that you should also catch
-** errors for ones that occur inline
-** onagent (optional) If given, a function to be called when
-** a VD agent is connected; a good opportunity
-** to request a resize
-**
-** Throws error if there are troubles. Requires a modern (by 2012 standards)
-** browser, including WebSocket and WebSocket.binaryType == arraybuffer
-**
-**--------------------------------------------------------------------------*/
-function SpiceMainConn()
-{
- if (typeof WebSocket === "undefined")
- throw new Error("WebSocket unavailable. You need to use a different
browser.");
-
- SpiceConn.apply(this, arguments);
-
-}
-
-SpiceMainConn.prototype = Object.create(SpiceConn.prototype);
-SpiceMainConn.prototype.process_channel_message = function(msg)
-{
- if (msg.type == SPICE_MSG_MAIN_INIT)
- {
- this.log_info("Connected to " + this.ws.url);
- this.report_success("Connected")
- this.main_init = new SpiceMsgMainInit(msg.data);
- this.connection_id = this.main_init.session_id;
-
- if (DEBUG > 0)
- {
- // FIXME - there is a lot here we don't handle; mouse modes, agent,
- // ram_hint, multi_media_time
- this.log_info("session id " +
this.main_init.session_id +
- " ; display_channels_hint " +
this.main_init.display_channels_hint +
- " ; supported_mouse_modes " +
this.main_init.supported_mouse_modes +
- " ; current_mouse_mode " +
this.main_init.current_mouse_mode +
- " ; agent_connected " +
this.main_init.agent_connected +
- " ; agent_tokens " +
this.main_init.agent_tokens +
- " ; multi_media_time " +
this.main_init.multi_media_time +
- " ; ram_hint " +
this.main_init.ram_hint);
- }
-
- this.handle_mouse_mode(this.main_init.current_mouse_mode,
- this.main_init.supported_mouse_modes);
-
- if (this.main_init.agent_connected)
- this.connect_agent();
-
- var attach = new SpiceMiniData;
- attach.type = SPICE_MSGC_MAIN_ATTACH_CHANNELS;
- attach.size = attach.buffer_size();
- this.send_msg(attach);
- return true;
- }
-
- if (msg.type == SPICE_MSG_MAIN_MOUSE_MODE)
- {
- var mode = new SpiceMsgMainMouseMode(msg.data);
- DEBUG > 0 && this.log_info("Mouse supported modes " +
mode.supported_modes + "; current " + mode.current_mode);
- this.handle_mouse_mode(mode.current_mode, mode.supported_modes);
- return true;
- }
-
- if (msg.type == SPICE_MSG_MAIN_CHANNELS_LIST)
- {
- var i;
- var chans;
- DEBUG > 0 && console.log("channels");
- chans = new SpiceMsgChannels(msg.data);
- for (i = 0; i < chans.channels.length; i++)
- {
- var conn = {
- uri: this.ws.url,
- parent: this,
- connection_id : this.connection_id,
- type : chans.channels[i].type,
- chan_id : chans.channels[i].id
- };
- if (chans.channels[i].type == SPICE_CHANNEL_DISPLAY)
- this.display = new SpiceDisplayConn(conn);
- else if (chans.channels[i].type == SPICE_CHANNEL_INPUTS)
- {
- this.inputs = new SpiceInputsConn(conn);
- this.inputs.mouse_mode = this.mouse_mode;
- }
- else if (chans.channels[i].type == SPICE_CHANNEL_CURSOR)
- this.cursor = new SpiceCursorConn(conn);
- else if (chans.channels[i].type == SPICE_CHANNEL_PLAYBACK)
- this.cursor = new SpicePlaybackConn(conn);
- else
- {
- this.log_err("Channel type " + chans.channels[i].type + "
unknown.");
- if (! ("extra_channels" in this))
- this.extra_channels = [];
- this.extra_channels[i] = new SpiceConn(conn);
- }
-
- }
-
- return true;
- }
-
- if (msg.type == SPICE_MSG_MAIN_AGENT_CONNECTED ||
- msg.type == SPICE_MSG_MAIN_AGENT_CONNECTED_TOKENS)
- {
- this.connect_agent();
- return true;
- }
-
- if (msg.type == SPICE_MSG_MAIN_AGENT_DISCONNECTED)
- {
- this.agent_connected = false;
- return true;
- }
-
- return false;
-}
-
-SpiceMainConn.prototype.stop = function(msg)
-{
- this.state = "closing";
-
- if (this.inputs)
- {
- this.inputs.cleanup();
- this.inputs = undefined;
- }
-
- if (this.cursor)
- {
- this.cursor.cleanup();
- this.cursor = undefined;
- }
-
- if (this.display)
- {
- this.display.cleanup();
- this.display.destroy_surfaces();
- this.display = undefined;
- }
-
- this.cleanup();
-
- if ("extra_channels" in this)
- for (var e in this.extra_channels)
- this.extra_channels[e].cleanup();
- this.extra_channels = undefined;
-}
-
-SpiceMainConn.prototype.resize_window = function(flags, width, height, depth, x, y)
-{
- if (this.agent_connected > 0)
- {
- var monitors_config = new VDAgentMonitorsConfig(flags, width, height, depth, x,
y);
- var agent_data = new SpiceMsgcMainAgentData(VD_AGENT_MONITORS_CONFIG,
monitors_config);
- var mr = new SpiceMiniData();
- mr.build_msg(SPICE_MSGC_MAIN_AGENT_DATA, agent_data);
- this.send_msg(mr);
- }
-}
-
-SpiceMainConn.prototype.connect_agent = function()
-{
- this.agent_connected = true;
-
- var agent_start = new SpiceMsgcMainAgentStart(0);
- var mr = new SpiceMiniData();
- mr.build_msg(SPICE_MSGC_MAIN_AGENT_START, agent_start);
- this.send_msg(mr);
-
- if (this.onagent !== undefined)
- this.onagent(this);
-
-}
-
-SpiceMainConn.prototype.handle_mouse_mode = function(current, supported)
-{
- this.mouse_mode = current;
- if (current != SPICE_MOUSE_MODE_CLIENT && (supported &
SPICE_MOUSE_MODE_CLIENT))
- {
- var mode_request = new SpiceMsgcMainMouseModeRequest(SPICE_MOUSE_MODE_CLIENT);
- var mr = new SpiceMiniData();
- mr.build_msg(SPICE_MSGC_MAIN_MOUSE_MODE_REQUEST, mode_request);
- this.send_msg(mr);
- }
-
- if (this.inputs)
- this.inputs.mouse_mode = current;
-}
-
diff --git a/plugins/kimchi/ui/spice-html5/pages/Makefile.am
b/plugins/kimchi/ui/spice-html5/pages/Makefile.am
deleted file mode 100644
index 431ec6c..0000000
--- a/plugins/kimchi/ui/spice-html5/pages/Makefile.am
+++ /dev/null
@@ -1,20 +0,0 @@
-#
-# Kimchi
-#
-# Copyright IBM, Corp. 2014
-#
-# 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.
-
-spicepagesdir = $(datadir)/wok/plugins/kimchi/ui/spice-html5/pages
-
-dist_spicepages_DATA = $(wildcard *.html) $(NULL)
diff --git a/plugins/kimchi/ui/spice-html5/pages/spice_auto.html
b/plugins/kimchi/ui/spice-html5/pages/spice_auto.html
deleted file mode 100644
index c87f5c2..0000000
--- a/plugins/kimchi/ui/spice-html5/pages/spice_auto.html
+++ /dev/null
@@ -1,200 +0,0 @@
-<!--
- Copyright (C) 2012 by Jeremy P. White <jwhite(a)codeweavers.com>
-
- This file is part of spice-html5.
-
- spice-html5 is free software: you can redistribute it and/or modify
- it under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- spice-html5 is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public License
- along with spice-html5. If not, see <
http://www.gnu.org/licenses/>.
-
- --------------------------------------------------
- Spice Javascript client template.
- Refer to main.js for more detailed information
- --------------------------------------------------
-
--->
-
-<!doctype html>
-<html>
- <head>
-
- <!--
- The below sources were updated according to Kimchi configuration
- to get the Javascript and CSS files from the installed spice-html5
- package.
- Kimchi is not using the default spice_auto.html because Kimchi uses
- wss:// for all connections and it is only supported by recent
- versions of spice-html5.
- In addition to it, Kimchi points user to the right token on URL
- (check line 146 of this file).
- -->
- <title>Spice Javascript client</title>
- <script src="spice-html5/spicearraybuffer.js"></script>
- <script src="spice-html5/enums.js"></script>
- <script src="spice-html5/atKeynames.js"></script>
- <script src="spice-html5/utils.js"></script>
- <script src="spice-html5/png.js"></script>
- <script src="spice-html5/lz.js"></script>
- <script src="spice-html5/quic.js"></script>
- <script src="spice-html5/bitmap.js"></script>
- <script src="spice-html5/spicedataview.js"></script>
- <script src="spice-html5/spicetype.js"></script>
- <script src="spice-html5/spicemsg.js"></script>
- <script src="spice-html5/wire.js"></script>
- <script src="spice-html5/spiceconn.js"></script>
- <script src="spice-html5/display.js"></script>
- <script src="spice-html5/main.js"></script>
- <script src="spice-html5/inputs.js"></script>
- <script src="spice-html5/webm.js"></script>
- <script src="spice-html5/playback.js"></script>
- <script src="spice-html5/simulatecursor.js"></script>
- <script src="spice-html5/cursor.js"></script>
- <script src="spice-html5/thirdparty/jsbn.js"></script>
- <script src="spice-html5/thirdparty/rsa.js"></script>
- <script src="spice-html5/thirdparty/prng4.js"></script>
- <script src="spice-html5/thirdparty/rng.js"></script>
- <script src="spice-html5/thirdparty/sha1.js"></script>
- <script src="spice-html5/ticket.js"></script>
- <script src="spice-html5/resize.js"></script>
- <link rel="stylesheet" type="text/css"
href="spice-html5/spice.css" />
-
- <script>
- var host = null, port = null;
- var sc;
-
- function spice_set_cookie(name, value, days) {
- var date, expires;
- date = new Date();
- date.setTime(date.getTime() + (days*24*60*60*1000));
- expires = "; expires=" + date.toGMTString();
- document.cookie = name + "=" + value + expires + ";
path=/";
- };
-
- function spice_query_var(name, defvalue) {
- var match = RegExp('[?&]' + name + '=([^&]*)')
- .exec(window.location.search);
- return match ?
- decodeURIComponent(match[1].replace(/\+/g, ' '))
- : defvalue;
- }
-
- function spice_error(e)
- {
- disconnect();
- }
-
- function connect()
- {
- var host, port, password, scheme = "ws://", uri;
-
- // By default, use the host and port of server that served this file
- host = spice_query_var('host', window.location.hostname);
-
- // Note that using the web server port only makes sense
- // if your web server has a reverse proxy to relay the WebSocket
- // traffic to the correct destination port.
- var default_port = window.location.port;
- if (!default_port) {
- if (window.location.protocol == 'http:') {
- default_port = 80;
- }
- else if (window.location.protocol == 'https:') {
- default_port = 443;
- }
- }
- port = spice_query_var('port', default_port);
- if (window.location.protocol == 'https:') {
- scheme = "wss://";
- }
-
- // If a token variable is passed in, set the parameter in a cookie.
- // This is used by nova-spiceproxy.
- token = spice_query_var('token', null);
- if (token) {
- spice_set_cookie('token', token, 1)
- }
-
- password = spice_query_var('password', '');
- path = spice_query_var('path', 'websockify');
-
- if ((!host) || (!port)) {
- console.log("must specify host and port in URL");
- return;
- }
-
- if (sc) {
- sc.stop();
- }
-
- /*
- * The following line was modified from the original one:
- *
- * 'uri = scheme + host + ":" + port;'
- *
- * to point wok.user to a specific console represented by
- * token value.
- */
- uri = scheme + host + ":" + port + "/?token=" +
token;
-
- try
- {
- sc = new SpiceMainConn({uri: uri, screen_id:
"spice-screen", dump_id: "debug-div",
- message_id: "message-div", password: password,
onerror: spice_error, onagent: agent_connected });
- }
- catch (e)
- {
- alert(e.toString());
- disconnect();
- }
-
- }
-
- function disconnect()
- {
- console.log(">> disconnect");
- if (sc) {
- sc.stop();
- }
- console.log("<< disconnect");
- }
-
- function agent_connected(sc)
- {
- window.addEventListener('resize', handle_resize);
- window.spice_connection = this;
-
- resize_helper(this);
- }
-
- connect();
- </script>
-
- </head>
-
- <body>
-
- <div id="login">
- <span class="logo">SPICE</span>
- </div>
-
- <div id="spice-area">
- <div id="spice-screen"
class="spice-screen"></div>
- </div>
-
- <div id="message-div"
class="spice-message"></div>
-
- <div id="debug-div">
- <!-- If DUMPXXX is turned on, dumped images will go here -->
- </div>
-
- </body>
-</html>
diff --git a/plugins/kimchi/ui/spice-html5/playback.js
b/plugins/kimchi/ui/spice-html5/playback.js
deleted file mode 100644
index 7209fbe..0000000
--- a/plugins/kimchi/ui/spice-html5/playback.js
+++ /dev/null
@@ -1,278 +0,0 @@
-"use strict";
-/*
- Copyright (C) 2014 by Jeremy P. White <jwhite(a)codeweavers.com>
-
- This file is part of spice-html5.
-
- spice-html5 is free software: you can redistribute it and/or modify
- it under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- spice-html5 is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public License
- along with spice-html5. If not, see <
http://www.gnu.org/licenses/>.
-*/
-
-/*----------------------------------------------------------------------------
-** SpicePlaybackConn
-** Drive the Spice Playback channel (sound out)
-**--------------------------------------------------------------------------*/
-function SpicePlaybackConn()
-{
- SpiceConn.apply(this, arguments);
-
- this.queue = new Array();
- this.append_okay = false;
- this.start_time = 0;
- this.skip_until = 0;
- this.gap_time = 0;
-}
-
-SpicePlaybackConn.prototype = Object.create(SpiceConn.prototype);
-SpicePlaybackConn.prototype.process_channel_message = function(msg)
-{
- if (!!!window.MediaSource)
- {
- this.log_err('MediaSource API is not available');
- return false;
- }
-
- if (msg.type == SPICE_MSG_PLAYBACK_START)
- {
- var start = new SpiceMsgPlaybackStart(msg.data);
-
- DEBUG > 0 && console.log("PlaybackStart; frequency " +
start.frequency);
-
- if (start.frequency != OPUS_FREQUENCY)
- {
- this.log_err('This player cannot handle frequency ' +
start.frequency);
- return false;
- }
-
- if (start.channels != OPUS_CHANNELS)
- {
- this.log_err('This player cannot handle ' + start.channels + '
channels');
- return false;
- }
-
- if (start.format != SPICE_AUDIO_FMT_S16)
- {
- this.log_err('This player cannot format ' + start.format);
- return false;
- }
-
- if (! this.source_buffer)
- {
- this.media_source = new MediaSource();
- this.media_source.spiceconn = this;
-
- this.audio = document.createElement("audio");
- this.audio.setAttribute('autoplay', true);
- this.audio.src = window.URL.createObjectURL(this.media_source);
- document.getElementById(this.parent.screen_id).appendChild(this.audio);
-
- this.media_source.addEventListener('sourceopen', handle_source_open,
false);
- this.media_source.addEventListener('sourceended',
handle_source_ended, false);
- this.media_source.addEventListener('sourceclosed',
handle_source_closed, false);
-
- this.bytes_written = 0;
-
- return true;
- }
- }
-
- if (msg.type == SPICE_MSG_PLAYBACK_DATA)
- {
- var data = new SpiceMsgPlaybackData(msg.data);
-
- // If this packet has the same time as the last, just bump up by one.
- if (this.last_data_time && data.time <= this.last_data_time)
- {
- // FIXME - this is arguably wrong. But delaying the transmission was worse,
- // in initial testing. Could use more research.
- DEBUG > 1 && console.log("Hacking time of " + data.time
+ " to " + this.last_data_time + 1);
- data.time = this.last_data_time + 1;
- }
-
- /* Gap detection: If there has been a delay since our last packet, then audio
must
- have paused. Handling that gets tricky. In Chrome, you can seek forward,
- but you cannot in Firefox. And seeking forward in Chrome is nice, as it
keeps
- Chrome from being overly cautious in it's buffer strategy.
-
- So we do two things. First, we seek forward. Second, we compute how much
of a gap
- there would have been, and essentially eliminate it.
- */
- if (this.last_data_time && data.time >= (this.last_data_time +
GAP_DETECTION_THRESHOLD))
- {
- this.skip_until = data.time;
- this.gap_time = (data.time - this.start_time) -
- (this.source_buffer.buffered.end(this.source_buffer.buffered.end.length -
1) * 1000.0).toFixed(0);
- }
-
- this.last_data_time = data.time;
-
-
- DEBUG > 1 && console.log("PlaybackData; time " + data.time +
"; length " + data.data.byteLength);
-
- if (! this.source_buffer)
- return true;
-
- if (this.start_time == 0)
- this.start_playback(data);
-
- else if (data.time - this.cluster_time >= MAX_CLUSTER_TIME || this.skip_until
> 0)
- this.new_cluster(data);
-
- else
- this.simple_block(data, false);
-
- if (this.skip_until > 0)
- {
- this.audio.currentTime = (this.skip_until - this.start_time - this.gap_time)
/ 1000.0;
- this.skip_until = 0;
- }
-
- if (this.audio.paused)
- this.audio.play();
-
- return true;
- }
-
- if (msg.type == SPICE_MSG_PLAYBACK_MODE)
- {
- var mode = new SpiceMsgPlaybackMode(msg.data);
- if (mode.mode != SPICE_AUDIO_DATA_MODE_OPUS)
- {
- this.log_err('This player cannot handle mode ' + mode.mode);
- delete this.source_buffer;
- }
- return true;
- }
-
- if (msg.type == SPICE_MSG_PLAYBACK_STOP)
- {
- return true;
- }
-
- return false;
-}
-
-SpicePlaybackConn.prototype.start_playback = function(data)
-{
- this.start_time = data.time;
-
- var h = new webm_Header();
-
- var mb = new ArrayBuffer(h.buffer_size())
-
- this.bytes_written = h.to_buffer(mb);
-
- this.source_buffer.addEventListener('error', handle_sourcebuffer_error,
false);
- this.source_buffer.addEventListener('updateend', handle_append_buffer_done,
false);
- playback_append_buffer(this, mb);
-
- this.new_cluster(data);
-}
-
-SpicePlaybackConn.prototype.new_cluster = function(data)
-{
- this.cluster_time = data.time;
-
- var c = new webm_Cluster(data.time - this.start_time - this.gap_time);
-
- var mb = new ArrayBuffer(c.buffer_size());
- this.bytes_written += c.to_buffer(mb);
-
- if (this.append_okay)
- playback_append_buffer(this, mb);
- else
- this.queue.push(mb);
-
- this.simple_block(data, true);
-}
-
-SpicePlaybackConn.prototype.simple_block = function(data, keyframe)
-{
- var sb = new webm_SimpleBlock(data.time - this.cluster_time, data.data, keyframe);
- var mb = new ArrayBuffer(sb.buffer_size());
-
- this.bytes_written += sb.to_buffer(mb);
-
- if (this.append_okay)
- playback_append_buffer(this, mb);
- else
- this.queue.push(mb);
-}
-
-function handle_source_open(e)
-{
- var p = this.spiceconn;
-
- if (p.source_buffer)
- return;
-
- p.source_buffer = this.addSourceBuffer(SPICE_PLAYBACK_CODEC);
- if (! p.source_buffer)
- {
- p.log_err('Codec ' + SPICE_PLAYBACK_CODEC + ' not available.');
- return;
- }
- p.source_buffer.spiceconn = p;
- p.source_buffer.mode = "segments";
-
- // FIXME - Experimentation with segments and sequences was unsatisfying.
- // Switching to sequence did not solve our gap problem,
- // but the browsers didn't fully support the time seek capability
- // we would expect to gain from 'segments'.
- // Segments worked at the time of this patch, so segments it is for now.
-
-}
-
-function handle_source_ended(e)
-{
- var p = this.spiceconn;
- p.log_err('Audio source unexpectedly ended.');
-}
-
-function handle_source_closed(e)
-{
- var p = this.spiceconn;
- p.log_err('Audio source unexpectedly closed.');
-}
-
-function handle_append_buffer_done(b)
-{
- var p = this.spiceconn;
- if (p.queue.length > 0)
- {
- var mb = p.queue.shift();
- playback_append_buffer(p, mb);
- }
- else
- p.append_okay = true;
-
-}
-
-function handle_sourcebuffer_error(e)
-{
- var p = this.spiceconn;
- p.log_err('source_buffer error ' + e.message);
-}
-
-function playback_append_buffer(p, b)
-{
- try
- {
- p.source_buffer.appendBuffer(b);
- p.append_okay = false;
- }
- catch (e)
- {
- p.log_err("Error invoking appendBuffer: " + e.message);
- }
-}
diff --git a/plugins/kimchi/ui/spice-html5/png.js b/plugins/kimchi/ui/spice-html5/png.js
deleted file mode 100644
index 6a26151..0000000
--- a/plugins/kimchi/ui/spice-html5/png.js
+++ /dev/null
@@ -1,256 +0,0 @@
-"use strict";
-/*
- Copyright (C) 2012 by Jeremy P. White <jwhite(a)codeweavers.com>
-
- This file is part of spice-html5.
-
- spice-html5 is free software: you can redistribute it and/or modify
- it under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- spice-html5 is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public License
- along with spice-html5. If not, see <
http://www.gnu.org/licenses/>.
-*/
-
-/*----------------------------------------------------------------------------
-** crc logic from rfc2083 ported to Javascript
-**--------------------------------------------------------------------------*/
-
-var rfc2083_crc_table = Array(256);
-var rfc2083_crc_table_computed = 0;
-/* Make the table for a fast CRC. */
-function rfc2083_make_crc_table()
-{
- var c;
- var n, k;
- for (n = 0; n < 256; n++)
- {
- c = n;
- for (k = 0; k < 8; k++)
- {
- if (c & 1)
- c = ((0xedb88320 ^ (c >>> 1)) >>> 0) & 0xffffffff;
- else
- c = c >>> 1;
- }
- rfc2083_crc_table[n] = c;
- }
-
- rfc2083_crc_table_computed = 1;
-}
-
-/* Update a running CRC with the bytes buf[0..len-1]--the CRC
- should be initialized to all 1's, and the transmitted value
- is the 1's complement of the final running CRC (see the
- crc() routine below)). */
-
-function rfc2083_update_crc(crc, u8buf, at, len)
-{
- var c = crc;
- var n;
-
- if (!rfc2083_crc_table_computed)
- rfc2083_make_crc_table();
-
- for (n = 0; n < len; n++)
- {
- c = rfc2083_crc_table[(c ^ u8buf[at + n]) & 0xff] ^ (c >>> 8);
- }
-
- return c;
-}
-
-function rfc2083_crc(u8buf, at, len)
-{
- return rfc2083_update_crc(0xffffffff, u8buf, at, len) ^ 0xffffffff;
-}
-
-function crc32(mb, at, len)
-{
- var u8 = new Uint8Array(mb);
- return rfc2083_crc(u8, at, len);
-}
-
-function PngIHDR(width, height)
-{
- this.width = width;
- this.height = height;
- this.depth = 8;
- this.type = 6;
- this.compression = 0;
- this.filter = 0;
- this.interlace = 0;
-}
-
-PngIHDR.prototype =
-{
- to_buffer: function(a, at)
- {
- at = at || 0;
- var orig = at;
- var dv = new SpiceDataView(a);
- dv.setUint32(at, this.buffer_size() - 12); at += 4;
- dv.setUint8(at, 'I'.charCodeAt(0)); at++;
- dv.setUint8(at, 'H'.charCodeAt(0)); at++;
- dv.setUint8(at, 'D'.charCodeAt(0)); at++;
- dv.setUint8(at, 'R'.charCodeAt(0)); at++;
- dv.setUint32(at, this.width); at += 4;
- dv.setUint32(at, this.height); at += 4;
- dv.setUint8(at, this.depth); at++;
- dv.setUint8(at, this.type); at++;
- dv.setUint8(at, this.compression); at++;
- dv.setUint8(at, this.filter); at++;
- dv.setUint8(at, this.interlace); at++;
- dv.setUint32(at, crc32(a, orig + 4, this.buffer_size() - 8)); at += 4;
- return at;
- },
- buffer_size: function()
- {
- return 12 + 13;
- }
-}
-
-
-function adler()
-{
- this.s1 = 1;
- this.s2 = 0;
-}
-
-adler.prototype.update = function(b)
-{
- this.s1 += b;
- this.s1 %= 65521;
- this.s2 += this.s1;
- this.s2 %= 65521;
-}
-
-function PngIDAT(width, height, bytes)
-{
- if (bytes.byteLength > 65535)
- {
- throw new Error("Cannot handle more than 64K");
- }
- this.data = bytes;
- this.width = width;
- this.height = height;
-}
-
-PngIDAT.prototype =
-{
- to_buffer: function(a, at)
- {
- at = at || 0;
- var orig = at;
- var x, y, i, j;
- var dv = new SpiceDataView(a);
- var zsum = new adler();
- dv.setUint32(at, this.buffer_size() - 12); at += 4;
- dv.setUint8(at, 'I'.charCodeAt(0)); at++;
- dv.setUint8(at, 'D'.charCodeAt(0)); at++;
- dv.setUint8(at, 'A'.charCodeAt(0)); at++;
- dv.setUint8(at, 'T'.charCodeAt(0)); at++;
-
- /* zlib header. */
- dv.setUint8(at, 0x78); at++;
- dv.setUint8(at, 0x01); at++;
-
- /* Deflate header. Specifies uncompressed, final bit */
- dv.setUint8(at, 0x80); at++;
- dv.setUint16(at, this.data.byteLength + this.height); at += 2;
- dv.setUint16(at, ~(this.data.byteLength + this.height)); at += 2;
- var u8 = new Uint8Array(this.data);
- for (i = 0, y = 0; y < this.height; y++)
- {
- /* Filter type 0 - uncompressed */
- dv.setUint8(at, 0); at++;
- zsum.update(0);
- for (x = 0; x < this.width && i < this.data.byteLength; x++)
- {
- zsum.update(u8[i]);
- dv.setUint8(at, u8[i++]); at++;
- zsum.update(u8[i]);
- dv.setUint8(at, u8[i++]); at++;
- zsum.update(u8[i]);
- dv.setUint8(at, u8[i++]); at++;
- zsum.update(u8[i]);
- dv.setUint8(at, u8[i++]); at++;
- }
- }
-
- /* zlib checksum. */
- dv.setUint16(at, zsum.s2); at+=2;
- dv.setUint16(at, zsum.s1); at+=2;
-
- /* FIXME - something is not quite right with the zlib code;
- you get an error from libpng if you open the image in
- gimp. But it works, so it's good enough for now... */
-
- dv.setUint32(at, crc32(a, orig + 4, this.buffer_size() - 8)); at += 4;
- return at;
- },
- buffer_size: function()
- {
- return 12 + this.data.byteLength + this.height + 4 + 2 + 1 + 2 + 2;
- }
-}
-
-
-function PngIEND()
-{
-}
-
-PngIEND.prototype =
-{
- to_buffer: function(a, at)
- {
- at = at || 0;
- var orig = at;
- var i;
- var dv = new SpiceDataView(a);
- dv.setUint32(at, this.buffer_size() - 12); at += 4;
- dv.setUint8(at, 'I'.charCodeAt(0)); at++;
- dv.setUint8(at, 'E'.charCodeAt(0)); at++;
- dv.setUint8(at, 'N'.charCodeAt(0)); at++;
- dv.setUint8(at, 'D'.charCodeAt(0)); at++;
- dv.setUint32(at, crc32(a, orig + 4, this.buffer_size() - 8)); at += 4;
- return at;
- },
- buffer_size: function()
- {
- return 12;
- }
-}
-
-
-function create_rgba_png(width, height, bytes)
-{
- var i;
- var ihdr = new PngIHDR(width, height);
- var idat = new PngIDAT(width, height, bytes);
- var iend = new PngIEND;
-
- var mb = new ArrayBuffer(ihdr.buffer_size() + idat.buffer_size() +
iend.buffer_size());
- var at = ihdr.to_buffer(mb);
- at = idat.to_buffer(mb, at);
- at = iend.to_buffer(mb, at);
-
- var u8 = new Uint8Array(mb);
- var str = "";
- for (i = 0; i < at; i++)
- {
- str += "%";
- if (u8[i] < 16)
- str += "0";
- str += u8[i].toString(16);
- }
-
-
- return "%89PNG%0D%0A%1A%0A" + str;
-}
diff --git a/plugins/kimchi/ui/spice-html5/quic.js
b/plugins/kimchi/ui/spice-html5/quic.js
deleted file mode 100644
index 9bb9f47..0000000
--- a/plugins/kimchi/ui/spice-html5/quic.js
+++ /dev/null
@@ -1,1335 +0,0 @@
-/*"use strict";*/
-/* use strict is commented out because it results in a 5x slowdone in chrome */
-/*
- * Copyright (C) 2012 by Jeremy P. White <jwhite(a)codeweavers.com>
- * Copyright (C) 2012 by Aric Stewart <aric(a)codeweavers.com>
- *
- * This file is part of spice-html5.
- *
- * spice-html5 is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * spice-html5 is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with spice-html5. If not, see <
http://www.gnu.org/licenses/>.
- */
-
-var encoder;
-
-var QUIC_IMAGE_TYPE_INVALID = 0;
-var QUIC_IMAGE_TYPE_GRAY = 1;
-var QUIC_IMAGE_TYPE_RGB16 = 2;
-var QUIC_IMAGE_TYPE_RGB24 = 3;
-var QUIC_IMAGE_TYPE_RGB32 = 4;
-var QUIC_IMAGE_TYPE_RGBA = 5;
-var DEFevol = 3;
-var DEFwmimax = 6;
-var DEFwminext = 2048;
-var need_init = true;
-var DEFmaxclen = 26;
-var evol = DEFevol;
-var wmimax = DEFwmimax;
-var wminext = DEFwminext;
-var family_5bpc = { nGRcodewords:[0,0,0,0,0,0,0,0],
- notGRcwlen:[0,0,0,0,0,0,0,0],
- notGRprefixmask:[0,0,0,0,0,0,0,0],
- notGRsuffixlen:[0,0,0,0,0,0,0,0],
- xlatU2L:[0,0,0,0,0,0,0,0],
- xlatL2U:[0,0,0,0,0,0,0,0]
- };
-var family_8bpc = { nGRcodewords:[0,0,0,0,0,0,0,0],
- notGRcwlen:[0,0,0,0,0,0,0,0],
- notGRprefixmask:[0,0,0,0,0,0,0,0],
- notGRsuffixlen:[0,0,0,0,0,0,0,0],
- xlatU2L:[0,0,0,0,0,0,0,0],
- xlatL2U:[0,0,0,0,0,0,0,0]
- };
-var bppmask = [ 0x00000000,
- 0x00000001, 0x00000003, 0x00000007, 0x0000000f,
- 0x0000001f, 0x0000003f, 0x0000007f, 0x000000ff,
- 0x000001ff, 0x000003ff, 0x000007ff, 0x00000fff,
- 0x00001fff, 0x00003fff, 0x00007fff, 0x0000ffff,
- 0x0001ffff, 0x0003ffff, 0x0007ffff, 0x000fffff,
- 0x001fffff, 0x003fffff, 0x007fffff, 0x00ffffff,
- 0x01ffffff, 0x03ffffff, 0x07ffffff, 0x0fffffff,
- 0x1fffffff, 0x3fffffff, 0x7fffffff, 0xffffffff];
-
-var zeroLUT = [];
-
-var besttrigtab = [
- [ 550, 900, 800, 700, 500, 350, 300, 200, 180, 180, 160],
- [ 110, 550, 900, 800, 550, 400, 350, 250, 140, 160, 140],
- [ 100, 120, 550, 900, 700, 500, 400, 300, 220, 250, 160]];
-
-var J = [ 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 5, 5, 6, 6,
- 7, 7, 8, 9, 10, 11, 12, 13, 14, 15];
-
-var lzeroes = [
- 8, 7, 6, 6, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4, 3, 3, 3, 3, 3, 3, 3, 3, 3,
- 3, 3, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0];
-
-var tabrand_chaos = [
- 0x02c57542, 0x35427717, 0x2f5a2153, 0x9244f155, 0x7bd26d07, 0x354c6052,
- 0x57329b28, 0x2993868e, 0x6cd8808c, 0x147b46e0, 0x99db66af, 0xe32b4cac,
- 0x1b671264, 0x9d433486, 0x62a4c192, 0x06089a4b, 0x9e3dce44, 0xdaabee13,
- 0x222425ea, 0xa46f331d, 0xcd589250, 0x8bb81d7f, 0xc8b736b9, 0x35948d33,
- 0xd7ac7fd0, 0x5fbe2803, 0x2cfbc105, 0x013dbc4e, 0x7a37820f, 0x39f88e9e,
- 0xedd58794, 0xc5076689, 0xfcada5a4, 0x64c2f46d, 0xb3ba3243, 0x8974b4f9,
- 0x5a05aebd, 0x20afcd00, 0x39e2b008, 0x88a18a45, 0x600bde29, 0xf3971ace,
- 0xf37b0a6b, 0x7041495b, 0x70b707ab, 0x06beffbb, 0x4206051f, 0xe13c4ee3,
- 0xc1a78327, 0x91aa067c, 0x8295f72a, 0x732917a6, 0x1d871b4d, 0x4048f136,
- 0xf1840e7e, 0x6a6048c1, 0x696cb71a, 0x7ff501c3, 0x0fc6310b, 0x57e0f83d,
- 0x8cc26e74, 0x11a525a2, 0x946934c7, 0x7cd888f0, 0x8f9d8604, 0x4f86e73b,
- 0x04520316, 0xdeeea20c, 0xf1def496, 0x67687288, 0xf540c5b2, 0x22401484,
- 0x3478658a, 0xc2385746, 0x01979c2c, 0x5dad73c8, 0x0321f58b, 0xf0fedbee,
- 0x92826ddf, 0x284bec73, 0x5b1a1975, 0x03df1e11, 0x20963e01, 0xa17cf12b,
- 0x740d776e, 0xa7a6bf3c, 0x01b5cce4, 0x1118aa76, 0xfc6fac0a, 0xce927e9b,
- 0x00bf2567, 0x806f216c, 0xbca69056, 0x795bd3e9, 0xc9dc4557, 0x8929b6c2,
- 0x789d52ec, 0x3f3fbf40, 0xb9197368, 0xa38c15b5, 0xc3b44fa8, 0xca8333b0,
- 0xb7e8d590, 0xbe807feb, 0xbf5f8360, 0xd99e2f5c, 0x372928e1, 0x7c757c4c,
- 0x0db5b154, 0xc01ede02, 0x1fc86e78, 0x1f3985be, 0xb4805c77, 0x00c880fa,
- 0x974c1b12, 0x35ab0214, 0xb2dc840d, 0x5b00ae37, 0xd313b026, 0xb260969d,
- 0x7f4c8879, 0x1734c4d3, 0x49068631, 0xb9f6a021, 0x6b863e6f, 0xcee5debf,
- 0x29f8c9fb, 0x53dd6880, 0x72b61223, 0x1f67a9fd, 0x0a0f6993, 0x13e59119,
- 0x11cca12e, 0xfe6b6766, 0x16b6effc, 0x97918fc4, 0xc2b8a563, 0x94f2f741,
- 0x0bfa8c9a, 0xd1537ae8, 0xc1da349c, 0x873c60ca, 0x95005b85, 0x9b5c080e,
- 0xbc8abbd9, 0xe1eab1d2, 0x6dac9070, 0x4ea9ebf1, 0xe0cf30d4, 0x1ef5bd7b,
- 0xd161043e, 0x5d2fa2e2, 0xff5d3cae, 0x86ed9f87, 0x2aa1daa1, 0xbd731a34,
- 0x9e8f4b22, 0xb1c2c67a, 0xc21758c9, 0xa182215d, 0xccb01948, 0x8d168df7,
- 0x04238cfe, 0x368c3dbc, 0x0aeadca5, 0xbad21c24, 0x0a71fee5, 0x9fc5d872,
- 0x54c152c6, 0xfc329483, 0x6783384a, 0xeddb3e1c, 0x65f90e30, 0x884ad098,
- 0xce81675a, 0x4b372f7d, 0x68bf9a39, 0x43445f1e, 0x40f8d8cb, 0x90d5acb6,
- 0x4cd07282, 0x349eeb06, 0x0c9d5332, 0x520b24ef, 0x80020447, 0x67976491,
- 0x2f931ca3, 0xfe9b0535, 0xfcd30220, 0x61a9e6cc, 0xa487d8d7, 0x3f7c5dd1,
- 0x7d0127c5, 0x48f51d15, 0x60dea871, 0xc9a91cb7, 0x58b53bb3, 0x9d5e0b2d,
- 0x624a78b4, 0x30dbee1b, 0x9bdf22e7, 0x1df5c299, 0x2d5643a7, 0xf4dd35ff,
- 0x03ca8fd6, 0x53b47ed8, 0x6f2c19aa, 0xfeb0c1f4, 0x49e54438, 0x2f2577e6,
- 0xbf876969, 0x72440ea9, 0xfa0bafb8, 0x74f5b3a0, 0x7dd357cd, 0x89ce1358,
- 0x6ef2cdda, 0x1e7767f3, 0xa6be9fdb, 0x4f5f88f8, 0xba994a3a, 0x08ca6b65,
- 0xe0893818, 0x9e00a16a, 0xf42bfc8f, 0x9972eedc, 0x749c8b51, 0x32c05f5e,
- 0xd706805f, 0x6bfbb7cf, 0xd9210a10, 0x31a1db97, 0x923a9559, 0x37a7a1f6,
- 0x059f8861, 0xca493e62, 0x65157e81, 0x8f6467dd, 0xab85ff9f, 0x9331aff2,
- 0x8616b9f5, 0xedbd5695, 0xee7e29b1, 0x313ac44f, 0xb903112f, 0x432ef649,
- 0xdc0a36c0, 0x61cf2bba, 0x81474925, 0xa8b6c7ad, 0xee5931de, 0xb2f8158d,
- 0x59fb7409, 0x2e3dfaed, 0x9af25a3f, 0xe1fed4d5 ];
-
-var rgb32_pixel_pad = 3;
-var rgb32_pixel_r = 2;
-var rgb32_pixel_g = 1;
-var rgb32_pixel_b = 0;
-var rgb32_pixel_size = 4;
-
-/* Helper Functions */
-
-function ceil_log_2(val)
-{
- if (val === 1)
- return 0;
-
- var result = 1;
- val -= 1;
- while (val = val >>> 1)
- result++;
-
- return result;
-}
-
-function family_init(family, bpc, limit)
-{
- var l;
- for (l = 0; l < bpc; l++)
- {
- var altprefixlen, altcodewords;
- altprefixlen = limit - bpc;
- if (altprefixlen > bppmask[bpc - l])
- altprefixlen = bppmask[bpc - l];
-
- altcodewords = bppmask[bpc] + 1 - (altprefixlen << l);
- family.nGRcodewords[l] = (altprefixlen << l);
- family.notGRcwlen[l] = altprefixlen + ceil_log_2(altcodewords);
- family.notGRprefixmask[l] = bppmask[32 - altprefixlen]>>>0;
- family.notGRsuffixlen[l] = ceil_log_2(altcodewords);
- }
-
- /* decorelate_init */
- var pixelbitmask = bppmask[bpc];
- var pixelbitmaskshr = pixelbitmask >>> 1;
- var s;
- for (s = 0; s <= pixelbitmask; s++) {
- if (s <= pixelbitmaskshr) {
- family.xlatU2L[s] = s << 1;
- } else {
- family.xlatU2L[s] = ((pixelbitmask - s) << 1) + 1;
- }
- }
-
- /* corelate_init */
- for (s = 0; s <= pixelbitmask; s++) {
- if (s & 0x01) {
- family.xlatL2U[s] = pixelbitmask - (s >>> 1);
- } else {
- family.xlatL2U[s] = (s >>> 1);
- }
- }
-}
-
-function quic_image_bpc(type)
-{
- switch (type) {
- case QUIC_IMAGE_TYPE_GRAY:
- return 8;
- case QUIC_IMAGE_TYPE_RGB16:
- return 5;
- case QUIC_IMAGE_TYPE_RGB24:
- return 8;
- case QUIC_IMAGE_TYPE_RGB32:
- return 8;
- case QUIC_IMAGE_TYPE_RGBA:
- return 8;
- case QUIC_IMAGE_TYPE_INVALID:
- default:
- console.log("quic: bad image type\n");
- return 0;
- }
-}
-
-function cnt_l_zeroes(bits)
-{
- if (bits & 0xff800000) {
- return lzeroes[bits >>> 24];
- } else if (bits & 0xffff8000) {
- return 8 + lzeroes[(bits >>> 16) & 0x000000ff];
- } else if (bits & 0xffffff80) {
- return 16 + lzeroes[(bits >>> 8) & 0x000000ff];
- } else {
- return 24 + lzeroes[bits & 0x000000ff];
- }
-}
-
-function golomb_decoding_8bpc(l, bits)
-{
- var rc;
- var cwlen;
-
- if (bits < 0 || bits > family_8bpc.notGRprefixmask[l])
- {
- var zeroprefix = cnt_l_zeroes(bits);
- cwlen = zeroprefix + 1 + l;
- rc = (zeroprefix << l) | (bits >> (32-cwlen)) & bppmask[l];
- }
- else
- {
- cwlen = family_8bpc.notGRcwlen[l];
- rc = family_8bpc.nGRcodewords[l] + ((bits >> (32-cwlen)) &
bppmask[family_8bpc.notGRsuffixlen[l]]);
- }
- return {'codewordlen':cwlen, 'rc':rc};
-}
-
-function golomb_code_len_8bpc(n, l)
-{
- if (n < family_8bpc.nGRcodewords[l]) {
- return (n >>> l) + 1 + l;
- } else {
- return family_8bpc.notGRcwlen[l];
- }
-}
-
-function QuicModel(bpc)
-{
- var bstart;
- var bend = 0;
-
- this.levels = 0x1 << bpc;
- this.n_buckets_ptrs = 0;
-
- switch (evol) {
- case 1:
- this.repfirst = 3;
- this.firstsize = 1;
- this.repnext = 2;
- this.mulsize = 2;
- break;
- case 3:
- this.repfirst = 1;
- this.firstsize = 1;
- this.repnext = 1;
- this.mulsize = 2;
- break;
- case 5:
- this.repfirst = 1;
- this.firstsize = 1;
- this.repnext = 1;
- this.mulsize = 4;
- break;
- case 0:
- case 2:
- case 4:
- console.log("quic: findmodelparams(): evol value obsolete!!!\n");
- default:
- console.log("quic: findmodelparams(): evol out of range!!!\n");
- }
-
- this.n_buckets = 0;
- var repcntr = this.repfirst + 1;
- var bsize = this.firstsize;
-
- do {
- if (this.n_buckets) {
- bstart = bend + 1;
- } else {
- bstart = 0;
- }
-
- if (!--repcntr) {
- repcntr = this.repnext;
- bsize *= this.mulsize;
- }
-
- bend = bstart + bsize - 1;
- if (bend + bsize >= this.levels) {
- bend = this.levels - 1;
- }
-
- if (!this.n_buckets_ptrs) {
- this.n_buckets_ptrs = this.levels;
- }
-
- (this.n_buckets)++;
- } while (bend < this.levels - 1);
-}
-
-QuicModel.prototype = {
- n_buckets : 0,
- n_buckets_ptrs : 0,
- repfirst : 0,
- firstsize : 0,
- repnext : 0,
- mulsize : 0,
- levels :0
-}
-
-function QuicBucket()
-{
- this.counters = [0,0,0,0,0,0,0,0];
-}
-
-QuicBucket.prototype = {
- bestcode: 0,
-
- reste : function (bpp)
- {
- this.bestcode = bpp;
- this.counters = [0,0,0,0,0,0,0,0];
- },
-
- update_model_8bpc : function (state, curval, bpp)
- {
- var i;
-
- var bestcode = bpp - 1;
- var bestcodelen = (this.counters[bestcode] += golomb_code_len_8bpc(curval,
bestcode));
-
- for (i = bpp - 2; i >= 0; i--) {
- var ithcodelen = (this.counters[i] += golomb_code_len_8bpc(curval, i));
-
- if (ithcodelen < bestcodelen) {
- bestcode = i;
- bestcodelen = ithcodelen;
- }
- }
-
- this.bestcode = bestcode;
-
- if (bestcodelen > state.wm_trigger) {
- for (i = 0; i < bpp; i++) {
- this.counters[i] = this.counters[i] >>> 1;
- }
- }
- }
-}
-
-function QuicFamilyStat()
-{
- this.buckets_ptrs = [];
- this.buckets_buf = [];
-}
-
-QuicFamilyStat.prototype = {
-
- fill_model_structures : function(model)
- {
- var bstart;
- var bend = 0;
- var bnumber = 0;
-
- var repcntr = model.repfirst + 1;
- var bsize = model.firstsize;
-
- do {
- if (bnumber) {
- bstart = bend + 1;
- } else {
- bstart = 0;
- }
-
- if (!--repcntr) {
- repcntr = model.repnext;
- bsize *= model.mulsize;
- }
-
- bend = bstart + bsize - 1;
- if (bend + bsize >= model.levels) {
- bend = model.levels - 1;
- }
-
- this.buckets_buf[bnumber] = new QuicBucket;
-
- var i;
- for (i = bstart; i <= bend; i++) {
- this.buckets_ptrs[i] = this.buckets_buf[bnumber];
- }
-
- bnumber++;
- } while (bend < model.levels - 1);
- return true;
- }
-}
-
-function QuicChannel(model_8bpc, model_5bpc)
-{
- this.state = new CommonState;
- this.family_stat_8bpc = new QuicFamilyStat;
- this.family_stat_5bpc = new QuicFamilyStat;
- this.correlate_row = { zero: 0 , row:[] };
- this.model_8bpc = model_8bpc;
- this.model_5bpc = model_5bpc;
- this.buckets_ptrs = [];
-
- if (!this.family_stat_8bpc.fill_model_structures(this.model_8bpc))
- return undefined;
-
- if (!this.family_stat_5bpc.fill_model_structures(this.model_5bpc))
- return undefined;
-}
-
-QuicChannel.prototype = {
-
- reste : function (bpc)
- {
- var j;
- this.correlate_row = { zero: 0 , row: []};
-
- if (bpc == 8) {
- for (j = 0; j < this.model_8bpc.n_buckets; j++)
- this.family_stat_8bpc.buckets_buf[j].reste(7);
- this.buckets_ptrs = this.family_stat_8bpc.buckets_ptrs;
- } else if (bpc == 5) {
- for (j = 0; j < this.model_5bpc.n_buckets; j++)
- this.family_stat_8bpc.buckets_buf[j].reste(4);
- this.buckets_ptrs = this.family_stat_5bpc.buckets_ptrs;
- } else {
- console.log("quic: %s: bad bpc %d\n", __FUNCTION__, bpc);
- return false;
- }
-
- this.state.reste();
- return true;
- }
-}
-
-function CommonState()
-{
-}
-
-CommonState.prototype = {
- waitcnt: 0,
- tabrand_seed: 0xff,
- wm_trigger: 0,
- wmidx: 0,
- wmileft: wminext,
- melcstate: 0,
- melclen: 0,
- melcorder: 0,
-
- set_wm_trigger : function()
- {
- var wm = this.wmidx;
- if (wm > 10) {
- wm = 10;
- }
-
- this.wm_trigger = besttrigtab[Math.floor(evol / 2)][wm];
- },
-
- reste : function()
- {
- this.waitcnt = 0;
- this.tabrand_seed = 0x0ff;
- this.wmidx = 0;
- this.wmileft = wminext;
-
- this.set_wm_trigger();
-
- this.melcstate = 0;
- this.melclen = J[0];
- this.melcorder = 1 << this.melclen;
- },
-
- tabrand : function()
- {
- this.tabrand_seed++;
- return tabrand_chaos[this.tabrand_seed & 0x0ff];
- }
-}
-
-
-function QuicEncoder()
-{
- this.rgb_state = new CommonState;
- this.model_8bpc = new QuicModel(8);
- this.model_5bpc = new QuicModel(5);
- this.channels = [];
-
- var i;
- for (i = 0; i < 4; i++) {
- this.channels[i] = new QuicChannel(this.model_8bpc, this.model_5bpc);
- if (!this.channels[i])
- {
- console.log("quic: failed to create channel");
- return undefined;
- }
- }
-}
-
-QuicEncoder.prototype = {
- type: 0,
- width: 0,
- height: 0,
- io_idx: 0,
- io_available_bits: 0,
- io_word: 0,
- io_next_word: 0,
- io_now: 0,
- io_end: 0,
- rows_completed: 0,
- };
-
-QuicEncoder.prototype.reste = function(io_ptr)
-{
- this.rgb_state.reste();
-
- this.io_now = io_ptr;
- this.io_end = this.io_now.length;
- this.io_idx = 0;
- this.rows_completed = 0;
- return true;
-}
-
-QuicEncoder.prototype.read_io_word = function()
-{
- if (this.io_idx >= this.io_end)
- throw("quic: out of data");
- this.io_next_word = this.io_now[this.io_idx++] | this.io_now[this.io_idx++]<<8
| this.io_now[this.io_idx++]<<16 | this.io_now[this.io_idx++]<<24;
-}
-
-QuicEncoder.prototype.decode_eatbits = function (len)
-{
- this.io_word = this.io_word << len;
-
- var delta = (this.io_available_bits - len);
- if (delta >= 0)
- {
- this.io_available_bits = delta;
- this.io_word |= this.io_next_word >>> this.io_available_bits;
- }
- else
- {
- delta = -1 * delta;
- this.io_word |= this.io_next_word << delta;
- this.read_io_word();
- this.io_available_bits = 32 - delta;
- this.io_word |= this.io_next_word >>> this.io_available_bits;
- }
-}
-
-QuicEncoder.prototype.decode_eat32bits = function()
-{
- this.decode_eatbits(16);
- this.decode_eatbits(16);
-}
-
-QuicEncoder.prototype.reste_channels = function(bpc)
-{
- var i;
-
- for (i = 0; i < 4; i++)
- if (!this.channels[i].reste(bpc))
- return false;
- return true;
-}
-
-QuicEncoder.prototype.quic_decode_begin = function(io_ptr)
-{
- if (!this.reste(io_ptr)) {
- return false;
- }
-
- this.io_idx = 0;
- this.io_next_word = this.io_now[this.io_idx++] | this.io_now[this.io_idx++]<<8
| this.io_now[this.io_idx++]<<16 | this.io_now[this.io_idx++]<<24;
- this.io_word = this.io_next_word;
- this.io_available_bits = 0;
-
- var magic = this.io_word;
- this.decode_eat32bits();
- if (magic != 0x43495551) /*QUIC*/ {
- console.log("quic: bad magic "+magic.toString(16));
- return false;
- }
-
- var version = this.io_word;
- this.decode_eat32bits();
- if (version != ((0 << 16) | (0 & 0xffff))) {
- console.log("quic: bad version "+version.toString(16));
- return false;
- }
-
- this.type = this.io_word;
- this.decode_eat32bits();
-
- this.width = this.io_word;
- this.decode_eat32bits();
-
- this.height = this.io_word;
- this.decode_eat32bits();
-
- var bpc = quic_image_bpc(this.type);
-
- if (!this.reste_channels(bpc))
- return false;
-
- return true;
-}
-
-QuicEncoder.prototype.quic_rgb32_uncompress_row0_seg = function (i, cur_row, end,
- waitmask, bpc, bpc_mask)
-{
- var stopidx;
- var n_channels = 3;
- var c;
- var a;
-
- if (!i) {
- cur_row[rgb32_pixel_pad] = 0;
- c = 0;
- do
- {
- a =
golomb_decoding_8bpc(this.channels[c].buckets_ptrs[this.channels[c].correlate_row.zero].bestcode,
this.io_word);
- this.channels[c].correlate_row.row[0] = a.rc;
- cur_row[2-c] = (family_8bpc.xlatL2U[a.rc]&0xFF);
- this.decode_eatbits(a.codewordlen);
- } while (++c < n_channels);
-
- if (this.rgb_state.waitcnt) {
- --this.rgb_state.waitcnt;
- } else {
- this.rgb_state.waitcnt = (this.rgb_state.tabrand() & waitmask);
- c = 0;
- do
- {
-
this.channels[c].buckets_ptrs[this.channels[c].correlate_row.zero].update_model_8bpc(this.rgb_state,
this.channels[c].correlate_row.row[0], bpc);
- } while (++c < n_channels);
- }
- stopidx = ++i + this.rgb_state.waitcnt;
- } else {
- stopidx = i + this.rgb_state.waitcnt;
- }
-
- while (stopidx < end) {
- for (; i <= stopidx; i++) {
- cur_row[(i* rgb32_pixel_size)+rgb32_pixel_pad] = 0;
- c = 0;
- do
- {
- a =
golomb_decoding_8bpc(this.channels[c].buckets_ptrs[this.channels[c].correlate_row.row[i -
1]].bestcode, this.io_word);
- this.channels[c].correlate_row.row[i] = a.rc;
- cur_row[(i* rgb32_pixel_size)+(2-c)] = (family_8bpc.xlatL2U[a.rc] +
cur_row[((i-1) * rgb32_pixel_size) + (2-c)]) & bpc_mask;
- this.decode_eatbits(a.codewordlen);
- } while (++c < n_channels);
- }
- c = 0;
- do
- {
- this.channels[c].buckets_ptrs[this.channels[c].correlate_row.row[stopidx -
1]].update_model_8bpc(this.rgb_state, this.channels[c].correlate_row.row[stopidx], bpc);
- } while (++c < n_channels);
- stopidx = i + (this.rgb_state.tabrand() & waitmask);
- }
-
- for (; i < end; i++) {
- cur_row[(i* rgb32_pixel_size)+rgb32_pixel_pad] = 0;
- c = 0;
- do
- {
- a =
golomb_decoding_8bpc(this.channels[c].buckets_ptrs[this.channels[c].correlate_row.row[i -
1]].bestcode, this.io_word);
- this.channels[c].correlate_row.row[i] = a.rc;
- cur_row[(i* rgb32_pixel_size)+(2-c)] = (family_8bpc.xlatL2U[a.rc] +
cur_row[((i-1) * rgb32_pixel_size) + (2-c)]) & bpc_mask;
- this.decode_eatbits(a.codewordlen);
- } while (++c < n_channels);
- }
- this.rgb_state.waitcnt = stopidx - end;
-}
-
-QuicEncoder.prototype.quic_rgb32_uncompress_row0 = function (cur_row)
-{
- var bpc = 8;
- var bpc_mask = 0xff;
- var pos = 0;
- var width = this.width;
-
- while ((wmimax > this.rgb_state.wmidx) && (this.rgb_state.wmileft <=
width)) {
- if (this.rgb_state.wmileft) {
- this.quic_rgb32_uncompress_row0_seg(pos, cur_row,
- pos + this.rgb_state.wmileft,
- bppmask[this.rgb_state.wmidx],
- bpc, bpc_mask);
- pos += this.rgb_state.wmileft;
- width -= this.rgb_state.wmileft;
- }
-
- this.rgb_state.wmidx++;
- this.rgb_state.set_wm_trigger();
- this.rgb_state.wmileft = wminext;
- }
-
- if (width) {
- this.quic_rgb32_uncompress_row0_seg(pos, cur_row, pos + width,
- bppmask[this.rgb_state.wmidx], bpc, bpc_mask);
- if (wmimax > this.rgb_state.wmidx) {
- this.rgb_state.wmileft -= width;
- }
- }
-}
-
-QuicEncoder.prototype.quic_rgb32_uncompress_row_seg = function( prev_row, cur_row, i,
end, bpc, bpc_mask)
-{
- var n_channels = 3;
- var waitmask = bppmask[this.rgb_state.wmidx];
-
- var a;
- var run_index = 0;
- var stopidx = 0;
- var run_end = 0;
- var c;
-
- if (!i)
- {
- cur_row[rgb32_pixel_pad] = 0;
-
- c = 0;
- do {
- a =
golomb_decoding_8bpc(this.channels[c].buckets_ptrs[this.channels[c].correlate_row.zero].bestcode,
this.io_word);
- this.channels[c].correlate_row.row[0] = a.rc;
- cur_row[2-c] = (family_8bpc.xlatL2U[this.channels[c].correlate_row.row[0]] +
prev_row[2-c]) & bpc_mask;
- this.decode_eatbits(a.codewordlen);
- } while (++c < n_channels);
-
- if (this.rgb_state.waitcnt) {
- --this.rgb_state.waitcnt;
- } else {
- this.rgb_state.waitcnt = (this.rgb_state.tabrand() & waitmask);
- c = 0;
- do {
-
this.channels[c].buckets_ptrs[this.channels[c].correlate_row.zero].update_model_8bpc(this.rgb_state,
this.channels[c].correlate_row.row[0], bpc);
- } while (++c < n_channels);
- }
- stopidx = ++i + this.rgb_state.waitcnt;
- } else {
- stopidx = i + this.rgb_state.waitcnt;
- }
- for (;;) {
- var rc = 0;
- while (stopidx < end && !rc) {
- for (; i <= stopidx && !rc; i++) {
- var pixel = i * rgb32_pixel_size;
- var pixelm1 = (i-1) * rgb32_pixel_size;
- var pixelm2 = (i-2) * rgb32_pixel_size;
-
- if ( prev_row[pixelm1+rgb32_pixel_r] == prev_row[pixel+rgb32_pixel_r]
&& prev_row[pixelm1+rgb32_pixel_g] == prev_row[pixel+rgb32_pixel_g] &&
prev_row[pixelm1 + rgb32_pixel_b] == prev_row[pixel+rgb32_pixel_b])
- {
- if (run_index != i && i > 2 &&
(cur_row[pixelm1+rgb32_pixel_r] == cur_row[pixelm2+rgb32_pixel_r] &&
cur_row[pixelm1+rgb32_pixel_g] == cur_row[pixelm2+rgb32_pixel_g] &&
cur_row[pixelm1+rgb32_pixel_b] == cur_row[pixelm2+rgb32_pixel_b]))
- {
- /* do run */
- this.rgb_state.waitcnt = stopidx - i;
- run_index = i;
- run_end = i + this.decode_run(this.rgb_state);
-
- for (; i < run_end; i++) {
- var pixel = i * rgb32_pixel_size;
- var pixelm1 = (i-1) * rgb32_pixel_size;
- cur_row[pixel+rgb32_pixel_pad] = 0;
- cur_row[pixel+rgb32_pixel_r] =
cur_row[pixelm1+rgb32_pixel_r];
- cur_row[pixel+rgb32_pixel_g] =
cur_row[pixelm1+rgb32_pixel_g];
- cur_row[pixel+rgb32_pixel_b] =
cur_row[pixelm1+rgb32_pixel_b];
- }
-
- if (i == end) {
- return;
- }
- else
- {
- stopidx = i + this.rgb_state.waitcnt;
- rc = 1;
- break;
- }
- }
- }
-
- c = 0;
- cur_row[pixel+rgb32_pixel_pad] = 0;
- do {
- var cc = this.channels[c];
- var cr = cc.correlate_row;
-
- a = golomb_decoding_8bpc(cc.buckets_ptrs[cr.row[i-1]].bestcode,
this.io_word);
- cr.row[i] = a.rc;
- cur_row[pixel+(2-c)] = (family_8bpc.xlatL2U[a.rc] +
((cur_row[pixelm1+(2-c)] + prev_row[pixel+(2-c)]) >> 1)) & bpc_mask;
- this.decode_eatbits(a.codewordlen);
- } while (++c < n_channels);
- }
- if (rc)
- break;
-
- c = 0;
- do {
- this.channels[c].buckets_ptrs[this.channels[c].correlate_row.row[stopidx
- 1]].update_model_8bpc(this.rgb_state, this.channels[c].correlate_row.row[stopidx],
bpc);
- } while (++c < n_channels);
-
- stopidx = i + (this.rgb_state.tabrand() & waitmask);
- }
-
- for (; i < end && !rc; i++) {
- var pixel = i * rgb32_pixel_size;
- var pixelm1 = (i-1) * rgb32_pixel_size;
- var pixelm2 = (i-2) * rgb32_pixel_size;
-
- if (prev_row[pixelm1+rgb32_pixel_r] == prev_row[pixel+rgb32_pixel_r]
&& prev_row[pixelm1+rgb32_pixel_g] == prev_row[pixel+rgb32_pixel_g] &&
prev_row[pixelm1+rgb32_pixel_b] == prev_row[pixel+rgb32_pixel_b])
- {
- if (run_index != i && i > 2 &&
(cur_row[pixelm1+rgb32_pixel_r] == cur_row[pixelm2+rgb32_pixel_r] &&
cur_row[pixelm1+rgb32_pixel_g] == cur_row[pixelm2+rgb32_pixel_g] &&
cur_row[pixelm1+rgb32_pixel_b] == cur_row[pixelm2+rgb32_pixel_b]))
- {
- /* do run */
- this.rgb_state.waitcnt = stopidx - i;
- run_index = i;
- run_end = i + this.decode_run(this.rgb_state);
-
- for (; i < run_end; i++) {
- var pixel = i * rgb32_pixel_size;
- var pixelm1 = (i-1) * rgb32_pixel_size;
- cur_row[pixel+rgb32_pixel_pad] = 0;
- cur_row[pixel+rgb32_pixel_r] = cur_row[pixelm1+rgb32_pixel_r];
- cur_row[pixel+rgb32_pixel_g] = cur_row[pixelm1+rgb32_pixel_g];
- cur_row[pixel+rgb32_pixel_b] = cur_row[pixelm1+rgb32_pixel_b];
- }
-
- if (i == end) {
- return;
- }
- else
- {
- stopidx = i + this.rgb_state.waitcnt;
- rc = 1;
- break;
- }
- }
- }
-
- cur_row[pixel+rgb32_pixel_pad] = 0;
- c = 0;
- do
- {
- a =
golomb_decoding_8bpc(this.channels[c].buckets_ptrs[this.channels[c].correlate_row.row[i-1]].bestcode,
this.io_word);
- this.channels[c].correlate_row.row[i] = a.rc;
- cur_row[pixel+(2-c)] = (family_8bpc.xlatL2U[a.rc] +
((cur_row[pixelm1+(2-c)] + prev_row[pixel+(2-c)]) >> 1)) & bpc_mask;
- this.decode_eatbits(a.codewordlen);
- } while (++c < n_channels);
- }
-
- if (!rc)
- {
- this.rgb_state.waitcnt = stopidx - end;
- return;
- }
- }
-}
-
-QuicEncoder.prototype.decode_run = function(state)
-{
- var runlen = 0;
-
- do {
- var hits;
- var x = (~(this.io_word >>> 24)>>>0)&0xff;
- var temp = zeroLUT[x];
-
- for (hits = 1; hits <= temp; hits++) {
- runlen += state.melcorder;
-
- if (state.melcstate < 32) {
- state.melclen = J[++state.melcstate];
- state.melcorder = (1 << state.melclen);
- }
- }
- if (temp != 8) {
- this.decode_eatbits(temp + 1);
-
- break;
- }
- this.decode_eatbits(8);
- } while (true);
-
- if (state.melclen) {
- runlen += this.io_word >>> (32 - state.melclen);
- this.decode_eatbits(state.melclen);
- }
-
- if (state.melcstate) {
- state.melclen = J[--state.melcstate];
- state.melcorder = (1 << state.melclen);
- }
-
- return runlen;
-}
-
-QuicEncoder.prototype.quic_rgb32_uncompress_row = function (prev_row, cur_row)
-{
- var bpc = 8;
- var bpc_mask = 0xff;
- var pos = 0;
- var width = this.width;
-
- while ((wmimax > this.rgb_state.wmidx) && (this.rgb_state.wmileft <=
width)) {
- if (this.rgb_state.wmileft) {
- this.quic_rgb32_uncompress_row_seg(prev_row, cur_row, pos,
- pos + this.rgb_state.wmileft, bpc, bpc_mask);
- pos += this.rgb_state.wmileft;
- width -= this.rgb_state.wmileft;
- }
-
- this.rgb_state.wmidx++;
- this.rgb_state.set_wm_trigger();
- this.rgb_state.wmileft = wminext;
- }
-
- if (width) {
- this.quic_rgb32_uncompress_row_seg(prev_row, cur_row, pos,
- pos + width, bpc, bpc_mask);
- if (wmimax > this.rgb_state.wmidx) {
- this.rgb_state.wmileft -= width;
- }
- }
-}
-
-QuicEncoder.prototype.quic_four_uncompress_row0_seg = function (channel, i,
- correlate_row, cur_row, end, waitmask,
- bpc, bpc_mask)
-{
- var stopidx;
- var a;
-
- if (i == 0) {
- a = golomb_decoding_8bpc(channel.buckets_ptrs[correlate_row.zero].bestcode,
this.io_word);
- correlate_row.row[0] = a.rc;
- cur_row[rgb32_pixel_pad] = family_8bpc.xlatL2U[a.rc];
- this.decode_eatbits(a.codewordlen);
-
- if (channel.state.waitcnt) {
- --channel.state.waitcnt;
- } else {
- channel.state.waitcnt = (channel.state.tabrand() & waitmask);
- channel.buckets_ptrs[correlate_row.zero].update_model_8bpc(channel.state,
correlate_row.row[0], bpc);
- }
- stopidx = ++i + channel.state.waitcnt;
- } else {
- stopidx = i + channel.state.waitcnt;
- }
-
- while (stopidx < end) {
- var pbucket;
-
- for (; i <= stopidx; i++) {
- pbucket = channel.buckets_ptrs[correlate_row.row[i - 1]];
-
- a = golomb_decoding_8bpc(pbucket.bestcode, this.io_word);
- correlate_row.row[i] = a.rc;
- cur_row[(i*rgb32_pixel_size)+rgb32_pixel_pad] = (family_8bpc.xlatL2U[a.rc] +
cur_row[((i-1)*rgb32_pixel_size)+rgb32_pixel_pad]) & bpc_mask;
- this.decode_eatbits(a.codewordlen);
- }
-
- pbucket.update_model_8bpc(channel.state, correlate_row.row[stopidx], bpc);
-
- stopidx = i + (channel.state.tabrand() & waitmask);
- }
-
- for (; i < end; i++) {
- a = golomb_decoding_8bpc(channel.buckets_ptrs[correlate_row.row[i-1]].bestcode,
this.io_word);
-
- correlate_row.row[i] = a.rc;
- cur_row[(i*rgb32_pixel_size)+rgb32_pixel_pad] = (family_8bpc.xlatL2U[a.rc] +
cur_row[((i-1)*rgb32_pixel_size)+rgb32_pixel_pad]) & bpc_mask;
- this.decode_eatbits(a.codewordlen);
- }
- channel.state.waitcnt = stopidx - end;
-}
-
-QuicEncoder.prototype.quic_four_uncompress_row0 = function(channel, cur_row)
-{
- var bpc = 8;
- var bpc_mask = 0xff;
- var correlate_row = channel.correlate_row;
- var pos = 0;
- var width = this.width;
-
- while ((wmimax > channel.state.wmidx) && (channel.state.wmileft <=
width)) {
- if (channel.state.wmileft) {
- this.quic_four_uncompress_row0_seg(channel, pos, correlate_row, cur_row,
- pos + channel.state.wmileft,
bppmask[channel.state.wmidx],
- bpc, bpc_mask);
- pos += channel.state.wmileft;
- width -= channel.state.wmileft;
- }
-
- channel.state.wmidx++;
- channel.state.set_wm_trigger();
- channel.state.wmileft = wminext;
- }
-
- if (width) {
- this.quic_four_uncompress_row0_seg(channel, pos, correlate_row, cur_row, pos +
width,
- bppmask[channel.state.wmidx], bpc, bpc_mask);
- if (wmimax > channel.state.wmidx) {
- channel.state.wmileft -= width;
- }
- }
-}
-
-QuicEncoder.prototype.quic_four_uncompress_row_seg = function (channel,
- correlate_row, prev_row, cur_row, i,
- end, bpc, bpc_mask)
-{
- var waitmask = bppmask[channel.state.wmidx];
- var stopidx;
-
- var run_index = 0;
- var run_end;
-
- var a;
-
- if (i == 0) {
- a = golomb_decoding_8bpc(channel.buckets_ptrs[correlate_row.zero].bestcode,
this.io_word);
-
- correlate_row.row[0] = a.rc
- cur_row[rgb32_pixel_pad] = (family_8bpc.xlatL2U[a.rc] +
prev_row[rgb32_pixel_pad]) & bpc_mask;
- this.decode_eatbits(a.codewordlen);
-
- if (channel.state.waitcnt) {
- --channel.state.waitcnt;
- } else {
- channel.state.waitcnt = (channel.state.tabrand() & waitmask);
- channel.buckets_ptrs[correlate_row.zero].update_model_8bpc(channel.state,
correlate_row.row[0], bpc);
- }
- stopidx = ++i + channel.state.waitcnt;
- } else {
- stopidx = i + channel.state.waitcnt;
- }
- for (;;) {
- var rc = 0;
- while (stopidx < end && !rc) {
- var pbucket;
- for (; i <= stopidx && !rc; i++) {
- var pixel = i * rgb32_pixel_size;
- var pixelm1 = (i-1) * rgb32_pixel_size;
- var pixelm2 = (i-2) * rgb32_pixel_size;
-
- if (prev_row[pixelm1+rgb32_pixel_pad] ==
prev_row[pixel+rgb32_pixel_pad])
- {
- if (run_index != i && i > 2 &&
cur_row[pixelm1+rgb32_pixel_pad] == cur_row[pixelm2+rgb32_pixel_pad])
- {
- /* do run */
- channel.state.waitcnt = stopidx - i;
- run_index = i;
-
- run_end = i + this.decode_run(channel.state);
-
- for (; i < run_end; i++) {
- var pixel = i * rgb32_pixel_size;
- var pixelm1 = (i-1) * rgb32_pixel_size;
- cur_row[pixel+rgb32_pixel_pad] =
cur_row[pixelm1+rgb32_pixel_pad];
- }
-
- if (i == end) {
- return;
- }
- else
- {
- stopidx = i + channel.state.waitcnt;
- rc = 1;
- break;
- }
- }
- }
-
- pbucket = channel.buckets_ptrs[correlate_row.row[i - 1]];
- a = golomb_decoding_8bpc(pbucket.bestcode, this.io_word);
- correlate_row.row[i] = a.rc
- cur_row[pixel+rgb32_pixel_pad] = (family_8bpc.xlatL2U[a.rc] +
((cur_row[pixelm1+rgb32_pixel_pad] + prev_row[pixel+rgb32_pixel_pad]) >> 1)) &
bpc_mask;
- this.decode_eatbits(a.codewordlen);
- }
- if (rc)
- break;
-
- pbucket.update_model_8bpc(channel.state, correlate_row.row[stopidx], bpc);
-
- stopidx = i + (channel.state.tabrand() & waitmask);
- }
-
- for (; i < end && !rc; i++) {
- var pixel = i * rgb32_pixel_size;
- var pixelm1 = (i-1) * rgb32_pixel_size;
- var pixelm2 = (i-2) * rgb32_pixel_size;
- if (prev_row[pixelm1+rgb32_pixel_pad] == prev_row[pixel+rgb32_pixel_pad])
- {
- if (run_index != i && i > 2 &&
cur_row[pixelm1+rgb32_pixel_pad] == cur_row[pixelm2+rgb32_pixel_pad])
- {
- /* do run */
- channel.state.waitcnt = stopidx - i;
- run_index = i;
-
- run_end = i + this.decode_run(channel.state);
-
- for (; i < run_end; i++) {
- var pixel = i * rgb32_pixel_size;
- var pixelm1 = (i-1) * rgb32_pixel_size;
- cur_row[pixel+rgb32_pixel_pad] =
cur_row[pixelm1+rgb32_pixel_pad];
- }
-
- if (i == end) {
- return;
- }
- else
- {
- stopidx = i + channel.state.waitcnt;
- rc = 1;
- break;
- }
- }
- }
-
- a =
golomb_decoding_8bpc(channel.buckets_ptrs[correlate_row.row[i-1]].bestcode,
this.io_word);
- correlate_row.row[i] = a.rc;
- cur_row[pixel+rgb32_pixel_pad] = (family_8bpc.xlatL2U[a.rc] +
((cur_row[pixelm1+rgb32_pixel_pad] + prev_row[pixel+rgb32_pixel_pad]) >> 1)) &
bpc_mask;
- this.decode_eatbits(a.codewordlen);
- }
-
- if (!rc)
- {
- channel.state.waitcnt = stopidx - end;
- return;
- }
- }
-}
-
-QuicEncoder.prototype.quic_four_uncompress_row = function(channel, prev_row,
- cur_row)
-{
- var bpc = 8;
- var bpc_mask = 0xff;
- var correlate_row = channel.correlate_row;
- var pos = 0;
- var width = this.width;
-
- while ((wmimax > channel.state.wmidx) && (channel.state.wmileft <=
width)) {
- if (channel.state.wmileft) {
- this.quic_four_uncompress_row_seg(channel, correlate_row, prev_row, cur_row,
pos,
- pos + channel.state.wmileft, bpc, bpc_mask);
- pos += channel.state.wmileft;
- width -= channel.state.wmileft;
- }
-
- channel.state.wmidx++;
- channel.state.set_wm_trigger();
- channel.state.wmileft = wminext;
- }
-
- if (width) {
- this.quic_four_uncompress_row_seg(channel, correlate_row, prev_row, cur_row,
pos,
- pos + width, bpc, bpc_mask);
- if (wmimax > channel.state.wmidx) {
- channel.state.wmileft -= width;
- }
- }
-}
-
-/* We need to be generating rgb32 or rgba */
-QuicEncoder.prototype.quic_decode = function(buf, stride)
-{
- var row;
-
- switch (this.type)
- {
- case QUIC_IMAGE_TYPE_RGB32:
- case QUIC_IMAGE_TYPE_RGB24:
- this.channels[0].correlate_row.zero = 0;
- this.channels[1].correlate_row.zero = 0;
- this.channels[2].correlate_row.zero = 0;
- this.quic_rgb32_uncompress_row0(buf);
-
- this.rows_completed++;
- for (row = 1; row < this.height; row++)
- {
- var prev = buf;
- buf = prev.subarray(stride);
- this.channels[0].correlate_row.zero =
this.channels[0].correlate_row.row[0];
- this.channels[1].correlate_row.zero =
this.channels[1].correlate_row.row[0];
- this.channels[2].correlate_row.zero =
this.channels[2].correlate_row.row[0];
- this.quic_rgb32_uncompress_row(prev, buf);
- this.rows_completed++;
- };
- break;
- case QUIC_IMAGE_TYPE_RGB16:
- console.log("quic: unsupported output format\n");
- return false;
- break;
- case QUIC_IMAGE_TYPE_RGBA:
- this.channels[0].correlate_row.zero = 0;
- this.channels[1].correlate_row.zero = 0;
- this.channels[2].correlate_row.zero = 0;
- this.quic_rgb32_uncompress_row0(buf);
-
- this.channels[3].correlate_row.zero = 0;
- this.quic_four_uncompress_row0(this.channels[3], buf);
-
- this.rows_completed++;
- for (row = 1; row < this.height; row++) {
- var prev = buf;
- buf = prev.subarray(stride);
-
- this.channels[0].correlate_row.zero =
this.channels[0].correlate_row.row[0];
- this.channels[1].correlate_row.zero =
this.channels[1].correlate_row.row[0];
- this.channels[2].correlate_row.zero =
this.channels[2].correlate_row.row[0];
- this.quic_rgb32_uncompress_row(prev, buf);
-
- this.channels[3].correlate_row.zero =
this.channels[3].correlate_row.row[0];
- this.quic_four_uncompress_row(encoder.channels[3], prev, buf);
- this.rows_completed++;
- }
- break;
-
- case QUIC_IMAGE_TYPE_GRAY:
- console.log("quic: unsupported output format\n");
- return false;
- break;
-
- case QUIC_IMAGE_TYPE_INVALID:
- default:
- console.log("quic: bad image type\n");
- return false;
- }
- return true;
-}
-
-QuicEncoder.prototype.simple_quic_decode = function(buf)
-{
- var stride = 4; /* FIXME - proper stride calc please */
- if (!this.quic_decode_begin(buf))
- return undefined;
- if (this.type != QUIC_IMAGE_TYPE_RGB32 && this.type != QUIC_IMAGE_TYPE_RGB24
- && this.type != QUIC_IMAGE_TYPE_RGBA)
- return undefined;
- var out = new Uint8Array(this.width*this.height*4);
- out[0] = 69;
- if (this.quic_decode( out, (this.width * stride)))
- return out;
- return undefined;
-}
-
-function SpiceQuic()
-{
-}
-
-SpiceQuic.prototype =
-{
- from_dv: function(dv, at, mb)
- {
- if (!encoder)
- throw("quic: no quic encoder");
- this.data_size = dv.getUint32(at, true);
- at += 4;
- var buf = new Uint8Array(mb.slice(at));
- this.outptr = encoder.simple_quic_decode(buf);
- if (this.outptr)
- {
- this.type = encoder.type;
- this.width = encoder.width;
- this.height = encoder.height;
- }
- at += buf.length;
- return at;
- },
-}
-
-function convert_spice_quic_to_web(context, spice_quic)
-{
- var ret = context.createImageData(spice_quic.width, spice_quic.height);
- var i;
- for (i = 0; i < (ret.width * ret.height * 4); i+=4)
- {
- ret.data[i + 0] = spice_quic.outptr[i + 2];
- ret.data[i + 1] = spice_quic.outptr[i + 1];
- ret.data[i + 2] = spice_quic.outptr[i + 0];
- if (spice_quic.type !== QUIC_IMAGE_TYPE_RGBA)
- ret.data[i + 3] = 255;
- else
- ret.data[i + 3] = 255 - spice_quic.outptr[i + 3];
- }
- return ret;
-}
-
-/* Module initialization */
-if (need_init)
-{
- need_init = false;
-
- family_init(family_8bpc, 8, DEFmaxclen);
- family_init(family_5bpc, 5, DEFmaxclen);
- /* init_zeroLUT */
- var i, j, k, l;
-
- j = k = 1;
- l = 8;
- for (i = 0; i < 256; ++i) {
- zeroLUT[i] = l;
- --k;
- if (k == 0) {
- k = j;
- --l;
- j *= 2;
- }
- }
-
- encoder = new QuicEncoder;
-
- if (!encoder)
- throw("quic: failed to create encoder");
-}
diff --git a/plugins/kimchi/ui/spice-html5/resize.js
b/plugins/kimchi/ui/spice-html5/resize.js
deleted file mode 100644
index f5410d3..0000000
--- a/plugins/kimchi/ui/spice-html5/resize.js
+++ /dev/null
@@ -1,70 +0,0 @@
-"use strict";
-/*
- Copyright (C) 2014 by Jeremy P. White <jwhite(a)codeweavers.com>
-
- This file is part of spice-html5.
-
- spice-html5 is free software: you can redistribute it and/or modify
- it under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- spice-html5 is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public License
- along with spice-html5. If not, see <
http://www.gnu.org/licenses/>.
-*/
-
-/*----------------------------------------------------------------------------
-** resize.js
-** This bit of Javascript is a set of logic to help with window
-** resizing, using the agent channel to request screen resizes.
-**
-** It's a bit tricky, as we want to wait for resizing to settle down
-** before sending a size. Further, while horizontal resizing to use the whole
-** browser width is fairly easy to arrange with css, resizing an element to use
-** the whole vertical space (or to force a middle div to consume the bulk of the
browser
-** window size) is tricky, and the consensus seems to be that Javascript is
-** the only right way to do it.
-**--------------------------------------------------------------------------*/
-function resize_helper(sc)
-{
- var w = document.getElementById(sc.screen_id).clientWidth;
- var h = document.getElementById(sc.screen_id).clientHeight;
-
- var m = document.getElementById(sc.message_id);
-
- /* Resize vertically; basically we leave a 20 pixel margin
- at the bottom, and use the position of the message window
- to figure out how to resize */
- var hd = window.innerHeight - m.offsetHeight - m.offsetTop - 20;
-
- /* Xorg requires height be a multiple of 8; round up */
- h = h + hd;
- if (h % 8 > 0)
- h += (8 - (h % 8));
-
- /* Xorg requires width be a multiple of 8; round up */
- if (w % 8 > 0)
- w += (8 - (w % 8));
-
-
- sc.resize_window(0, w, h, 32, 0, 0);
- sc.spice_resize_timer = undefined;
-}
-
-function handle_resize(e)
-{
- var sc = window.spice_connection;
-
- if (sc && sc.spice_resize_timer)
- {
- window.clearTimeout(sc.spice_resize_timer);
- sc.spice_resize_timer = undefined;
- }
-
- sc.spice_resize_timer = window.setTimeout(resize_helper, 200, sc);
-}
diff --git a/plugins/kimchi/ui/spice-html5/simulatecursor.js
b/plugins/kimchi/ui/spice-html5/simulatecursor.js
deleted file mode 100644
index b1fce06..0000000
--- a/plugins/kimchi/ui/spice-html5/simulatecursor.js
+++ /dev/null
@@ -1,202 +0,0 @@
-"use strict";
-/*
- Copyright (C) 2013 by Jeremy P. White <jwhite(a)codeweavers.com>
-
- This file is part of spice-html5.
-
- spice-html5 is free software: you can redistribute it and/or modify
- it under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- spice-html5 is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public License
- along with spice-html5. If not, see <
http://www.gnu.org/licenses/>.
-*/
-
-/*----------------------------------------------------------------------------
-** SpiceSimulateCursor
-** Internet Explorer 10 does not support data uri's in cursor assignment.
-** This file provides a number of gimmicks to compensate. First, if there
-** is a preloaded cursor available, we will use that. Failing that, we will
-** simulate a cursor using an image that is moved around the screen.
-**--------------------------------------------------------------------------*/
-var SpiceSimulateCursor = {
-
-cursors : new Array(),
-unknown_cursors : new Array(),
-warned: false,
-
-add_cursor: function(sha1, value)
-{
- SpiceSimulateCursor.cursors[sha1] = value;
-},
-
-unknown_cursor: function(sha1, curdata)
-{
- if (! SpiceSimulateCursor.warned)
- {
- SpiceSimulateCursor.warned = true;
- alert("Internet Explorer does not support dynamic cursors. " +
- "This page will now simulate cursors with images, " +
- "which will be imperfect. We recommend using Chrome or Firefox
instead. " +
- "\n\nIf you need to use Internet Explorer, you can create a static
cursor " +
- "file for each cursor your application uses. " +
- "View the console log for more information on creating static cursors
for your environment.");
- }
-
- if (! SpiceSimulateCursor.unknown_cursors[sha1])
- {
- SpiceSimulateCursor.unknown_cursors[sha1] = curdata;
- console.log('Unknown cursor. Simulation required. To avoid simulation for
this cursor, create and include a custom javascript file, and add the following
line:');
- console.log('SpiceCursorSimulator.add_cursor("' + sha1 +
'"), "<your filename here>.cur");');
- console.log('And then run following command, redirecting output into <your
filename here>.cur:');
- console.log('php -r "echo urldecode(\'' + curdata +
'\');"');
- }
-},
-
-simulate_cursor: function (spicecursor, cursor, screen, pngstr)
-{
- var cursor_sha = hex_sha1(pngstr + ' ' + cursor.header.hot_spot_x + '
' + cursor.header.hot_spot_y);
- if (typeof SpiceSimulateCursor.cursors != 'undefined')
- if (typeof SpiceSimulateCursor.cursors[cursor_sha] != 'undefined')
- {
- var curstr = 'url(' + SpiceSimulateCursor.cursors[cursor_sha] +
'), default';
- screen.style.cursor = curstr;
- }
-
- if (window.getComputedStyle(screen, null).cursor == 'auto')
- {
- SpiceSimulateCursor.unknown_cursor(cursor_sha,
- SpiceSimulateCursor.create_icondir(cursor.header.width,
cursor.header.height,
- cursor.data.byteLength, cursor.header.hot_spot_x, cursor.header.hot_spot_y) +
pngstr);
-
- document.getElementById(spicecursor.parent.screen_id).style.cursor =
'none';
- if (! spicecursor.spice_simulated_cursor)
- {
- spicecursor.spice_simulated_cursor = document.createElement('img');
-
- spicecursor.spice_simulated_cursor.style.position = 'absolute';
- spicecursor.spice_simulated_cursor.style.display = 'none';
- spicecursor.spice_simulated_cursor.style.overflow = 'hidden';
-
- spicecursor.spice_simulated_cursor.spice_screen =
document.getElementById(spicecursor.parent.screen_id);
-
- spicecursor.spice_simulated_cursor.addEventListener('mousemove',
SpiceSimulateCursor.handle_sim_mousemove);
-
-
spicecursor.spice_simulated_cursor.spice_screen.appendChild(spicecursor.spice_simulated_cursor);
- }
-
- spicecursor.spice_simulated_cursor.src = 'data:image/png,' + pngstr;
-
- spicecursor.spice_simulated_cursor.spice_hot_x = cursor.header.hot_spot_x;
- spicecursor.spice_simulated_cursor.spice_hot_y = cursor.header.hot_spot_y;
-
- spicecursor.spice_simulated_cursor.style.pointerEvents = "none";
- }
- else
- {
- if (spicecursor.spice_simulated_cursor)
- {
-
spicecursor.spice_simulated_cursor.spice_screen.removeChild(spicecursor.spice_simulated_cursor);
- delete spicecursor.spice_simulated_cursor;
- }
- }
-},
-
-handle_sim_mousemove: function(e)
-{
- var retval;
- var f = SpiceSimulateCursor.duplicate_mouse_event(e, this.spice_screen);
- return this.spice_screen.dispatchEvent(f);
-},
-
-duplicate_mouse_event: function(e, target)
-{
- var evt = document.createEvent("mouseevent");
- evt.initMouseEvent(e.type, true, true, e.view, e.detail,
- e.screenX, e.screenY, e.clientX, e.clientY,
- e.ctrlKey, e.altKey, e.shiftKey, e.metaKey, e.button, e.relatedTarget);
- return evt;
-},
-
-ICONDIR: function ()
-{
-},
-
-ICONDIRENTRY: function(width, height, bytes, hot_x, hot_y)
-{
- this.width = width;
- this.height = height;
- this.bytes = bytes;
- this.hot_x = hot_x;
- this.hot_y = hot_y;
-},
-
-
-create_icondir: function (width, height, bytes, hot_x, hot_y)
-{
- var i;
- var header = new SpiceSimulateCursor.ICONDIR();
- var entry = new SpiceSimulateCursor.ICONDIRENTRY(width, height, bytes, hot_x,
hot_y);
-
- var mb = new ArrayBuffer(header.buffer_size() + entry.buffer_size());
- var at = header.to_buffer(mb);
- at = entry.to_buffer(mb, at);
-
- var u8 = new Uint8Array(mb);
- var str = "";
- for (i = 0; i < at; i++)
- {
- str += "%";
- if (u8[i] < 16)
- str += "0";
- str += u8[i].toString(16);
- }
- return str;
-},
-
-};
-
-SpiceSimulateCursor.ICONDIR.prototype =
-{
- to_buffer: function(a, at)
- {
- at = at || 0;
- var dv = new SpiceDataView(a);
- dv.setUint16(at, 0, true); at += 2;
- dv.setUint16(at, 2, true); at += 2;
- dv.setUint16(at, 1, true); at += 2;
- return at;
- },
- buffer_size: function()
- {
- return 6;
- }
-};
-
-SpiceSimulateCursor.ICONDIRENTRY.prototype =
-{
- to_buffer: function(a, at)
- {
- at = at || 0;
- var dv = new SpiceDataView(a);
- dv.setUint8(at, this.width); at++;
- dv.setUint8(at, this.height); at++;
- dv.setUint8(at, 0); at++; /* color palette count, unused */
- dv.setUint8(at, 0); at++; /* reserved */
- dv.setUint16(at, this.hot_x, true); at += 2;
- dv.setUint16(at, this.hot_y, true); at += 2;
- dv.setUint32(at, this.bytes, true); at += 4;
- dv.setUint32(at, at + 4, true); at += 4; /* Offset to bytes */
- return at;
- },
- buffer_size: function()
- {
- return 16;
- }
-};
diff --git a/plugins/kimchi/ui/spice-html5/spicearraybuffer.js
b/plugins/kimchi/ui/spice-html5/spicearraybuffer.js
deleted file mode 100644
index 228bce6..0000000
--- a/plugins/kimchi/ui/spice-html5/spicearraybuffer.js
+++ /dev/null
@@ -1,58 +0,0 @@
-"use strict";
-/*
- Copyright (C) 2012 by Jeremy P. White <jwhite(a)codeweavers.com>
-
- This file is part of spice-html5.
-
- spice-html5 is free software: you can redistribute it and/or modify
- it under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- spice-html5 is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public License
- along with spice-html5. If not, see <
http://www.gnu.org/licenses/>.
-*/
-
-/*----------------------------------------------------------------------------
-** SpiceArrayBufferSlice
-** This function is a work around for IE 10, which has no slice()
-** method in it's subclass.
-**--------------------------------------------------------------------------*/
-function SpiceArrayBufferSlice(start, end)
-{
- start = start || 0;
- end = end || this.byteLength;
- if (end < 0)
- end = this.byteLength + end;
- if (start < 0)
- start = this.byteLength + start;
- if (start < 0)
- start = 0;
- if (end < 0)
- end = 0;
- if (end > this.byteLength)
- end = this.byteLength;
- if (start > end)
- start = end;
-
- var ret = new ArrayBuffer(end - start);
- var in1 = new Uint8Array(this, start, end - start);
- var out = new Uint8Array(ret);
- var i;
-
- for (i = 0; i < end - start; i++)
- out[i] = in1[i];
-
- return ret;
-}
-
-if (! ArrayBuffer.prototype.slice)
-{
- ArrayBuffer.prototype.slice = SpiceArrayBufferSlice;
- console.log("WARNING: ArrayBuffer.slice() is missing; we are extending
ArrayBuffer to compensate");
-}
diff --git a/plugins/kimchi/ui/spice-html5/spiceconn.js
b/plugins/kimchi/ui/spice-html5/spiceconn.js
deleted file mode 100644
index e33227e..0000000
--- a/plugins/kimchi/ui/spice-html5/spiceconn.js
+++ /dev/null
@@ -1,460 +0,0 @@
-"use strict";
-/*
- Copyright (C) 2012 by Jeremy P. White <jwhite(a)codeweavers.com>
-
- This file is part of spice-html5.
-
- spice-html5 is free software: you can redistribute it and/or modify
- it under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- spice-html5 is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public License
- along with spice-html5. If not, see <
http://www.gnu.org/licenses/>.
-*/
-
-/*----------------------------------------------------------------------------
-** SpiceConn
-** This is the base Javascript class for establishing and
-** managing a connection to a Spice Server.
-** It is used to provide core functionality to the Spice main,
-** display, inputs, and cursor channels. See main.js for
-** usage.
-**--------------------------------------------------------------------------*/
-function SpiceConn(o)
-{
- if (o === undefined || o.uri === undefined || ! o.uri)
- throw new Error("You must specify a uri");
-
- this.ws = new WebSocket(o.uri, 'binary');
-
- if (! this.ws.binaryType)
- throw new Error("WebSocket doesn't support binaryType. Try a different
browser.");
-
- this.connection_id = o.connection_id !== undefined ? o.connection_id : 0;
- this.type = o.type !== undefined ? o.type : SPICE_CHANNEL_MAIN;
- this.chan_id = o.chan_id !== undefined ? o.chan_id : 0;
- if (o.parent !== undefined)
- {
- this.parent = o.parent;
- this.message_id = o.parent.message_id;
- this.password = o.parent.password;
- }
- if (o.screen_id !== undefined)
- this.screen_id = o.screen_id;
- if (o.dump_id !== undefined)
- this.dump_id = o.dump_id;
- if (o.message_id !== undefined)
- this.message_id = o.message_id;
- if (o.password !== undefined)
- this.password = o.password;
- if (o.onerror !== undefined)
- this.onerror = o.onerror;
- if (o.onsuccess !== undefined)
- this.onsuccess = o.onsuccess;
- if (o.onagent !== undefined)
- this.onagent = o.onagent;
-
- this.state = "connecting";
- this.ws.parent = this;
- this.wire_reader = new SpiceWireReader(this, this.process_inbound);
- this.messages_sent = 0;
- this.warnings = [];
-
- this.ws.addEventListener('open', function(e) {
- DEBUG > 0 && console.log(">> WebSockets.onopen");
- DEBUG > 0 && console.log("id " + this.parent.connection_id
+"; type " + this.parent.type);
-
- /***********************************************************************
- ** WHERE IT ALL REALLY BEGINS
- ***********************************************************************/
- this.parent.send_hdr();
- this.parent.wire_reader.request(SpiceLinkHeader.prototype.buffer_size());
- this.parent.state = "start";
- });
- this.ws.addEventListener('error', function(e) {
- this.parent.log_err(">> WebSockets.onerror" + e.toString());
- this.parent.report_error(e);
- });
- this.ws.addEventListener('close', function(e) {
- DEBUG > 0 && console.log(">> WebSockets.onclose");
- DEBUG > 0 && console.log("id " + this.parent.connection_id
+"; type " + this.parent.type);
- DEBUG > 0 && console.log(e);
- if (this.parent.state != "closing" && this.parent.state !=
"error" && this.parent.onerror !== undefined)
- {
- var e;
- if (this.parent.state == "connecting")
- e = new Error("Connection refused.");
- else if (this.parent.state == "start" || this.parent.state ==
"link")
- e = new Error("Unexpected protocol mismatch.");
- else if (this.parent.state == "ticket")
- e = new Error("Bad password.");
- else
- e = new Error("Unexpected close while " + this.parent.state);
-
- this.parent.onerror(e);
- this.parent.log_err(e.toString());
- }
- });
-
- if (this.ws.readyState == 2 || this.ws.readyState == 3)
- throw new Error("Unable to connect to " + o.uri);
-
- this.timeout = window.setTimeout(spiceconn_timeout, SPICE_CONNECT_TIMEOUT, this);
-}
-
-SpiceConn.prototype =
-{
- send_hdr : function ()
- {
- var hdr = new SpiceLinkHeader;
- var msg = new SpiceLinkMess;
-
- msg.connection_id = this.connection_id;
- msg.channel_type = this.type;
- // FIXME - we're not setting a channel_id...
- msg.common_caps.push(
- (1 << SPICE_COMMON_CAP_PROTOCOL_AUTH_SELECTION) |
- (1 << SPICE_COMMON_CAP_MINI_HEADER)
- );
-
- if (msg.channel_type == SPICE_CHANNEL_PLAYBACK)
- msg.channel_caps.push(
- (1 << SPICE_PLAYBACK_CAP_OPUS)
- );
-
- hdr.size = msg.buffer_size();
-
- var mb = new ArrayBuffer(hdr.buffer_size() + msg.buffer_size());
- hdr.to_buffer(mb);
- msg.to_buffer(mb, hdr.buffer_size());
-
- DEBUG > 1 && console.log("Sending header:");
- DEBUG > 2 && hexdump_buffer(mb);
- this.ws.send(mb);
- },
-
- send_ticket: function(ticket)
- {
- var hdr = new SpiceLinkAuthTicket();
- hdr.auth_mechanism = SPICE_COMMON_CAP_AUTH_SPICE;
- // FIXME - we need to implement RSA to make this work right
- hdr.encrypted_data = ticket;
- var mb = new ArrayBuffer(hdr.buffer_size());
-
- hdr.to_buffer(mb);
- DEBUG > 1 && console.log("Sending ticket:");
- DEBUG > 2 && hexdump_buffer(mb);
- this.ws.send(mb);
- },
-
- send_msg: function(msg)
- {
- var mb = new ArrayBuffer(msg.buffer_size());
- msg.to_buffer(mb);
- this.messages_sent++;
- DEBUG > 0 && console.log(">> hdr " +
this.channel_type() + " type " + msg.type + " size " +
mb.byteLength);
- DEBUG > 2 && hexdump_buffer(mb);
- this.ws.send(mb);
- },
-
- process_inbound: function(mb, saved_header)
- {
- DEBUG > 2 && console.log(this.type + ": processing message of
size " + mb.byteLength + "; state is " + this.state);
- if (this.state == "ready")
- {
- if (saved_header == undefined)
- {
- var msg = new SpiceMiniData(mb);
-
- if (msg.type > 500)
- {
- alert("Something has gone very wrong; we think we have message
of type " + msg.type);
- debugger;
- }
-
- if (msg.size == 0)
- {
- this.process_message(msg);
- this.wire_reader.request(SpiceMiniData.prototype.buffer_size());
- }
- else
- {
- this.wire_reader.request(msg.size);
- this.wire_reader.save_header(msg);
- }
- }
- else
- {
- saved_header.data = mb;
- this.process_message(saved_header);
- this.wire_reader.request(SpiceMiniData.prototype.buffer_size());
- this.wire_reader.save_header(undefined);
- }
- }
-
- else if (this.state == "start")
- {
- this.reply_hdr = new SpiceLinkHeader(mb);
- if (this.reply_hdr.magic != SPICE_MAGIC)
- {
- this.state = "error";
- var e = new Error('Error: magic mismatch: ' +
this.reply_hdr.magic);
- this.report_error(e);
- }
- else
- {
- // FIXME - Determine major/minor version requirements
- this.wire_reader.request(this.reply_hdr.size);
- this.state = "link";
- }
- }
-
- else if (this.state == "link")
- {
- this.reply_link = new SpiceLinkReply(mb);
- // FIXME - Screen the caps - require minihdr at least, right?
- if (this.reply_link.error)
- {
- this.state = "error";
- var e = new Error('Error: reply link error ' +
this.reply_link.error);
- this.report_error(e);
- }
- else
- {
- this.send_ticket(rsa_encrypt(this.reply_link.pub_key, this.password +
String.fromCharCode(0)));
- this.state = "ticket";
- this.wire_reader.request(SpiceLinkAuthReply.prototype.buffer_size());
- }
- }
-
- else if (this.state == "ticket")
- {
- this.auth_reply = new SpiceLinkAuthReply(mb);
- if (this.auth_reply.auth_code == SPICE_LINK_ERR_OK)
- {
- DEBUG > 0 && console.log(this.type + ': Connected');
-
- if (this.type == SPICE_CHANNEL_DISPLAY)
- {
- // FIXME - pixmap and glz dictionary config info?
- var dinit = new SpiceMsgcDisplayInit();
- var reply = new SpiceMiniData();
- reply.build_msg(SPICE_MSGC_DISPLAY_INIT, dinit);
- DEBUG > 0 && console.log("Request display
init");
- this.send_msg(reply);
- }
- this.state = "ready";
- this.wire_reader.request(SpiceMiniData.prototype.buffer_size());
- if (this.timeout)
- {
- window.clearTimeout(this.timeout);
- delete this.timeout;
- }
- }
- else
- {
- this.state = "error";
- if (this.auth_reply.auth_code == SPICE_LINK_ERR_PERMISSION_DENIED)
- {
- var e = new Error("Permission denied.");
- }
- else
- {
- var e = new Error("Unexpected link error " +
this.auth_reply.auth_code);
- }
- this.report_error(e);
- }
- }
- },
-
- process_common_messages : function(msg)
- {
- if (msg.type == SPICE_MSG_SET_ACK)
- {
- var ack = new SpiceMsgSetAck(msg.data);
- // FIXME - what to do with generation?
- this.ack_window = ack.window;
- DEBUG > 1 && console.log(this.type + ": set ack to " +
ack.window);
- this.msgs_until_ack = this.ack_window;
- var ackack = new SpiceMsgcAckSync(ack);
- var reply = new SpiceMiniData();
- reply.build_msg(SPICE_MSGC_ACK_SYNC, ackack);
- this.send_msg(reply);
- return true;
- }
-
- if (msg.type == SPICE_MSG_PING)
- {
- DEBUG > 1 && console.log("ping!");
- var pong = new SpiceMiniData;
- pong.type = SPICE_MSGC_PONG;
- if (msg.data)
- {
- pong.data = msg.data.slice(0, 12);
- }
- pong.size = pong.buffer_size();
- this.send_msg(pong);
- return true;
- }
-
- if (msg.type == SPICE_MSG_NOTIFY)
- {
- // FIXME - Visibility + what
- var notify = new SpiceMsgNotify(msg.data);
- if (notify.severity == SPICE_NOTIFY_SEVERITY_ERROR)
- this.log_err(notify.message);
- else if (notify.severity == SPICE_NOTIFY_SEVERITY_WARN )
- this.log_warn(notify.message);
- else
- this.log_info(notify.message);
- return true;
- }
-
- return false;
-
- },
-
- process_message: function(msg)
- {
- var rc;
- DEBUG > 0 && console.log("<< hdr " +
this.channel_type() + " type " + msg.type + " size " + (msg.data
&& msg.data.byteLength));
- rc = this.process_common_messages(msg);
- if (! rc)
- {
- if (this.process_channel_message)
- {
- rc = this.process_channel_message(msg);
- if (! rc)
- this.log_warn(this.type + ": Unknown message type " +
msg.type + "!");
- }
- else
- this.log_err(this.type + ": No message handlers for this channel;
message " + msg.type);
- }
-
- if (this.msgs_until_ack !== undefined && this.ack_window)
- {
- this.msgs_until_ack--;
- if (this.msgs_until_ack <= 0)
- {
- this.msgs_until_ack = this.ack_window;
- var ack = new SpiceMiniData();
- ack.type = SPICE_MSGC_ACK;
- this.send_msg(ack);
- DEBUG > 1 && console.log(this.type + ": sent ack");
- }
- }
-
- return rc;
- },
-
- channel_type: function()
- {
- if (this.type == SPICE_CHANNEL_MAIN)
- return "main";
- else if (this.type == SPICE_CHANNEL_DISPLAY)
- return "display";
- else if (this.type == SPICE_CHANNEL_INPUTS)
- return "inputs";
- else if (this.type == SPICE_CHANNEL_CURSOR)
- return "cursor";
- return "unknown-" + this.type;
-
- },
-
- log_info: function()
- {
- var msg = Array.prototype.join.call(arguments, " ");
- console.log(msg);
- if (this.message_id)
- {
- var p = document.createElement("p");
- p.appendChild(document.createTextNode(msg));
- p.className += "spice-message-info";
- document.getElementById(this.message_id).appendChild(p);
- }
- },
-
- log_warn: function()
- {
- var msg = Array.prototype.join.call(arguments, " ");
- console.log("WARNING: " + msg);
- if (this.message_id)
- {
- var p = document.createElement("p");
- p.appendChild(document.createTextNode(msg));
- p.className += "spice-message-warning";
- document.getElementById(this.message_id).appendChild(p);
- }
- },
-
- log_err: function()
- {
- var msg = Array.prototype.join.call(arguments, " ");
- console.log("ERROR: " + msg);
- if (this.message_id)
- {
- var p = document.createElement("p");
- p.appendChild(document.createTextNode(msg));
- p.className += "spice-message-error";
- document.getElementById(this.message_id).appendChild(p);
- }
- },
-
- known_unimplemented: function(type, msg)
- {
- if ( (!this.warnings[type]) || DEBUG > 1)
- {
- var str = "";
- if (DEBUG <= 1)
- str = " [ further notices suppressed ]";
- this.log_warn("Unimplemented function " + type + "(" +
msg + ")" + str);
- this.warnings[type] = true;
- }
- },
-
- report_error: function(e)
- {
- this.log_err(e.toString());
- if (this.onerror != undefined)
- this.onerror(e);
- else
- throw(e);
- },
-
- report_success: function(m)
- {
- if (this.onsuccess != undefined)
- this.onsuccess(m);
- },
-
- cleanup: function()
- {
- if (this.timeout)
- {
- window.clearTimeout(this.timeout);
- delete this.timeout;
- }
- if (this.ws)
- {
- this.ws.close();
- this.ws = undefined;
- }
- },
-
- handle_timeout: function()
- {
- var e = new Error("Connection timed out.");
- this.report_error(e);
- },
-}
-
-function spiceconn_timeout(sc)
-{
- SpiceConn.prototype.handle_timeout.call(sc);
-}
diff --git a/plugins/kimchi/ui/spice-html5/spicedataview.js
b/plugins/kimchi/ui/spice-html5/spicedataview.js
deleted file mode 100644
index 800df03..0000000
--- a/plugins/kimchi/ui/spice-html5/spicedataview.js
+++ /dev/null
@@ -1,120 +0,0 @@
-"use strict";
-/*
- Copyright (C) 2012 by Jeremy P. White <jwhite(a)codeweavers.com>
-
- This file is part of spice-html5.
-
- spice-html5 is free software: you can redistribute it and/or modify
- it under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- spice-html5 is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public License
- along with spice-html5. If not, see <
http://www.gnu.org/licenses/>.
-*/
-
-/*----------------------------------------------------------------------------
-** SpiceDataView
-** FIXME FIXME
-** This is used because Firefox does not have DataView yet.
-** We should use DataView if we have it, because it *has* to
-** be faster than this code
-**--------------------------------------------------------------------------*/
-function SpiceDataView(buffer, byteOffset, byteLength)
-{
- if (byteOffset !== undefined)
- {
- if (byteLength !== undefined)
- this.u8 = new Uint8Array(buffer, byteOffset, byteLength);
- else
- this.u8 = new Uint8Array(buffer, byteOffset);
- }
- else
- this.u8 = new Uint8Array(buffer);
-};
-
-SpiceDataView.prototype = {
- getUint8: function(byteOffset)
- {
- return this.u8[byteOffset];
- },
- getUint16: function(byteOffset, littleEndian)
- {
- var low = 1, high = 0;
- if (littleEndian)
- {
- low = 0;
- high = 1;
- }
-
- return (this.u8[byteOffset + high] << 8) | this.u8[byteOffset + low];
- },
- getUint32: function(byteOffset, littleEndian)
- {
- var low = 2, high = 0;
- if (littleEndian)
- {
- low = 0;
- high = 2;
- }
-
- return (this.getUint16(byteOffset + high, littleEndian) << 16) |
- this.getUint16(byteOffset + low, littleEndian);
- },
- getUint64: function (byteOffset, littleEndian)
- {
- var low = 4, high = 0;
- if (littleEndian)
- {
- low = 0;
- high = 4;
- }
-
- return (this.getUint32(byteOffset + high, littleEndian) << 32) |
- this.getUint32(byteOffset + low, littleEndian);
- },
- setUint8: function(byteOffset, b)
- {
- this.u8[byteOffset] = (b & 0xff);
- },
- setUint16: function(byteOffset, i, littleEndian)
- {
- var low = 1, high = 0;
- if (littleEndian)
- {
- low = 0;
- high = 1;
- }
- this.u8[byteOffset + high] = (i & 0xffff) >> 8;
- this.u8[byteOffset + low] = (i & 0x00ff);
- },
- setUint32: function(byteOffset, w, littleEndian)
- {
- var low = 2, high = 0;
- if (littleEndian)
- {
- low = 0;
- high = 2;
- }
-
- this.setUint16(byteOffset + high, (w & 0xffffffff) >> 16,
littleEndian);
- this.setUint16(byteOffset + low, (w & 0x0000ffff), littleEndian);
- },
- setUint64: function(byteOffset, w, littleEndian)
- {
- var low = 4, high = 0;
- if (littleEndian)
- {
- low = 0;
- high = 4;
- }
-
- this.setUint32(byteOffset + high, (w & 0xffffffffffffffff) >> 32,
littleEndian);
- this.setUint32(byteOffset + low, (w & 0x00000000ffffffff), littleEndian);
- },
-}
diff --git a/plugins/kimchi/ui/spice-html5/spicemsg.js
b/plugins/kimchi/ui/spice-html5/spicemsg.js
deleted file mode 100644
index c64f5a3..0000000
--- a/plugins/kimchi/ui/spice-html5/spicemsg.js
+++ /dev/null
@@ -1,1047 +0,0 @@
-"use strict";
-/*
- Copyright (C) 2012 by Jeremy P. White <jwhite(a)codeweavers.com>
-
- This file is part of spice-html5.
-
- spice-html5 is free software: you can redistribute it and/or modify
- it under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- spice-html5 is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public License
- along with spice-html5. If not, see <
http://www.gnu.org/licenses/>.
-*/
-
-/*----------------------------------------------------------------------------
-** Spice messages
-** This file contains classes for passing messages to and from
-** a spice server. This file should arguably be generated from
-** spice.proto, but it was instead put together by hand.
-**--------------------------------------------------------------------------*/
-function SpiceLinkHeader(a, at)
-{
- this.magic = SPICE_MAGIC;
- this.major_version = SPICE_VERSION_MAJOR;
- this.minor_version = SPICE_VERSION_MINOR;
- this.size = 0;
- if (a !== undefined)
- this.from_buffer(a, at);
-}
-
-SpiceLinkHeader.prototype =
-{
- from_buffer: function(a, at)
- {
- at = at || 0;
- var dv = new SpiceDataView(a);
- this.magic = "";
- for (var i = 0; i < 4; i++)
- this.magic += String.fromCharCode(dv.getUint8(at + i));
- at += 4;
-
- this.major_version = dv.getUint32(at, true); at += 4;
- this.minor_version = dv.getUint32(at, true); at += 4;
- this.size = dv.getUint32(at, true); at += 4;
- },
-
- to_buffer: function(a, at)
- {
- at = at || 0;
- var dv = new SpiceDataView(a);
- for (var i = 0; i < 4; i++)
- dv.setUint8(at + i, this.magic.charCodeAt(i));
- at += 4;
-
- dv.setUint32(at, this.major_version, true); at += 4;
- dv.setUint32(at, this.minor_version, true); at += 4;
- dv.setUint32(at, this.size, true); at += 4;
- },
- buffer_size: function()
- {
- return 16;
- },
-}
-
-function SpiceLinkMess(a, at)
-{
- this.connection_id = 0;
- this.channel_type = 0;
- this.channel_id = 0;
- this.common_caps = [];
- this.channel_caps = [];
-
- if (a !== undefined)
- this.from_buffer(a, at);
-}
-
-SpiceLinkMess.prototype =
-{
- from_buffer: function(a, at)
- {
- at = at || 0;
- var i;
- var orig_at = at;
- var dv = new SpiceDataView(a);
- this.connection_id = dv.getUint32(at, true); at += 4;
- this.channel_type = dv.getUint8(at, true); at++;
- this.channel_id = dv.getUint8(at, true); at++;
- var num_common_caps = dv.getUint32(at, true); at += 4;
- var num_channel_caps = dv.getUint32(at, true); at += 4;
- var caps_offset = dv.getUint32(at, true); at += 4;
-
- at = orig_at + caps_offset;
- this.common_caps = [];
- for (i = 0; i < num_common_caps; i++)
- {
- this.common_caps.unshift(dv.getUint32(at, true)); at += 4;
- }
-
- this.channel_caps = [];
- for (i = 0; i < num_channel_caps; i++)
- {
- this.channel_caps.unshift(dv.getUint32(at, true)); at += 4;
- }
- },
-
- to_buffer: function(a, at)
- {
- at = at || 0;
- var orig_at = at;
- var i;
- var dv = new SpiceDataView(a);
- dv.setUint32(at, this.connection_id, true); at += 4;
- dv.setUint8(at, this.channel_type, true); at++;
- dv.setUint8(at, this.channel_id, true); at++;
- dv.setUint32(at, this.common_caps.length, true); at += 4;
- dv.setUint32(at, this.channel_caps.length, true); at += 4;
- dv.setUint32(at, (at - orig_at) + 4, true); at += 4;
-
- for (i = 0; i < this.common_caps.length; i++)
- {
- dv.setUint32(at, this.common_caps[i], true); at += 4;
- }
-
- for (i = 0; i < this.channel_caps.length; i++)
- {
- dv.setUint32(at, this.channel_caps[i], true); at += 4;
- }
- },
- buffer_size: function()
- {
- return 18 + (4 * this.common_caps.length) + (4 * this.channel_caps.length);
- }
-}
-
-function SpiceLinkReply(a, at)
-{
- this.error = 0;
- this.pub_key = undefined;
- this.common_caps = [];
- this.channel_caps = [];
-
- if (a !== undefined)
- this.from_buffer(a, at);
-}
-
-SpiceLinkReply.prototype =
-{
- from_buffer: function(a, at)
- {
- at = at || 0;
- var i;
- var orig_at = at;
- var dv = new SpiceDataView(a);
- this.error = dv.getUint32(at, true); at += 4;
-
- this.pub_key = create_rsa_from_mb(a, at);
- at += SPICE_TICKET_PUBKEY_BYTES;
-
- var num_common_caps = dv.getUint32(at, true); at += 4;
- var num_channel_caps = dv.getUint32(at, true); at += 4;
- var caps_offset = dv.getUint32(at, true); at += 4;
-
- at = orig_at + caps_offset;
- this.common_caps = [];
- for (i = 0; i < num_common_caps; i++)
- {
- this.common_caps.unshift(dv.getUint32(at, true)); at += 4;
- }
-
- this.channel_caps = [];
- for (i = 0; i < num_channel_caps; i++)
- {
- this.channel_caps.unshift(dv.getUint32(at, true)); at += 4;
- }
- },
-}
-
-function SpiceLinkAuthTicket(a, at)
-{
- this.auth_mechanism = 0;
- this.encrypted_data = undefined;
-}
-
-SpiceLinkAuthTicket.prototype =
-{
- to_buffer: function(a, at)
- {
- at = at || 0;
- var i;
- var dv = new SpiceDataView(a);
- dv.setUint32(at, this.auth_mechanism, true); at += 4;
- for (i = 0; i < SPICE_TICKET_KEY_PAIR_LENGTH / 8; i++)
- {
- if (this.encrypted_data && i < this.encrypted_data.length)
- dv.setUint8(at, this.encrypted_data[i], true);
- else
- dv.setUint8(at, 0, true);
- at++;
- }
- },
- buffer_size: function()
- {
- return 4 + (SPICE_TICKET_KEY_PAIR_LENGTH / 8);
- }
-}
-
-function SpiceLinkAuthReply(a, at)
-{
- this.auth_code = 0;
- if (a !== undefined)
- this.from_buffer(a, at);
-}
-
-SpiceLinkAuthReply.prototype =
-{
- from_buffer: function(a, at)
- {
- at = at || 0;
- var dv = new SpiceDataView(a);
- this.auth_code = dv.getUint32(at, true); at += 4;
- },
- buffer_size: function()
- {
- return 4;
- }
-}
-
-function SpiceMiniData(a, at)
-{
- this.type = 0;
- this.size = 0;
- this.data = undefined;
- if (a !== undefined)
- this.from_buffer(a, at);
-}
-
-SpiceMiniData.prototype =
-{
- from_buffer: function(a, at)
- {
- at = at || 0;
- var i;
- var dv = new SpiceDataView(a);
- this.type = dv.getUint16(at, true); at += 2;
- this.size = dv.getUint32(at, true); at += 4;
- if (a.byteLength > at)
- {
- this.data = a.slice(at);
- at += this.data.byteLength;
- }
- },
- to_buffer : function(a, at)
- {
- at = at || 0;
- var i;
- var dv = new SpiceDataView(a);
- dv.setUint16(at, this.type, true); at += 2;
- dv.setUint32(at, this.data ? this.data.byteLength : 0, true); at += 4;
- if (this.data && this.data.byteLength > 0)
- {
- var u8arr = new Uint8Array(this.data);
- for (i = 0; i < u8arr.length; i++, at++)
- dv.setUint8(at, u8arr[i], true);
- }
- },
- build_msg : function(in_type, extra)
- {
- this.type = in_type;
- this.size = extra.buffer_size();
- this.data = new ArrayBuffer(this.size);
- extra.to_buffer(this.data);
- },
- buffer_size: function()
- {
- if (this.data)
- return 6 + this.data.byteLength;
- else
- return 6;
- },
-}
-
-function SpiceMsgChannels(a, at)
-{
- this.num_of_channels = 0;
- this.channels = [];
- if (a !== undefined)
- this.from_buffer(a, at);
-}
-
-SpiceMsgChannels.prototype =
-{
- from_buffer: function(a, at)
- {
- at = at || 0;
- var i;
- var dv = new SpiceDataView(a);
- this.num_of_channels = dv.getUint32(at, true); at += 4;
- for (i = 0; i < this.num_of_channels; i++)
- {
- var chan = new SpiceChannelId();
- at = chan.from_dv(dv, at, a);
- this.channels.push(chan);
- }
- },
-}
-
-function SpiceMsgMainInit(a, at)
-{
- this.from_buffer(a, at);
-}
-
-SpiceMsgMainInit.prototype =
-{
- from_buffer: function(a, at)
- {
- at = at || 0;
- var dv = new SpiceDataView(a);
- this.session_id = dv.getUint32(at, true); at += 4;
- this.display_channels_hint = dv.getUint32(at, true); at += 4;
- this.supported_mouse_modes = dv.getUint32(at, true); at += 4;
- this.current_mouse_mode = dv.getUint32(at, true); at += 4;
- this.agent_connected = dv.getUint32(at, true); at += 4;
- this.agent_tokens = dv.getUint32(at, true); at += 4;
- this.multi_media_time = dv.getUint32(at, true); at += 4;
- this.ram_hint = dv.getUint32(at, true); at += 4;
- },
-}
-
-function SpiceMsgMainMouseMode(a, at)
-{
- this.from_buffer(a, at);
-}
-
-SpiceMsgMainMouseMode.prototype =
-{
- from_buffer: function(a, at)
- {
- at = at || 0;
- var dv = new SpiceDataView(a);
- this.supported_modes = dv.getUint16(at, true); at += 2;
- this.current_mode = dv.getUint16(at, true); at += 2;
- },
-}
-
-function SpiceMsgSetAck(a, at)
-{
- this.from_buffer(a, at);
-}
-
-SpiceMsgSetAck.prototype =
-{
- from_buffer: function(a, at)
- {
- at = at || 0;
- var dv = new SpiceDataView(a);
- this.generation = dv.getUint32(at, true); at += 4;
- this.window = dv.getUint32(at, true); at += 4;
- },
-}
-
-function SpiceMsgcAckSync(ack)
-{
- this.generation = ack.generation;
-}
-
-SpiceMsgcAckSync.prototype =
-{
- to_buffer: function(a, at)
- {
- at = at || 0;
- var dv = new SpiceDataView(a);
- dv.setUint32(at, this.generation, true); at += 4;
- },
- buffer_size: function()
- {
- return 4;
- }
-}
-
-function SpiceMsgcMainMouseModeRequest(mode)
-{
- this.mode = mode;
-}
-
-SpiceMsgcMainMouseModeRequest.prototype =
-{
- to_buffer: function(a, at)
- {
- at = at || 0;
- var dv = new SpiceDataView(a);
- dv.setUint16(at, this.mode, true); at += 2;
- },
- buffer_size: function()
- {
- return 2;
- }
-}
-
-function SpiceMsgcMainAgentStart(num_tokens)
-{
- this.num_tokens = num_tokens;
-}
-
-SpiceMsgcMainAgentStart.prototype =
-{
- to_buffer: function(a, at)
- {
- at = at || 0;
- var dv = new SpiceDataView(a);
- dv.setUint32(at, this.num_tokens, true); at += 4;
- },
- buffer_size: function()
- {
- return 4;
- }
-}
-
-function SpiceMsgcMainAgentData(type, data)
-{
- this.protocol = VD_AGENT_PROTOCOL;
- this.type = type;
- this.opaque = 0;
- this.size = data.buffer_size();
- this.data = data;
-}
-
-SpiceMsgcMainAgentData.prototype =
-{
- to_buffer: function(a, at)
- {
- at = at || 0;
- var dv = new SpiceDataView(a);
- dv.setUint32(at, this.protocol, true); at += 4;
- dv.setUint32(at, this.type, true); at += 4;
- dv.setUint64(at, this.opaque, true); at += 8;
- dv.setUint32(at, this.size, true); at += 4;
- this.data.to_buffer(a, at);
- },
- buffer_size: function()
- {
- return 4 + 4 + 8 + 4 + this.data.buffer_size();
- }
-}
-
-function VDAgentMonitorsConfig(flags, width, height, depth, x, y)
-{
- this.num_mon = 1;
- this.flags = flags;
- this.width = width;
- this.height = height;
- this.depth = depth;
- this.x = x;
- this.y = y;
-}
-
-VDAgentMonitorsConfig.prototype =
-{
- to_buffer: function(a, at)
- {
- at = at || 0;
- var dv = new SpiceDataView(a);
- dv.setUint32(at, this.num_mon, true); at += 4;
- dv.setUint32(at, this.flags, true); at += 4;
- dv.setUint32(at, this.height, true); at += 4;
- dv.setUint32(at, this.width, true); at += 4;
- dv.setUint32(at, this.depth, true); at += 4;
- dv.setUint32(at, this.x, true); at += 4;
- dv.setUint32(at, this.y, true); at += 4;
- },
- buffer_size: function()
- {
- return 28;
- }
-}
-
-function SpiceMsgNotify(a, at)
-{
- this.from_buffer(a, at);
-}
-
-SpiceMsgNotify.prototype =
-{
- from_buffer: function(a, at)
- {
- at = at || 0;
- var i;
- var dv = new SpiceDataView(a);
- this.time_stamp = dv.getUint64(at, true); at += 8;
- this.severity = dv.getUint32(at, true); at += 4;
- this.visibility = dv.getUint32(at, true); at += 4;
- this.what = dv.getUint32(at, true); at += 4;
- this.message_len = dv.getUint32(at, true); at += 4;
- this.message = "";
- for (i = 0; i < this.message_len; i++)
- {
- var c = dv.getUint8(at, true); at++;
- this.message += String.fromCharCode(c);
- }
- },
-}
-
-function SpiceMsgcDisplayInit()
-{
- this.pixmap_cache_id = 1;
- this.glz_dictionary_id = 0;
- this.pixmap_cache_size = 10 * 1024 * 1024;
- this.glz_dictionary_window_size = 0;
-}
-
-SpiceMsgcDisplayInit.prototype =
-{
- to_buffer: function(a, at)
- {
- at = at || 0;
- var dv = new SpiceDataView(a);
- dv.setUint8(at, this.pixmap_cache_id, true); at++;
- dv.setUint64(at, this.pixmap_cache_size, true); at += 8;
- dv.setUint8(at, this.glz_dictionary_id, true); at++;
- dv.setUint32(at, this.glz_dictionary_window_size, true); at += 4;
- },
- buffer_size: function()
- {
- return 14;
- }
-}
-
-function SpiceMsgDisplayBase()
-{
-}
-
-SpiceMsgDisplayBase.prototype =
-{
- from_dv : function(dv, at, mb)
- {
- this.surface_id = dv.getUint32(at, true); at += 4;
- this.box = new SpiceRect;
- at = this.box.from_dv(dv, at, mb);
- this.clip = new SpiceClip;
- return this.clip.from_dv(dv, at, mb);
- },
-}
-
-function SpiceMsgDisplayDrawCopy(a, at)
-{
- this.from_buffer(a, at);
-}
-
-SpiceMsgDisplayDrawCopy.prototype =
-{
- from_buffer: function(a, at)
- {
- at = at || 0;
- var dv = new SpiceDataView(a);
- this.base = new SpiceMsgDisplayBase;
- at = this.base.from_dv(dv, at, a);
- this.data = new SpiceCopy;
- return this.data.from_dv(dv, at, a);
- },
-}
-
-function SpiceMsgDisplayDrawFill(a, at)
-{
- this.from_buffer(a, at);
-}
-
-SpiceMsgDisplayDrawFill.prototype =
-{
- from_buffer: function(a, at)
- {
- at = at || 0;
- var dv = new SpiceDataView(a);
- this.base = new SpiceMsgDisplayBase;
- at = this.base.from_dv(dv, at, a);
- this.data = new SpiceFill;
- return this.data.from_dv(dv, at, a);
- },
-}
-
-function SpiceMsgDisplayCopyBits(a, at)
-{
- this.from_buffer(a, at);
-}
-
-SpiceMsgDisplayCopyBits.prototype =
-{
- from_buffer: function(a, at)
- {
- at = at || 0;
- var dv = new SpiceDataView(a);
- this.base = new SpiceMsgDisplayBase;
- at = this.base.from_dv(dv, at, a);
- this.src_pos = new SpicePoint;
- return this.src_pos.from_dv(dv, at, a);
- },
-}
-
-
-function SpiceMsgSurfaceCreate(a, at)
-{
- this.from_buffer(a, at);
-}
-
-SpiceMsgSurfaceCreate.prototype =
-{
- from_buffer: function(a, at)
- {
- at = at || 0;
- var dv = new SpiceDataView(a);
- this.surface = new SpiceSurface;
- return this.surface.from_dv(dv, at, a);
- },
-}
-
-function SpiceMsgSurfaceDestroy(a, at)
-{
- this.from_buffer(a, at);
-}
-
-SpiceMsgSurfaceDestroy.prototype =
-{
- from_buffer: function(a, at)
- {
- at = at || 0;
- var dv = new SpiceDataView(a);
- this.surface_id = dv.getUint32(at, true); at += 4;
- },
-}
-
-function SpiceMsgInputsInit(a, at)
-{
- this.from_buffer(a, at);
-}
-
-SpiceMsgInputsInit.prototype =
-{
- from_buffer: function(a, at)
- {
- at = at || 0;
- var dv = new SpiceDataView(a);
- this.keyboard_modifiers = dv.getUint16(at, true); at += 2;
- return at;
- },
-}
-
-function SpiceMsgInputsKeyModifiers(a, at)
-{
- this.from_buffer(a, at);
-}
-
-SpiceMsgInputsKeyModifiers.prototype =
-{
- from_buffer: function(a, at)
- {
- at = at || 0;
- var dv = new SpiceDataView(a);
- this.keyboard_modifiers = dv.getUint16(at, true); at += 2;
- return at;
- },
-}
-
-function SpiceMsgCursorInit(a, at)
-{
- this.from_buffer(a, at);
-}
-
-SpiceMsgCursorInit.prototype =
-{
- from_buffer: function(a, at, mb)
- {
- at = at || 0;
- var dv = new SpiceDataView(a);
- this.position = new SpicePoint16;
- at = this.position.from_dv(dv, at, mb);
- this.trail_length = dv.getUint16(at, true); at += 2;
- this.trail_frequency = dv.getUint16(at, true); at += 2;
- this.visible = dv.getUint8(at, true); at ++;
- this.cursor = new SpiceCursor;
- return this.cursor.from_dv(dv, at, a);
- },
-}
-
-function SpiceMsgPlaybackData(a, at)
-{
- this.from_buffer(a, at);
-}
-
-SpiceMsgPlaybackData.prototype =
-{
- from_buffer: function(a, at, mb)
- {
- at = at || 0;
- var dv = new SpiceDataView(a);
- this.time = dv.getUint32(at, true); at += 4;
- if (a.byteLength > at)
- {
- this.data = a.slice(at);
- at += this.data.byteLength;
- }
- return at;
- },
-}
-
-function SpiceMsgPlaybackMode(a, at)
-{
- this.from_buffer(a, at);
-}
-
-SpiceMsgPlaybackMode.prototype =
-{
- from_buffer: function(a, at, mb)
- {
- at = at || 0;
- var dv = new SpiceDataView(a);
- this.time = dv.getUint32(at, true); at += 4;
- this.mode = dv.getUint16(at, true); at += 2;
- if (a.byteLength > at)
- {
- this.data = a.slice(at);
- at += this.data.byteLength;
- }
- return at;
- },
-}
-
-function SpiceMsgPlaybackStart(a, at)
-{
- this.from_buffer(a, at);
-}
-
-SpiceMsgPlaybackStart.prototype =
-{
- from_buffer: function(a, at, mb)
- {
- at = at || 0;
- var dv = new SpiceDataView(a);
- this.channels = dv.getUint32(at, true); at += 4;
- this.format = dv.getUint16(at, true); at += 2;
- this.frequency = dv.getUint32(at, true); at += 4;
- this.time = dv.getUint32(at, true); at += 4;
- return at;
- },
-}
-
-
-
-function SpiceMsgCursorSet(a, at)
-{
- this.from_buffer(a, at);
-}
-
-SpiceMsgCursorSet.prototype =
-{
- from_buffer: function(a, at, mb)
- {
- at = at || 0;
- var dv = new SpiceDataView(a);
- this.position = new SpicePoint16;
- at = this.position.from_dv(dv, at, mb);
- this.visible = dv.getUint8(at, true); at ++;
- this.cursor = new SpiceCursor;
- return this.cursor.from_dv(dv, at, a);
- },
-}
-
-
-function SpiceMsgcMousePosition(sc, e)
-{
- // FIXME - figure out how to correctly compute display_id
- this.display_id = 0;
- this.buttons_state = sc.buttons_state;
- if (e)
- {
- var scrollTop = document.body.scrollTop || document.documentElement.scrollTop;
- var scrollLeft = document.body.scrollLeft ||
document.documentElement.scrollLeft;
-
- this.x = e.clientX -
sc.display.surfaces[sc.display.primary_surface].canvas.offsetLeft + scrollLeft;
- this.y = e.clientY -
sc.display.surfaces[sc.display.primary_surface].canvas.offsetTop + scrollTop;
- sc.mousex = this.x;
- sc.mousey = this.y;
- }
- else
- {
- this.x = this.y = this.buttons_state = 0;
- }
-}
-
-SpiceMsgcMousePosition.prototype =
-{
- to_buffer: function(a, at)
- {
- at = at || 0;
- var dv = new SpiceDataView(a);
- dv.setUint32(at, this.x, true); at += 4;
- dv.setUint32(at, this.y, true); at += 4;
- dv.setUint16(at, this.buttons_state, true); at += 2;
- dv.setUint8(at, this.display_id, true); at += 1;
- return at;
- },
- buffer_size: function()
- {
- return 11;
- }
-}
-
-function SpiceMsgcMouseMotion(sc, e)
-{
- // FIXME - figure out how to correctly compute display_id
- this.display_id = 0;
- this.buttons_state = sc.buttons_state;
- if (e)
- {
- this.x = e.clientX -
sc.display.surfaces[sc.display.primary_surface].canvas.offsetLeft;
- this.y = e.clientY -
sc.display.surfaces[sc.display.primary_surface].canvas.offsetTop;
-
- if (sc.mousex !== undefined)
- {
- this.x -= sc.mousex;
- this.y -= sc.mousey;
- }
- sc.mousex = e.clientX -
sc.display.surfaces[sc.display.primary_surface].canvas.offsetLeft;
- sc.mousey = e.clientY -
sc.display.surfaces[sc.display.primary_surface].canvas.offsetTop;
- }
- else
- {
- this.x = this.y = this.buttons_state = 0;
- }
-}
-
-/* Use the same functions as for MousePosition */
-SpiceMsgcMouseMotion.prototype.to_buffer = SpiceMsgcMousePosition.prototype.to_buffer;
-SpiceMsgcMouseMotion.prototype.buffer_size =
SpiceMsgcMousePosition.prototype.buffer_size;
-
-function SpiceMsgcMousePress(sc, e)
-{
- if (e)
- {
- this.button = e.button + 1;
- this.buttons_state = 1 << e.button;
- sc.buttons_state = this.buttons_state;
- }
- else
- {
- this.button = SPICE_MOUSE_BUTTON_LEFT;
- this.buttons_state = SPICE_MOUSE_BUTTON_MASK_LEFT;
- }
-}
-
-SpiceMsgcMousePress.prototype =
-{
- to_buffer: function(a, at)
- {
- at = at || 0;
- var dv = new SpiceDataView(a);
- dv.setUint8(at, this.button, true); at ++;
- dv.setUint16(at, this.buttons_state, true); at += 2;
- return at;
- },
- buffer_size: function()
- {
- return 3;
- }
-}
-
-function SpiceMsgcMouseRelease(sc, e)
-{
- if (e)
- {
- this.button = e.button + 1;
- this.buttons_state = 0;
- sc.buttons_state = this.buttons_state;
- }
- else
- {
- this.button = SPICE_MOUSE_BUTTON_LEFT;
- this.buttons_state = 0;
- }
-}
-
-/* Use the same functions as for MousePress */
-SpiceMsgcMouseRelease.prototype.to_buffer = SpiceMsgcMousePress.prototype.to_buffer;
-SpiceMsgcMouseRelease.prototype.buffer_size = SpiceMsgcMousePress.prototype.buffer_size;
-
-
-function SpiceMsgcKeyDown(e)
-{
- if (e)
- {
- this.code = keycode_to_start_scan(e.keyCode);
- }
- else
- {
- this.code = 0;
- }
-}
-
-SpiceMsgcKeyDown.prototype =
-{
- to_buffer: function(a, at)
- {
- at = at || 0;
- var dv = new SpiceDataView(a);
- dv.setUint32(at, this.code, true); at += 4;
- return at;
- },
- buffer_size: function()
- {
- return 4;
- }
-}
-
-function SpiceMsgcKeyUp(e)
-{
- if (e)
- {
- this.code = keycode_to_end_scan(e.keyCode);
- }
- else
- {
- this.code = 0;
- }
-}
-
-/* Use the same functions as for KeyDown */
-SpiceMsgcKeyUp.prototype.to_buffer = SpiceMsgcKeyDown.prototype.to_buffer;
-SpiceMsgcKeyUp.prototype.buffer_size = SpiceMsgcKeyDown.prototype.buffer_size;
-
-function SpiceMsgDisplayStreamCreate(a, at)
-{
- this.from_buffer(a, at);
-}
-
-SpiceMsgDisplayStreamCreate.prototype =
-{
- from_buffer: function(a, at)
- {
- at = at || 0;
- var dv = new SpiceDataView(a);
- this.surface_id = dv.getUint32(at, true); at += 4;
- this.id = dv.getUint32(at, true); at += 4;
- this.flags = dv.getUint8(at, true); at += 1;
- this.codec_type = dv.getUint8(at, true); at += 1;
- this.stamp = dv.getUint64(at, true); at += 8;
- this.stream_width = dv.getUint32(at, true); at += 4;
- this.stream_height = dv.getUint32(at, true); at += 4;
- this.src_width = dv.getUint32(at, true); at += 4;
- this.src_height = dv.getUint32(at, true); at += 4;
-
- this.dest = new SpiceRect;
- at = this.dest.from_dv(dv, at, a);
- this.clip = new SpiceClip;
- this.clip.from_dv(dv, at, a);
- },
-}
-
-function SpiceStreamDataHeader(a, at)
-{
-}
-
-SpiceStreamDataHeader.prototype =
-{
- from_dv : function(dv, at, mb)
- {
- this.id = dv.getUint32(at, true); at += 4;
- this.multi_media_time = dv.getUint32(at, true); at += 4;
- return at;
- },
-}
-
-function SpiceMsgDisplayStreamData(a, at)
-{
- this.from_buffer(a, at);
-}
-
-SpiceMsgDisplayStreamData.prototype =
-{
- from_buffer: function(a, at)
- {
- at = at || 0;
- var dv = new SpiceDataView(a);
- this.base = new SpiceStreamDataHeader;
- at = this.base.from_dv(dv, at, a);
- this.data_size = dv.getUint32(at, true); at += 4;
- this.data = dv.u8.subarray(at, at + this.data_size);
- },
-}
-
-function SpiceMsgDisplayStreamClip(a, at)
-{
- this.from_buffer(a, at);
-}
-
-SpiceMsgDisplayStreamClip.prototype =
-{
- from_buffer: function(a, at)
- {
- at = at || 0;
- var dv = new SpiceDataView(a);
- this.id = dv.getUint32(at, true); at += 4;
- this.clip = new SpiceClip;
- this.clip.from_dv(dv, at, a);
- },
-}
-
-function SpiceMsgDisplayStreamDestroy(a, at)
-{
- this.from_buffer(a, at);
-}
-
-SpiceMsgDisplayStreamDestroy.prototype =
-{
- from_buffer: function(a, at)
- {
- at = at || 0;
- var dv = new SpiceDataView(a);
- this.id = dv.getUint32(at, true); at += 4;
- },
-}
-
-function SpiceMsgDisplayInvalList(a, at)
-{
- this.count = 0;
- this.resources = [];
- this.from_buffer(a,at);
-}
-
-SpiceMsgDisplayInvalList.prototype =
-{
- from_buffer: function (a, at)
- {
- var i;
- at = at || 0;
- var dv = new SpiceDataView(a);
- this.count = dv.getUint16(at, true); at += 2;
- for (i = 0; i < this.count; i++)
- {
- this.resources[i] = {};
- this.resources[i].type = dv.getUint8(at, true); at++;
- this.resources[i].id = dv.getUint64(at, true); at += 8;
- }
- },
-}
diff --git a/plugins/kimchi/ui/spice-html5/spicetype.js
b/plugins/kimchi/ui/spice-html5/spicetype.js
deleted file mode 100644
index 951b277..0000000
--- a/plugins/kimchi/ui/spice-html5/spicetype.js
+++ /dev/null
@@ -1,473 +0,0 @@
-"use strict";
-/*
- Copyright (C) 2012 by Jeremy P. White <jwhite(a)codeweavers.com>
-
- This file is part of spice-html5.
-
- spice-html5 is free software: you can redistribute it and/or modify
- it under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- spice-html5 is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public License
- along with spice-html5. If not, see <
http://www.gnu.org/licenses/>.
-*/
-
-/*----------------------------------------------------------------------------
-** Spice types
-** This file contains classes for common spice types.
-** Generally, they are used as helpers in reading and writing messages
-** to and from the server.
-**--------------------------------------------------------------------------*/
-
-function SpiceChannelId()
-{
-}
-SpiceChannelId.prototype =
-{
- from_dv: function(dv, at, mb)
- {
- this.type = dv.getUint8(at, true); at ++;
- this.id = dv.getUint8(at, true); at ++;
- return at;
- },
-}
-
-function SpiceRect()
-{
-}
-
-SpiceRect.prototype =
-{
- from_dv: function(dv, at, mb)
- {
- this.top = dv.getUint32(at, true); at += 4;
- this.left = dv.getUint32(at, true); at += 4;
- this.bottom = dv.getUint32(at, true); at += 4;
- this.right = dv.getUint32(at, true); at += 4;
- return at;
- },
- is_same_size : function(r)
- {
- if ((this.bottom - this.top) == (r.bottom - r.top) &&
- (this.right - this.left) == (r.right - r.left) )
- return true;
-
- return false;
- },
-}
-
-function SpiceClipRects()
-{
-}
-
-SpiceClipRects.prototype =
-{
- from_dv: function(dv, at, mb)
- {
- var i;
- this.num_rects = dv.getUint32(at, true); at += 4;
- if (this.num_rects > 0)
- this.rects = [];
- for (i = 0; i < this.num_rects; i++)
- {
- this.rects[i] = new SpiceRect();
- at = this.rects[i].from_dv(dv, at, mb);
- }
- return at;
- },
-}
-
-function SpiceClip()
-{
-}
-
-SpiceClip.prototype =
-{
- from_dv: function(dv, at, mb)
- {
- this.type = dv.getUint8(at, true); at ++;
- if (this.type == SPICE_CLIP_TYPE_RECTS)
- {
- this.rects = new SpiceClipRects();
- at = this.rects.from_dv(dv, at, mb);
- }
- return at;
- },
-}
-
-function SpiceImageDescriptor()
-{
-}
-
-SpiceImageDescriptor.prototype =
-{
- from_dv: function(dv, at, mb)
- {
- this.id = dv.getUint64(at, true); at += 8;
- this.type = dv.getUint8(at, true); at ++;
- this.flags = dv.getUint8(at, true); at ++;
- this.width = dv.getUint32(at, true); at += 4;
- this.height= dv.getUint32(at, true); at += 4;
- return at;
- },
-}
-
-function SpicePalette()
-{
-}
-
-SpicePalette.prototype =
-{
- from_dv: function(dv, at, mb)
- {
- var i;
- this.unique = dv.getUint64(at, true); at += 8;
- this.num_ents = dv.getUint16(at, true); at += 2;
- this.ents = [];
- for (i = 0; i < this.num_ents; i++)
- {
- this.ents[i] = dv.getUint32(at, true); at += 4;
- }
- return at;
- },
-}
-
-function SpiceBitmap()
-{
-}
-
-SpiceBitmap.prototype =
-{
- from_dv: function(dv, at, mb)
- {
- this.format = dv.getUint8(at, true); at++;
- this.flags = dv.getUint8(at, true); at++;
- this.x = dv.getUint32(at, true); at += 4;
- this.y = dv.getUint32(at, true); at += 4;
- this.stride = dv.getUint32(at, true); at += 4;
- if (this.flags & SPICE_BITMAP_FLAGS_PAL_FROM_CACHE)
- {
- this.palette_id = dv.getUint64(at, true); at += 8;
- }
- else
- {
- var offset = dv.getUint32(at, true); at += 4;
- if (offset == 0)
- this.palette = null;
- else
- {
- this.palette = new SpicePalette;
- this.palette.from_dv(dv, offset, mb);
- }
- }
- // FIXME - should probably constrain this to the offset
- // of palette, if non zero
- this.data = mb.slice(at);
- at += this.data.byteLength;
- return at;
- },
-}
-
-function SpiceImage()
-{
-}
-
-SpiceImage.prototype =
-{
- from_dv: function(dv, at, mb)
- {
- this.descriptor = new SpiceImageDescriptor;
- at = this.descriptor.from_dv(dv, at, mb);
-
- if (this.descriptor.type == SPICE_IMAGE_TYPE_LZ_RGB)
- {
- this.lz_rgb = new Object();
- this.lz_rgb.length = dv.getUint32(at, true); at += 4;
- var initial_at = at;
- this.lz_rgb.magic = "";
- for (var i = 3; i >= 0; i--)
- this.lz_rgb.magic += String.fromCharCode(dv.getUint8(at + i));
- at += 4;
-
- // NOTE: The endian change is *correct*
- this.lz_rgb.version = dv.getUint32(at); at += 4;
- this.lz_rgb.type = dv.getUint32(at); at += 4;
- this.lz_rgb.width = dv.getUint32(at); at += 4;
- this.lz_rgb.height = dv.getUint32(at); at += 4;
- this.lz_rgb.stride = dv.getUint32(at); at += 4;
- this.lz_rgb.top_down = dv.getUint32(at); at += 4;
-
- var header_size = at - initial_at;
-
- this.lz_rgb.data = mb.slice(at, this.lz_rgb.length + at - header_size);
- at += this.lz_rgb.data.byteLength;
-
- }
-
- if (this.descriptor.type == SPICE_IMAGE_TYPE_BITMAP)
- {
- this.bitmap = new SpiceBitmap;
- at = this.bitmap.from_dv(dv, at, mb);
- }
-
- if (this.descriptor.type == SPICE_IMAGE_TYPE_SURFACE)
- {
- this.surface_id = dv.getUint32(at, true); at += 4;
- }
-
- if (this.descriptor.type == SPICE_IMAGE_TYPE_JPEG)
- {
- this.jpeg = new Object;
- this.jpeg.data_size = dv.getUint32(at, true); at += 4;
- this.jpeg.data = mb.slice(at);
- at += this.jpeg.data.byteLength;
- }
-
- if (this.descriptor.type == SPICE_IMAGE_TYPE_JPEG_ALPHA)
- {
- this.jpeg_alpha = new Object;
- this.jpeg_alpha.flags = dv.getUint8(at, true); at += 1;
- this.jpeg_alpha.jpeg_size = dv.getUint32(at, true); at += 4;
- this.jpeg_alpha.data_size = dv.getUint32(at, true); at += 4;
- this.jpeg_alpha.data = mb.slice(at, this.jpeg_alpha.jpeg_size + at);
- at += this.jpeg_alpha.data.byteLength;
- // Alpha channel is an LZ image
- this.jpeg_alpha.alpha = new Object();
- this.jpeg_alpha.alpha.length = this.jpeg_alpha.data_size -
this.jpeg_alpha.jpeg_size;
- var initial_at = at;
- this.jpeg_alpha.alpha.magic = "";
- for (var i = 3; i >= 0; i--)
- this.jpeg_alpha.alpha.magic += String.fromCharCode(dv.getUint8(at + i));
- at += 4;
-
- // NOTE: The endian change is *correct*
- this.jpeg_alpha.alpha.version = dv.getUint32(at); at += 4;
- this.jpeg_alpha.alpha.type = dv.getUint32(at); at += 4;
- this.jpeg_alpha.alpha.width = dv.getUint32(at); at += 4;
- this.jpeg_alpha.alpha.height = dv.getUint32(at); at += 4;
- this.jpeg_alpha.alpha.stride = dv.getUint32(at); at += 4;
- this.jpeg_alpha.alpha.top_down = dv.getUint32(at); at += 4;
-
- var header_size = at - initial_at;
-
- this.jpeg_alpha.alpha.data = mb.slice(at, this.jpeg_alpha.alpha.length + at
- header_size);
- at += this.jpeg_alpha.alpha.data.byteLength;
- }
-
- if (this.descriptor.type == SPICE_IMAGE_TYPE_QUIC)
- {
- this.quic = new SpiceQuic;
- at = this.quic.from_dv(dv, at, mb);
- }
- return at;
- },
-}
-
-
-function SpiceQMask()
-{
-}
-
-SpiceQMask.prototype =
-{
- from_dv: function(dv, at, mb)
- {
- this.flags = dv.getUint8(at, true); at++;
- this.pos = new SpicePoint;
- at = this.pos.from_dv(dv, at, mb);
- var offset = dv.getUint32(at, true); at += 4;
- if (offset == 0)
- {
- this.bitmap = null;
- return at;
- }
-
- this.bitmap = new SpiceImage;
- return this.bitmap.from_dv(dv, offset, mb);
- },
-}
-
-
-function SpicePattern()
-{
-}
-
-SpicePattern.prototype =
-{
- from_dv: function(dv, at, mb)
- {
- var offset = dv.getUint32(at, true); at += 4;
- if (offset == 0)
- {
- this.pat = null;
- }
- else
- {
- this.pat = new SpiceImage;
- this.pat.from_dv(dv, offset, mb);
- }
-
- this.pos = new SpicePoint;
- return this.pos.from_dv(dv, at, mb);
- }
-}
-
-function SpiceBrush()
-{
-}
-
-SpiceBrush.prototype =
-{
- from_dv: function(dv, at, mb)
- {
- this.type = dv.getUint8(at, true); at ++;
- if (this.type == SPICE_BRUSH_TYPE_SOLID)
- {
- this.color = dv.getUint32(at, true); at += 4;
- }
- else if (this.type == SPICE_BRUSH_TYPE_PATTERN)
- {
- this.pattern = new SpicePattern;
- at = this.pattern.from_dv(dv, at, mb);
- }
- return at;
- },
-}
-
-function SpiceFill()
-{
-}
-
-SpiceFill.prototype =
-{
- from_dv: function(dv, at, mb)
- {
- this.brush = new SpiceBrush;
- at = this.brush.from_dv(dv, at, mb);
- this.rop_descriptor = dv.getUint16(at, true); at += 2;
- this.mask = new SpiceQMask;
- return this.mask.from_dv(dv, at, mb);
- },
-}
-
-
-function SpiceCopy()
-{
-}
-
-SpiceCopy.prototype =
-{
- from_dv: function(dv, at, mb)
- {
- var offset = dv.getUint32(at, true); at += 4;
- if (offset == 0)
- {
- this.src_bitmap = null;
- }
- else
- {
- this.src_bitmap = new SpiceImage;
- this.src_bitmap.from_dv(dv, offset, mb);
- }
- this.src_area = new SpiceRect;
- at = this.src_area.from_dv(dv, at, mb);
- this.rop_descriptor = dv.getUint16(at, true); at += 2;
- this.scale_mode = dv.getUint8(at, true); at ++;
- this.mask = new SpiceQMask;
- return this.mask.from_dv(dv, at, mb);
- },
-}
-
-function SpicePoint16()
-{
-}
-
-SpicePoint16.prototype =
-{
- from_dv: function(dv, at, mb)
- {
- this.x = dv.getUint16(at, true); at += 2;
- this.y = dv.getUint16(at, true); at += 2;
- return at;
- },
-}
-
-function SpicePoint()
-{
-}
-
-SpicePoint.prototype =
-{
- from_dv: function(dv, at, mb)
- {
- this.x = dv.getUint32(at, true); at += 4;
- this.y = dv.getUint32(at, true); at += 4;
- return at;
- },
-}
-
-function SpiceCursorHeader()
-{
-}
-
-SpiceCursorHeader.prototype =
-{
- from_dv: function(dv, at, mb)
- {
- this.unique = dv.getUint64(at, true); at += 8;
- this.type = dv.getUint8(at, true); at ++;
- this.width = dv.getUint16(at, true); at += 2;
- this.height = dv.getUint16(at, true); at += 2;
- this.hot_spot_x = dv.getUint16(at, true); at += 2;
- this.hot_spot_y = dv.getUint16(at, true); at += 2;
- return at;
- },
-}
-
-function SpiceCursor()
-{
-}
-
-SpiceCursor.prototype =
-{
- from_dv: function(dv, at, mb)
- {
- this.flags = dv.getUint16(at, true); at += 2;
- if (this.flags & SPICE_CURSOR_FLAGS_NONE)
- this.header = null;
- else
- {
- this.header = new SpiceCursorHeader;
- at = this.header.from_dv(dv, at, mb);
- this.data = mb.slice(at);
- at += this.data.byteLength;
- }
- return at;
- },
-}
-
-function SpiceSurface()
-{
-}
-
-SpiceSurface.prototype =
-{
- from_dv: function(dv, at, mb)
- {
- this.surface_id = dv.getUint32(at, true); at += 4;
- this.width = dv.getUint32(at, true); at += 4;
- this.height = dv.getUint32(at, true); at += 4;
- this.format = dv.getUint32(at, true); at += 4;
- this.flags = dv.getUint32(at, true); at += 4;
- return at;
- },
-}
-
-/* FIXME - SpiceImage types lz_plt, jpeg, zlib_glz, and jpeg_alpha are
- completely unimplemented */
diff --git a/plugins/kimchi/ui/spice-html5/thirdparty/Makefile.am
b/plugins/kimchi/ui/spice-html5/thirdparty/Makefile.am
deleted file mode 100644
index 474478d..0000000
--- a/plugins/kimchi/ui/spice-html5/thirdparty/Makefile.am
+++ /dev/null
@@ -1,20 +0,0 @@
-#
-# Kimchi
-#
-# Copyright IBM, Corp. 2014
-#
-# 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.
-
-thirdpartydir = $(datadir)/wok/plugins/kimchi/ui/spice-html5/thirdparty
-
-dist_thirdparty_DATA = $(wildcard *.js) $(NULL)
diff --git a/plugins/kimchi/ui/spice-html5/thirdparty/jsbn.js
b/plugins/kimchi/ui/spice-html5/thirdparty/jsbn.js
deleted file mode 100644
index 9b9476e..0000000
--- a/plugins/kimchi/ui/spice-html5/thirdparty/jsbn.js
+++ /dev/null
@@ -1,589 +0,0 @@
-// Downloaded from
http://www-cs-students.stanford.edu/~tjw/jsbn/ by Jeremy White on
6/1/2012
-
-/*
- * Copyright (c) 2003-2005 Tom Wu
- * All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining
- * a copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including
- * without limitation the rights to use, copy, modify, merge, publish,
- * distribute, sublicense, and/or sell copies of the Software, and to
- * permit persons to whom the Software is furnished to do so, subject to
- * the following conditions:
- *
- * The above copyright notice and this permission notice shall be
- * included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
- * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
- *
- * IN NO EVENT SHALL TOM WU BE LIABLE FOR ANY SPECIAL, INCIDENTAL,
- * INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, OR ANY DAMAGES WHATSOEVER
- * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER OR NOT ADVISED OF
- * THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF LIABILITY, ARISING OUT
- * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- *
- * In addition, the following condition applies:
- *
- * All redistributions must retain an intact copy of this copyright notice
- * and disclaimer.
- */
-
-
-// Basic JavaScript BN library - subset useful for RSA encryption.
-
-// Bits per digit
-var dbits;
-
-// JavaScript engine analysis
-var canary = 0xdeadbeefcafe;
-var j_lm = ((canary&0xffffff)==0xefcafe);
-
-// (public) Constructor
-function BigInteger(a,b,c) {
- if(a != null)
- if("number" == typeof a) this.fromNumber(a,b,c);
- else if(b == null && "string" != typeof a) this.fromString(a,256);
- else this.fromString(a,b);
-}
-
-// return new, unset BigInteger
-function nbi() { return new BigInteger(null); }
-
-// am: Compute w_j += (x*this_i), propagate carries,
-// c is initial carry, returns final carry.
-// c < 3*dvalue, x < 2*dvalue, this_i < dvalue
-// We need to select the fastest one that works in this environment.
-
-// am1: use a single mult and divide to get the high bits,
-// max digit bits should be 26 because
-// max internal value = 2*dvalue^2-2*dvalue (< 2^53)
-function am1(i,x,w,j,c,n) {
- while(--n >= 0) {
- var v = x*this[i++]+w[j]+c;
- c = Math.floor(v/0x4000000);
- w[j++] = v&0x3ffffff;
- }
- return c;
-}
-// am2 avoids a big mult-and-extract completely.
-// Max digit bits should be <= 30 because we do bitwise ops
-// on values up to 2*hdvalue^2-hdvalue-1 (< 2^31)
-function am2(i,x,w,j,c,n) {
- var xl = x&0x7fff, xh = x>>15;
- while(--n >= 0) {
- var l = this[i]&0x7fff;
- var h = this[i++]>>15;
- var m = xh*l+h*xl;
- l = xl*l+((m&0x7fff)<<15)+w[j]+(c&0x3fffffff);
- c = (l>>>30)+(m>>>15)+xh*h+(c>>>30);
- w[j++] = l&0x3fffffff;
- }
- return c;
-}
-// Alternately, set max digit bits to 28 since some
-// browsers slow down when dealing with 32-bit numbers.
-function am3(i,x,w,j,c,n) {
- var xl = x&0x3fff, xh = x>>14;
- while(--n >= 0) {
- var l = this[i]&0x3fff;
- var h = this[i++]>>14;
- var m = xh*l+h*xl;
- l = xl*l+((m&0x3fff)<<14)+w[j]+c;
- c = (l>>28)+(m>>14)+xh*h;
- w[j++] = l&0xfffffff;
- }
- return c;
-}
-if(j_lm && (navigator.appName == "Microsoft Internet Explorer")) {
- BigInteger.prototype.am = am2;
- dbits = 30;
-}
-else if(j_lm && (navigator.appName != "Netscape")) {
- BigInteger.prototype.am = am1;
- dbits = 26;
-}
-else { // Mozilla/Netscape seems to prefer am3
- BigInteger.prototype.am = am3;
- dbits = 28;
-}
-
-BigInteger.prototype.DB = dbits;
-BigInteger.prototype.DM = ((1<<dbits)-1);
-BigInteger.prototype.DV = (1<<dbits);
-
-var BI_FP = 52;
-BigInteger.prototype.FV = Math.pow(2,BI_FP);
-BigInteger.prototype.F1 = BI_FP-dbits;
-BigInteger.prototype.F2 = 2*dbits-BI_FP;
-
-// Digit conversions
-var BI_RM = "0123456789abcdefghijklmnopqrstuvwxyz";
-var BI_RC = new Array();
-var rr,vv;
-rr = "0".charCodeAt(0);
-for(vv = 0; vv <= 9; ++vv) BI_RC[rr++] = vv;
-rr = "a".charCodeAt(0);
-for(vv = 10; vv < 36; ++vv) BI_RC[rr++] = vv;
-rr = "A".charCodeAt(0);
-for(vv = 10; vv < 36; ++vv) BI_RC[rr++] = vv;
-
-function int2char(n) { return BI_RM.charAt(n); }
-function intAt(s,i) {
- var c = BI_RC[s.charCodeAt(i)];
- return (c==null)?-1:c;
-}
-
-// (protected) copy this to r
-function bnpCopyTo(r) {
- for(var i = this.t-1; i >= 0; --i) r[i] = this[i];
- r.t = this.t;
- r.s = this.s;
-}
-
-// (protected) set from integer value x, -DV <= x < DV
-function bnpFromInt(x) {
- this.t = 1;
- this.s = (x<0)?-1:0;
- if(x > 0) this[0] = x;
- else if(x < -1) this[0] = x+DV;
- else this.t = 0;
-}
-
-// return bigint initialized to value
-function nbv(i) { var r = nbi(); r.fromInt(i); return r; }
-
-// (protected) set from string and radix
-function bnpFromString(s,b) {
- var k;
- if(b == 16) k = 4;
- else if(b == 8) k = 3;
- else if(b == 256) k = 8; // byte array
- else if(b == 2) k = 1;
- else if(b == 32) k = 5;
- else if(b == 4) k = 2;
- else { this.fromRadix(s,b); return; }
- this.t = 0;
- this.s = 0;
- var i = s.length, mi = false, sh = 0;
- while(--i >= 0) {
- var x = (k==8)?s[i]&0xff:intAt(s,i);
- if(x < 0) {
- if(s.charAt(i) == "-") mi = true;
- continue;
- }
- mi = false;
- if(sh == 0)
- this[this.t++] = x;
- else if(sh+k > this.DB) {
- this[this.t-1] |= (x&((1<<(this.DB-sh))-1))<<sh;
- this[this.t++] = (x>>(this.DB-sh));
- }
- else
- this[this.t-1] |= x<<sh;
- sh += k;
- if(sh >= this.DB) sh -= this.DB;
- }
- if(k == 8 && (s[0]&0x80) != 0) {
- this.s = -1;
- if(sh > 0) this[this.t-1] |= ((1<<(this.DB-sh))-1)<<sh;
- }
- this.clamp();
- if(mi) BigInteger.ZERO.subTo(this,this);
-}
-
-// (protected) clamp off excess high words
-function bnpClamp() {
- var c = this.s&this.DM;
- while(this.t > 0 && this[this.t-1] == c) --this.t;
-}
-
-// (public) return string representation in given radix
-function bnToString(b) {
- if(this.s < 0) return "-"+this.negate().toString(b);
- var k;
- if(b == 16) k = 4;
- else if(b == 8) k = 3;
- else if(b == 2) k = 1;
- else if(b == 32) k = 5;
- else if(b == 4) k = 2;
- else return this.toRadix(b);
- var km = (1<<k)-1, d, m = false, r = "", i = this.t;
- var p = this.DB-(i*this.DB)%k;
- if(i-- > 0) {
- if(p < this.DB && (d = this[i]>>p) > 0) { m = true; r =
int2char(d); }
- while(i >= 0) {
- if(p < k) {
- d = (this[i]&((1<<p)-1))<<(k-p);
- d |= this[--i]>>(p+=this.DB-k);
- }
- else {
- d = (this[i]>>(p-=k))&km;
- if(p <= 0) { p += this.DB; --i; }
- }
- if(d > 0) m = true;
- if(m) r += int2char(d);
- }
- }
- return m?r:"0";
-}
-
-// (public) -this
-function bnNegate() { var r = nbi(); BigInteger.ZERO.subTo(this,r); return r; }
-
-// (public) |this|
-function bnAbs() { return (this.s<0)?this.negate():this; }
-
-// (public) return + if this > a, - if this < a, 0 if equal
-function bnCompareTo(a) {
- var r = this.s-a.s;
- if(r != 0) return r;
- var i = this.t;
- r = i-a.t;
- if(r != 0) return r;
- while(--i >= 0) if((r=this[i]-a[i]) != 0) return r;
- return 0;
-}
-
-// returns bit length of the integer x
-function nbits(x) {
- var r = 1, t;
- if((t=x>>>16) != 0) { x = t; r += 16; }
- if((t=x>>8) != 0) { x = t; r += 8; }
- if((t=x>>4) != 0) { x = t; r += 4; }
- if((t=x>>2) != 0) { x = t; r += 2; }
- if((t=x>>1) != 0) { x = t; r += 1; }
- return r;
-}
-
-// (public) return the number of bits in "this"
-function bnBitLength() {
- if(this.t <= 0) return 0;
- return this.DB*(this.t-1)+nbits(this[this.t-1]^(this.s&this.DM));
-}
-
-// (protected) r = this << n*DB
-function bnpDLShiftTo(n,r) {
- var i;
- for(i = this.t-1; i >= 0; --i) r[i+n] = this[i];
- for(i = n-1; i >= 0; --i) r[i] = 0;
- r.t = this.t+n;
- r.s = this.s;
-}
-
-// (protected) r = this >> n*DB
-function bnpDRShiftTo(n,r) {
- for(var i = n; i < this.t; ++i) r[i-n] = this[i];
- r.t = Math.max(this.t-n,0);
- r.s = this.s;
-}
-
-// (protected) r = this << n
-function bnpLShiftTo(n,r) {
- var bs = n%this.DB;
- var cbs = this.DB-bs;
- var bm = (1<<cbs)-1;
- var ds = Math.floor(n/this.DB), c = (this.s<<bs)&this.DM, i;
- for(i = this.t-1; i >= 0; --i) {
- r[i+ds+1] = (this[i]>>cbs)|c;
- c = (this[i]&bm)<<bs;
- }
- for(i = ds-1; i >= 0; --i) r[i] = 0;
- r[ds] = c;
- r.t = this.t+ds+1;
- r.s = this.s;
- r.clamp();
-}
-
-// (protected) r = this >> n
-function bnpRShiftTo(n,r) {
- r.s = this.s;
- var ds = Math.floor(n/this.DB);
- if(ds >= this.t) { r.t = 0; return; }
- var bs = n%this.DB;
- var cbs = this.DB-bs;
- var bm = (1<<bs)-1;
- r[0] = this[ds]>>bs;
- for(var i = ds+1; i < this.t; ++i) {
- r[i-ds-1] |= (this[i]&bm)<<cbs;
- r[i-ds] = this[i]>>bs;
- }
- if(bs > 0) r[this.t-ds-1] |= (this.s&bm)<<cbs;
- r.t = this.t-ds;
- r.clamp();
-}
-
-// (protected) r = this - a
-function bnpSubTo(a,r) {
- var i = 0, c = 0, m = Math.min(a.t,this.t);
- while(i < m) {
- c += this[i]-a[i];
- r[i++] = c&this.DM;
- c >>= this.DB;
- }
- if(a.t < this.t) {
- c -= a.s;
- while(i < this.t) {
- c += this[i];
- r[i++] = c&this.DM;
- c >>= this.DB;
- }
- c += this.s;
- }
- else {
- c += this.s;
- while(i < a.t) {
- c -= a[i];
- r[i++] = c&this.DM;
- c >>= this.DB;
- }
- c -= a.s;
- }
- r.s = (c<0)?-1:0;
- if(c < -1) r[i++] = this.DV+c;
- else if(c > 0) r[i++] = c;
- r.t = i;
- r.clamp();
-}
-
-// (protected) r = this * a, r != this,a (HAC 14.12)
-// "this" should be the larger one if appropriate.
-function bnpMultiplyTo(a,r) {
- var x = this.abs(), y = a.abs();
- var i = x.t;
- r.t = i+y.t;
- while(--i >= 0) r[i] = 0;
- for(i = 0; i < y.t; ++i) r[i+x.t] = x.am(0,y[i],r,i,0,x.t);
- r.s = 0;
- r.clamp();
- if(this.s != a.s) BigInteger.ZERO.subTo(r,r);
-}
-
-// (protected) r = this^2, r != this (HAC 14.16)
-function bnpSquareTo(r) {
- var x = this.abs();
- var i = r.t = 2*x.t;
- while(--i >= 0) r[i] = 0;
- for(i = 0; i < x.t-1; ++i) {
- var c = x.am(i,x[i],r,2*i,0,1);
- if((r[i+x.t]+=x.am(i+1,2*x[i],r,2*i+1,c,x.t-i-1)) >= x.DV) {
- r[i+x.t] -= x.DV;
- r[i+x.t+1] = 1;
- }
- }
- if(r.t > 0) r[r.t-1] += x.am(i,x[i],r,2*i,0,1);
- r.s = 0;
- r.clamp();
-}
-
-// (protected) divide this by m, quotient and remainder to q, r (HAC 14.20)
-// r != q, this != m. q or r may be null.
-function bnpDivRemTo(m,q,r) {
- var pm = m.abs();
- if(pm.t <= 0) return;
- var pt = this.abs();
- if(pt.t < pm.t) {
- if(q != null) q.fromInt(0);
- if(r != null) this.copyTo(r);
- return;
- }
- if(r == null) r = nbi();
- var y = nbi(), ts = this.s, ms = m.s;
- var nsh = this.DB-nbits(pm[pm.t-1]); // normalize modulus
- if(nsh > 0) { pm.lShiftTo(nsh,y); pt.lShiftTo(nsh,r); }
- else { pm.copyTo(y); pt.copyTo(r); }
- var ys = y.t;
- var y0 = y[ys-1];
- if(y0 == 0) return;
- var yt = y0*(1<<this.F1)+((ys>1)?y[ys-2]>>this.F2:0);
- var d1 = this.FV/yt, d2 = (1<<this.F1)/yt, e = 1<<this.F2;
- var i = r.t, j = i-ys, t = (q==null)?nbi():q;
- y.dlShiftTo(j,t);
- if(r.compareTo(t) >= 0) {
- r[r.t++] = 1;
- r.subTo(t,r);
- }
- BigInteger.ONE.dlShiftTo(ys,t);
- t.subTo(y,y); // "negative" y so we can replace sub with am later
- while(y.t < ys) y[y.t++] = 0;
- while(--j >= 0) {
- // Estimate quotient digit
- var qd = (r[--i]==y0)?this.DM:Math.floor(r[i]*d1+(r[i-1]+e)*d2);
- if((r[i]+=y.am(0,qd,r,j,0,ys)) < qd) { // Try it out
- y.dlShiftTo(j,t);
- r.subTo(t,r);
- while(r[i] < --qd) r.subTo(t,r);
- }
- }
- if(q != null) {
- r.drShiftTo(ys,q);
- if(ts != ms) BigInteger.ZERO.subTo(q,q);
- }
- r.t = ys;
- r.clamp();
- if(nsh > 0) r.rShiftTo(nsh,r); // Denormalize remainder
- if(ts < 0) BigInteger.ZERO.subTo(r,r);
-}
-
-// (public) this mod a
-function bnMod(a) {
- var r = nbi();
- this.abs().divRemTo(a,null,r);
- if(this.s < 0 && r.compareTo(BigInteger.ZERO) > 0) a.subTo(r,r);
- return r;
-}
-
-// Modular reduction using "classic" algorithm
-function Classic(m) { this.m = m; }
-function cConvert(x) {
- if(x.s < 0 || x.compareTo(this.m) >= 0) return x.mod(this.m);
- else return x;
-}
-function cRevert(x) { return x; }
-function cReduce(x) { x.divRemTo(this.m,null,x); }
-function cMulTo(x,y,r) { x.multiplyTo(y,r); this.reduce(r); }
-function cSqrTo(x,r) { x.squareTo(r); this.reduce(r); }
-
-Classic.prototype.convert = cConvert;
-Classic.prototype.revert = cRevert;
-Classic.prototype.reduce = cReduce;
-Classic.prototype.mulTo = cMulTo;
-Classic.prototype.sqrTo = cSqrTo;
-
-// (protected) return "-1/this % 2^DB"; useful for Mont. reduction
-// justification:
-// xy == 1 (mod m)
-// xy = 1+km
-// xy(2-xy) = (1+km)(1-km)
-// x[y(2-xy)] = 1-k^2m^2
-// x[y(2-xy)] == 1 (mod m^2)
-// if y is 1/x mod m, then y(2-xy) is 1/x mod m^2
-// should reduce x and y(2-xy) by m^2 at each step to keep size bounded.
-// JS multiply "overflows" differently from C/C++, so care is needed here.
-function bnpInvDigit() {
- if(this.t < 1) return 0;
- var x = this[0];
- if((x&1) == 0) return 0;
- var y = x&3; // y == 1/x mod 2^2
- y = (y*(2-(x&0xf)*y))&0xf; // y == 1/x mod 2^4
- y = (y*(2-(x&0xff)*y))&0xff; // y == 1/x mod 2^8
- y = (y*(2-(((x&0xffff)*y)&0xffff)))&0xffff; // y == 1/x mod 2^16
- // last step - calculate inverse mod DV directly;
- // assumes 16 < DB <= 32 and assumes ability to handle 48-bit ints
- y = (y*(2-x*y%this.DV))%this.DV; // y == 1/x mod 2^dbits
- // we really want the negative inverse, and -DV < y < DV
- return (y>0)?this.DV-y:-y;
-}
-
-// Montgomery reduction
-function Montgomery(m) {
- this.m = m;
- this.mp = m.invDigit();
- this.mpl = this.mp&0x7fff;
- this.mph = this.mp>>15;
- this.um = (1<<(m.DB-15))-1;
- this.mt2 = 2*m.t;
-}
-
-// xR mod m
-function montConvert(x) {
- var r = nbi();
- x.abs().dlShiftTo(this.m.t,r);
- r.divRemTo(this.m,null,r);
- if(x.s < 0 && r.compareTo(BigInteger.ZERO) > 0) this.m.subTo(r,r);
- return r;
-}
-
-// x/R mod m
-function montRevert(x) {
- var r = nbi();
- x.copyTo(r);
- this.reduce(r);
- return r;
-}
-
-// x = x/R mod m (HAC 14.32)
-function montReduce(x) {
- while(x.t <= this.mt2) // pad x so am has enough room later
- x[x.t++] = 0;
- for(var i = 0; i < this.m.t; ++i) {
- // faster way of calculating u0 = x[i]*mp mod DV
- var j = x[i]&0x7fff;
- var u0 =
(j*this.mpl+(((j*this.mph+(x[i]>>15)*this.mpl)&this.um)<<15))&x.DM;
- // use am to combine the multiply-shift-add into one call
- j = i+this.m.t;
- x[j] += this.m.am(0,u0,x,i,0,this.m.t);
- // propagate carry
- while(x[j] >= x.DV) { x[j] -= x.DV; x[++j]++; }
- }
- x.clamp();
- x.drShiftTo(this.m.t,x);
- if(x.compareTo(this.m) >= 0) x.subTo(this.m,x);
-}
-
-// r = "x^2/R mod m"; x != r
-function montSqrTo(x,r) { x.squareTo(r); this.reduce(r); }
-
-// r = "xy/R mod m"; x,y != r
-function montMulTo(x,y,r) { x.multiplyTo(y,r); this.reduce(r); }
-
-Montgomery.prototype.convert = montConvert;
-Montgomery.prototype.revert = montRevert;
-Montgomery.prototype.reduce = montReduce;
-Montgomery.prototype.mulTo = montMulTo;
-Montgomery.prototype.sqrTo = montSqrTo;
-
-// (protected) true iff this is even
-function bnpIsEven() { return ((this.t>0)?(this[0]&1):this.s) == 0; }
-
-// (protected) this^e, e < 2^32, doing sqr and mul with "r" (HAC 14.79)
-function bnpExp(e,z) {
- if(e > 0xffffffff || e < 1) return BigInteger.ONE;
- var r = nbi(), r2 = nbi(), g = z.convert(this), i = nbits(e)-1;
- g.copyTo(r);
- while(--i >= 0) {
- z.sqrTo(r,r2);
- if((e&(1<<i)) > 0) z.mulTo(r2,g,r);
- else { var t = r; r = r2; r2 = t; }
- }
- return z.revert(r);
-}
-
-// (public) this^e % m, 0 <= e < 2^32
-function bnModPowInt(e,m) {
- var z;
- if(e < 256 || m.isEven()) z = new Classic(m); else z = new Montgomery(m);
- return this.exp(e,z);
-}
-
-// protected
-BigInteger.prototype.copyTo = bnpCopyTo;
-BigInteger.prototype.fromInt = bnpFromInt;
-BigInteger.prototype.fromString = bnpFromString;
-BigInteger.prototype.clamp = bnpClamp;
-BigInteger.prototype.dlShiftTo = bnpDLShiftTo;
-BigInteger.prototype.drShiftTo = bnpDRShiftTo;
-BigInteger.prototype.lShiftTo = bnpLShiftTo;
-BigInteger.prototype.rShiftTo = bnpRShiftTo;
-BigInteger.prototype.subTo = bnpSubTo;
-BigInteger.prototype.multiplyTo = bnpMultiplyTo;
-BigInteger.prototype.squareTo = bnpSquareTo;
-BigInteger.prototype.divRemTo = bnpDivRemTo;
-BigInteger.prototype.invDigit = bnpInvDigit;
-BigInteger.prototype.isEven = bnpIsEven;
-BigInteger.prototype.exp = bnpExp;
-
-// public
-BigInteger.prototype.toString = bnToString;
-BigInteger.prototype.negate = bnNegate;
-BigInteger.prototype.abs = bnAbs;
-BigInteger.prototype.compareTo = bnCompareTo;
-BigInteger.prototype.bitLength = bnBitLength;
-BigInteger.prototype.mod = bnMod;
-BigInteger.prototype.modPowInt = bnModPowInt;
-
-// "constants"
-BigInteger.ZERO = nbv(0);
-BigInteger.ONE = nbv(1);
diff --git a/plugins/kimchi/ui/spice-html5/thirdparty/prng4.js
b/plugins/kimchi/ui/spice-html5/thirdparty/prng4.js
deleted file mode 100644
index 4715372..0000000
--- a/plugins/kimchi/ui/spice-html5/thirdparty/prng4.js
+++ /dev/null
@@ -1,79 +0,0 @@
-// Downloaded from
http://www-cs-students.stanford.edu/~tjw/jsbn/ by Jeremy White on
6/1/2012
-
-/*
- * Copyright (c) 2003-2005 Tom Wu
- * All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining
- * a copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including
- * without limitation the rights to use, copy, modify, merge, publish,
- * distribute, sublicense, and/or sell copies of the Software, and to
- * permit persons to whom the Software is furnished to do so, subject to
- * the following conditions:
- *
- * The above copyright notice and this permission notice shall be
- * included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
- * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
- *
- * IN NO EVENT SHALL TOM WU BE LIABLE FOR ANY SPECIAL, INCIDENTAL,
- * INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, OR ANY DAMAGES WHATSOEVER
- * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER OR NOT ADVISED OF
- * THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF LIABILITY, ARISING OUT
- * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- *
- * In addition, the following condition applies:
- *
- * All redistributions must retain an intact copy of this copyright notice
- * and disclaimer.
- */
-
-
-// prng4.js - uses Arcfour as a PRNG
-
-function Arcfour() {
- this.i = 0;
- this.j = 0;
- this.S = new Array();
-}
-
-// Initialize arcfour context from key, an array of ints, each from [0..255]
-function ARC4init(key) {
- var i, j, t;
- for(i = 0; i < 256; ++i)
- this.S[i] = i;
- j = 0;
- for(i = 0; i < 256; ++i) {
- j = (j + this.S[i] + key[i % key.length]) & 255;
- t = this.S[i];
- this.S[i] = this.S[j];
- this.S[j] = t;
- }
- this.i = 0;
- this.j = 0;
-}
-
-function ARC4next() {
- var t;
- this.i = (this.i + 1) & 255;
- this.j = (this.j + this.S[this.i]) & 255;
- t = this.S[this.i];
- this.S[this.i] = this.S[this.j];
- this.S[this.j] = t;
- return this.S[(t + this.S[this.i]) & 255];
-}
-
-Arcfour.prototype.init = ARC4init;
-Arcfour.prototype.next = ARC4next;
-
-// Plug in your RNG constructor here
-function prng_newstate() {
- return new Arcfour();
-}
-
-// Pool size must be a multiple of 4 and greater than 32.
-// An array of bytes the size of the pool will be passed to init()
-var rng_psize = 256;
diff --git a/plugins/kimchi/ui/spice-html5/thirdparty/rng.js
b/plugins/kimchi/ui/spice-html5/thirdparty/rng.js
deleted file mode 100644
index 829a23c..0000000
--- a/plugins/kimchi/ui/spice-html5/thirdparty/rng.js
+++ /dev/null
@@ -1,102 +0,0 @@
-// Downloaded from
http://www-cs-students.stanford.edu/~tjw/jsbn/ by Jeremy White on
6/1/2012
-
-/*
- * Copyright (c) 2003-2005 Tom Wu
- * All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining
- * a copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including
- * without limitation the rights to use, copy, modify, merge, publish,
- * distribute, sublicense, and/or sell copies of the Software, and to
- * permit persons to whom the Software is furnished to do so, subject to
- * the following conditions:
- *
- * The above copyright notice and this permission notice shall be
- * included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
- * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
- *
- * IN NO EVENT SHALL TOM WU BE LIABLE FOR ANY SPECIAL, INCIDENTAL,
- * INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, OR ANY DAMAGES WHATSOEVER
- * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER OR NOT ADVISED OF
- * THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF LIABILITY, ARISING OUT
- * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- *
- * In addition, the following condition applies:
- *
- * All redistributions must retain an intact copy of this copyright notice
- * and disclaimer.
- */
-
-
-// Random number generator - requires a PRNG backend, e.g. prng4.js
-
-// For best results, put code like
-// <body onClick='rng_seed_time();' onKeyPress='rng_seed_time();'>
-// in your main HTML document.
-
-var rng_state;
-var rng_pool;
-var rng_pptr;
-
-// Mix in a 32-bit integer into the pool
-function rng_seed_int(x) {
- rng_pool[rng_pptr++] ^= x & 255;
- rng_pool[rng_pptr++] ^= (x >> 8) & 255;
- rng_pool[rng_pptr++] ^= (x >> 16) & 255;
- rng_pool[rng_pptr++] ^= (x >> 24) & 255;
- if(rng_pptr >= rng_psize) rng_pptr -= rng_psize;
-}
-
-// Mix in the current time (w/milliseconds) into the pool
-function rng_seed_time() {
- rng_seed_int(new Date().getTime());
-}
-
-// Initialize the pool with junk if needed.
-if(rng_pool == null) {
- rng_pool = new Array();
- rng_pptr = 0;
- var t;
- if(navigator.appName == "Netscape" && navigator.appVersion <
"5" && window.crypto) {
- // Extract entropy (256 bits) from NS4 RNG if available
- var z = window.crypto.random(32);
- for(t = 0; t < z.length; ++t)
- rng_pool[rng_pptr++] = z.charCodeAt(t) & 255;
- }
- while(rng_pptr < rng_psize) { // extract some randomness from Math.random()
- t = Math.floor(65536 * Math.random());
- rng_pool[rng_pptr++] = t >>> 8;
- rng_pool[rng_pptr++] = t & 255;
- }
- rng_pptr = 0;
- rng_seed_time();
- //rng_seed_int(window.screenX);
- //rng_seed_int(window.screenY);
-}
-
-function rng_get_byte() {
- if(rng_state == null) {
- rng_seed_time();
- rng_state = prng_newstate();
- rng_state.init(rng_pool);
- for(rng_pptr = 0; rng_pptr < rng_pool.length; ++rng_pptr)
- rng_pool[rng_pptr] = 0;
- rng_pptr = 0;
- //rng_pool = null;
- }
- // TODO: allow reseeding after first request
- return rng_state.next();
-}
-
-function rng_get_bytes(ba) {
- var i;
- for(i = 0; i < ba.length; ++i) ba[i] = rng_get_byte();
-}
-
-function SecureRandom() {}
-
-SecureRandom.prototype.nextBytes = rng_get_bytes;
diff --git a/plugins/kimchi/ui/spice-html5/thirdparty/rsa.js
b/plugins/kimchi/ui/spice-html5/thirdparty/rsa.js
deleted file mode 100644
index 1bbf249..0000000
--- a/plugins/kimchi/ui/spice-html5/thirdparty/rsa.js
+++ /dev/null
@@ -1,146 +0,0 @@
-// Downloaded from
http://www-cs-students.stanford.edu/~tjw/jsbn/ by Jeremy White on
6/1/2012
-
-/*
- * Copyright (c) 2003-2005 Tom Wu
- * All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining
- * a copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including
- * without limitation the rights to use, copy, modify, merge, publish,
- * distribute, sublicense, and/or sell copies of the Software, and to
- * permit persons to whom the Software is furnished to do so, subject to
- * the following conditions:
- *
- * The above copyright notice and this permission notice shall be
- * included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
- * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
- *
- * IN NO EVENT SHALL TOM WU BE LIABLE FOR ANY SPECIAL, INCIDENTAL,
- * INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, OR ANY DAMAGES WHATSOEVER
- * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER OR NOT ADVISED OF
- * THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF LIABILITY, ARISING OUT
- * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- *
- * In addition, the following condition applies:
- *
- * All redistributions must retain an intact copy of this copyright notice
- * and disclaimer.
- */
-
-
-// Depends on jsbn.js and rng.js
-
-// Version 1.1: support utf-8 encoding in pkcs1pad2
-
-// convert a (hex) string to a bignum object
-function parseBigInt(str,r) {
- return new BigInteger(str,r);
-}
-
-function linebrk(s,n) {
- var ret = "";
- var i = 0;
- while(i + n < s.length) {
- ret += s.substring(i,i+n) + "\n";
- i += n;
- }
- return ret + s.substring(i,s.length);
-}
-
-function byte2Hex(b) {
- if(b < 0x10)
- return "0" + b.toString(16);
- else
- return b.toString(16);
-}
-
-// PKCS#1 (type 2, random) pad input string s to n bytes, and return a bigint
-function pkcs1pad2(s,n) {
- if(n < s.length + 11) { // TODO: fix for utf-8
- alert("Message too long for RSA");
- return null;
- }
- var ba = new Array();
- var i = s.length - 1;
- while(i >= 0 && n > 0) {
- var c = s.charCodeAt(i--);
- if(c < 128) { // encode using utf-8
- ba[--n] = c;
- }
- else if((c > 127) && (c < 2048)) {
- ba[--n] = (c & 63) | 128;
- ba[--n] = (c >> 6) | 192;
- }
- else {
- ba[--n] = (c & 63) | 128;
- ba[--n] = ((c >> 6) & 63) | 128;
- ba[--n] = (c >> 12) | 224;
- }
- }
- ba[--n] = 0;
- var rng = new SecureRandom();
- var x = new Array();
- while(n > 2) { // random non-zero pad
- x[0] = 0;
- while(x[0] == 0) rng.nextBytes(x);
- ba[--n] = x[0];
- }
- ba[--n] = 2;
- ba[--n] = 0;
- return new BigInteger(ba);
-}
-
-// "empty" RSA key constructor
-function RSAKey() {
- this.n = null;
- this.e = 0;
- this.d = null;
- this.p = null;
- this.q = null;
- this.dmp1 = null;
- this.dmq1 = null;
- this.coeff = null;
-}
-
-// Set the public key fields N and e from hex strings
-function RSASetPublic(N,E) {
- if(N != null && E != null && N.length > 0 && E.length >
0) {
- this.n = parseBigInt(N,16);
- this.e = parseInt(E,16);
- }
- else
- alert("Invalid RSA public key");
-}
-
-// Perform raw public operation on "x": return x^e (mod n)
-function RSADoPublic(x) {
- return x.modPowInt(this.e, this.n);
-}
-
-// Return the PKCS#1 RSA encryption of "text" as an even-length hex string
-function RSAEncrypt(text) {
- var m = pkcs1pad2(text,(this.n.bitLength()+7)>>3);
- if(m == null) return null;
- var c = this.doPublic(m);
- if(c == null) return null;
- var h = c.toString(16);
- if((h.length & 1) == 0) return h; else return "0" + h;
-}
-
-// Return the PKCS#1 RSA encryption of "text" as a Base64-encoded string
-//function RSAEncryptB64(text) {
-// var h = this.encrypt(text);
-// if(h) return hex2b64(h); else return null;
-//}
-
-// protected
-RSAKey.prototype.doPublic = RSADoPublic;
-
-// public
-RSAKey.prototype.setPublic = RSASetPublic;
-RSAKey.prototype.encrypt = RSAEncrypt;
-//RSAKey.prototype.encrypt_b64 = RSAEncryptB64;
diff --git a/plugins/kimchi/ui/spice-html5/thirdparty/sha1.js
b/plugins/kimchi/ui/spice-html5/thirdparty/sha1.js
deleted file mode 100644
index 8118cb4..0000000
--- a/plugins/kimchi/ui/spice-html5/thirdparty/sha1.js
+++ /dev/null
@@ -1,346 +0,0 @@
-/*
- * A JavaScript implementation of the Secure Hash Algorithm, SHA-1, as defined
- * in FIPS 180-1
- * Version 2.2 Copyright Paul Johnston 2000 - 2009.
- * Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet
- * Distributed under the BSD License
- * See
http://pajhome.org.uk/crypt/md5 for details.
- */
-
- /* Downloaded 6/1/2012 from the above address by Jeremy White.
- License reproduce here for completeness:
-
-Copyright (c) 1998 - 2009, Paul Johnston & Contributors
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without modification, are
permitted provided that the following conditions are met:
-
-Redistributions of source code must retain the above copyright notice, this list of
conditions and the following disclaimer. Redistributions in binary form must reproduce the
above copyright notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
-
-Neither the name of the author nor the names of its contributors may be used to endorse
or promote products derived from this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
- */
-
-/*
- * Configurable variables. You may need to tweak these to be compatible with
- * the server-side, but the defaults work in most cases.
- */
-var hexcase = 0; /* hex output format. 0 - lowercase; 1 - uppercase */
-var b64pad = ""; /* base-64 pad character. "=" for strict RFC
compliance */
-
-/*
- * These are the functions you'll usually want to call
- * They take string arguments and return either hex or base-64 encoded strings
- */
-function hex_sha1(s) { return rstr2hex(rstr_sha1(str2rstr_utf8(s))); }
-function b64_sha1(s) { return rstr2b64(rstr_sha1(str2rstr_utf8(s))); }
-function any_sha1(s, e) { return rstr2any(rstr_sha1(str2rstr_utf8(s)), e); }
-function hex_hmac_sha1(k, d)
- { return rstr2hex(rstr_hmac_sha1(str2rstr_utf8(k), str2rstr_utf8(d))); }
-function b64_hmac_sha1(k, d)
- { return rstr2b64(rstr_hmac_sha1(str2rstr_utf8(k), str2rstr_utf8(d))); }
-function any_hmac_sha1(k, d, e)
- { return rstr2any(rstr_hmac_sha1(str2rstr_utf8(k), str2rstr_utf8(d)), e); }
-
-/*
- * Perform a simple self-test to see if the VM is working
- */
-function sha1_vm_test()
-{
- return hex_sha1("abc").toLowerCase() ==
"a9993e364706816aba3e25717850c26c9cd0d89d";
-}
-
-/*
- * Calculate the SHA1 of a raw string
- */
-function rstr_sha1(s)
-{
- return binb2rstr(binb_sha1(rstr2binb(s), s.length * 8));
-}
-
-/*
- * Calculate the HMAC-SHA1 of a key and some data (raw strings)
- */
-function rstr_hmac_sha1(key, data)
-{
- var bkey = rstr2binb(key);
- if(bkey.length > 16) bkey = binb_sha1(bkey, key.length * 8);
-
- var ipad = Array(16), opad = Array(16);
- for(var i = 0; i < 16; i++)
- {
- ipad[i] = bkey[i] ^ 0x36363636;
- opad[i] = bkey[i] ^ 0x5C5C5C5C;
- }
-
- var hash = binb_sha1(ipad.concat(rstr2binb(data)), 512 + data.length * 8);
- return binb2rstr(binb_sha1(opad.concat(hash), 512 + 160));
-}
-
-/*
- * Convert a raw string to a hex string
- */
-function rstr2hex(input)
-{
- try { hexcase } catch(e) { hexcase=0; }
- var hex_tab = hexcase ? "0123456789ABCDEF" : "0123456789abcdef";
- var output = "";
- var x;
- for(var i = 0; i < input.length; i++)
- {
- x = input.charCodeAt(i);
- output += hex_tab.charAt((x >>> 4) & 0x0F)
- + hex_tab.charAt( x & 0x0F);
- }
- return output;
-}
-
-/*
- * Convert a raw string to a base-64 string
- */
-function rstr2b64(input)
-{
- try { b64pad } catch(e) { b64pad=''; }
- var tab =
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
- var output = "";
- var len = input.length;
- for(var i = 0; i < len; i += 3)
- {
- var triplet = (input.charCodeAt(i) << 16)
- | (i + 1 < len ? input.charCodeAt(i+1) << 8 : 0)
- | (i + 2 < len ? input.charCodeAt(i+2) : 0);
- for(var j = 0; j < 4; j++)
- {
- if(i * 8 + j * 6 > input.length * 8) output += b64pad;
- else output += tab.charAt((triplet >>> 6*(3-j)) & 0x3F);
- }
- }
- return output;
-}
-
-/*
- * Convert a raw string to an arbitrary string encoding
- */
-function rstr2any(input, encoding)
-{
- var divisor = encoding.length;
- var remainders = Array();
- var i, q, x, quotient;
-
- /* Convert to an array of 16-bit big-endian values, forming the dividend */
- var dividend = Array(Math.ceil(input.length / 2));
- for(i = 0; i < dividend.length; i++)
- {
- dividend[i] = (input.charCodeAt(i * 2) << 8) | input.charCodeAt(i * 2 + 1);
- }
-
- /*
- * Repeatedly perform a long division. The binary array forms the dividend,
- * the length of the encoding is the divisor. Once computed, the quotient
- * forms the dividend for the next step. We stop when the dividend is zero.
- * All remainders are stored for later use.
- */
- while(dividend.length > 0)
- {
- quotient = Array();
- x = 0;
- for(i = 0; i < dividend.length; i++)
- {
- x = (x << 16) + dividend[i];
- q = Math.floor(x / divisor);
- x -= q * divisor;
- if(quotient.length > 0 || q > 0)
- quotient[quotient.length] = q;
- }
- remainders[remainders.length] = x;
- dividend = quotient;
- }
-
- /* Convert the remainders to the output string */
- var output = "";
- for(i = remainders.length - 1; i >= 0; i--)
- output += encoding.charAt(remainders[i]);
-
- /* Append leading zero equivalents */
- var full_length = Math.ceil(input.length * 8 /
- (Math.log(encoding.length) / Math.log(2)))
- for(i = output.length; i < full_length; i++)
- output = encoding[0] + output;
-
- return output;
-}
-
-/*
- * Encode a string as utf-8.
- * For efficiency, this assumes the input is valid utf-16.
- */
-function str2rstr_utf8(input)
-{
- var output = "";
- var i = -1;
- var x, y;
-
- while(++i < input.length)
- {
- /* Decode utf-16 surrogate pairs */
- x = input.charCodeAt(i);
- y = i + 1 < input.length ? input.charCodeAt(i + 1) : 0;
- if(0xD800 <= x && x <= 0xDBFF && 0xDC00 <= y && y
<= 0xDFFF)
- {
- x = 0x10000 + ((x & 0x03FF) << 10) + (y & 0x03FF);
- i++;
- }
-
- /* Encode output as utf-8 */
- if(x <= 0x7F)
- output += String.fromCharCode(x);
- else if(x <= 0x7FF)
- output += String.fromCharCode(0xC0 | ((x >>> 6 ) & 0x1F),
- 0x80 | ( x & 0x3F));
- else if(x <= 0xFFFF)
- output += String.fromCharCode(0xE0 | ((x >>> 12) & 0x0F),
- 0x80 | ((x >>> 6 ) & 0x3F),
- 0x80 | ( x & 0x3F));
- else if(x <= 0x1FFFFF)
- output += String.fromCharCode(0xF0 | ((x >>> 18) & 0x07),
- 0x80 | ((x >>> 12) & 0x3F),
- 0x80 | ((x >>> 6 ) & 0x3F),
- 0x80 | ( x & 0x3F));
- }
- return output;
-}
-
-/*
- * Encode a string as utf-16
- */
-function str2rstr_utf16le(input)
-{
- var output = "";
- for(var i = 0; i < input.length; i++)
- output += String.fromCharCode( input.charCodeAt(i) & 0xFF,
- (input.charCodeAt(i) >>> 8) & 0xFF);
- return output;
-}
-
-function str2rstr_utf16be(input)
-{
- var output = "";
- for(var i = 0; i < input.length; i++)
- output += String.fromCharCode((input.charCodeAt(i) >>> 8) & 0xFF,
- input.charCodeAt(i) & 0xFF);
- return output;
-}
-
-/*
- * Convert a raw string to an array of big-endian words
- * Characters >255 have their high-byte silently ignored.
- */
-function rstr2binb(input)
-{
- var output = Array(input.length >> 2);
- for(var i = 0; i < output.length; i++)
- output[i] = 0;
- for(var i = 0; i < input.length * 8; i += 8)
- output[i>>5] |= (input.charCodeAt(i / 8) & 0xFF) << (24 - i % 32);
- return output;
-}
-
-/*
- * Convert an array of big-endian words to a string
- */
-function binb2rstr(input)
-{
- var output = "";
- for(var i = 0; i < input.length * 32; i += 8)
- output += String.fromCharCode((input[i>>5] >>> (24 - i % 32)) &
0xFF);
- return output;
-}
-
-/*
- * Calculate the SHA-1 of an array of big-endian words, and a bit length
- */
-function binb_sha1(x, len)
-{
- /* append padding */
- x[len >> 5] |= 0x80 << (24 - len % 32);
- x[((len + 64 >> 9) << 4) + 15] = len;
-
- var w = Array(80);
- var a = 1732584193;
- var b = -271733879;
- var c = -1732584194;
- var d = 271733878;
- var e = -1009589776;
-
- for(var i = 0; i < x.length; i += 16)
- {
- var olda = a;
- var oldb = b;
- var oldc = c;
- var oldd = d;
- var olde = e;
-
- for(var j = 0; j < 80; j++)
- {
- if(j < 16) w[j] = x[i + j];
- else w[j] = bit_rol(w[j-3] ^ w[j-8] ^ w[j-14] ^ w[j-16], 1);
- var t = safe_add(safe_add(bit_rol(a, 5), sha1_ft(j, b, c, d)),
- safe_add(safe_add(e, w[j]), sha1_kt(j)));
- e = d;
- d = c;
- c = bit_rol(b, 30);
- b = a;
- a = t;
- }
-
- a = safe_add(a, olda);
- b = safe_add(b, oldb);
- c = safe_add(c, oldc);
- d = safe_add(d, oldd);
- e = safe_add(e, olde);
- }
- return Array(a, b, c, d, e);
-
-}
-
-/*
- * Perform the appropriate triplet combination function for the current
- * iteration
- */
-function sha1_ft(t, b, c, d)
-{
- if(t < 20) return (b & c) | ((~b) & d);
- if(t < 40) return b ^ c ^ d;
- if(t < 60) return (b & c) | (b & d) | (c & d);
- return b ^ c ^ d;
-}
-
-/*
- * Determine the appropriate additive constant for the current iteration
- */
-function sha1_kt(t)
-{
- return (t < 20) ? 1518500249 : (t < 40) ? 1859775393 :
- (t < 60) ? -1894007588 : -899497514;
-}
-
-/*
- * Add integers, wrapping at 2^32. This uses 16-bit operations internally
- * to work around bugs in some JS interpreters.
- */
-function safe_add(x, y)
-{
- var lsw = (x & 0xFFFF) + (y & 0xFFFF);
- var msw = (x >> 16) + (y >> 16) + (lsw >> 16);
- return (msw << 16) | (lsw & 0xFFFF);
-}
-
-/*
- * Bitwise rotate a 32-bit number to the left.
- */
-function bit_rol(num, cnt)
-{
- return (num << cnt) | (num >>> (32 - cnt));
-}
diff --git a/plugins/kimchi/ui/spice-html5/ticket.js
b/plugins/kimchi/ui/spice-html5/ticket.js
deleted file mode 100644
index 96577a3..0000000
--- a/plugins/kimchi/ui/spice-html5/ticket.js
+++ /dev/null
@@ -1,250 +0,0 @@
-"use strict";
-/*
- Copyright (C) 2012 by Jeremy P. White <jwhite(a)codeweavers.com>
-
- This file is part of spice-html5.
-
- spice-html5 is free software: you can redistribute it and/or modify
- it under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- spice-html5 is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public License
- along with spice-html5. If not, see <
http://www.gnu.org/licenses/>.
-*/
-
-var SHA_DIGEST_LENGTH = 20;
-
-/*----------------------------------------------------------------------------
-** General ticket RSA encryption functions - just good enough to
-** support what we need to send back an encrypted ticket.
-**--------------------------------------------------------------------------*/
-
-
-/*----------------------------------------------------------------------------
-** OAEP padding functions. Inspired by the OpenSSL implementation.
-**--------------------------------------------------------------------------*/
-function MGF1(mask, seed)
-{
- var i, j, outlen;
- for (i = 0, outlen = 0; outlen < mask.length; i++)
- {
- var combo_buf = new String;
-
- for (j = 0; j < seed.length; j++)
- combo_buf += String.fromCharCode(seed[j]);
- combo_buf += String.fromCharCode((i >> 24) & 255);
- combo_buf += String.fromCharCode((i >> 16) & 255);
- combo_buf += String.fromCharCode((i >> 8) & 255);
- combo_buf += String.fromCharCode((i) & 255);
-
- var combo_hash = rstr_sha1(combo_buf);
- for (j = 0; j < combo_hash.length && outlen < mask.length; j++,
outlen++)
- {
- mask[outlen] = combo_hash.charCodeAt(j);
- }
- }
-}
-
-
-function RSA_padding_add_PKCS1_OAEP(tolen, from, param)
-{
- var seed = new Array(SHA_DIGEST_LENGTH);
- var rand = new SecureRandom();
- rand.nextBytes(seed);
-
- var dblen = tolen - 1 - seed.length;
- var db = new Array(dblen);
- var padlen = dblen - from.length - 1;
- var i;
-
- if (param === undefined)
- param = "";
-
- if (padlen < SHA_DIGEST_LENGTH)
- {
- console.log("Error - data too large for key size.");
- return null;
- }
-
- for (i = 0; i < padlen; i++)
- db[i] = 0;
-
- var param_hash = rstr_sha1(param);
- for (i = 0; i < param_hash.length; i++)
- db[i] = param_hash.charCodeAt(i);
-
- db[padlen] = 1;
- for (i = 0; i < from.length; i++)
- db[i + padlen + 1] = from.charCodeAt(i);
-
- var dbmask = new Array(dblen);
- if (MGF1(dbmask, seed) < 0)
- return null;
-
- for (i = 0; i < dbmask.length; i++)
- db[i] ^= dbmask[i];
-
-
- var seedmask = Array(SHA_DIGEST_LENGTH);
- if (MGF1(seedmask, db) < 0)
- return null;
-
- for (i = 0; i < seedmask.length; i++)
- seed[i] ^= seedmask[i];
-
- var ret = new String;
- ret += String.fromCharCode(0);
- for (i = 0; i < seed.length; i++)
- ret += String.fromCharCode(seed[i]);
- for (i = 0; i < db.length; i++)
- ret += String.fromCharCode(db[i]);
- return ret;
-}
-
-
-function asn_get_length(u8, at)
-{
- var len = u8[at++];
- if (len > 0x80)
- {
- if (len != 0x81)
- {
- console.log("Error: we lazily don't support keys bigger than 255
bytes. It'd be easy to fix.");
- return null;
- }
- len = u8[at++];
- }
-
- return [ at, len];
-}
-
-function find_sequence(u8, at)
-{
- var lenblock;
- at = at || 0;
- if (u8[at++] != 0x30)
- {
- console.log("Error: public key should start with a sequence flag.");
- return null;
- }
-
- lenblock = asn_get_length(u8, at);
- if (! lenblock)
- return null;
- return lenblock;
-}
-
-/*----------------------------------------------------------------------------
-** Extract an RSA key from a memory buffer
-**--------------------------------------------------------------------------*/
-function create_rsa_from_mb(mb, at)
-{
- var u8 = new Uint8Array(mb);
- var lenblock;
- var seq;
- var ba;
- var i;
- var ret;
-
- /* We have a sequence which contains a sequence followed by a bit string */
- seq = find_sequence(u8, at);
- if (! seq)
- return null;
-
- at = seq[0];
- seq = find_sequence(u8, at);
- if (! seq)
- return null;
-
- /* Skip over the contained sequence */
- at = seq[0] + seq[1];
- if (u8[at++] != 0x3)
- {
- console.log("Error: expecting bit string next.");
- return null;
- }
-
- /* Get the bit string, which is *itself* a sequence. Having fun yet? */
- lenblock = asn_get_length(u8, at);
- if (! lenblock)
- return null;
-
- at = lenblock[0];
- if (u8[at] != 0 && u8[at + 1] != 0x30)
- {
- console.log("Error: unexpected values in bit string.");
- return null;
- }
-
- /* Okay, now we have a sequence of two binary values, we hope. */
- seq = find_sequence(u8, at + 1);
- if (! seq)
- return null;
-
- at = seq[0];
- if (u8[at++] != 0x02)
- {
- console.log("Error: expecting integer n next.");
- return null;
- }
- lenblock = asn_get_length(u8, at);
- if (! lenblock)
- return null;
- at = lenblock[0];
-
- ba = new Array(lenblock[1]);
- for (i = 0; i < lenblock[1]; i++)
- ba[i] = u8[at + i];
-
- ret = new RSAKey();
- ret.n = new BigInteger(ba);
-
- at += lenblock[1];
-
- if (u8[at++] != 0x02)
- {
- console.log("Error: expecting integer e next.");
- return null;
- }
- lenblock = asn_get_length(u8, at);
- if (! lenblock)
- return null;
- at = lenblock[0];
-
- ret.e = u8[at++];
- for (i = 1; i < lenblock[1]; i++)
- {
- ret.e <<= 8;
- ret.e |= u8[at++];
- }
-
- return ret;
-}
-
-function rsa_encrypt(rsa, str)
-{
- var i;
- var ret = [];
- var oaep = RSA_padding_add_PKCS1_OAEP((rsa.n.bitLength()+7)>>3, str);
- if (! oaep)
- return null;
-
- var ba = new Array(oaep.length);
-
- for (i = 0; i < oaep.length; i++)
- ba[i] = oaep.charCodeAt(i);
- var bigint = new BigInteger(ba);
- var enc = rsa.doPublic(bigint);
- var h = enc.toString(16);
- if ((h.length & 1) != 0)
- h = "0" + h;
- for (i = 0; i < h.length; i += 2)
- ret[i / 2] = parseInt(h.substring(i, i + 2), 16);
- return ret;
-}
diff --git a/plugins/kimchi/ui/spice-html5/utils.js
b/plugins/kimchi/ui/spice-html5/utils.js
deleted file mode 100644
index 9eb42ff..0000000
--- a/plugins/kimchi/ui/spice-html5/utils.js
+++ /dev/null
@@ -1,265 +0,0 @@
-"use strict";
-/*
- Copyright (C) 2012 by Jeremy P. White <jwhite(a)codeweavers.com>
-
- This file is part of spice-html5.
-
- spice-html5 is free software: you can redistribute it and/or modify
- it under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- spice-html5 is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public License
- along with spice-html5. If not, see <
http://www.gnu.org/licenses/>.
-*/
-
-/*----------------------------------------------------------------------------
-** Utility settings and functions for Spice
-**--------------------------------------------------------------------------*/
-var DEBUG = 0;
-var DUMP_DRAWS = false;
-var DUMP_CANVASES = false;
-
-
-/*----------------------------------------------------------------------------
-** combine_array_buffers
-** Combine two array buffers.
-** FIXME - this can't be optimal. See wire.js about eliminating the need.
-**--------------------------------------------------------------------------*/
-function combine_array_buffers(a1, a2)
-{
- var in1 = new Uint8Array(a1);
- var in2 = new Uint8Array(a2);
- var ret = new ArrayBuffer(a1.byteLength + a2.byteLength);
- var out = new Uint8Array(ret);
- var o = 0;
- var i;
- for (i = 0; i < in1.length; i++)
- out[o++] = in1[i];
- for (i = 0; i < in2.length; i++)
- out[o++] = in2[i];
-
- return ret;
-}
-
-/*----------------------------------------------------------------------------
-** hexdump_buffer
-**--------------------------------------------------------------------------*/
-function hexdump_buffer(a)
-{
- var mg = new Uint8Array(a);
- var hex = "";
- var str = "";
- var last_zeros = 0;
- for (var i = 0; i < mg.length; i++)
- {
- var h = Number(mg[i]).toString(16);
- if (h.length == 1)
- hex += "0";
- hex += h + " ";
-
- if (mg[i] == 10 || mg[i] == 13 || mg[i] == 8)
- str += ".";
- else
- str += String.fromCharCode(mg[i]);
-
- if ((i % 16 == 15) || (i == (mg.length - 1)))
- {
- while (i % 16 != 15)
- {
- hex += " ";
- i++;
- }
-
- if (last_zeros == 0)
- console.log(hex + " | " + str);
-
- if (hex == "00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ")
- {
- if (last_zeros == 1)
- {
- console.log(".");
- last_zeros++;
- }
- else if (last_zeros == 0)
- last_zeros++;
- }
- else
- last_zeros = 0;
-
- hex = str = "";
- }
- }
-}
-
-/*----------------------------------------------------------------------------
-** Converting keycodes to AT scancodes is very hard.
-** luckly there are some resources on the web and in the Xorg driver that help
-** us figure out what browser depenend keycodes match to what scancodes.
-**
-** This will most likely not work for non US keyboard and browsers other than
-** modern Chrome and FireFox.
-**--------------------------------------------------------------------------*/
-var common_scanmap = [];
-common_scanmap['Q'.charCodeAt(0)] = KEY_Q;
-common_scanmap['W'.charCodeAt(0)] = KEY_W;
-common_scanmap['E'.charCodeAt(0)] = KEY_E;
-common_scanmap['R'.charCodeAt(0)] = KEY_R;
-common_scanmap['T'.charCodeAt(0)] = KEY_T;
-common_scanmap['Y'.charCodeAt(0)] = KEY_Y;
-common_scanmap['U'.charCodeAt(0)] = KEY_U;
-common_scanmap['I'.charCodeAt(0)] = KEY_I;
-common_scanmap['O'.charCodeAt(0)] = KEY_O;
-common_scanmap['P'.charCodeAt(0)] = KEY_P;
-common_scanmap['A'.charCodeAt(0)] = KEY_A;
-common_scanmap['S'.charCodeAt(0)] = KEY_S;
-common_scanmap['D'.charCodeAt(0)] = KEY_D;
-common_scanmap['F'.charCodeAt(0)] = KEY_F;
-common_scanmap['G'.charCodeAt(0)] = KEY_G;
-common_scanmap['H'.charCodeAt(0)] = KEY_H;
-common_scanmap['J'.charCodeAt(0)] = KEY_J;
-common_scanmap['K'.charCodeAt(0)] = KEY_K;
-common_scanmap['L'.charCodeAt(0)] = KEY_L;
-common_scanmap['Z'.charCodeAt(0)] = KEY_Z;
-common_scanmap['X'.charCodeAt(0)] = KEY_X;
-common_scanmap['C'.charCodeAt(0)] = KEY_C;
-common_scanmap['V'.charCodeAt(0)] = KEY_V;
-common_scanmap['B'.charCodeAt(0)] = KEY_B;
-common_scanmap['N'.charCodeAt(0)] = KEY_N;
-common_scanmap['M'.charCodeAt(0)] = KEY_M;
-common_scanmap[' '.charCodeAt(0)] = KEY_Space;
-common_scanmap[13] = KEY_Enter;
-common_scanmap[27] = KEY_Escape;
-common_scanmap[8] = KEY_BackSpace;
-common_scanmap[9] = KEY_Tab;
-common_scanmap[16] = KEY_ShiftL;
-common_scanmap[17] = KEY_LCtrl;
-common_scanmap[18] = KEY_Alt;
-common_scanmap[20] = KEY_CapsLock;
-common_scanmap[144] = KEY_NumLock;
-common_scanmap[112] = KEY_F1;
-common_scanmap[113] = KEY_F2;
-common_scanmap[114] = KEY_F3;
-common_scanmap[115] = KEY_F4;
-common_scanmap[116] = KEY_F5;
-common_scanmap[117] = KEY_F6;
-common_scanmap[118] = KEY_F7;
-common_scanmap[119] = KEY_F8;
-common_scanmap[120] = KEY_F9;
-common_scanmap[121] = KEY_F10;
-common_scanmap[122] = KEY_F11;
-common_scanmap[123] = KEY_F12;
-
-/* These externded scancodes do not line up with values from atKeynames */
-common_scanmap[42] = 99;
-common_scanmap[19] = 101; // Break
-common_scanmap[111] = 0xE035; // KP_Divide
-common_scanmap[106] = 0xE037; // KP_Multiply
-common_scanmap[36] = 0xE047; // Home
-common_scanmap[38] = 0xE048; // Up
-common_scanmap[33] = 0xE049; // PgUp
-common_scanmap[37] = 0xE04B; // Left
-common_scanmap[39] = 0xE04D; // Right
-common_scanmap[35] = 0xE04F; // End
-common_scanmap[40] = 0xE050; // Down
-common_scanmap[34] = 0xE051; // PgDown
-common_scanmap[45] = 0xE052; // Insert
-common_scanmap[46] = 0xE053; // Delete
-common_scanmap[44] = 0x2A37; // Print
-
-/* These are not common between ALL browsers but are between Firefox and DOM3 */
-common_scanmap['1'.charCodeAt(0)] = KEY_1;
-common_scanmap['2'.charCodeAt(0)] = KEY_2;
-common_scanmap['3'.charCodeAt(0)] = KEY_3;
-common_scanmap['4'.charCodeAt(0)] = KEY_4;
-common_scanmap['5'.charCodeAt(0)] = KEY_5;
-common_scanmap['6'.charCodeAt(0)] = KEY_6;
-common_scanmap['7'.charCodeAt(0)] = KEY_7;
-common_scanmap['8'.charCodeAt(0)] = KEY_8;
-common_scanmap['9'.charCodeAt(0)] = KEY_9;
-common_scanmap['0'.charCodeAt(0)] = KEY_0;
-common_scanmap[145] = KEY_ScrollLock;
-common_scanmap[103] = KEY_KP_7;
-common_scanmap[104] = KEY_KP_8;
-common_scanmap[105] = KEY_KP_9;
-common_scanmap[100] = KEY_KP_4;
-common_scanmap[101] = KEY_KP_5;
-common_scanmap[102] = KEY_KP_6;
-common_scanmap[107] = KEY_KP_Plus;
-common_scanmap[97] = KEY_KP_1;
-common_scanmap[98] = KEY_KP_2;
-common_scanmap[99] = KEY_KP_3;
-common_scanmap[96] = KEY_KP_0;
-common_scanmap[110] = KEY_KP_Decimal;
-common_scanmap[191] = KEY_Slash;
-common_scanmap[190] = KEY_Period;
-common_scanmap[188] = KEY_Comma;
-common_scanmap[220] = KEY_BSlash;
-common_scanmap[192] = KEY_Tilde;
-common_scanmap[222] = KEY_Quote;
-common_scanmap[219] = KEY_LBrace;
-common_scanmap[221] = KEY_RBrace;
-
-common_scanmap[91] = 0xE05B; //KEY_LMeta
-common_scanmap[92] = 0xE05C; //KEY_RMeta
-common_scanmap[93] = 0xE05D; //KEY_Menu
-
-/* Firefox/Mozilla codes */
-var firefox_scanmap = [];
-firefox_scanmap[173] = KEY_Minus;
-firefox_scanmap[109] = KEY_Minus;
-firefox_scanmap[61] = KEY_Equal;
-firefox_scanmap[59] = KEY_SemiColon;
-
-/* DOM3 codes */
-var DOM_scanmap = [];
-DOM_scanmap[189] = KEY_Minus;
-DOM_scanmap[187] = KEY_Equal;
-DOM_scanmap[186] = KEY_SemiColon;
-
-function get_scancode(code)
-{
- if (common_scanmap[code] === undefined)
- {
- if (navigator.userAgent.indexOf("Firefox") != -1)
- return firefox_scanmap[code];
- else
- return DOM_scanmap[code];
- }
- else
- return common_scanmap[code];
-}
-
-function keycode_to_start_scan(code)
-{
- var scancode = get_scancode(code);
- if (scancode === undefined)
- {
- alert('no map for ' + code);
- return 0;
- }
-
- if (scancode < 0x100) {
- return scancode;
- } else {
- return 0xe0 | ((scancode - 0x100) << 8);
- }
-}
-
-function keycode_to_end_scan(code)
-{
- var scancode = get_scancode(code);
- if (scancode === undefined)
- return 0;
-
- if (scancode < 0x100) {
- return scancode | 0x80;
- } else {
- return 0x80e0 | ((scancode - 0x100) << 8);
- }
-}
diff --git a/plugins/kimchi/ui/spice-html5/webm.js
b/plugins/kimchi/ui/spice-html5/webm.js
deleted file mode 100644
index 35cbc07..0000000
--- a/plugins/kimchi/ui/spice-html5/webm.js
+++ /dev/null
@@ -1,553 +0,0 @@
-"use strict";
-/*
- Copyright (C) 2014 by Jeremy P. White <jwhite(a)codeweavers.com>
-
- This file is part of spice-html5.
-
- spice-html5 is free software: you can redistribute it and/or modify
- it under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- spice-html5 is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public License
- along with spice-html5. If not, see <
http://www.gnu.org/licenses/>.
-*/
-
-
-/*----------------------------------------------------------------------------
-** EBML identifiers
-**--------------------------------------------------------------------------*/
-var EBML_HEADER = [ 0x1a, 0x45, 0xdf, 0xa3 ];
-var EBML_HEADER_VERSION = [ 0x42, 0x86 ];
-var EBML_HEADER_READ_VERSION = [ 0x42, 0xf7 ];
-var EBML_HEADER_MAX_ID_LENGTH = [ 0x42, 0xf2 ];
-var EBML_HEADER_MAX_SIZE_LENGTH = [ 0x42, 0xf3 ];
-var EBML_HEADER_DOC_TYPE = [ 0x42, 0x82 ];
-var EBML_HEADER_DOC_TYPE_VERSION = [ 0x42, 0x87 ];
-var EBML_HEADER_DOC_TYPE_READ_VERSION = [ 0x42, 0x85 ];
-
-var WEBM_SEGMENT_HEADER = [ 0x18, 0x53, 0x80, 0x67 ];
-var WEBM_SEGMENT_INFORMATION = [ 0x15, 0x49, 0xA9, 0x66 ];
-
-var WEBM_TIMECODE_SCALE = [ 0x2A, 0xD7, 0xB1 ];
-var WEBM_MUXING_APP = [ 0x4D, 0x80 ];
-var WEBM_WRITING_APP = [ 0x57, 0x41 ];
-
-var WEBM_SEEK_HEAD = [ 0x11, 0x4D, 0x9B, 0x74 ];
-var WEBM_SEEK = [ 0x4D, 0xBB ];
-var WEBM_SEEK_ID = [ 0x53, 0xAB ];
-var WEBM_SEEK_POSITION = [ 0x53, 0xAC ];
-
-var WEBM_TRACKS = [ 0x16, 0x54, 0xAE, 0x6B ];
-var WEBM_TRACK_ENTRY = [ 0xAE ];
-var WEBM_TRACK_NUMBER = [ 0xD7 ];
-var WEBM_TRACK_UID = [ 0x73, 0xC5 ];
-var WEBM_TRACK_TYPE = [ 0x83 ];
-var WEBM_FLAG_ENABLED = [ 0xB9 ];
-var WEBM_FLAG_DEFAULT = [ 0x88 ];
-var WEBM_FLAG_FORCED = [ 0x55, 0xAA ];
-var WEBM_FLAG_LACING = [ 0x9C ];
-var WEBM_MIN_CACHE = [ 0x6D, 0xE7 ];
-
-var WEBM_MAX_BLOCK_ADDITION_ID = [ 0x55, 0xEE ];
-var WEBM_CODEC_DECODE_ALL = [ 0xAA ];
-var WEBM_SEEK_PRE_ROLL = [ 0x56, 0xBB ];
-var WEBM_CODEC_DELAY = [ 0x56, 0xAA ];
-var WEBM_CODEC_PRIVATE = [ 0x63, 0xA2 ];
-var WEBM_CODEC_ID = [ 0x86 ];
-
-var WEBM_AUDIO = [ 0xE1 ] ;
-var WEBM_SAMPLING_FREQUENCY = [ 0xB5 ] ;
-var WEBM_CHANNELS = [ 0x9F ] ;
-
-var WEBM_CLUSTER = [ 0x1F, 0x43, 0xB6, 0x75 ];
-var WEBM_TIME_CODE = [ 0xE7 ] ;
-var WEBM_SIMPLE_BLOCK = [ 0xA3 ] ;
-
-/*----------------------------------------------------------------------------
-** Various OPUS / Webm constants
-**--------------------------------------------------------------------------*/
-var CLUSTER_SIMPLEBLOCK_FLAG_KEYFRAME = 1 << 7;
-
-var OPUS_FREQUENCY = 48000;
-var OPUS_CHANNELS = 2;
-
-var SPICE_PLAYBACK_CODEC = 'audio/webm;
codecs="opus"';
-var MAX_CLUSTER_TIME = 1000;
-
-var GAP_DETECTION_THRESHOLD = 50;
-
-/*----------------------------------------------------------------------------
-** EBML utility functions
-** These classes can create the binary representation of a webm file
-**--------------------------------------------------------------------------*/
-function EBML_write_u1_data_len(len, dv, at)
-{
- var b = 0x80 | len;
- dv.setUint8(at, b);
- return at + 1;
-}
-
-function EBML_write_u8_value(id, val, dv, at)
-{
- at = EBML_write_array(id, dv, at);
- at = EBML_write_u1_data_len(1, dv, at);
- dv.setUint8(at, val);
- return at + 1;
-}
-
-function EBML_write_u32_value(id, val, dv, at)
-{
- at = EBML_write_array(id, dv, at);
- at = EBML_write_u1_data_len(4, dv, at);
- dv.setUint32(at, val);
- return at + 4;
-}
-
-function EBML_write_u16_value(id, val, dv, at)
-{
- at = EBML_write_array(id, dv, at);
- at = EBML_write_u1_data_len(2, dv, at);
- dv.setUint16(at, val);
- return at + 2;
-}
-
-function EBML_write_float_value(id, val, dv, at)
-{
- at = EBML_write_array(id, dv, at);
- at = EBML_write_u1_data_len(4, dv, at);
- dv.setFloat32(at, val);
- return at + 4;
-}
-
-
-
-function EBML_write_u64_data_len(len, dv, at)
-{
- /* Javascript doesn't do 64 bit ints, so this cheats and
- just has a max of 32 bits. Fine for our purposes */
- dv.setUint8(at++, 0x01);
- dv.setUint8(at++, 0x00);
- dv.setUint8(at++, 0x00);
- dv.setUint8(at++, 0x00);
- var val = len & 0xFFFFFFFF;
- for (var shift = 24; shift >= 0; shift -= 8)
- dv.setUint8(at++, val >> shift);
- return at;
-}
-
-function EBML_write_array(arr, dv, at)
-{
- for (var i = 0; i < arr.length; i++)
- dv.setUint8(at + i, arr[i]);
- return at + arr.length;
-}
-
-function EBML_write_string(str, dv, at)
-{
- for (var i = 0; i < str.length; i++)
- dv.setUint8(at + i, str.charCodeAt(i));
- return at + str.length;
-}
-
-function EBML_write_data(id, data, dv, at)
-{
- at = EBML_write_array(id, dv, at);
- if (data.length < 127)
- at = EBML_write_u1_data_len(data.length, dv, at);
- else
- at = EBML_write_u64_data_len(data.length, dv, at);
- if ((typeof data) == "string")
- at = EBML_write_string(data, dv, at);
- else
- at = EBML_write_array(data, dv, at);
- return at;
-}
-
-/*----------------------------------------------------------------------------
-** Webm objects
-** These classes can create the binary representation of a webm file
-**--------------------------------------------------------------------------*/
-function EBMLHeader()
-{
- this.id = EBML_HEADER;
- this.Version = 1;
- this.ReadVersion = 1;
- this.MaxIDLength = 4;
- this.MaxSizeLength = 8;
- this.DocType = "webm";
- this.DocTypeVersion = 2; /* Not well specified by the WebM guys, but functionally
required for Firefox */
- this.DocTypeReadVersion = 2;
-}
-
-EBMLHeader.prototype =
-{
- to_buffer: function(a, at)
- {
- at = at || 0;
- var dv = new DataView(a);
-
- at = EBML_write_array(this.id, dv, at);
- at = EBML_write_u64_data_len(0x1f, dv, at);
- at = EBML_write_u8_value(EBML_HEADER_VERSION, this.Version, dv, at);
- at = EBML_write_u8_value(EBML_HEADER_READ_VERSION, this.ReadVersion, dv, at);
- at = EBML_write_u8_value(EBML_HEADER_MAX_ID_LENGTH, this.MaxIDLength, dv, at);
- at = EBML_write_u8_value(EBML_HEADER_MAX_SIZE_LENGTH, this.MaxSizeLength, dv,
at);
- at = EBML_write_data(EBML_HEADER_DOC_TYPE, this.DocType, dv, at);
- at = EBML_write_u8_value(EBML_HEADER_DOC_TYPE_VERSION, this.DocTypeVersion, dv,
at);
- at = EBML_write_u8_value(EBML_HEADER_DOC_TYPE_READ_VERSION,
this.DocTypeReadVersion, dv, at);
-
- return at;
- },
- buffer_size: function()
- {
- return 0x1f + 8 + this.id.length;
- },
-}
-
-function webm_Segment()
-{
- this.id = WEBM_SEGMENT_HEADER;
-}
-
-webm_Segment.prototype =
-{
- to_buffer: function(a, at)
- {
- at = at || 0;
- var dv = new DataView(a);
-
- at = EBML_write_array(this.id, dv, at);
- dv.setUint8(at++, 0xff);
- return at;
- },
- buffer_size: function()
- {
- return this.id.length + 1;
- },
-}
-
-function webm_SegmentInformation()
-{
- this.id = WEBM_SEGMENT_INFORMATION;
- this.timecode_scale = 1000000; /* 1 ms */
- this.muxing_app = "spice";
- this.writing_app = "spice-html5";
-
-}
-
-webm_SegmentInformation.prototype =
-{
- to_buffer: function(a, at)
- {
- at = at || 0;
- var dv = new DataView(a);
-
- at = EBML_write_array(this.id, dv, at);
- at = EBML_write_u64_data_len(this.buffer_size() - 8 - this.id.length, dv, at);
- at = EBML_write_u32_value(WEBM_TIMECODE_SCALE, this.timecode_scale, dv, at);
- at = EBML_write_data(WEBM_MUXING_APP, this.muxing_app, dv, at);
- at = EBML_write_data(WEBM_WRITING_APP, this.writing_app, dv, at);
- return at;
- },
- buffer_size: function()
- {
- return this.id.length + 8 +
- WEBM_TIMECODE_SCALE.length + 1 + 4 +
- WEBM_MUXING_APP.length + 1 + this.muxing_app.length +
- WEBM_WRITING_APP.length + 1 + this.writing_app.length;
- },
-}
-
-function webm_Audio(frequency)
-{
- this.id = WEBM_AUDIO;
- this.sampling_frequency = frequency;
- this.channels = OPUS_CHANNELS;
-}
-
-webm_Audio.prototype =
-{
- to_buffer: function(a, at)
- {
- at = at || 0;
- var dv = new DataView(a);
- at = EBML_write_array(this.id, dv, at);
- at = EBML_write_u64_data_len(this.buffer_size() - 8 - this.id.length, dv, at);
- at = EBML_write_u8_value(WEBM_CHANNELS, this.channels, dv, at);
- at = EBML_write_float_value(WEBM_SAMPLING_FREQUENCY, this.sampling_frequency, dv,
at);
- return at;
- },
- buffer_size: function()
- {
- return this.id.length + 8 +
- WEBM_SAMPLING_FREQUENCY.length + 1 + 4 +
- WEBM_CHANNELS.length + 1 + 1;
- },
-}
-
-
-/* ---------------------------
- SeekHead not currently used. Hopefully not needed.
-*/
-function webm_Seek(seekid, pos)
-{
- this.id = WEBM_SEEK;
- this.pos = pos;
- this.seekid = seekid;
-}
-
-webm_Seek.prototype =
-{
- to_buffer: function(a, at)
- {
- at = at || 0;
- var dv = new DataView(a);
- at = EBML_write_array(this.id, dv, at);
- at = EBML_write_u1_data_len(this.buffer_size() - 1 - this.id.length, dv, at);
-
- at = EBML_write_data(WEBM_SEEK_ID, this.seekid, dv, at)
- at = EBML_write_u16_value(WEBM_SEEK_POSITION, this.pos, dv, at)
-
- return at;
- },
- buffer_size: function()
- {
- return this.id.length + 1 +
- WEBM_SEEK_ID.length + 1 + this.seekid.length +
- WEBM_SEEK_POSITION.length + 1 + 2;
- },
-}
-function webm_SeekHead(info_pos, track_pos)
-{
- this.id = WEBM_SEEK_HEAD;
- this.info = new webm_Seek(WEBM_SEGMENT_INFORMATION, info_pos);
- this.track = new webm_Seek(WEBM_TRACKS, track_pos);
-}
-
-webm_SeekHead.prototype =
-{
- to_buffer: function(a, at)
- {
- at = at || 0;
- var dv = new DataView(a);
- at = EBML_write_array(this.id, dv, at);
- at = EBML_write_u64_data_len(this.buffer_size() - 8 - this.id.length, dv, at);
-
- at = this.info.to_buffer(a, at);
- at = this.track.to_buffer(a, at);
-
- return at;
- },
- buffer_size: function()
- {
- return this.id.length + 8 +
- this.info.buffer_size() +
- this.track.buffer_size();
- },
-}
-
-/* -------------------------------
- End of Seek Head
-*/
-
-function webm_TrackEntry()
-{
- this.id = WEBM_TRACK_ENTRY;
- this.number = 1;
- this.uid = 1;
- this.type = 2; // Audio
- this.flag_enabled = 1;
- this.flag_default = 1;
- this.flag_forced = 1;
- this.flag_lacing = 0;
- this.min_cache = 0; // fixme - check
- this.max_block_addition_id = 0;
- this.codec_decode_all = 0; // fixme - check
- this.seek_pre_roll = 0; // 80000000; // fixme - check
- this.codec_delay = 80000000; // Must match codec_private.preskip
- this.codec_id = "A_OPUS";
- this.audio = new webm_Audio(OPUS_FREQUENCY);
-
- // See:
http://tools.ietf.org/html/draft-terriberry-oggopus-01
- this.codec_private = [ 0x4f, 0x70, 0x75, 0x73, 0x48, 0x65, 0x61, 0x64, // OpusHead
- 0x01, // Version
- OPUS_CHANNELS,
- 0x00, 0x0F, // Preskip - 3840 samples - should be 8ms at
48kHz
- 0x80, 0xbb, 0x00, 0x00, // 48000
- 0x00, 0x00, // Output gain
- 0x00 // Channel mapping family
- ];
-}
-
-webm_TrackEntry.prototype =
-{
- to_buffer: function(a, at)
- {
- at = at || 0;
- var dv = new DataView(a);
- at = EBML_write_array(this.id, dv, at);
- at = EBML_write_u64_data_len(this.buffer_size() - 8 - this.id.length, dv, at);
- at = EBML_write_u8_value(WEBM_TRACK_NUMBER, this.number, dv, at);
- at = EBML_write_u8_value(WEBM_TRACK_UID, this.uid, dv, at);
- at = EBML_write_u8_value(WEBM_FLAG_ENABLED, this.flag_enabled, dv, at);
- at = EBML_write_u8_value(WEBM_FLAG_DEFAULT, this.flag_default, dv, at);
- at = EBML_write_u8_value(WEBM_FLAG_FORCED, this.flag_forced, dv, at);
- at = EBML_write_u8_value(WEBM_FLAG_LACING, this.flag_lacing, dv, at);
- at = EBML_write_data(WEBM_CODEC_ID, this.codec_id, dv, at);
- at = EBML_write_u8_value(WEBM_MIN_CACHE, this.min_cache, dv, at);
- at = EBML_write_u8_value(WEBM_MAX_BLOCK_ADDITION_ID, this.max_block_addition_id,
dv, at);
- at = EBML_write_u8_value(WEBM_CODEC_DECODE_ALL, this.codec_decode_all, dv, at);
- at = EBML_write_u32_value(WEBM_CODEC_DELAY, this.codec_delay, dv, at);
- at = EBML_write_u32_value(WEBM_SEEK_PRE_ROLL, this.seek_pre_roll, dv, at);
- at = EBML_write_u8_value(WEBM_TRACK_TYPE, this.type, dv, at);
- at = EBML_write_data(WEBM_CODEC_PRIVATE, this.codec_private, dv, at);
-
- at = this.audio.to_buffer(a, at);
- return at;
- },
- buffer_size: function()
- {
- return this.id.length + 8 +
- WEBM_TRACK_NUMBER.length + 1 + 1 +
- WEBM_TRACK_UID.length + 1 + 1 +
- WEBM_TRACK_TYPE.length + 1 + 1 +
- WEBM_FLAG_ENABLED.length + 1 + 1 +
- WEBM_FLAG_DEFAULT.length + 1 + 1 +
- WEBM_FLAG_FORCED.length + 1 + 1 +
- WEBM_FLAG_LACING.length + 1 + 1 +
- WEBM_MIN_CACHE.length + 1 + 1 +
- WEBM_MAX_BLOCK_ADDITION_ID.length + 1 + 1 +
- WEBM_CODEC_DECODE_ALL.length + 1 + 1 +
- WEBM_SEEK_PRE_ROLL.length + 1 + 4 +
- WEBM_CODEC_DELAY.length + 1 + 4 +
- WEBM_CODEC_ID.length + this.codec_id.length + 1 +
- WEBM_CODEC_PRIVATE.length + 1 + this.codec_private.length +
- this.audio.buffer_size();
- },
-}
-function webm_Tracks(entry)
-{
- this.id = WEBM_TRACKS;
- this.track_entry = entry;
-}
-
-webm_Tracks.prototype =
-{
- to_buffer: function(a, at)
- {
- at = at || 0;
- var dv = new DataView(a);
- at = EBML_write_array(this.id, dv, at);
- at = EBML_write_u64_data_len(this.buffer_size() - 8 - this.id.length, dv, at);
- at = this.track_entry.to_buffer(a, at);
- return at;
- },
- buffer_size: function()
- {
- return this.id.length + 8 +
- this.track_entry.buffer_size();
- },
-}
-
-function webm_Cluster(timecode, data)
-{
- this.id = WEBM_CLUSTER;
- this.timecode = timecode;
- this.data = data;
-}
-
-webm_Cluster.prototype =
-{
- to_buffer: function(a, at)
- {
- at = at || 0;
- var dv = new DataView(a);
- at = EBML_write_array(this.id, dv, at);
- dv.setUint8(at++, 0xff);
- at = EBML_write_u32_value(WEBM_TIME_CODE, this.timecode, dv, at);
- return at;
- },
- buffer_size: function()
- {
- return this.id.length + 1 +
- WEBM_TIME_CODE.length + 1 + 4;
- },
-}
-
-function webm_SimpleBlock(timecode, data, keyframe)
-{
- this.id = WEBM_SIMPLE_BLOCK;
- this.timecode = timecode;
- this.data = data;
- this.keyframe = keyframe;
-}
-
-webm_SimpleBlock.prototype =
-{
- to_buffer: function(a, at)
- {
- at = at || 0;
- var dv = new DataView(a);
- at = EBML_write_array(this.id, dv, at);
- at = EBML_write_u64_data_len(this.data.byteLength + 4, dv, at);
- at = EBML_write_u1_data_len(1, dv, at); // Track #
- dv.setUint16(at, this.timecode); at += 2; // timecode - relative to cluster
- dv.setUint8(at, this.keyframe ? CLUSTER_SIMPLEBLOCK_FLAG_KEYFRAME : 0); at += 1;
// flags
-
- // FIXME - There should be a better way to copy
- var u8 = new Uint8Array(this.data);
- for (var i = 0; i < this.data.byteLength; i++)
- dv.setUint8(at++, u8[i]);
-
- return at;
- },
- buffer_size: function()
- {
- return this.id.length + 8 +
- 1 + 2 + 1 +
- this.data.byteLength;
- },
-}
-
-function webm_Header()
-{
- this.ebml = new EBMLHeader;
- this.segment = new webm_Segment;
- this.seek_head = new webm_SeekHead(0, 0);
-
- this.seek_head.info.pos = this.segment.buffer_size() + this.seek_head.buffer_size();
-
- this.info = new webm_SegmentInformation;
-
- this.seek_head.track.pos = this.seek_head.info.pos + this.info.buffer_size();
-
- this.track_entry = new webm_TrackEntry;
- this.tracks = new webm_Tracks(this.track_entry);
-}
-
-webm_Header.prototype =
-{
- to_buffer: function(a, at)
- {
- at = at || 0;
- at = this.ebml.to_buffer(a, at);
- at = this.segment.to_buffer(a, at);
- at = this.info.to_buffer(a, at);
- at = this.tracks.to_buffer(a, at);
-
- return at;
- },
- buffer_size: function()
- {
- return this.ebml.buffer_size() +
- this.segment.buffer_size() +
- this.info.buffer_size() +
- this.tracks.buffer_size();
- },
-}
diff --git a/plugins/kimchi/ui/spice-html5/wire.js
b/plugins/kimchi/ui/spice-html5/wire.js
deleted file mode 100644
index 7407ce7..0000000
--- a/plugins/kimchi/ui/spice-html5/wire.js
+++ /dev/null
@@ -1,123 +0,0 @@
-"use strict";
-/*
- Copyright (C) 2012 by Jeremy P. White <jwhite(a)codeweavers.com>
-
- This file is part of spice-html5.
-
- spice-html5 is free software: you can redistribute it and/or modify
- it under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- spice-html5 is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public License
- along with spice-html5. If not, see <
http://www.gnu.org/licenses/>.
-*/
-
-/*--------------------------------------------------------------------------------------
-** SpiceWireReader
-** This class will receive messages from a WebSocket and relay it to a given
-** callback. It will optionally save and pass along a header, useful in processing
-** the mini message format.
-**--------------------------------------------------------------------------------------*/
-function SpiceWireReader(sc, callback)
-{
- this.sc = sc;
- this.callback = callback;
- this.needed = 0;
-
- this.buffers = [];
-
- this.sc.ws.wire_reader = this;
- this.sc.ws.binaryType = "arraybuffer";
- this.sc.ws.addEventListener('message', wire_blob_catcher);
-}
-
-SpiceWireReader.prototype =
-{
-
- /*------------------------------------------------------------------------
- ** Process messages coming in from our WebSocket
- **----------------------------------------------------------------------*/
- inbound: function (mb)
- {
- var at;
-
- /* Just buffer if we don't need anything yet */
- if (this.needed == 0)
- {
- this.buffers.push(mb);
- return;
- }
-
- /* Optimization - if we have just one inbound block, and it's
- suitable for our needs, just use it. */
- if (this.buffers.length == 0 && mb.byteLength >= this.needed)
- {
- if (mb.byteLength > this.needed)
- {
- this.buffers.push(mb.slice(this.needed));
- mb = mb.slice(0, this.needed);
- }
- this.callback.call(this.sc, mb,
- this.saved_msg_header || undefined);
- }
- else
- {
- this.buffers.push(mb);
- }
-
-
- /* If we have fragments that add up to what we need, combine them */
- /* FIXME - it would be faster to revise the processing code to handle
- ** multiple fragments directly. Essentially, we should be
- ** able to do this without any slice() or combine_array_buffers() calls
*/
- while (this.buffers.length > 1 && this.buffers[0].byteLength <
this.needed)
- {
- var mb1 = this.buffers.shift();
- var mb2 = this.buffers.shift();
-
- this.buffers.unshift(combine_array_buffers(mb1, mb2));
- }
-
-
- while (this.buffers.length > 0 && this.buffers[0].byteLength >=
this.needed)
- {
- mb = this.buffers.shift();
- if (mb.byteLength > this.needed)
- {
- this.buffers.unshift(mb.slice(this.needed));
- mb = mb.slice(0, this.needed);
- }
- this.callback.call(this.sc, mb,
- this.saved_msg_header || undefined);
- }
-
- },
-
- request: function(n)
- {
- this.needed = n;
- },
-
- save_header: function(h)
- {
- this.saved_msg_header = h;
- },
-
- clear_header: function()
- {
- this.saved_msg_header = undefined;
- },
-}
-
-function wire_blob_catcher(e)
-{
- DEBUG > 1 && console.log(">> WebSockets.onmessage");
- DEBUG > 1 && console.log("id " +
this.wire_reader.sc.connection_id +"; type " + this.wire_reader.sc.type);
- SpiceWireReader.prototype.inbound.call(this.wire_reader, e.data);
-}
diff --git a/plugins/kimchi/utils.py b/plugins/kimchi/utils.py
deleted file mode 100644
index 2480362..0000000
--- a/plugins/kimchi/utils.py
+++ /dev/null
@@ -1,39 +0,0 @@
-#
-# Project Kimchi
-#
-# Copyright IBM, Corp. 2013-2015
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-#
-
-import re
-
-from wok.exception import InvalidParameter
-
-
-def _uri_to_name(collection, uri):
- expr = '/plugins/kimchi/%s/(.*?)$' % collection
- m = re.match(expr, uri)
- if not m:
- raise InvalidParameter("WOKUTILS0001E", {'uri': uri})
- return m.group(1)
-
-
-def template_name_from_uri(uri):
- return _uri_to_name('templates', uri)
-
-
-def pool_name_from_uri(uri):
- return _uri_to_name('storagepools', uri)
diff --git a/plugins/kimchi/vmtemplate.py b/plugins/kimchi/vmtemplate.py
deleted file mode 100644
index 07e70ba..0000000
--- a/plugins/kimchi/vmtemplate.py
+++ /dev/null
@@ -1,431 +0,0 @@
-#
-# Project Kimchi
-#
-# Copyright IBM, Corp. 2013-2015
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-
-import os
-import stat
-import time
-import urlparse
-import uuid
-from lxml import etree
-from lxml.builder import E
-
-from wok.exception import InvalidParameter, ImageFormatError, IsoFormatError
-from wok.exception import MissingParameter, OperationFailed
-from wok.utils import check_url_path
-
-import imageinfo
-import osinfo
-from isoinfo import IsoImage
-from utils import pool_name_from_uri
-from xmlutils.cpu import get_cpu_xml
-from xmlutils.disk import get_disk_xml
-from xmlutils.graphics import get_graphics_xml
-from xmlutils.interface import get_iface_xml
-from xmlutils.qemucmdline import get_qemucmdline_xml
-
-
-class VMTemplate(object):
- def __init__(self, args, scan=False):
- """
- Construct a VM Template from a widely variable amount of information.
- The only required parameter is a name for the VMTemplate. If present,
- the os_distro and os_version fields are used to lookup recommended
- settings. Any parameters provided by the caller will override the
- defaults. If scan is True and a cdrom or a base img is present, the
- operating system will be detected by probing the installation media.
- """
- self.info = {}
- self.fc_host_support = args.get('fc_host_support')
-
- # Fetch defaults based on the os distro and version
- try:
- distro, version = self._get_os_info(args, scan)
- except ImageFormatError as e:
- raise OperationFailed('KCHTMPL0020E', {'err': e.message})
- os_distro = args.get('os_distro', distro)
- os_version = args.get('os_version', version)
- entry = osinfo.lookup(os_distro, os_version)
- self.info.update(entry)
-
- # Auto-generate a template name and no one is passed
- if 'name' not in args or args['name'] == '':
- args['name'] = self._gen_name(distro, version)
- self.name = args['name']
-
- # Override with the passed in parameters
- graph_args = args.get('graphics')
- if graph_args:
- graphics = dict(self.info['graphics'])
- graphics.update(graph_args)
- args['graphics'] = graphics
- self.info.update(args)
-
- # Assign right disk format to logical and [i]scsi storagepools
- if self._get_storage_type() in ['logical', 'iscsi',
'scsi']:
- for i, disk in enumerate(self.info['disks']):
- self.info['disks'][i]['format'] = 'raw'
-
- def _get_os_info(self, args, scan):
- distro = version = 'unknown'
-
- # Identify the cdrom if present
- iso = args.get('cdrom', '')
- if len(iso) > 0:
- if not iso.startswith('/'):
- self.info.update({'iso_stream': True})
-
- if scan:
- distro, version = self.get_iso_info(iso)
-
- return distro, version
-
- # CDROM is not presented: check for base image
- base_imgs = []
- for d in args.get('disks', []):
- if 'base' in d.keys():
- base_imgs.append(d)
- if scan:
- distro, version = imageinfo.probe_image(d['base'])
-
- if 'size' not in d.keys():
- d_info = imageinfo.probe_img_info(d['base'])
- d['size'] = d_info['virtual-size']
-
- if len(base_imgs) == 0:
- raise MissingParameter("KCHTMPL0016E")
-
- return distro, version
-
- def _gen_name(self, distro, version):
- if distro == 'unknown':
- name = str(uuid.uuid4())
- else:
- name = distro + version + '.' + str(int(time.time() * 1000))
- return name
-
- def get_iso_info(self, iso):
- iso_prefixes = ['/', 'http', 'https', 'ftp',
'ftps', 'tftp']
- if len(filter(iso.startswith, iso_prefixes)) == 0:
- raise InvalidParameter("KCHTMPL0006E", {'param': iso})
- try:
- iso_img = IsoImage(iso)
- return iso_img.probe()
- except IsoFormatError:
- raise InvalidParameter("KCHISO0001E", {'filename': iso})
-
- def _get_cdrom_xml(self, libvirt_stream_protocols):
- if 'cdrom' not in self.info:
- return ''
-
- params = {}
- params['type'] = 'cdrom'
- params['format'] = 'raw'
- params['bus'] = self.info['cdrom_bus']
- params['index'] = self.info['cdrom_index']
- params['path'] = self.info['cdrom']
-
- if self.info.get('iso_stream', False):
- protocol = urlparse.urlparse(params['path']).scheme
- if protocol not in libvirt_stream_protocols:
- driveOpt = 'file=%(path)s,if=none,id=drive-%(bus)s0-1-0,'
- driveOpt += 'readonly=on,format=%(format)s'
-
- deviceOpt = '%(bus)s-cd,bus=%(bus)s.1,unit=0,'
- deviceOpt += 'drive=drive-%(bus)s0-1-0,id=%(bus)s0-1-0'
-
- args = {}
- args['-drive'] = driveOpt % params
- args['-device'] = deviceOpt % params
- # return qemucmdline XML
- return get_qemucmdline_xml(args)
-
- dev, xml = get_disk_xml(params)
- return xml
-
- def _get_disks_xml(self, vm_uuid):
- # Current implementation just allows to create disk in one single
- # storage pool, so we cannot mix the types (scsi volumes vs img file)
- storage_type = self._get_storage_type()
- storage_path = self._get_storage_path()
-
- base_disk_params = {'type': 'disk', 'disk':
'file',
- 'bus': self.info['disk_bus'],
'format': 'qcow2'}
- logical_disk_params = {'format': 'raw'}
- iscsi_disk_params = {'disk': 'block', 'format':
'raw'}
-
- scsi_disk = 'volume' if self.fc_host_support else 'block'
- scsi_disk_params = {'disk': scsi_disk, 'type': 'lun',
- 'format': 'raw', 'bus':
'scsi'}
-
- disks_xml = ''
- pool_name = pool_name_from_uri(self.info['storagepool'])
- for index, disk in enumerate(self.info['disks']):
- params = dict(base_disk_params)
- params['format'] = disk.get('format',
params['format'])
- params.update(locals().get('%s_disk_params' % storage_type, {}))
- params['index'] = index
-
- volume = disk.get('volume')
- if volume is not None:
- params['path'] = self._get_volume_path(pool_name, volume)
- else:
- volume = "%s-%s.img" % (vm_uuid, params['index'])
- params['path'] = os.path.join(storage_path, volume)
-
- disks_xml += get_disk_xml(params)[1]
-
- return unicode(disks_xml, 'utf-8')
-
- def to_volume_list(self, vm_uuid):
- storage_path = self._get_storage_path()
- fmt = 'raw' if self._get_storage_type() in ['logical'] else
'qcow2'
- ret = []
- for i, d in enumerate(self.info['disks']):
- index = d.get('index', i)
- volume = "%s-%s.img" % (vm_uuid, index)
-
- info = {'name': volume,
- 'capacity': d['size'],
- 'format': fmt,
- 'path': '%s/%s' % (storage_path, volume)}
-
- if 'logical' == self._get_storage_type() or \
- fmt not in ['qcow2', 'raw']:
- info['allocation'] = info['capacity']
- else:
- info['allocation'] = 0
-
- if 'base' in d:
- info['base'] = dict()
- base_fmt = imageinfo.probe_img_info(d['base'])['format']
- if base_fmt is None:
- raise InvalidParameter("KCHTMPL0024E", {'path':
d['base']})
- info['base']['path'] = d['base']
- info['base']['format'] = base_fmt
-
- v_tree = E.volume(E.name(info['name']))
- v_tree.append(E.allocation(str(info['allocation']),
unit='G'))
- v_tree.append(E.capacity(str(info['capacity']), unit='G'))
- target = E.target(
- E.format(type=info['format']), E.path(info['path']))
- if 'base' in d:
- v_tree.append(E.backingStore(
- E.path(info['base']['path']),
- E.format(type=info['base']['format'])))
- v_tree.append(target)
- info['xml'] = etree.tostring(v_tree)
- ret.append(info)
- return ret
-
- def _get_networks_xml(self):
- networks = ""
- params = {'type': 'network',
- 'model': self.info['nic_model']}
- for nw in self.info['networks']:
- params['network'] = nw
- networks += get_iface_xml(params, self.info['arch'],
- self.info['os_distro'],
- self.info['os_version'])
- return unicode(networks, 'utf-8')
-
- def _get_input_output_xml(self):
- sound = """
- <sound model='%(sound_model)s' />
- """
- mouse = """
- <input type='mouse' bus='%(mouse_bus)s'/>
- """
-
- keyboard = """
- <input type='%(kbd_type)s' bus='%(kbd_bus)s'>
</input>
- """
-
- tablet = """
- <input type='tablet' bus='%(kbd_bus)s'> </input>
- """
-
- video = """
- <video>
- <model type='%(video_model)s'/>
- </video>
- """
-
- input_output = ""
- if 'mouse_bus' in self.info.keys():
- input_output += mouse % self.info
- if 'kbd_bus' in self.info.keys():
- input_output += keyboard % self.info
- if 'tablet_bus' in self.info.keys():
- input_output += tablet % self.info
- if 'sound_model' in self.info.keys():
- input_output += sound % self.info
- if 'video_model' in self.info.keys():
- input_output += video % self.info
- return input_output
-
- def _get_cpu_xml(self):
- # Include CPU topology, if provided
- cpu_info = self.info.get('cpu_info')
- if cpu_info is not None:
- cpu_topo = cpu_info.get('topology')
- return get_cpu_xml(self.info.get('cpus'),
- self.info.get('memory') << 10,
- cpu_topo)
-
- def to_vm_xml(self, vm_name, vm_uuid, **kwargs):
- params = dict(self.info)
- params['name'] = vm_name
- params['uuid'] = vm_uuid
- params['networks'] = self._get_networks_xml()
- params['input_output'] = self._get_input_output_xml()
- params['qemu-namespace'] = ''
- params['cdroms'] = ''
- params['qemu-stream-cmdline'] = ''
- params['cpu_info'] = self._get_cpu_xml()
- params['disks'] = self._get_disks_xml(vm_uuid)
-
- graphics = dict(self.info['graphics'])
- graphics.update(kwargs.get('graphics', {}))
- params['graphics'] = get_graphics_xml(graphics)
-
- libvirt_stream_protocols = kwargs.get('libvirt_stream_protocols', [])
- cdrom_xml = self._get_cdrom_xml(libvirt_stream_protocols)
-
- if not urlparse.urlparse(self.info.get('cdrom', "")).scheme in
\
- libvirt_stream_protocols and \
- params.get('iso_stream', False):
- params['qemu-stream-cmdline'] = cdrom_xml
- else:
- params['cdroms'] = cdrom_xml
-
- # Setting maximum number of slots to avoid errors when hotplug memory
- # Number of slots are the numbers of chunks of 1GB that fit inside
- # the max_memory of the host minus memory assigned to the VM
- params['slots'] = ((params['max_memory'] >> 10) -
- params['memory']) >> 10
- if params['slots'] < 0:
- raise OperationFailed("KCHVM0041E")
- elif params['slots'] == 0:
- params['slots'] = 1
-
- xml = """
- <domain type='%(domain)s'>
- %(qemu-stream-cmdline)s
- <name>%(name)s</name>
- <uuid>%(uuid)s</uuid>
- <maxMemory slots='%(slots)s'
unit='KiB'>%(max_memory)s</maxMemory>
- <memory unit='MiB'>%(memory)s</memory>
- <vcpu>%(cpus)s</vcpu>
- %(cpu_info)s
- <os>
- <type arch='%(arch)s'>hvm</type>
- <boot dev='hd'/>
- <boot dev='cdrom'/>
- </os>
- <features>
- <acpi/>
- <apic/>
- <pae/>
- </features>
- <clock offset='utc'/>
- <on_poweroff>destroy</on_poweroff>
- <on_reboot>restart</on_reboot>
- <on_crash>restart</on_crash>
- <devices>
- %(disks)s
- %(cdroms)s
- %(networks)s
- %(graphics)s
- %(input_output)s
- <memballoon model='virtio' />
- </devices>
- </domain>
- """ % params
-
- # Adding PPC console configuration
- if params['arch'] in ['ppc', 'ppc64']:
- ppc_console = """<memballoon model='virtio' />
- <console type='pty'>
- <target type='serial' port='1'/>
- <address type='spapr-vio' reg='0x30001000'/>
- </console>"""
- xml = xml.replace("<memballoon model='virtio' />",
ppc_console)
-
- return xml
-
- def validate(self):
- self._storage_validate()
- self._network_validate()
- self._iso_validate()
-
- def _iso_validate(self):
- pass
-
- def _network_validate(self):
- pass
-
- def _storage_validate(self):
- pass
-
- def fork_vm_storage(self, vm_uuid):
- pass
-
- def _get_storage_path(self):
- return ''
-
- def _get_storage_type(self):
- return ''
-
- def _get_volume_path(self):
- return ''
-
- def _get_all_networks_name(self):
- return []
-
- def _get_all_storagepools_name(self):
- return []
-
- def validate_integrity(self):
- invalid = {}
- # validate networks integrity
- invalid_networks = list(set(self.info['networks']) -
- set(self._get_all_networks_name()))
- if invalid_networks:
- invalid['networks'] = invalid_networks
-
- # validate storagepools integrity
- pool_uri = self.info['storagepool']
- pool_name = pool_name_from_uri(pool_uri)
- if pool_name not in self._get_all_storagepools_name():
- invalid['storagepools'] = [pool_name]
-
- # validate iso integrity
- # FIXME when we support multiples cdrom devices
- iso = self.info.get('cdrom')
- if iso:
- if os.path.exists(iso):
- st_mode = os.stat(iso).st_mode
- if not (stat.S_ISREG(st_mode) or stat.S_ISBLK(st_mode)):
- invalid['cdrom'] = [iso]
- elif not check_url_path(iso):
- invalid['cdrom'] = [iso]
-
- self.info['invalid'] = invalid
-
- return self.info
diff --git a/plugins/kimchi/vnc.py b/plugins/kimchi/vnc.py
deleted file mode 100644
index 2532449..0000000
--- a/plugins/kimchi/vnc.py
+++ /dev/null
@@ -1,77 +0,0 @@
-#!/usr/bin/env python2
-#
-# Project Kimchi
-#
-# Copyright IBM, Corp. 2013-2015
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-
-import base64
-import errno
-import os
-from multiprocessing import Process
-from websockify import WebSocketProxy
-
-from wok.config import config, paths
-
-
-WS_TOKENS_DIR = '/var/lib/wok/vnc-tokens'
-
-
-def new_ws_proxy():
- try:
- os.makedirs(WS_TOKENS_DIR, mode=0755)
- except OSError as e:
- if e.errno == errno.EEXIST:
- pass
-
- cert = config.get('server', 'ssl_cert')
- key = config.get('server', 'ssl_key')
- if not (cert and key):
- cert = '%s/wok-cert.pem' % paths.conf_dir
- key = '%s/wok-key.pem' % paths.conf_dir
-
- params = {'web': os.path.join(paths.ui_dir, 'pages/websockify'),
- 'listen_port': config.get('display',
'display_proxy_port'),
- 'target_cfg': WS_TOKENS_DIR,
- 'key': key, 'cert': cert, 'ssl_only': True}
-
- def start_proxy():
- server = WebSocketProxy(**params)
- server.start_server()
-
- proc = Process(target=start_proxy)
- proc.start()
- return proc
-
-
-def add_proxy_token(name, port):
- with open(os.path.join(WS_TOKENS_DIR, name), 'w') as f:
- """
- From python documentation base64.urlsafe_b64encode(s)
- substitutes - instead of + and _ instead of / in the
- standard Base64 alphabet, BUT the result can still
- contain = which is not safe in a URL query component.
- So remove it when needed as base64 can work well without it.
- """
- name = base64.urlsafe_b64encode(name).rstrip('=')
- f.write('%s: localhost:%s' % (name.encode('utf-8'), port))
-
-
-def remove_proxy_token(name):
- try:
- os.unlink(os.path.join(WS_TOKENS_DIR, name))
- except OSError:
- pass
diff --git a/plugins/kimchi/xmlutils/Makefile.am b/plugins/kimchi/xmlutils/Makefile.am
deleted file mode 100644
index 207ad7f..0000000
--- a/plugins/kimchi/xmlutils/Makefile.am
+++ /dev/null
@@ -1,25 +0,0 @@
-#
-# Kimchi
-#
-# Copyright IBM Corp, 2014
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-
-xmlutils_PYTHON = *.py
-
-xmlutilsdir = $(pythondir)/wok/plugins/kimchi/xmlutils
-
-install-data-local:
- $(MKDIR_P) $(DESTDIR)$(xmlutilsdir)
diff --git a/plugins/kimchi/xmlutils/__init__.py b/plugins/kimchi/xmlutils/__init__.py
deleted file mode 100644
index ca7ede4..0000000
--- a/plugins/kimchi/xmlutils/__init__.py
+++ /dev/null
@@ -1,18 +0,0 @@
-#
-# Project Kimchi
-#
-# Copyright IBM, Corp. 2014
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
diff --git a/plugins/kimchi/xmlutils/cpu.py b/plugins/kimchi/xmlutils/cpu.py
deleted file mode 100644
index 32c01a4..0000000
--- a/plugins/kimchi/xmlutils/cpu.py
+++ /dev/null
@@ -1,60 +0,0 @@
-#
-# Project Kimchi
-#
-# Copyright IBM, Corp. 2015
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-
-import lxml.etree as ET
-from lxml.builder import E
-
-
-def get_numa_xml(cpus, memory):
- # Returns the NUMA xml to be add into CPU element
- # Currently, supports only one node/cell
- # <numa>
- # <cell id='0' cpus='0-3' memory='512000'
unit='KiB'/>
- # </numa>
- xml = E.numa(E.cell(
- id='0',
- cpus='0-' + str(cpus - 1) if cpus > 1 else '0',
- memory=str(memory),
- unit='KiB'))
- return ET.tostring(xml)
-
-
-def get_topology_xml(cpu_topo):
- # Return the cpu TOPOLOGY element
- # <topology sockets='1' cores='2' threads='1'/>
- xml = E.topology(
- sockets=str(cpu_topo['sockets']),
- cores=str(cpu_topo['cores']),
- threads=str(cpu_topo['threads']))
- return ET.tostring(xml)
-
-
-def get_cpu_xml(cpus, memory, cpu_topo=None):
- # Returns the libvirt CPU element based on given numa and topology
- # CPU element will always have numa element
- # <cpu>
- # <numa>
- # <cell id='0' cpus='0-3' memory='512000'
unit='KiB'/>
- # </numa>
- # <topology sockets='1' cores='2' threads='1'/>
- # </cpu>
- xml = E.cpu(ET.fromstring(get_numa_xml(cpus, memory)))
- if cpu_topo is not None:
- xml.insert(0, ET.fromstring(get_topology_xml(cpu_topo)))
- return ET.tostring(xml)
diff --git a/plugins/kimchi/xmlutils/disk.py b/plugins/kimchi/xmlutils/disk.py
deleted file mode 100644
index 126ce77..0000000
--- a/plugins/kimchi/xmlutils/disk.py
+++ /dev/null
@@ -1,164 +0,0 @@
-#
-# Project Kimchi
-#
-# Copyright IBM, Corp. 2014
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-
-import lxml.etree as ET
-import os
-import socket
-import stat
-import string
-import urlparse
-from lxml import objectify
-from lxml.builder import E
-
-from wok.exception import InvalidParameter, NotFoundError
-from wok.utils import check_url_path
-
-
-BUS_TO_DEV_MAP = {'ide': 'hd', 'virtio': 'vd',
'scsi': 'sd'}
-DEV_TYPE_SRC_ATTR_MAP = {'file': 'file', 'block': 'dev'}
-
-
-def get_disk_xml(params):
- """
- <disk type='file' device='cdrom'>
- <driver name='qemu' type='raw'/>
-
- [source XML according to src_type]
-
- <target dev='%(dev)s' bus='%(bus)s'/>
- <readonly/>
- </disk>
- """
- path = params['path']
- disk_type = params.get('disk', None)
- if disk_type is None:
- disk_type = _get_disk_type(path) if len(path) > 0 else 'file'
- disk = E.disk(type=disk_type, device=params['type'])
- driver = E.driver(name='qemu', type=params['format'])
- if params['type'] != 'cdrom':
- driver.set('cache', 'none')
-
- disk.append(driver)
-
- # Get device name according to bus and index values
- dev = params.get('dev', (BUS_TO_DEV_MAP[params['bus']] +
- string.lowercase[params.get('index', 0)]))
- disk.append(E.target(dev=dev, bus=params['bus']))
-
- if params.get('address'):
- # ide disk target id is always '0'
- disk.append(E.address(
- type='drive',
controller=params['address']['controller'],
- bus=params['address']['bus'], target='0',
- unit=params['address']['unit']))
-
- if len(params['path']) == 0:
- return (dev, ET.tostring(disk, encoding='utf-8', pretty_print=True))
-
- if disk_type == 'network':
- """
- <source protocol='%(protocol)s' name='%(url_path)s'>
- <host name='%(hostname)s' port='%(port)s'/>
- </source>
- """
- output = urlparse.urlparse(params['path'])
- port = str(output.port or socket.getservbyname(output.scheme))
-
- source = E.source(protocol=output.scheme, name=output.path)
- source.append(E.host(name=output.hostname, port=port))
- else:
- """
- <source file='%(src)s' />
- """
- source = E.source()
- source.set(DEV_TYPE_SRC_ATTR_MAP[disk_type], params['path'])
-
- disk.append(source)
- return (dev, ET.tostring(disk, encoding='utf-8', pretty_print=True))
-
-
-def _get_disk_type(path):
- if check_url_path(path):
- return 'network'
-
- if not os.path.exists(path):
- raise InvalidParameter("KCHVMSTOR0003E", {'value': path})
-
- # Check if path is a valid local path
- if os.path.isfile(path):
- return 'file'
-
- r_path = os.path.realpath(path)
- if stat.S_ISBLK(os.stat(r_path).st_mode):
- return 'block'
-
- raise InvalidParameter("KCHVMSTOR0003E", {'value': path})
-
-
-def get_device_node(dom, dev_name):
- xml = dom.XMLDesc(0)
- devices = objectify.fromstring(xml).devices
- disk = devices.xpath("./disk/target[@dev='%s']/.." % dev_name)
-
- if not disk:
- raise NotFoundError("KCHVMSTOR0007E",
- {'dev_name': dev_name,
- 'vm_name': dom.name()})
-
- return disk[0]
-
-
-def get_vm_disk_info(dom, dev_name):
- # Retrieve disk xml and format return dict
- disk = get_device_node(dom, dev_name)
- if disk is None:
- return None
-
- try:
- source = disk.source
- if source is not None:
- src_type = disk.attrib['type']
- if src_type == 'network':
- host = source.host
- path = (source.attrib['protocol'] + '://' +
- host.attrib['name'] + ':' +
- host.attrib['port'] + source.attrib['name'])
- else:
- path = source.attrib[DEV_TYPE_SRC_ATTR_MAP[src_type]]
- except:
- path = ""
-
- return {'dev': dev_name,
- 'path': path,
- 'type': disk.attrib['device'],
- 'format': disk.driver.attrib['type'],
- 'bus': disk.target.attrib['bus']}
-
-
-def get_vm_disks(dom):
- xml = dom.XMLDesc(0)
- devices = objectify.fromstring(xml).devices
-
- storages = {}
- all_disks = devices.xpath("./disk[@device='disk']")
- all_disks.extend(devices.xpath("./disk[@device='cdrom']"))
- for disk in all_disks:
- storages[disk.target.attrib['dev']] = disk.target.attrib['bus']
-
- return storages
diff --git a/plugins/kimchi/xmlutils/graphics.py b/plugins/kimchi/xmlutils/graphics.py
deleted file mode 100644
index 2b4346a..0000000
--- a/plugins/kimchi/xmlutils/graphics.py
+++ /dev/null
@@ -1,45 +0,0 @@
-#
-# Project Kimchi
-#
-# Copyright IBM, Corp. 2014
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-
-import lxml.etree as ET
-from lxml.builder import E
-
-
-def get_graphics_xml(params):
- """
- <graphics type='%(type)s' autoport='yes'
listen='%(listen)s'/>
-
- - For spice graphics:
-
- <channel type='spicevmc'>
- <target type='virtio' name='com.redhat.spice.0'/>
- </channel>
- """
- graphics = E.graphics(type=params['type'], autoport='yes',
- listen=params['listen'])
- graphics_xml = ET.tostring(graphics, encoding='utf-8', pretty_print=True)
-
- if params['type'] == 'vnc':
- return graphics_xml
-
- # For spice graphics, a channel also must be configured
- channel = E.channel(type='spicevmc')
- channel.append(E.target(type='virtio', name='com.redhat.spice.0'))
- channel_xml = ET.tostring(channel, encoding='utf-8', pretty_print=True)
- return graphics_xml + channel_xml
diff --git a/plugins/kimchi/xmlutils/interface.py b/plugins/kimchi/xmlutils/interface.py
deleted file mode 100644
index 0f3e848..0000000
--- a/plugins/kimchi/xmlutils/interface.py
+++ /dev/null
@@ -1,61 +0,0 @@
-#
-# Project Kimchi
-#
-# Copyright IBM, Corp. 2014-2015
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-
-import lxml.etree as ET
-from distutils.version import LooseVersion
-from lxml.builder import E
-
-from .. import osinfo
-
-
-def get_iface_xml(params, arch=None, os_distro=None, os_version=None):
- """
- <interface type='network'>
- <source network='default'/>
- <model type='virtio'/>
- </interface>
- """
- interface = E.interface(type=params['type'])
- interface.append(E.source(network=params['network']))
-
- model = params.get('model')
-
- # no model specified; let's try querying osinfo
- if model is None:
- # if os_distro and os_version are invalid, nic_model will also be None
- model = osinfo.lookup(os_distro, os_version).get('nic_model')
-
- # only append 'model' to the XML if it's been specified as a parameter
or
- # returned by osinfo.lookup; otherwise let libvirt use its default value
- if model is not None:
- interface.append(E.model(type=model))
-
- mac = params.get('mac', None)
- if mac is not None:
- interface.append(E.mac(address=mac))
-
- # Hack to disable vhost feature in Ubuntu LE and SLES LE (PPC)
- if arch == 'ppc64' and \
- ((os_distro == 'ubuntu' and
- LooseVersion(os_version) >= LooseVersion('14.04')) or
- (os_distro == 'sles' and
- LooseVersion(os_version) >= LooseVersion('12'))):
- interface.append(E.driver(name='qemu'))
-
- return ET.tostring(interface, encoding='utf-8', pretty_print=True)
diff --git a/plugins/kimchi/xmlutils/network.py b/plugins/kimchi/xmlutils/network.py
deleted file mode 100644
index c73aad9..0000000
--- a/plugins/kimchi/xmlutils/network.py
+++ /dev/null
@@ -1,122 +0,0 @@
-#
-# Project Kimchi
-#
-# Copyright IBM, Corp. 2014
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-
-import ipaddr
-import lxml.etree as ET
-from lxml.builder import E
-
-
-# FIXME, do not support ipv6
-def _get_dhcp_elem(**kwargs):
- """
- <dhcp>
- <range start="192.168.122.100" end="192.168.122.254" />
- <host mac="00:16:3e:77:e2:ed" name="foo.test.com"
ip="192.168.122.10" />
- <host mac="00:16:3e:3e:a9:1a" name="bar.test.com"
ip="192.168.122.11" />
- </dhcp>
- """
- dhcp = E.dhcp()
- if 'range' in kwargs.keys():
- dhcp_range = E.range(start=kwargs['range']['start'],
- end=kwargs['range']['end'])
- dhcp.append(dhcp_range)
-
- if 'hosts' in kwargs.keys():
- for host in kwargs['hosts']:
- dhcp.append(E.host(mac=host['mac'],
- name=host['name'],
- ip=host['ip']))
-
- return dhcp if len(dhcp) > 0 else None
-
-
-def _get_ip_elem(**kwargs):
- """
- <ip address="192.168.152.1" netmask="255.255.255.0">
- <dhcp>
- <range start="192.168.152.2" end="192.168.152.254" />
- </dhcp>
- </ip>
- """
- if 'net' not in kwargs.keys():
- return None
-
- net = ipaddr.IPNetwork(kwargs['net'])
- ip = E.ip(address=str(net.ip), netmask=str(net.netmask))
-
- dhcp_params = kwargs.get('dhcp', {})
- dhcp = _get_dhcp_elem(**dhcp_params)
- if dhcp is not None:
- ip.append(dhcp)
-
- return ip
-
-
-def _get_forward_elem(**kwargs):
- """
- <forward mode='hostdev' dev='eth0' managed='yes'>
- </forward>
- """
- if "mode" in kwargs.keys() and kwargs['mode'] is None:
- return None
-
- forward = E.forward()
- if 'mode' in kwargs.keys():
- forward.set('mode', kwargs['mode'])
-
- if 'dev' in kwargs.keys():
- forward.set('dev', kwargs['dev'])
-
- if 'managed' in kwargs.keys():
- forward.set('managed', kwargs['managed'])
-
- return forward
-
-
-def to_network_xml(**kwargs):
- network = E.network(E.name(kwargs['name']))
- bridge = kwargs.get('bridge')
- if bridge:
- network.append(E.bridge(name=bridge))
-
- # None means is Isolated network, {} means default mode nat
- params = kwargs.get('forward', {"mode": None})
- forward = _get_forward_elem(**params)
- if forward is not None:
- network.append(forward)
-
- if 'net' in kwargs:
- network.append(_get_ip_elem(**kwargs))
-
- return ET.tostring(network)
-
-
-def create_vlan_tagged_bridge_xml(bridge, interface, vlan_id):
- vlan = E.vlan(E.interface(name=interface))
- vlan.set('tag', vlan_id)
- m = E.interface(
- E.start(mode='onboot'),
- E.bridge(
- E.interface(
- vlan,
- type='vlan',
- name='.'.join([interface, vlan_id]))),
- type='bridge',
- name=bridge)
- return ET.tostring(m)
diff --git a/plugins/kimchi/xmlutils/qemucmdline.py
b/plugins/kimchi/xmlutils/qemucmdline.py
deleted file mode 100644
index 66238a7..0000000
--- a/plugins/kimchi/xmlutils/qemucmdline.py
+++ /dev/null
@@ -1,45 +0,0 @@
-#
-# Project Kimchi
-#
-# Copyright IBM, Corp. 2014
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-
-import lxml.etree as ET
-from lxml.builder import ElementMaker
-
-QEMU_NAMESPACE = "http://libvirt.org/schemas/domain/qemu/1.0"
-
-
-def get_qemucmdline_xml(args):
- """
- <qemu:commandline
xmlns:qemu="http://libvirt.org/schemas/domain/qemu/1.0">
- <qemu:arg value='-drive'/>
- <qemu:arg value='file=%(path)s,if=none,id=drive-%(bus)s0-1-0,
- readonly=on,format=%(format)s'/>
- <qemu:arg value='-device'/>
- <qemu:arg value='%(bus)s-cd,bus=%(bus)s.1,unit=0,
- drive=drive-%(bus)s0-1-0,id=%(bus)s0-1-0'/>
- </qemu:commandline>
- """
- EM = ElementMaker(namespace=QEMU_NAMESPACE,
- nsmap={'qemu': QEMU_NAMESPACE})
-
- root = EM.commandline()
- for opt, value in args.iteritems():
- root.append(EM.arg(value=opt))
- root.append(EM.arg(value=value))
-
- return ET.tostring(root, encoding='utf-8', pretty_print=True)
diff --git a/plugins/kimchi/yumparser.py b/plugins/kimchi/yumparser.py
deleted file mode 100644
index 74f9fa0..0000000
--- a/plugins/kimchi/yumparser.py
+++ /dev/null
@@ -1,283 +0,0 @@
-#
-# Project Kimchi
-#
-# Copyright IBM, Corp. 2015
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-
-import subprocess
-from os import listdir
-from os.path import isfile, splitext
-
-
-class YumRepoObject(object):
-
- def __init__(self, repo_id, repofile):
- self.repo_id = repo_id
- self.name = None
- self.baseurl = None
- self.enabled = True
- self.gpgcheck = True
- self.gpgkey = None
- self.metalink = None
- self.mirrorlist = None
- self.repofile = repofile
- self.string_attrs = ['baseurl', 'gpgkey', 'name',
- 'metalink', 'mirrorlist']
- self.boolean_attrs = ['enabled', 'gpgcheck']
-
- def set_attribute(self, key, strvalue):
- if key in self.string_attrs:
- setattr(self, key, strvalue)
- elif key in self.boolean_attrs:
- setattr(self, key, (strvalue == '1'))
-
- def get_attribute_str(self, key):
- if key not in self.get_attributes():
- return None
-
- if key in self.boolean_attrs:
- str_value = '1' if getattr(self, key) is True else '0'
- else:
- str_value = getattr(self, key)
-
- if str_value is None:
- return None
-
- return key + '=' + str_value
-
- def get_attributes(self):
- return self.string_attrs + self.boolean_attrs
-
- def enable(self):
- self.enabled = True
-
- def disable(self):
- self.enabled = False
-
- def __str__(self):
- str_obj = '[' + self.repo_id + ']' + '\n'
- for key in self.get_attributes():
- if self.get_attribute_str(key) is not None:
- str_obj += self.get_attribute_str(key) + '\n'
- return str_obj
-
-
-def get_repo_files():
- def _is_repository_file(f):
- _, f_extension = splitext(f)
- return isfile(f) and (f_extension == '.repo')
-
- YUM_REPO_DIR = '/etc/yum.repos.d'
- return [YUM_REPO_DIR+'/'+f for f in listdir(YUM_REPO_DIR)
- if _is_repository_file(YUM_REPO_DIR+'/'+f)]
-
-
-def _ignore_line_repo_file(line):
- return line.startswith("#") or '=' not in line
-
-
-def _get_repos_from_file(repo_file):
- repos_from_file = {}
- current_repo = None
- current_repo_id = None
- with open(repo_file) as f:
- for line in f.readlines():
- line = line.strip()
- if line.startswith("["):
- if current_repo is not None:
- repos_from_file[current_repo_id] = current_repo
- current_repo_id = line.strip('[]')
- current_repo = YumRepoObject(current_repo_id, repo_file)
- continue
- if _ignore_line_repo_file(line):
- continue
- key, value = line.split('=', 1)
- key = key.strip()
- value = value.strip()
- current_repo.set_attribute(key, value)
-
- # add the last repo from file.
- if current_repo is not None:
- repos_from_file[current_repo_id] = current_repo
-
- return repos_from_file
-
-
-def get_yum_repositories():
- repo_files = get_repo_files()
- repos = {}
- for yum_repo in repo_files:
- repos.update(_get_repos_from_file(yum_repo))
-
- return repos
-
-
-def _retrieve_repo_line_index(data, repo):
- repo_entry = '[' + repo.repo_id + ']\n'
- try:
- repo_index = data.index(repo_entry)
- except:
- return None
- return repo_index
-
-
-def _update_repo_file_data(data, repo, repo_index):
- remaining_repo_attrs = repo.get_attributes()
-
- for i in range(repo_index + 1, len(data)):
- line = data[i].strip()
- if line.startswith('['):
- break
- if _ignore_line_repo_file(line):
- continue
- key, _ = line.split('=', 1)
- key = key.strip()
- attr_str = repo.get_attribute_str(key)
- if attr_str is None:
- continue
- remaining_repo_attrs.remove(key)
- data[i] = attr_str + '\n'
-
- for attr in remaining_repo_attrs:
- attr_str = repo.get_attribute_str(attr)
- if attr_str is None:
- continue
- data.insert(repo_index+1, attr_str + '\n')
-
- return data
-
-
-def write_repo_to_file(repo):
- with open(repo.repofile) as f:
- data = f.readlines()
-
- repo_index = _retrieve_repo_line_index(data, repo)
- if repo_index is None:
- return
-
- data = _update_repo_file_data(data, repo, repo_index)
-
- with open(repo.repofile, 'w') as f:
- f.writelines(data)
-
-
-def _get_last_line_repo(data, repo_index):
- stop_delete_index = None
- for i in range(repo_index+1, len(data)):
- line = data[i].strip()
- if line.startswith('['):
- stop_delete_index = i - 1
- break
- if stop_delete_index is None:
- stop_delete_index = len(data) - 1
-
- return stop_delete_index
-
-
-def _remove_repo_file_data(data, repo_index):
- last_line_repo = _get_last_line_repo(data, repo_index)
- for i in range(last_line_repo, repo_index - 1, -1):
- data.pop(i)
- return data
-
-
-def delete_repo_from_file(repo):
- with open(repo.repofile) as f:
- data = f.readlines()
-
- repo_index = _retrieve_repo_line_index(data, repo)
- if repo_index is None:
- return
-
- data = _remove_repo_file_data(data, repo_index)
-
- with open(repo.repofile, 'w') as f:
- f.writelines(data)
-
-
-class YumUpdatePackageObject(object):
-
- def __init__(self, name, arch, version, repo):
- self.name = name
- self.arch = arch
- self.version = version
- self.ui_from_repo = repo
-
-
-def _include_line_checkupdate_output(line):
- tokens = line.split()
-
- if len(tokens) != 3:
- return False
-
- if '.' not in tokens[0]:
- return False
-
- return True
-
-
-def _ignore_obsoleting_packages_in(output):
- out = ''
- for l in output.split('\n'):
- if 'Obsoleting ' in l:
- break
- out += l + '\n'
- return out
-
-
-def _filter_lines_checkupdate_output(output):
- if output is None:
- return []
-
- output = _ignore_obsoleting_packages_in(output)
-
- out = [l for l in output.split('\n')
- if _include_line_checkupdate_output(l)]
- return out
-
-
-def _get_yum_checkupdate_output():
- cmd = ['yum', 'check-update', '-d0']
- yum_update_cmd = subprocess.Popen(cmd,
- stdout=subprocess.PIPE,
- stderr=subprocess.PIPE)
- out, error = yum_update_cmd.communicate()
- return_code = yum_update_cmd.returncode
- if return_code == 1:
- return None
-
- return out
-
-
-def get_yum_packages_list_update(checkupdate_output=None):
- if checkupdate_output is None:
- checkupdate_output = _get_yum_checkupdate_output()
-
- filtered_output = _filter_lines_checkupdate_output(checkupdate_output)
-
- packages = []
- for line in filtered_output:
- line = line.split()
- index = 0
- name_arch = line[index]
- index += 1
- version = line[index]
- index += 1
- repo = line[index]
- name, arch = name_arch.rsplit('.', 1)
- packages.append(YumUpdatePackageObject(name, arch, version, repo))
-
- return packages
diff --git a/plugins/sample/API.json b/plugins/sample/API.json
deleted file mode 100644
index 6ee7d91..0000000
--- a/plugins/sample/API.json
+++ /dev/null
@@ -1,56 +0,0 @@
-{
- "$schema": "http://json-schema.org/draft-03/schema#",
- "title": "Plugin Sample API",
- "description": "Json schema for Wok's Sample Plugin API",
- "type": "object",
- "error": "SPAPI0001E",
- "properties": {
- "rectangles_create": {
- "type": "object",
- "error": "SPRET0003E",
- "properties": {
- "name": {
- "description": "The name of the new rectangle
instance",
- "type": "string",
- "required": true,
- "error": "SPRET0004E"
- },
- "length": {
- "$ref": "#/definitions/positiveNumber",
- "required": true,
- "error": "SPRET0005E"
- },
- "width": {
- "$ref": "#/definitions/positiveNumber",
- "required": true,
- "error": "SPRET0006E"
- }
- }
- },
- "circles_create": {
- "type": "object",
- "error": "SPCIRC0003E",
- "properties": {
- "name": {
- "description": "The name of the new circle
instance",
- "type": "string",
- "required": true,
- "error": "SPCIRC0004E"
- },
- "radius": {
- "$ref": "#/definitions/positiveNumber",
- "required": true,
- "error": "SPCIRC0005E"
- }
- }
- }
- },
- "definitions": {
- "positiveNumber": {
- "error": "SPAPI0002E",
- "type": "number",
- "minimum": 0,
- "exclusiveMinimum": true
- }
- }
-}
diff --git a/plugins/sample/Makefile.am b/plugins/sample/Makefile.am
deleted file mode 100644
index 876ab54..0000000
--- a/plugins/sample/Makefile.am
+++ /dev/null
@@ -1,29 +0,0 @@
-#
-# Kimchi
-#
-# Copyright IBM Corp, 2013
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-
-SUBDIRS = ui po
-
-EXTRA_DIST = API.json sample.conf.in $(wildcard *.py) config.status
-
-all-local:
- while read L && test -n "$$L"; do \
- dir=mo/$$L/LC_MESSAGES ; \
- $(MKDIR_P) $$dir ; \
- ln -sf ../../../po/$$L.gmo $$dir/sample.mo ; \
- done < po/LINGUAS
diff --git a/plugins/sample/__init__.py b/plugins/sample/__init__.py
deleted file mode 100644
index a3a8f05..0000000
--- a/plugins/sample/__init__.py
+++ /dev/null
@@ -1,97 +0,0 @@
-#
-# Project Kimchi
-#
-# Copyright IBM, Corp. 2013-2014
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-
-import json
-import os
-from cherrypy import expose
-
-
-from wok.config import PluginPaths
-from wok.control.base import Collection, Resource
-from wok.root import WokRoot
-
-
-from plugins.sample.i18n import messages
-from plugins.sample.model import Model
-
-
-model = Model()
-
-
-class Drawings(WokRoot):
- def __init__(self, wok_options):
- Resource.__init__(self, model)
- self.description = Description(model)
- self.rectangles = Rectangles(model)
- self.circles = Circles(model)
- self.paths = PluginPaths('sample')
- self.domain = 'sample'
- self.messages = messages
- self.api_schema = json.load(open(os.path.join(os.path.dirname(
- os.path.abspath(__file__)), 'API.json')))
-
- @expose
- def index(self):
- return 'This is a sample plugin for Wok'
-
-
-class Description(Resource):
- def __init__(self, model):
- super(Description, self).__init__(model)
-
- @property
- def data(self):
- return {'name': 'sample', 'version': '0.1'}
-
-
-class Circles(Collection):
- def __init__(self, model):
- super(Circles, self).__init__(model)
- self.resource = Circle
- self.admin_methods = ['POST', 'PUT']
-
-
-class Rectangles(Collection):
- def __init__(self, model):
- super(Rectangles, self).__init__(model)
- self.resource = Rectangle
- self.admin_methods = ['POST', 'PUT']
-
-
-class Circle(Resource):
- def __init__(self, model, ident):
- super(Circle, self).__init__(model, ident)
- self.update_params = ['radius']
-
- @property
- def data(self):
- ret = {'name': self.ident}
- ret.update(self.info)
- return ret
-
-
-class Rectangle(Resource):
- def __init__(self, model, ident):
- super(Rectangle, self).__init__(model, ident)
- self.update_params = ['length', 'width']
-
- @property
- def data(self):
- self.info.update({'name': self.ident})
- return self.info
diff --git a/plugins/sample/config.status b/plugins/sample/config.status
deleted file mode 120000
index 6cd6b4f..0000000
--- a/plugins/sample/config.status
+++ /dev/null
@@ -1 +0,0 @@
-../../config.status
\ No newline at end of file
diff --git a/plugins/sample/i18n.py b/plugins/sample/i18n.py
deleted file mode 100644
index 763970f..0000000
--- a/plugins/sample/i18n.py
+++ /dev/null
@@ -1,40 +0,0 @@
-#
-# Project Kimchi
-#
-# Copyright IBM, Corp. 2014
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-
-import gettext
-
-_ = gettext.gettext
-
-
-messages = {
- "SPAPI0001E": _("Unkown parameter specified %(value)s"),
- "SPAPI0002E": _("The specified value %(value)s is not a positive
number"),
-
- "SPCIRC0002E": _("Circle %(name)s does not exist"),
- "SPCIRC0003E": _("Specify name and radius to create a Circle"),
- "SPCIRC0004E": _("Circle name must be a string"),
- "SPCIRC0005E": _("Circle radius must be a positive number"),
-
- "SPRET0001E": _("Rectangle %(name)s already exists"),
- "SPRET0002E": _("Rectangle %(name)s does not exist"),
- "SPRET0003E": _("Specify name, length and width to create a
Rectangle"),
- "SPRET0004E": _("Rectangle name must be a string"),
- "SPRET0005E": _("Rectangle length must be a positive number"),
- "SPRET0006E": _("Rectangle width must be a positive number"),
-}
diff --git a/plugins/sample/model.py b/plugins/sample/model.py
deleted file mode 100644
index 4ada648..0000000
--- a/plugins/sample/model.py
+++ /dev/null
@@ -1,131 +0,0 @@
-#
-# Project Kimchi
-#
-# Copyright IBM, Corp. 2013-2014
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-
-from wok.basemodel import BaseModel
-from wok.exception import InvalidOperation, NotFoundError
-
-
-class CirclesModel(object):
- def __init__(self):
- self._circles = {}
-
- def create(self, params):
- name = params['name']
- if name in self._circles:
- raise InvalidOperation("SPCIRCLE0001E", {'name': name})
- self._circles[name] = Circle(params['radius'])
- return name
-
- def get_list(self):
- return sorted(self._circles)
-
-
-class CircleModel(object):
- def __init__(self, parent_model):
- # Circel and Circles models are friends, it's OK to share _circles.
- self._circles = parent_model._circles
-
- def lookup(self, name):
- try:
- circle = self._circles[name]
- except KeyError:
- raise NotFoundError("SPCIRC0002E", {'name': name})
- return {'radius': circle.radius}
-
- def update(self, name, params):
- if name not in self._circles:
- raise NotFoundError("SPCIRC0002E", {'name': name})
- self._circles[name].radius = params['radius']
- return name
-
- def delete(self, name):
- try:
- del self._circles[name]
- except KeyError:
- pass
-
-
-class RectanglesModel(object):
- def __init__(self):
- self._rectangles = {}
-
- def create(self, params):
- name = params['name']
- if name in self._rectangles:
- raise InvalidOperation("SPRET0001E", {'name': name})
- self._rectangles[name] = Rectangle(params['length'],
params['width'])
- return name
-
- def get_list(self):
- return sorted(self._rectangles)
-
-
-class RectangleModel(object):
- def __init__(self, parent_model):
- self._rectangles = parent_model._rectangles
-
- def lookup(self, name):
- try:
- rectangle = self._rectangles[name]
- except KeyError:
- raise NotFoundError("SPRET0002E", {'name': name})
- return {'length': rectangle.length, 'width': rectangle.width}
-
- def update(self, name, params):
- if name not in self._rectangles:
- raise NotFoundError("SPRET0002E", {'name': name})
- try:
- self._rectangles[name].length = params['length']
- except KeyError:
- pass
-
- try:
- self._rectangles[name].width = params['width']
- except KeyError:
- pass
- return name
-
- def delete(self, name):
- try:
- del self._rectangles[name]
- except KeyError:
- pass
-
-
-class Model(BaseModel):
- def __init__(self):
- circles = CirclesModel()
- circle = CircleModel(circles)
-
- rectangles = RectanglesModel()
- rectangle = RectangleModel(rectangles)
-
- return super(Model, self).__init__(
- [circle, circles, rectangle, rectangles])
-
-
-class Rectangle(object):
- def __init__(self, length, width):
- self.length = length
- self.width = width
-
-
-class Circle(object):
- def __init__(self, radius):
- self.radius = radius
diff --git a/plugins/sample/po/LINGUAS b/plugins/sample/po/LINGUAS
deleted file mode 100644
index 469998e..0000000
--- a/plugins/sample/po/LINGUAS
+++ /dev/null
@@ -1,3 +0,0 @@
-en_US
-pt_BR
-zh_CN
diff --git a/plugins/sample/po/Makefile.in.in b/plugins/sample/po/Makefile.in.in
deleted file mode 100644
index 52ab81c..0000000
--- a/plugins/sample/po/Makefile.in.in
+++ /dev/null
@@ -1,400 +0,0 @@
-# Makefile for PO directory in any package using GNU gettext.
-# Copyright (C) 1995-1997, 2000-2007, 2009-2010 by Ulrich Drepper
<drepper(a)gnu.ai.mit.edu>
-#
-# This file can be copied and used freely without restrictions. It can
-# be used in projects which are not available under the GNU General Public
-# License but which still want to provide support for the GNU gettext
-# functionality.
-# Please note that the actual code of GNU gettext is covered by the GNU
-# General Public License and is *not* in the public domain.
-#
-# Origin: gettext-0.18
-GETTEXT_MACRO_VERSION = 0.18
-
-PACKAGE = @PACKAGE@
-VERSION = @VERSION@
-PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
-
-SHELL = /bin/sh
-@SET_MAKE@
-
-srcdir = @srcdir@
-top_srcdir = @top_srcdir@
-VPATH = @srcdir@
-
-prefix = @prefix@
-exec_prefix = @exec_prefix@
-datarootdir = @datarootdir@
-datadir = @datadir@
-localedir = @prefix@/share/locale
-gettextsrcdir = $(datadir)/gettext/po
-
-INSTALL = @INSTALL@
-INSTALL_DATA = @INSTALL_DATA@
-
-# We use $(MKDIR_P).
-# This macro uses the 'mkdir -p' command if possible. Otherwise, it falls back
-# on invoking install-sh with the -d option, so your package should contain
-# install-sh as described under AC_PROG_INSTALL.
-mkinstalldirs = $(SHELL) @install_sh@ -d
-install_sh = $(SHELL) @install_sh@
-MKDIR_P = @MKDIR_P@
-MKDIR_P = @MKDIR_P@
-
-GMSGFMT_ = @GMSGFMT@
-GMSGFMT_no = @GMSGFMT@
-GMSGFMT_yes = @GMSGFMT_015@
-GMSGFMT = $(GMSGFMT_$(USE_MSGCTXT))
-MSGFMT_ = @MSGFMT@
-MSGFMT_no = @MSGFMT@
-MSGFMT_yes = @MSGFMT_015@
-MSGFMT = $(MSGFMT_$(USE_MSGCTXT))
-XGETTEXT_ = @XGETTEXT@
-XGETTEXT_no = @XGETTEXT@
-XGETTEXT_yes = @XGETTEXT_015@
-XGETTEXT = $(XGETTEXT_$(USE_MSGCTXT))
-MSGMERGE = msgmerge
-MSGMERGE_UPDATE = @MSGMERGE@ --update
-MSGINIT = msginit
-MSGCONV = msgconv
-MSGFILTER = msgfilter
-
-POFILES = @POFILES@
-GMOFILES = @GMOFILES@
-UPDATEPOFILES = @UPDATEPOFILES@
-DUMMYPOFILES = @DUMMYPOFILES@
-DISTFILES.common = Makefile.in.in \
-$(DISTFILES.common.extra1) $(DISTFILES.common.extra2) $(DISTFILES.common.extra3)
-DISTFILES = $(DISTFILES.common) Makevars POTFILES.in gen-pot \
-$(POFILES) $(GMOFILES) \
-$(DISTFILES.extra1) $(DISTFILES.extra2) $(DISTFILES.extra3)
-
-POTFILES = \
-
-CATALOGS = @CATALOGS@
-
-# Makevars gets inserted here. (Don't remove this line!)
-
-.SUFFIXES:
-.SUFFIXES: .po .gmo .mo .sed .sin .nop .po-create .po-update
-
-.po.mo:
- @echo "$(MSGFMT) -c -o $@ $<"; \
- $(MSGFMT) -c -o t-$@ $< && mv t-$@ $@
-
-.po.gmo:
- @lang=`echo $* | sed -e 's,.*/,,'`; \
- test "$(srcdir)" = . && cdcmd="" || cdcmd="cd $(srcdir)
&& "; \
- echo "$${cdcmd}rm -f $${lang}.gmo && $(GMSGFMT) -c --statistics --verbose
-o $${lang}.gmo $${lang}.po"; \
- cd $(srcdir) && rm -f $${lang}.gmo && $(GMSGFMT) -c --statistics
--verbose -o t-$${lang}.gmo $${lang}.po && mv t-$${lang}.gmo $${lang}.gmo
-
-.sin.sed:
- sed -e '/^#/d' $< > t-$@
- mv t-$@ $@
-
-
-all: check-macro-version update-gmo all-@USE_NLS@
-
-all-yes: stamp-po
-all-no:
-
-# Ensure that the gettext macros and this Makefile.in.in are in sync.
-check-macro-version:
- @test "$(GETTEXT_MACRO_VERSION)" = "@GETTEXT_MACRO_VERSION@" \
- || { echo "*** error: gettext infrastructure mismatch: using a Makefile.in.in
from gettext version $(GETTEXT_MACRO_VERSION) but the autoconf macros are from gettext
version @GETTEXT_MACRO_VERSION@" 1>&2; \
- exit 1; \
- }
-
-# $(srcdir)/$(DOMAIN).pot is only created when needed. When xgettext finds no
-# internationalized messages, no $(srcdir)/$(DOMAIN).pot is created (because
-# we don't want to bother translators with empty POT files). We assume that
-# LINGUAS is empty in this case, i.e. $(POFILES) and $(GMOFILES) are empty.
-# In this case, stamp-po is a nop (i.e. a phony target).
-
-# stamp-po is a timestamp denoting the last time at which the CATALOGS have
-# been loosely updated. Its purpose is that when a developer or translator
-# checks out the package via CVS, and the $(DOMAIN).pot file is not in CVS,
-# "make" will update the $(DOMAIN).pot and the $(CATALOGS), but subsequent
-# invocations of "make" will do nothing. This timestamp would not be necessary
-# if updating the $(CATALOGS) would always touch them; however, the rule for
-# $(POFILES) has been designed to not touch files that don't need to be
-# changed.
-stamp-po: $(srcdir)/$(DOMAIN).pot
- test ! -f $(srcdir)/$(DOMAIN).pot || \
- test -z "$(GMOFILES)" || $(MAKE) $(GMOFILES)
- @test ! -f $(srcdir)/$(DOMAIN).pot || { \
- echo "touch stamp-po" && \
- echo timestamp > stamp-poT && \
- mv stamp-poT stamp-po; \
- }
-
-# Note: Target 'all' must not depend on target '$(DOMAIN).pot-update',
-# otherwise packages like GCC can not be built if only parts of the source
-# have been downloaded.
-
-$(DOMAIN).pot-update: $(POTFILES) $(srcdir)/POTFILES.in
- $(srcdir)/gen-pot $(POTFILES)
-
-# This rule has no dependencies: we don't need to update $(DOMAIN).pot at
-# every "make" invocation, only create it when it is missing.
-# Only "make $(DOMAIN).pot-update" or "make dist" will force an
update.
-$(srcdir)/$(DOMAIN).pot:
- $(MAKE) $(DOMAIN).pot-update
-
-# This target rebuilds a PO file if $(DOMAIN).pot has changed.
-# Note that a PO file is not touched if it doesn't need to be changed.
-$(POFILES): $(srcdir)/$(DOMAIN).pot
- @lang=`echo $@ | sed -e 's,.*/,,' -e 's/\.po$$//'`; \
- if test -f "$(srcdir)/$${lang}.po"; then \
- test "$(srcdir)" = . && cdcmd="" || cdcmd="cd
$(srcdir) && "; \
- echo "$${cdcmd}$(MSGMERGE_UPDATE) $(MSGMERGE_OPTIONS) --lang=$${lang} $${lang}.po
$(DOMAIN).pot"; \
- cd $(srcdir) \
- && { case `$(MSGMERGE_UPDATE) --version | sed 1q | sed -e
's,^[^0-9]*,,'` in \
- '' | 0.[0-9] | 0.[0-9].* | 0.1[0-7] | 0.1[0-7].*) \
- $(MSGMERGE_UPDATE) $(MSGMERGE_OPTIONS) $${lang}.po $(DOMAIN).pot;; \
- *) \
- $(MSGMERGE_UPDATE) $(MSGMERGE_OPTIONS) --lang=$${lang} $${lang}.po
$(DOMAIN).pot;; \
- esac; \
- }; \
- else \
- $(MAKE) $${lang}.po-create; \
- fi
-
-
-install:
-
-install-exec:
-install-data: install-data-@USE_NLS@
- if test "$(PACKAGE)" = "gettext-tools"; then \
- $(MKDIR_P) $(DESTDIR)$(gettextsrcdir); \
- for file in $(DISTFILES.common) Makevars.template; do \
- $(INSTALL_DATA) $(srcdir)/$$file \
- $(DESTDIR)$(gettextsrcdir)/$$file; \
- done; \
- for file in Makevars; do \
- rm -f $(DESTDIR)$(gettextsrcdir)/$$file; \
- done; \
- else \
- : ; \
- fi
-install-data-no: all
-install-data-yes: all
- @catalogs='$(CATALOGS)'; \
- for cat in $$catalogs; do \
- cat=`basename $$cat`; \
- lang=`echo $$cat | sed -e 's/\.gmo$$//'`; \
- dir=$(localedir)/$$lang/LC_MESSAGES; \
- $(MKDIR_P) $(DESTDIR)$$dir; \
- if test -r $$cat; then realcat=$$cat; else realcat=$(srcdir)/$$cat; fi; \
- $(INSTALL_DATA) $$realcat $(DESTDIR)$$dir/$(DOMAIN).mo; \
- echo "installing $$realcat as $(DESTDIR)$$dir/$(DOMAIN).mo"; \
- for lc in '' $(EXTRA_LOCALE_CATEGORIES); do \
- if test -n "$$lc"; then \
- if (cd $(DESTDIR)$(localedir)/$$lang && LC_ALL=C ls -l -d $$lc
2>/dev/null) | grep ' -> ' >/dev/null; then \
- link=`cd $(DESTDIR)$(localedir)/$$lang && LC_ALL=C ls -l -d $$lc | sed
-e 's/^.* -> //'`; \
- mv $(DESTDIR)$(localedir)/$$lang/$$lc $(DESTDIR)$(localedir)/$$lang/$$lc.old; \
- mkdir $(DESTDIR)$(localedir)/$$lang/$$lc; \
- (cd $(DESTDIR)$(localedir)/$$lang/$$lc.old && \
- for file in *; do \
- if test -f $$file; then \
- ln -s ../$$link/$$file $(DESTDIR)$(localedir)/$$lang/$$lc/$$file; \
- fi; \
- done); \
- rm -f $(DESTDIR)$(localedir)/$$lang/$$lc.old; \
- else \
- if test -d $(DESTDIR)$(localedir)/$$lang/$$lc; then \
- :; \
- else \
- rm -f $(DESTDIR)$(localedir)/$$lang/$$lc; \
- mkdir $(DESTDIR)$(localedir)/$$lang/$$lc; \
- fi; \
- fi; \
- rm -f $(DESTDIR)$(localedir)/$$lang/$$lc/$(DOMAIN).mo; \
- ln -s ../LC_MESSAGES/$(DOMAIN).mo $(DESTDIR)$(localedir)/$$lang/$$lc/$(DOMAIN).mo
2>/dev/null || \
- ln $(DESTDIR)$(localedir)/$$lang/LC_MESSAGES/$(DOMAIN).mo
$(DESTDIR)$(localedir)/$$lang/$$lc/$(DOMAIN).mo 2>/dev/null || \
- cp -p $(DESTDIR)$(localedir)/$$lang/LC_MESSAGES/$(DOMAIN).mo
$(DESTDIR)$(localedir)/$$lang/$$lc/$(DOMAIN).mo; \
- echo "installing $$realcat link as
$(DESTDIR)$(localedir)/$$lang/$$lc/$(DOMAIN).mo"; \
- fi; \
- done; \
- done
-
-install-strip: install
-
-installdirs: installdirs-exec installdirs-data
-installdirs-exec:
-installdirs-data: installdirs-data-@USE_NLS@
- if test "$(PACKAGE)" = "gettext-tools"; then \
- $(MKDIR_P) $(DESTDIR)$(gettextsrcdir); \
- else \
- : ; \
- fi
-installdirs-data-no:
-installdirs-data-yes:
- @catalogs='$(CATALOGS)'; \
- for cat in $$catalogs; do \
- cat=`basename $$cat`; \
- lang=`echo $$cat | sed -e 's/\.gmo$$//'`; \
- dir=$(localedir)/$$lang/LC_MESSAGES; \
- $(MKDIR_P) $(DESTDIR)$$dir; \
- for lc in '' $(EXTRA_LOCALE_CATEGORIES); do \
- if test -n "$$lc"; then \
- if (cd $(DESTDIR)$(localedir)/$$lang && LC_ALL=C ls -l -d $$lc
2>/dev/null) | grep ' -> ' >/dev/null; then \
- link=`cd $(DESTDIR)$(localedir)/$$lang && LC_ALL=C ls -l -d $$lc | sed
-e 's/^.* -> //'`; \
- mv $(DESTDIR)$(localedir)/$$lang/$$lc $(DESTDIR)$(localedir)/$$lang/$$lc.old; \
- mkdir $(DESTDIR)$(localedir)/$$lang/$$lc; \
- (cd $(DESTDIR)$(localedir)/$$lang/$$lc.old && \
- for file in *; do \
- if test -f $$file; then \
- ln -s ../$$link/$$file $(DESTDIR)$(localedir)/$$lang/$$lc/$$file; \
- fi; \
- done); \
- rm -f $(DESTDIR)$(localedir)/$$lang/$$lc.old; \
- else \
- if test -d $(DESTDIR)$(localedir)/$$lang/$$lc; then \
- :; \
- else \
- rm -f $(DESTDIR)$(localedir)/$$lang/$$lc; \
- mkdir $(DESTDIR)$(localedir)/$$lang/$$lc; \
- fi; \
- fi; \
- fi; \
- done; \
- done
-
-# Define this as empty until I found a useful application.
-installcheck:
-
-uninstall:
-
-uninstall-exec:
-uninstall-data: uninstall-data-@USE_NLS@
- if test "$(PACKAGE)" = "gettext-tools"; then \
- for file in $(DISTFILES.common) Makevars.template; do \
- rm -f $(DESTDIR)$(gettextsrcdir)/$$file; \
- done; \
- else \
- : ; \
- fi
-uninstall-data-no:
-uninstall-data-yes:
- catalogs='$(CATALOGS)'; \
- for cat in $$catalogs; do \
- cat=`basename $$cat`; \
- lang=`echo $$cat | sed -e 's/\.gmo$$//'`; \
- for lc in LC_MESSAGES $(EXTRA_LOCALE_CATEGORIES); do \
- rm -f $(DESTDIR)$(localedir)/$$lang/$$lc/$(DOMAIN).mo; \
- done; \
- done
-
-check: all
-
-info dvi ps pdf html tags TAGS ctags CTAGS ID:
-
-mostlyclean:
- rm -f remove-potcdate.sed
- rm -f stamp-poT
- rm -f core core.* $(DOMAIN).po $(DOMAIN).1po $(DOMAIN).2po *.new.po
- rm -fr *.o
-
-clean: mostlyclean
-
-distclean: clean
- rm -f Makefile Makefile.in POTFILES *.mo
-
-maintainer-clean: distclean
- @echo "This command is intended for maintainers to use;"
- @echo "it deletes files that may require special tools to rebuild."
- rm -f stamp-po $(GMOFILES)
-
-distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir)
-dist distdir:
- $(MAKE) update-po
- @$(MAKE) dist2
-# This is a separate target because 'update-po' must be executed before.
-dist2: stamp-po $(DISTFILES)
- dists="$(DISTFILES)"; \
- if test "$(PACKAGE)" = "gettext-tools"; then \
- dists="$$dists Makevars.template"; \
- fi; \
- if test -f $(srcdir)/$(DOMAIN).pot; then \
- dists="$$dists $(DOMAIN).pot stamp-po"; \
- fi; \
- if test -f $(srcdir)/ChangeLog; then \
- dists="$$dists ChangeLog"; \
- fi; \
- for i in 0 1 2 3 4 5 6 7 8 9; do \
- if test -f $(srcdir)/ChangeLog.$$i; then \
- dists="$$dists ChangeLog.$$i"; \
- fi; \
- done; \
- if test -f $(srcdir)/LINGUAS; then dists="$$dists LINGUAS"; fi; \
- for file in $$dists; do \
- if test -f $$file; then \
- cp -p $$file $(distdir) || exit 1; \
- else \
- cp -p $(srcdir)/$$file $(distdir) || exit 1; \
- fi; \
- done
-
-update-po: Makefile
- $(MAKE) $(DOMAIN).pot-update
- test -z "$(UPDATEPOFILES)" || $(MAKE) $(UPDATEPOFILES)
- $(MAKE) update-gmo
-
-# General rule for creating PO files.
-
-.nop.po-create:
- @lang=`echo $@ | sed -e 's/\.po-create$$//'`; \
- echo "File $$lang.po does not exist. If you are a translator, you can create it
through 'msginit'." 1>&2; \
- exit 1
-
-# General rule for updating PO files.
-
-.nop.po-update:
- @lang=`echo $@ | sed -e 's/\.po-update$$//'`; \
- if test "$(PACKAGE)" = "gettext-tools"; then
PATH=`pwd`/../src:$$PATH; fi; \
- tmpdir=`pwd`; \
- echo "$$lang:"; \
- test "$(srcdir)" = . && cdcmd="" || cdcmd="cd $(srcdir)
&& "; \
- echo "$${cdcmd}$(MSGMERGE) $(MSGMERGE_OPTIONS) --lang=$$lang $$lang.po
$(DOMAIN).pot -o $$lang.new.po"; \
- cd $(srcdir); \
- if { case `$(MSGMERGE) --version | sed 1q | sed -e 's,^[^0-9]*,,'` in \
- '' | 0.[0-9] | 0.[0-9].* | 0.1[0-7] | 0.1[0-7].*) \
- $(MSGMERGE) $(MSGMERGE_OPTIONS) -o $$tmpdir/$$lang.new.po $$lang.po
$(DOMAIN).pot;; \
- *) \
- $(MSGMERGE) $(MSGMERGE_OPTIONS) --lang=$$lang -o $$tmpdir/$$lang.new.po
$$lang.po $(DOMAIN).pot;; \
- esac; \
- }; then \
- if cmp $$lang.po $$tmpdir/$$lang.new.po >/dev/null 2>&1; then \
- rm -f $$tmpdir/$$lang.new.po; \
- else \
- if mv -f $$tmpdir/$$lang.new.po $$lang.po; then \
- :; \
- else \
- echo "msgmerge for $$lang.po failed: cannot move $$tmpdir/$$lang.new.po to
$$lang.po" 1>&2; \
- exit 1; \
- fi; \
- fi; \
- else \
- echo "msgmerge for $$lang.po failed!" 1>&2; \
- rm -f $$tmpdir/$$lang.new.po; \
- fi
-
-$(DUMMYPOFILES):
-
-update-gmo: Makefile $(GMOFILES)
- @:
-
-# Recreate Makefile by invoking config.status. Explicitly invoke the shell,
-# because execution permission bits may not work on the current file system.
-# Use @SHELL@, which is the shell determined by autoconf for the use by its
-# scripts, not $(SHELL) which is hardwired to /bin/sh and may be deficient.
-Makefile: Makefile.in.in Makevars $(top_builddir)/config.status @POMAKEFILEDEPS@
- cd $(top_builddir) \
- && @SHELL@ ./config.status $(subdir)/$@.in po-directories
-
-force:
-
-# Tell versions [3.59,3.63) of GNU make not to export all variables.
-# Otherwise a system limit (for SysV at least) may be exceeded.
-.NOEXPORT:
diff --git a/plugins/sample/po/Makevars b/plugins/sample/po/Makevars
deleted file mode 100644
index 60de3f1..0000000
--- a/plugins/sample/po/Makevars
+++ /dev/null
@@ -1,41 +0,0 @@
-# Makefile variables for PO directory in any package using GNU gettext.
-
-# Usually the message domain is the same as the package name.
-DOMAIN = sample
-
-# These two variables depend on the location of this directory.
-subdir = po
-top_builddir = ..
-
-# These options get passed to xgettext.
-XGETTEXT_OPTIONS = --keyword=_ --keyword=N_
-
-# This is the copyright holder that gets inserted into the header of the
-# $(DOMAIN).pot file. Set this to the copyright holder of the surrounding
-# package. (Note that the msgstr strings, extracted from the package's
-# sources, belong to the copyright holder of the package.) Translators are
-# expected to transfer the copyright for their translations to this person
-# or entity, or to disclaim their copyright. The empty string stands for
-# the public domain; in this case the translators are expected to disclaim
-# their copyright.
-COPYRIGHT_HOLDER =
-
-# This is the email address or URL to which the translators shall report
-# bugs in the untranslated strings:
-# - Strings which are not entire sentences, see the maintainer guidelines
-# in the GNU gettext documentation, section 'Preparing Strings'.
-# - Strings which use unclear terms or require additional context to be
-# understood.
-# - Strings which make invalid assumptions about notation of date, time or
-# money.
-# - Pluralisation problems.
-# - Incorrect English spelling.
-# - Incorrect formatting.
-# It can be your email address, or a mailing list address where translators
-# can write to without being subscribed, or the URL of a web page through
-# which the translators can contact you.
-MSGID_BUGS_ADDRESS = kimchi-devel(a)ovirt.org
-
-# This is the list of locale categories, beyond LC_MESSAGES, for which the
-# message catalogs shall be used. It is usually empty.
-EXTRA_LOCALE_CATEGORIES =
diff --git a/plugins/sample/po/POTFILES.in b/plugins/sample/po/POTFILES.in
deleted file mode 100644
index 7dbfb6c..0000000
--- a/plugins/sample/po/POTFILES.in
+++ /dev/null
@@ -1,2 +0,0 @@
-# List of source files which contain translatable strings.
-plugins/sample/ui/pages/*.tmpl
diff --git a/plugins/sample/po/en_US.po b/plugins/sample/po/en_US.po
deleted file mode 100644
index 207d3c3..0000000
--- a/plugins/sample/po/en_US.po
+++ /dev/null
@@ -1,21 +0,0 @@
-# English translations for kimchi package.
-# Copyright (C) 2014 THE kimchi'S COPYRIGHT HOLDER
-# This file is distributed under the same license as the kimchi package.
-# shhfeng <shaohef(a)linux.vnet.ibm.com>, 2014.
-#
-msgid ""
-msgstr ""
-"Project-Id-Version: kimchi 1.2.0\n"
-"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2015-06-24 09:39-0300\n"
-"PO-Revision-Date: 2014-05-17 02:08+0800\n"
-"Last-Translator: shhfeng <shaohef(a)linux.vnet.ibm.com>\n"
-"Language-Team: English\n"
-"Language: en_US\n"
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=ASCII\n"
-"Content-Transfer-Encoding: 8bit\n"
-"Generated-By: pygettext.py 1.5\n"
-
-msgid "SampleTab"
-msgstr "SampleTab"
diff --git a/plugins/sample/po/gen-pot b/plugins/sample/po/gen-pot
deleted file mode 100755
index c1cfb8f..0000000
--- a/plugins/sample/po/gen-pot
+++ /dev/null
@@ -1,9 +0,0 @@
-#!/bin/bash
-
-for src in $@; do
- if [ ${src: -3} == ".py" ]; then
- cat $src
- else
- cat $src | cheetah compile -
- fi
-done | xgettext --no-location -o sample.pot -L Python -
diff --git a/plugins/sample/po/pt_BR.po b/plugins/sample/po/pt_BR.po
deleted file mode 100644
index 8519d74..0000000
--- a/plugins/sample/po/pt_BR.po
+++ /dev/null
@@ -1,24 +0,0 @@
-# Portuguese translations for kimchi package
-# Copyright (C) 2014 THE kimchi'S COPYRIGHT HOLDER
-# This file is distributed under the same license as the kimchi package.
-# shhfeng <shaohef(a)linux.vnet.ibm.com>, 2014.
-#
-msgid ""
-msgstr ""
-"Project-Id-Version: kimchi 1.2.0\n"
-"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2015-06-24 09:39-0300\n"
-"PO-Revision-Date: 2014-05-17 02:09+0800\n"
-"Last-Translator: Cr��stian Viana <vianac(a)linux.vnet.ibm.com>\n"
-"Language-Team: Aline Manera <alinefm(a)br.ibm.com>\n"
-"Language: pt_BR\n"
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
-"Content-Transfer-Encoding: 8bit\n"
-"Generated-By: pygettext.py 1.5\n"
-"X-Poedit-Country: Brazil\n"
-"X-Poedit-Language: Portuguese\n"
-"X-Poedit-SourceCharset: utf-8\n"
-
-msgid "SampleTab"
-msgstr "Tab de exemplo"
diff --git a/plugins/sample/po/sample.pot b/plugins/sample/po/sample.pot
deleted file mode 100644
index 458ffe9..0000000
--- a/plugins/sample/po/sample.pot
+++ /dev/null
@@ -1,21 +0,0 @@
-# SOME DESCRIPTIVE TITLE.
-# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
-# This file is distributed under the same license as the PACKAGE package.
-# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
-#
-#, fuzzy
-msgid ""
-msgstr ""
-"Project-Id-Version: PACKAGE VERSION\n"
-"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2015-06-24 09:39-0300\n"
-"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
-"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
-"Language-Team: LANGUAGE <LL(a)li.org>\n"
-"Language: \n"
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=CHARSET\n"
-"Content-Transfer-Encoding: 8bit\n"
-
-msgid "SampleTab"
-msgstr ""
diff --git a/plugins/sample/po/zh_CN.po b/plugins/sample/po/zh_CN.po
deleted file mode 100644
index 04b2501..0000000
--- a/plugins/sample/po/zh_CN.po
+++ /dev/null
@@ -1,24 +0,0 @@
-# Chinese translations for kimchi package
-# Copyright (C) 2014 THE kimchi'S COPYRIGHT HOLDER
-# This file is distributed under the same license as the kimchi package.
-# shhfeng <shaohef(a)linux.vnet.ibm.com>, 2014.
-#
-msgid ""
-msgstr ""
-"Project-Id-Version: kimchi 1.2.0\n"
-"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2015-06-24 09:39-0300\n"
-"PO-Revision-Date: 2014-05-17 02:10+0800\n"
-"Last-Translator: shhfeng <shaohef(a)linux.vnet.ibm.com>\n"
-"Language-Team: Chinese (simplified)\n"
-"Language: zh_CN\n"
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
-"Content-Transfer-Encoding: 8bit\n"
-"Generated-By: pygettext.py 1.5\n"
-"X-Poedit-Country: CHINA\n"
-"X-Poedit-Language: Chinese\n"
-"X-Poedit-SourceCharset: utf-8\n"
-
-msgid "SampleTab"
-msgstr "������������"
diff --git a/plugins/sample/sample.conf.in b/plugins/sample/sample.conf.in
deleted file mode 100644
index 9da33e1..0000000
--- a/plugins/sample/sample.conf.in
+++ /dev/null
@@ -1,27 +0,0 @@
-[wok]
-enable = @ENABLE_SAMPLE@
-plugin_class = "Drawings"
-uri = "/plugins/sample"
-
-[/]
-tools.nocache.on = True
-tools.trailing_slash.on = False
-tools.sessions.on = True
-tools.sessions.name = 'wok'
-tools.sessions.httponly = True
-tools.sessions.locking = 'explicit'
-tools.sessions.storage_type = 'ram'
-
-[/description]
-tools.wokauth.on = True
-
-[/rectangles]
-tools.wokauth.on = True
-
-[/circles]
-tools.wokauth.on = True
-
-[/help]
-tools.staticdir.on = True
-tools.nocache.on = True
-tools.staticdir.dir = wok.config.PluginPaths('sample').ui_dir +
'/pages/help'
diff --git a/plugins/sample/ui/Makefile.am b/plugins/sample/ui/Makefile.am
deleted file mode 100644
index 37fec98..0000000
--- a/plugins/sample/ui/Makefile.am
+++ /dev/null
@@ -1,22 +0,0 @@
-#
-# Kimchi
-#
-# Copyright IBM Corp, 2013
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-
-SUBDIRS = config js pages
-
-
diff --git a/plugins/sample/ui/config/Makefile.am b/plugins/sample/ui/config/Makefile.am
deleted file mode 100644
index cf9e09e..0000000
--- a/plugins/sample/ui/config/Makefile.am
+++ /dev/null
@@ -1,21 +0,0 @@
-#
-# Kimchi
-#
-# Copyright IBM Corp, 2013
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-
-EXTRA_DIST = tab-ext.xml
-
diff --git a/plugins/sample/ui/config/tab-ext.xml b/plugins/sample/ui/config/tab-ext.xml
deleted file mode 100644
index aff0d14..0000000
--- a/plugins/sample/ui/config/tab-ext.xml
+++ /dev/null
@@ -1,17 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<tabs-ext>
- <tab>
- <access role="admin" mode="admin"/>
- <access role="user" mode="none"/>
-
- <title>SampleTab 1</title>
- <path>plugins/sample/sample-tab1.html</path>
- </tab>
- <tab>
- <access role="admin" mode="admin"/>
- <access role="user" mode="none"/>
-
- <title>SampleTab 2</title>
- <path>plugins/sample/sample-tab2.html</path>
- </tab>
-</tabs-ext>
diff --git a/plugins/sample/ui/css/.gitignore b/plugins/sample/ui/css/.gitignore
deleted file mode 100644
index e69de29..0000000
diff --git a/plugins/sample/ui/images/.gitignore b/plugins/sample/ui/images/.gitignore
deleted file mode 100644
index e69de29..0000000
diff --git a/plugins/sample/ui/js/.gitignore b/plugins/sample/ui/js/.gitignore
deleted file mode 100644
index e69de29..0000000
diff --git a/plugins/sample/ui/js/Makefile.am b/plugins/sample/ui/js/Makefile.am
deleted file mode 100644
index 4d536ae..0000000
--- a/plugins/sample/ui/js/Makefile.am
+++ /dev/null
@@ -1,20 +0,0 @@
-#
-# Kimchi
-#
-# Copyright IBM Corp, 2014
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-
-EXTRA_DIST = util.js
diff --git a/plugins/sample/ui/js/util.js b/plugins/sample/ui/js/util.js
deleted file mode 100644
index 7689a81..0000000
--- a/plugins/sample/ui/js/util.js
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * Project Kimchi
- *
- * Copyright IBM, Corp. 2014
- *
- * 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.
- */
-
-sample = {};
-
-sample.description = function(suc, err){
- wok.requestJSON({
- url : 'plugins/sample/description',
- type : 'GET',
- contentType : 'application/json',
- dataType : 'json',
- resend : true,
- success : suc,
- error : err || function(data) {
- wok.message.error(data.responseJSON.reason);
- }
- });
-};
diff --git a/plugins/sample/ui/libs/.gitignore b/plugins/sample/ui/libs/.gitignore
deleted file mode 100644
index e69de29..0000000
diff --git a/plugins/sample/ui/pages/Makefile.am b/plugins/sample/ui/pages/Makefile.am
deleted file mode 100644
index 3da95a2..0000000
--- a/plugins/sample/ui/pages/Makefile.am
+++ /dev/null
@@ -1,20 +0,0 @@
-#
-# Kimchi
-#
-# Copyright IBM Corp, 2014
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-
-EXTRA_DIST = i18n.json.tmpl sample-tab1.html.tmpl sample-tab2.html.tmpl
diff --git a/plugins/sample/ui/pages/help/en_US/sample-tab1.html
b/plugins/sample/ui/pages/help/en_US/sample-tab1.html
deleted file mode 100644
index 7122124..0000000
--- a/plugins/sample/ui/pages/help/en_US/sample-tab1.html
+++ /dev/null
@@ -1 +0,0 @@
-Help page for TAB 1 of Wok's Sample plugin.
diff --git a/plugins/sample/ui/pages/help/en_US/sample-tab2.html
b/plugins/sample/ui/pages/help/en_US/sample-tab2.html
deleted file mode 100644
index 1bfe448..0000000
--- a/plugins/sample/ui/pages/help/en_US/sample-tab2.html
+++ /dev/null
@@ -1 +0,0 @@
-Help page for TAB 2 of Wok's Sample plugin.
diff --git a/plugins/sample/ui/pages/i18n.json.tmpl
b/plugins/sample/ui/pages/i18n.json.tmpl
deleted file mode 100644
index 737bb39..0000000
--- a/plugins/sample/ui/pages/i18n.json.tmpl
+++ /dev/null
@@ -1,26 +0,0 @@
-#*
- * Kimchi
- *
- * Copyright IBM, Corp. 2014
- *
- * 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.
- *#
-#unicode UTF-8
-#import gettext
-#from wok.cachebust import href
-#silent t = gettext.translation($lang.domain, $lang.localedir, languages=$lang.lang)
-#silent _ = t.gettext
-#silent _t = t.gettext
-{
- "SampleTab": "$_("SampleTab")"
-}
diff --git a/plugins/sample/ui/pages/sample-tab1.html.tmpl
b/plugins/sample/ui/pages/sample-tab1.html.tmpl
deleted file mode 100644
index 4354d81..0000000
--- a/plugins/sample/ui/pages/sample-tab1.html.tmpl
+++ /dev/null
@@ -1,30 +0,0 @@
-#*
- * Project Kimchi
- *
- * Copyright IBM, Corp. 2014
- *
- * 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.
- *#
-#unicode UTF-8
-<!DOCTYPE html>
-<html>
-<script type="text/javascript"
src="plugins/sample/js/util.js"></script>
-<body>
- <div id="samplebody"/>
-</body>
-<script>
- sample.description(function(r){
- \$("#samplebody").html("name: " + r.name + " version:
" + r.version);
- });
-</script>
-</html>
diff --git a/plugins/sample/ui/pages/sample-tab2.html.tmpl
b/plugins/sample/ui/pages/sample-tab2.html.tmpl
deleted file mode 100644
index 4354d81..0000000
--- a/plugins/sample/ui/pages/sample-tab2.html.tmpl
+++ /dev/null
@@ -1,30 +0,0 @@
-#*
- * Project Kimchi
- *
- * Copyright IBM, Corp. 2014
- *
- * 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.
- *#
-#unicode UTF-8
-<!DOCTYPE html>
-<html>
-<script type="text/javascript"
src="plugins/sample/js/util.js"></script>
-<body>
- <div id="samplebody"/>
-</body>
-<script>
- sample.description(function(r){
- \$("#samplebody").html("name: " + r.name + " version:
" + r.version);
- });
-</script>
-</html>
diff --git a/src/wok/plugins/Makefile.am b/src/wok/plugins/Makefile.am
new file mode 100644
index 0000000..21a6ece
--- /dev/null
+++ b/src/wok/plugins/Makefile.am
@@ -0,0 +1,25 @@
+#
+# Kimchi
+#
+# Copyright IBM Corp, 2013
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+SUBDIRS = sample
+
+plugins_PYTHON = \
+ __init__.py
+
+pluginsdir = $(pythondir)/wok/plugins
diff --git a/src/wok/plugins/__init__.py b/src/wok/plugins/__init__.py
new file mode 100644
index 0000000..0539a76
--- /dev/null
+++ b/src/wok/plugins/__init__.py
@@ -0,0 +1,18 @@
+#
+# Project Kimchi
+#
+# Copyright IBM, Corp. 2013-2014
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
diff --git a/src/wok/plugins/kimchi/.gitignore b/src/wok/plugins/kimchi/.gitignore
new file mode 100644
index 0000000..1dae610
--- /dev/null
+++ b/src/wok/plugins/kimchi/.gitignore
@@ -0,0 +1,37 @@
+*.pyc
+*~
+i18n/mo/*
+log
+data
+mo
+autom4te.cache
+Makefile
+Makefile.in
+aclocal.m4
+build-aux/compile
+build-aux/config.guess
+build-aux/config.sub
+build-aux/install-sh
+build-aux/missing
+build-aux/py-compile
+configure
+config.log
+config.py
+config.status
+contrib/DEBIAN/control
+contrib/kimchi.spec.fedora
+contrib/kimchi.spec.suse
+contrib/make-deb.sh
+*.min.css
+*.min.js
+*.gmo
+stamp-po
+kimchi-*.tar.gz
+tests/run_tests.sh
+tests/test_config.py
+po/POTFILES
+po/gen-pot
+*.orig
+*.rej
+*.pem
+ui/pages/help/*/*.html
diff --git a/src/wok/plugins/kimchi/API.json b/src/wok/plugins/kimchi/API.json
new file mode 100644
index 0000000..f1f58ff
--- /dev/null
+++ b/src/wok/plugins/kimchi/API.json
@@ -0,0 +1,836 @@
+{
+ "$schema": "http://json-schema.org/draft-03/schema#",
+ "title": "Kimchi API",
+ "description": "Json schema for Kimchi API",
+ "type": "object",
+ "kimchitype": {
+ "graphics": {
+ "description": "Configure graphics parameters for the new
VM",
+ "type": "object",
+ "properties": {
+ "type": {
+ "enum": ["spice", "vnc"],
+ "error": "KCHVM0014E"
+ },
+ "listen": {
+ "error": "KCHVM0015E",
+ "type": [
+ {
+ "type": "string",
+ "format": "ip-address"
+ },
+ {
+ "type": "string",
+ "format": "ipv6"
+ }
+ ]
+ }
+ }
+ },
+ "cpu_info": {
+ "description": "Configure CPU specifics for a VM.",
+ "type": "object",
+ "properties": {
+ "topology": {
+ "description": "Configure the guest CPU
topology.",
+ "type": "object",
+ "properties": {
+ "sockets": {
+ "type": "integer",
+ "required": true,
+ "minimum": 1,
+ "error": "KCHTMPL0026E"
+ },
+ "cores": {
+ "type": "integer",
+ "required": true,
+ "minimum": 1,
+ "error": "KCHTMPL0026E"
+ },
+ "threads": {
+ "type": "integer",
+ "required": true,
+ "minimum": 1,
+ "error": "KCHTMPL0026E"
+ }
+ }
+ }
+ }
+ }
+ },
+ "properties": {
+ "debugreports_create": {
+ "type": "object",
+ "error": "KCHDR0006E",
+ "properties": {
+ "name": {
+ "description": "The name for the debug report
file.",
+ "type": "string",
+ "pattern": "^[_A-Za-z0-9-]*$",
+ "error": "KCHDR0007E"
+ }
+ }
+ },
+ "debugreport_update": {
+ "type": "object",
+ "properties": {
+ "name": {
+ "description": "New name of debug report",
+ "type": "string",
+ "pattern": "^[_A-Za-z0-9-]*$",
+ "error": "KCHDR0007E"
+ }
+ },
+ "additionalProperties": false
+ },
+ "storagepools_create": {
+ "type": "object",
+ "error": "KCHPOOL0026E",
+ "properties": {
+ "name": {
+ "description": "The name of the Storage Pool",
+ "type": "string",
+ "minLength": 1,
+ "pattern": "^[^/]*$",
+ "required": true,
+ "error": "KCHPOOL0016E"
+ },
+ "type": {
+ "description": "The type of the defined Storage
Pool",
+ "type": "string",
+ "pattern":
"^dir|netfs|logical|kimchi-iso|iscsi|scsi$",
+ "required": true,
+ "error": "KCHPOOL0017E"
+ },
+ "path": {
+ "description": "The path of the defined Storage
Pool",
+ "type": "string",
+ "error": "KCHPOOL0018E"
+ },
+ "source": {
+ "description": "Dictionary containing source
information of the pool",
+ "type": "object",
+ "properties": {
+ "host": {
+ "description": "IP or hostname of server for a
pool backed from a remote host",
+ "type": "string",
+ "error": "KCHPOOL0019E"
+ },
+ "path": {
+ "description": "Export path on NFS server for
NFS pool",
+ "type": "string",
+ "error": "KCHPOOL0018E"
+ },
+ "devices": {
+ "description": "Array of devices to be used in
the Storage Pool",
+ "type": "array",
+ "minItems": 1,
+ "uniqueItems": true,
+ "error": "KCHPOOL0021E",
+ "items": {
+ "description": "Full path of the block
device node",
+ "type": "string",
+ "error": "KCHPOOL0020E"
+ }
+ },
+ "target": {
+ "description": "Target IQN of an iSCSI
pool",
+ "type": "string",
+ "error": "KCHPOOL0022E"
+ },
+ "port": {
+ "description": "Listening port of a remote
storage server",
+ "type": "integer",
+ "minimum": 1,
+ "maximum": 65535,
+ "error": "KCHPOOL0023E"
+ },
+ "adapter_name": {
+ "description": "SCSI host name",
+ "type": "string",
+ "error": "KCHPOOL0030E"
+ },
+ "auth": {
+ "description": "Storage back-end
authentication information",
+ "type": "object",
+ "properties": {
+ "username": {
+ "description": "Login username of the
iSCSI target",
+ "type": "string",
+ "error": "KCHPOOL0024E"
+ },
+ "password": {
+ "description": "Login password of the
iSCSI target",
+ "type": "string",
+ "error": "KCHPOOL0025E"
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "storagepool_update": {
+ "type": "object",
+ "properties": {
+ "autostart": {
+ "description": "Set autostart value of the
pool",
+ "type": "boolean"
+ },
+ "disks": {
+ "description": "List of disks/partitions to be
added",
+ "type": "array",
+ "items": { "type": "string" },
+ "minItems": 1,
+ "uniqueItems": true
+ }
+ },
+ "additionalProperties": false
+ },
+ "storagevolumes_create": {
+ "type": "object",
+ "properties": {
+ "name": {
+ "description": "The name of the Storage Volume",
+ "type": "string",
+ "minLength": 1,
+ "error": "KCHVOL0013E"
+ },
+ "capacity": {
+ "description": "The total size (MiB) of the storage
volume",
+ "type": "number",
+ "minimum": 1,
+ "error": "KCHVOL0020E"
+ },
+ "upload": {
+ "description": "When the storage volume will be
uploaded",
+ "type": "boolean",
+ "error": "KCHVOL0025E"
+ },
+ "allocation": {
+ "description": "The size(MiB) of allocation when
create the storage volume",
+ "type": "number",
+ "minimum": 1,
+ "error": "KCHVOL0014E"
+ },
+ "format": {
+ "description": "The format of the volume",
+ "type": "string",
+ "pattern":
"^(|bochs|cloop|cow|dmg|qcow|qcow2|qed|raw|vmdk|vpc)$",
+ "error": "KCHVOL0015E"
+ },
+ "url": {
+ "description": "The remote URL of the storage
volume",
+ "type": "string",
+ "pattern": "^(http|ftp)[s]?://",
+ "error": "KCHVOL0021E"
+ }
+ }
+ },
+ "storagevolume_update": {
+ "type": "object",
+ "properties": {
+ "chunk": {
+ "description": "Upload storage volume chunk",
+ "error": "KCHVOL0024E",
+ "required": true
+ },
+ "chunk_size": {
+ "description": "Chunk size of uploaded storage
volume",
+ "type": "string",
+ "error": "KCHVOL0024E",
+ "required": true
+ }
+ },
+ "additionalProperties": false
+ },
+ "vms_create": {
+ "type": "object",
+ "error": "KCHVM0016E",
+ "properties": {
+ "name": {
+ "description": "The name of the new VM",
+ "type": "string",
+ "pattern": "^[^/]*$",
+ "error": "KCHVM0011E"
+ },
+ "template": {
+ "description": "The URI of a template to use when
building a VM",
+ "type": "string",
+ "pattern":
"^/plugins/kimchi/templates/(.*?)/?$",
+ "required": true,
+ "error": "KCHVM0012E"
+ },
+ "storagepool": {
+ "description": "Assign a specefic Storage Pool to the
new VM",
+ "type": "string",
+ "pattern":
"^/plugins/kimchi/storagepools/[^/]+/?$",
+ "error": "KCHVM0013E"
+ },
+ "graphics": { "$ref":
"#/kimchitype/graphics" }
+ }
+ },
+ "vm_update": {
+ "type": "object",
+ "properties": {
+ "name": {
+ "description": "New name of VM",
+ "type": "string",
+ "pattern": "^[^/]*$",
+ "minLength": 1,
+ "error": "KCHVM0011E"
+ },
+ "users": {
+ "description": "Array of users who have permission to
the VM",
+ "type": "array",
+ "uniqueItems": true,
+ "error": "KCHVM0023E",
+ "items": {
+ "description": "User name",
+ "type": "string",
+ "error": "KCHVM0024E"
+ }
+ },
+ "groups": {
+ "description": "Array of groups who have permission to
the VM",
+ "type": "array",
+ "uniqueItems": true,
+ "error": "KCHVM0025E",
+ "items": {
+ "description": "Group name",
+ "type": "string",
+ "error": "KCHVM0026E"
+ }
+ },
+ "graphics": {
+ "description": "Graphics information from
guest",
+ "type": "object",
+ "properties": {
+ "passwd": {
+ "description": "New graphics password.",
+ "type": "string",
+ "error": "KCHVM0031E"
+ },
+ "passwdValidTo": {
+ "description": "Life time for the graphics
password.",
+ "type": "number",
+ "error": "KCHVM0032E"
+ }
+ }
+ },
+ "cpus": {
+ "description": "The new number of virtual CPUs for the
VM",
+ "type": "integer",
+ "minimum": 1,
+ "error": "KCHTMPL0012E"
+ },
+ "memory": {
+ "description": "The new amount (MB) of memory for the
VM",
+ "type": "integer",
+ "minimum": 512,
+ "error": "KCHTMPL0013E"
+ }
+ },
+ "additionalProperties": false
+ },
+ "networks_create": {
+ "type": "object",
+ "error": "KCHNET0016E",
+ "properties": {
+ "name": {
+ "description": "The name of the new network",
+ "type": "string",
+ "minLength": 1,
+ "pattern": "^[^/\"]*$",
+ "required": true,
+ "error": "KCHNET0011E"
+ },
+ "connection": {
+ "description": "Specifies how this network should be
connected to the other networks",
+ "type": "string",
+ "pattern": "^isolated|nat|bridge$",
+ "required": true,
+ "error": "KCHNET0012E"
+ },
+ "subnet": {
+ "description": "Network segment in slash-separated
format with ip address and prefix or netmask",
+ "type": "string",
+ "error": "KCHNET0013E"
+ },
+ "interface": {
+ "description": "The name of a network interface on the
host",
+ "type": "string",
+ "error": "KCHNET0014E"
+ },
+ "vlan_id": {
+ "description": "Network's VLAN ID",
+ "type": "integer",
+ "maximum": 4094,
+ "minimum": 1,
+ "error": "KCHNET0015E"
+ }
+ }
+ },
+ "vmifaces_create": {
+ "type": "object",
+ "error": "KCHVMIF0007E",
+ "properties": {
+ "type": {
+ "description": "The type of VM network interface that
libvirt supports",
+ "type": "string",
+ "pattern": "^network$",
+ "required": true,
+ "error": "KCHVMIF0004E"
+ },
+ "network": {
+ "description": "the name of one available
network",
+ "minLength": 1,
+ "type": "string",
+ "error": "KCHVMIF0005E"
+ },
+ "model": {
+ "description": "model of emulated network interface
card",
+ "type": "string",
+ "pattern":
"^ne2k_pci|i82551|i82557b|i82559er|rtl8139|e1000|pcnet|virtio$",
+ "error": "KCHVMIF0006E"
+ },
+ "mac": {
+ "description": "Network Interface Card MAC
address",
+ "type": "string",
+ "pattern":
"(^$)|^(([0-9a-fA-F]{2}:){5}[0-9a-fA-F]{2}$)",
+ "error": "KCHVMIF0010E"
+ }
+ }
+ },
+ "vmiface_update": {
+ "type": "object",
+ "error": "KCHVMIF0008E",
+ "properties": {
+ "mac": {
+ "description": "Network Interface Card MAC
address",
+ "type": "string",
+ "pattern":
"^([0-9a-fA-F]{2}:){5}[0-9a-fA-F]{2}$",
+ "error": "KCHVMIF0010E"
+ }
+ }
+ },
+ "templates_create": {
+ "type": "object",
+ "error": "KCHTMPL0016E",
+ "properties": {
+ "name": {
+ "description": "The name of the template",
+ "type": "string",
+ "pattern": "^[^ ]+( +[^ ]+)*$",
+ "minLength": 1,
+ "error": "KCHTMPL0008E"
+ },
+ "icon": {
+ "description": "The template icon path",
+ "type": "string",
+ "pattern": "^/plugins/kimchi/images/",
+ "error": "KCHTMPL0009E"
+ },
+ "os_distro": {
+ "description": "Distribution name of the Operating
System",
+ "type": "string",
+ "minLength": 1,
+ "error": "KCHTMPL0010E"
+ },
+ "os_version": {
+ "description": "Version of the Operating
System",
+ "type": "string",
+ "minLength": 1,
+ "error": "KCHTMPL0011E"
+ },
+ "cpus": {
+ "description": "Number of CPUs for the
template",
+ "type": "integer",
+ "minimum": 1,
+ "error": "KCHTMPL0012E"
+ },
+ "memory": {
+ "description": "Memory (MB) for the template",
+ "type": "integer",
+ "minimum": 512,
+ "error": "KCHTMPL0013E"
+ },
+ "cdrom": {
+ "description": "Path for cdrom",
+ "type": "string",
+ "pattern":
"^((/)|(http)[s]?:|[t]?(ftp)[s]?:)+.*$",
+ "error": "KCHTMPL0014E"
+ },
+ "disks": {
+ "description": "List of disks",
+ "type": "array",
+ "items": {
+ "type": "object",
+ "properties": {
+ "index": {
+ "description": "Index of the disk",
+ "type": "integer",
+ "minimum": 0
+ },
+ "size": {
+ "description": "Size (GB) of the
disk",
+ "type": "number",
+ "minimum": 1,
+ "error": "KCHTMPL0022E"
+ },
+ "base": {
+ "description": "Base image of the
disk",
+ "type": "string",
+ "pattern": "^/.+$",
+ "error": "KCHTMPL0023E"
+ }
+
+ }
+ },
+ "minItems": 1,
+ "uniqueItems": true
+ },
+ "storagepool": {
+ "description": "Location of the storage pool",
+ "type": "string",
+ "pattern":
"^/plugins/kimchi/storagepools/[^/]+/?$",
+ "error": "KCHTMPL0015E"
+ },
+ "networks": {
+ "description": "list of which networks will be
assigned to the new VM.",
+ "type": "array",
+ "items": { "type": "string" },
+ "error": "KCHTMPL0017E"
+ },
+ "folder": {
+ "description": "Folder",
+ "type": "array",
+ "items": { "type": "string" }
+ },
+ "graphics": { "$ref":
"#/kimchitype/graphics" },
+ "cpu_info": { "$ref":
"#/kimchitype/cpu_info" }
+ },
+ "additionalProperties": false,
+ "error": "KCHAPI0001E"
+ },
+ "storageservers_get_list": {
+ "type": "object",
+ "properties": {
+ "_target_type": {
+ "description": "List storage servers of given
type",
+ "type": "string",
+ "pattern": "^netfs|iscsi$"
+ }
+ },
+ "additionalProperties": false,
+ "error": "KCHAPI0001E"
+ },
+ "storagetargets_get_list": {
+ "type": "object",
+ "properties": {
+ "_target_type": {
+ "description": "List storage servers of given
type",
+ "type": "string",
+ "pattern": "^netfs|iscsi$"
+ },
+ "_server_port": {
+ "description": "the port of iscsi storage
servers",
+ "type": "string",
+ "pattern": "^[0-9]{1,5}$"
+ }
+ },
+ "additionalProperties": false,
+ "error": "KCHAPI0001E"
+ },
+ "vmstorages_create": {
+ "type": "object",
+ "error": "KCHVMSTOR0012E",
+ "properties": {
+ "type": {
+ "description": "The storage type",
+ "type": "string",
+ "pattern": "^cdrom|disk$",
+ "required": true,
+ "error": "KCHVMSTOR0002E"
+ },
+ "pool": {
+ "description": "Storage pool name disk image locate
in",
+ "type": "string",
+ "minLength": 1,
+ "error": "KCHVMSTOR0012E"
+ },
+ "vol": {
+ "description": "Storage volume name of disk
image",
+ "type": "string",
+ "minLength": 1,
+ "error": "KCHVMSTOR0012E"
+ },
+ "path": {
+ "description": "Path of iso image file or disk mount
point",
+ "type": "string",
+ "pattern":
"^((/)|(http)[s]?:|[t]?(ftp)[s]?:)+.*$",
+ "error": "KCHVMSTOR0003E"
+ }
+ }
+ },
+ "vmstorage_update": {
+ "type": "object",
+ "error": "KCHVMSTOR0013E",
+ "properties": {
+ "path": {
+ "description": "Path of iso image file or disk mount
point",
+ "type": "string",
+ "pattern":
"^(|(/)|(http)[s]?:|[t]?(ftp)[s]?:)+.*$",
+ "required": true,
+ "error": "KCHVMSTOR0003E"
+ }
+ },
+ "additionalProperties": false
+ },
+ "template_update": {
+ "type": "object",
+ "properties": {
+ "name": {
+ "description": "The name of the template",
+ "type": "string",
+ "pattern": "^[^ ]+( +[^ ]+)*$",
+ "minLength": 1,
+ "error": "KCHTMPL0008E"
+ },
+ "icon": {
+ "description": "The template icon path",
+ "type": "string",
+ "pattern": "^/plugins/kimchi/images/",
+ "error": "KCHTMPL0009E"
+ },
+ "os_distro": {
+ "description": "Distribution name of the Operating
System",
+ "type": "string",
+ "minLength": 1,
+ "error": "KCHTMPL0010E"
+ },
+ "os_version": {
+ "description": "Version of the Operating
System",
+ "type": "string",
+ "minLength": 1,
+ "error": "KCHTMPL0011E"
+ },
+ "cpus": {
+ "description": "Number of CPUs for the
template",
+ "type": "integer",
+ "minimum": 1,
+ "error": "KCHTMPL0012E"
+ },
+ "memory": {
+ "description": "Memory (MB) for the template",
+ "type": "integer",
+ "minimum": 512,
+ "error": "KCHTMPL0013E"
+ },
+ "cdrom": {
+ "description": "Path for cdrom",
+ "type": "string",
+ "pattern":
"^((/)|(http)[s]?:|[t]?(ftp)[s]?:)+.*$",
+ "error": "KCHTMPL0014E"
+ },
+ "disks": {
+ "description": "List of disks",
+ "type": "array",
+ "items": {
+ "type": "object",
+ "properties": {
+ "index": {
+ "description": "Index of the disk",
+ "type": "integer",
+ "minimum": 0
+ },
+ "size": {
+ "description": "Size (GB) of the
disk",
+ "type": "integer",
+ "minimum": 1,
+ "error": "KCHTMPL0022E"
+ },
+ "format": {
+ "description": "Type of the image of the
disk",
+ "type": "string",
+ "pattern":
"^(bochs|cloop|cow|dmg|qcow|qcow2|qed|raw|vmdk|vpc)$",
+ "error": "KCHTMPL0027E"
+ }
+ }
+ },
+ "minItems": 1,
+ "uniqueItems": true
+ },
+ "storagepool": {
+ "description": "Location of the storage pool",
+ "type": "string",
+ "pattern":
"^/plugins/kimchi/storagepools/[^/]+/?$",
+ "error": "KCHTMPL0015E"
+ },
+ "networks": {
+ "description": "list of which networks will be
assigned to the new VM.",
+ "type": "array",
+ "items": { "type": "string" },
+ "error": "KCHTMPL0017E"
+ },
+ "folder": {
+ "description": "Folder",
+ "type": "array",
+ "items": { "type": "string" }
+ },
+ "graphics": { "$ref":
"#/kimchitype/graphics" },
+ "cpu_info": { "$ref":
"#/kimchitype/cpu_info" }
+ },
+ "additionalProperties": false,
+ "error": "KCHAPI0001E"
+ },
+ "repositories_create": {
+ "type": "object",
+ "properties": {
+ "repo_id": {
+ "description": "Repository ID used for YUM
repository.",
+ "type": "string",
+ "error": "KCHREPOS0001E"
+ },
+ "baseurl": {
+ "description": "URL to the directory where the
repodata directory of a repository is located. Can be an http://, ftp:// or file://
URL.",
+ "type": "string",
+ "error": "KCHREPOS0002E"
+ },
+ "config": {
+ "description": "Dictionary containing repository
configuration",
+ "type": "object",
+ "error": "KCHREPOS0003E",
+ "properties": {
+ "dist": {
+ "description": "Distribution to DEB
repository",
+ "type": "string",
+ "error": "KCHREPOS0004E"
+ },
+ "comps": {
+ "description": "List of components to DEB
repository",
+ "type": "array",
+ "error": "KCHREPOS0005E",
+ "uniqueItems": true,
+ "items": {
+ "description": "Component name",
+ "type": "string",
+ "error": "KCHREPOS0006E"
+ }
+ },
+ "repo_name": {
+ "description": "YUM repository name",
+ "type": "string",
+ "error": "KCHREPOS0023E"
+ },
+ "mirrorlist": {
+ "description": "URL to a file containing a
list of baseurls",
+ "type": "string",
+ "error": "KCHREPOS0007E"
+ },
+ "metalink": {
+ "description": "URL to a metalink file for the
repomd.xml",
+ "type": "string",
+ "error": "KCHREPOS0029E"
+ }
+ }
+ }
+ },
+ "additionalProperties": false,
+ "error": "KCHAPI0001E"
+ },
+ "repository_update": {
+ "type": "object",
+ "properties": {
+ "baseurl": {
+ "description": "URL to the directory where the
repodata directory of a repository is located. Can be an http://, ftp:// or file://
URL.",
+ "type": "string",
+ "error": "KCHREPOS0002E"
+ },
+ "config": {
+ "description": "Dictionary containing repository
configuration",
+ "type": "object",
+ "error": "KCHREPOS0003E",
+ "properties": {
+ "dist": {
+ "description": "Distribution to DEB
repository",
+ "type": "string",
+ "error": "KCHREPOS0004E"
+ },
+ "comps": {
+ "description": "List of components to DEB
repository",
+ "type": "array",
+ "error": "KCHREPOS0005E",
+ "uniqueItems": true,
+ "items": {
+ "description": "Component name",
+ "type": "string",
+ "error": "KCHREPOS0006E"
+ }
+ },
+ "repo_name": {
+ "description": "Human-readable string
describing the YUM repository.",
+ "type": "string",
+ "error": "KCHREPOS0008E"
+ },
+ "mirrorlist": {
+ "description": "URL to a file containing a
list of baseurls for YUM repository",
+ "type": "string",
+ "error": "KCHREPOS0007E"
+ },
+ "gpgcheck": {
+ "description": "Indicates if a GPG signature
check on the packages gotten from repository should be performed.",
+ "type": "boolean",
+ "error": "KCHREPOS0009E"
+ },
+ "gpgkey": {
+ "description": "URL pointing to the
ASCII-armored GPG key file for the repository.",
+ "type": "string",
+ "error": "KCHREPOS0010E"
+ }
+ }
+ }
+ },
+ "additionalProperties": false,
+ "error": "KCHAPI0001E"
+ },
+ "devices_get_list": {
+ "type": "object",
+ "properties": {
+ "_cap": {
+ "description": "List specific type of device",
+ "type": "string",
+ "pattern":
"^fc_host|net|pci|scsi|scsi_host|storage|system|usb|usb_device$",
+ "error": "KCHDEVS0001E"
+ },
+ "_passthrough": {
+ "description": "List only devices eligible to be
assigned to guest",
+ "type": "string",
+ "pattern": "^true|false$",
+ "error": "KCHDEVS0002E"
+ },
+ "_passthrough_affected_by": {
+ "description": "List the affected devices in the same
group of a certain device to be assigned to guest",
+ "type": "string",
+ "pattern": "^[_A-Za-z0-9-]+$",
+ "error": "KCHDEVS0003E"
+ }
+ },
+ "additionalProperties": false,
+ "error": "KCHAPI0001E"
+ },
+ "vmhostdevs_create": {
+ "type": "object",
+ "properties": {
+ "name": {
+ "description": "Then name of the device to assign to
VM",
+ "type": "string",
+ "pattern": "^[_A-Za-z0-9-]+$",
+ "required": true,
+ "error": "KCHVMHDEV0004E"
+ }
+ },
+ "error": "KCHAPI0001E"
+ }
+ }
+}
diff --git a/src/wok/plugins/kimchi/INSTALL b/src/wok/plugins/kimchi/INSTALL
new file mode 100644
index 0000000..63bf076
--- /dev/null
+++ b/src/wok/plugins/kimchi/INSTALL
@@ -0,0 +1,369 @@
+Installation Instructions
+*************************
+
+Copyright (C) 1994-1996, 1999-2002, 2004-2011 Free Software Foundation,
+Inc.
+
+ Copying and distribution of this file, with or without modification,
+are permitted in any medium without royalty provided the copyright
+notice and this notice are preserved. This file is offered as-is,
+without warranty of any kind.
+
+Basic Installation
+==================
+
+ Briefly, the shell commands `./configure; make; make install' should
+configure, build, and install this package. The following
+more-detailed instructions are generic; see the `README' file for
+instructions specific to this package. Some packages provide this
+`INSTALL' file but do not implement all of the features documented
+below. The lack of an optional feature in a given package is not
+necessarily a bug. More recommendations for GNU packages can be found
+in *note Makefile Conventions: (standards)Makefile Conventions.
+
+ The `configure' shell script attempts to guess correct values for
+various system-dependent variables used during compilation. It uses
+those values to create a `Makefile' in each directory of the package.
+It may also create one or more `.h' files containing system-dependent
+definitions. Finally, it creates a shell script `config.status' that
+you can run in the future to recreate the current configuration, and a
+file `config.log' containing compiler output (useful mainly for
+debugging `configure').
+
+ It can also use an optional file (typically called `config.cache'
+and enabled with `--cache-file=config.cache' or simply `-C') that saves
+the results of its tests to speed up reconfiguring. Caching is
+disabled by default to prevent problems with accidental use of stale
+cache files.
+
+ If you need to do unusual things to compile the package, please try
+to figure out how `configure' could check whether to do them, and mail
+diffs or instructions to the address given in the `README' so they can
+be considered for the next release. If you are using the cache, and at
+some point `config.cache' contains results you don't want to keep, you
+may remove or edit it.
+
+ The file `configure.ac' (or `configure.in') is used to create
+`configure' by a program called `autoconf'. You need `configure.ac' if
+you want to change it or regenerate `configure' using a newer version
+of `autoconf'.
+
+ The simplest way to compile this package is:
+
+ 1. `cd' to the directory containing the package's source code and type
+ `./configure' to configure the package for your system.
+
+ Running `configure' might take a while. While running, it prints
+ some messages telling which features it is checking for.
+
+ 2. Type `make' to compile the package.
+
+ 3. Optionally, type `make check' to run any self-tests that come with
+ the package, generally using the just-built uninstalled binaries.
+
+ 4. Type `make install' to install the programs and any data files and
+ documentation. When installing into a prefix owned by root, it is
+ recommended that the package be configured and built as a regular
+ user, and only the `make install' phase executed with root
+ privileges.
+
+ 5. Optionally, type `make installcheck' to repeat any self-tests, but
+ this time using the binaries in their final installed location.
+ This target does not install anything. Running this target as a
+ regular user, particularly if the prior `make install' required
+ root privileges, verifies that the installation completed
+ correctly.
+
+ 6. You can remove the program binaries and object files from the
+ source code directory by typing `make clean'. To also remove the
+ files that `configure' created (so you can compile the package for
+ a different kind of computer), type `make distclean'. There is
+ also a `make maintainer-clean' target, but that is intended mainly
+ for the package's developers. If you use it, you may have to get
+ all sorts of other programs in order to regenerate files that came
+ with the distribution.
+
+ 7. Often, you can also type `make uninstall' to remove the installed
+ files again. In practice, not all packages have tested that
+ uninstallation works correctly, even though it is required by the
+ GNU Coding Standards.
+
+ 8. Some packages, particularly those that use Automake, provide `make
+ distcheck', which can by used by developers to test that all other
+ targets like `make install' and `make uninstall' work correctly.
+ This target is generally not run by end users.
+
+Compilers and Options
+=====================
+
+ Some systems require unusual options for compilation or linking that
+the `configure' script does not know about. Run `./configure --help'
+for details on some of the pertinent environment variables.
+
+ You can give `configure' initial values for configuration parameters
+by setting variables in the command line or in the environment. Here
+is an example:
+
+ ./configure CC=c99 CFLAGS=-g LIBS=-lposix
+
+ *Note Defining Variables::, for more details.
+
+Compiling For Multiple Architectures
+====================================
+
+ You can compile the package for more than one kind of computer at the
+same time, by placing the object files for each architecture in their
+own directory. To do this, you can use GNU `make'. `cd' to the
+directory where you want the object files and executables to go and run
+the `configure' script. `configure' automatically checks for the
+source code in the directory that `configure' is in and in `..'. This
+is known as a "VPATH" build.
+
+ With a non-GNU `make', it is safer to compile the package for one
+architecture at a time in the source code directory. After you have
+installed the package for one architecture, use `make distclean' before
+reconfiguring for another architecture.
+
+ On MacOS X 10.5 and later systems, you can create libraries and
+executables that work on multiple system types--known as "fat" or
+"universal" binaries--by specifying multiple `-arch' options to the
+compiler but only a single `-arch' option to the preprocessor. Like
+this:
+
+ ./configure CC="gcc -arch i386 -arch x86_64 -arch ppc -arch ppc64" \
+ CXX="g++ -arch i386 -arch x86_64 -arch ppc -arch ppc64" \
+ CPP="gcc -E" CXXCPP="g++ -E"
+
+ This is not guaranteed to produce working output in all cases, you
+may have to build one architecture at a time and combine the results
+using the `lipo' tool if you have problems.
+
+Installation Names
+==================
+
+ By default, `make install' installs the package's commands under
+`/usr/local/bin', include files under `/usr/local/include', etc. You
+can specify an installation prefix other than `/usr/local' by giving
+`configure' the option `--prefix=PREFIX', where PREFIX must be an
+absolute file name.
+
+ You can specify separate installation prefixes for
+architecture-specific files and architecture-independent files. If you
+pass the option `--exec-prefix=PREFIX' to `configure', the package uses
+PREFIX as the prefix for installing programs and libraries.
+Documentation and other data files still use the regular prefix.
+
+ In addition, if you use an unusual directory layout you can give
+options like `--bindir=DIR' to specify different values for particular
+kinds of files. Run `configure --help' for a list of the directories
+you can set and what kinds of files go in them. In general, the
+default for these options is expressed in terms of `${prefix}', so that
+specifying just `--prefix' will affect all of the other directory
+specifications that were not explicitly provided.
+
+ The most portable way to affect installation locations is to pass the
+correct locations to `configure'; however, many packages provide one or
+both of the following shortcuts of passing variable assignments to the
+`make install' command line to change installation locations without
+having to reconfigure or recompile.
+
+ The first method involves providing an override variable for each
+affected directory. For example, `make install
+prefix=/alternate/directory' will choose an alternate location for all
+directory configuration variables that were expressed in terms of
+`${prefix}'. Any directories that were specified during `configure',
+but not in terms of `${prefix}', must each be overridden at install
+time for the entire installation to be relocated. The approach of
+makefile variable overrides for each directory variable is required by
+the GNU Coding Standards, and ideally causes no recompilation.
+However, some platforms have known limitations with the semantics of
+shared libraries that end up requiring recompilation when using this
+method, particularly noticeable in packages that use GNU Libtool.
+
+ The second method involves providing the `DESTDIR' variable. For
+example, `make install DESTDIR=/alternate/directory' will prepend
+`/alternate/directory' before all installation names. The approach of
+`DESTDIR' overrides is not required by the GNU Coding Standards, and
+does not work on platforms that have drive letters. On the other hand,
+it does better at avoiding recompilation issues, and works well even
+when some directory options were not specified in terms of `${prefix}'
+at `configure' time.
+
+Optional Features
+=================
+
+ If the package supports it, you can cause programs to be installed
+with an extra prefix or suffix on their names by giving `configure' the
+option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'.
+
+ Some packages pay attention to `--enable-FEATURE' options to
+`configure', where FEATURE indicates an optional part of the package.
+They may also pay attention to `--with-PACKAGE' options, where PACKAGE
+is something like `gnu-as' or `x' (for the X Window System). The
+`README' should mention any `--enable-' and `--with-' options that the
+package recognizes.
+
+ For packages that use the X Window System, `configure' can usually
+find the X include and library files automatically, but if it doesn't,
+you can use the `configure' options `--x-includes=DIR' and
+`--x-libraries=DIR' to specify their locations.
+
+ Some packages offer the ability to configure how verbose the
+execution of `make' will be. For these packages, running `./configure
+--enable-silent-rules' sets the default to minimal output, which can be
+overridden with `make V=1'; while running `./configure
+--disable-silent-rules' sets the default to verbose, which can be
+overridden with `make V=0'.
+
+Particular systems
+==================
+
+ On HP-UX, the default C compiler is not ANSI C compatible. If GNU
+CC is not installed, it is recommended to use the following options in
+order to use an ANSI C compiler:
+
+ ./configure CC="cc -Ae -D_XOPEN_SOURCE=500"
+
+and if that doesn't work, install pre-built binaries of GCC for HP-UX.
+
+ HP-UX `make' updates targets which have the same time stamps as
+their prerequisites, which makes it generally unusable when shipped
+generated files such as `configure' are involved. Use GNU `make'
+instead.
+
+ On OSF/1 a.k.a. Tru64, some versions of the default C compiler cannot
+parse its `<wchar.h>' header file. The option `-nodtk' can be used as
+a workaround. If GNU CC is not installed, it is therefore recommended
+to try
+
+ ./configure CC="cc"
+
+and if that doesn't work, try
+
+ ./configure CC="cc -nodtk"
+
+ On Solaris, don't put `/usr/ucb' early in your `PATH'. This
+directory contains several dysfunctional programs; working variants of
+these programs are available in `/usr/bin'. So, if you need `/usr/ucb'
+in your `PATH', put it _after_ `/usr/bin'.
+
+ On Haiku, software installed for all users goes in `/boot/common',
+not `/usr/local'. It is recommended to use the following options:
+
+ ./configure --prefix=/boot/common
+
+Specifying the System Type
+==========================
+
+ There may be some features `configure' cannot figure out
+automatically, but needs to determine by the type of machine the package
+will run on. Usually, assuming the package is built to be run on the
+_same_ architectures, `configure' can figure that out, but if it prints
+a message saying it cannot guess the machine type, give it the
+`--build=TYPE' option. TYPE can either be a short name for the system
+type, such as `sun4', or a canonical name which has the form:
+
+ CPU-COMPANY-SYSTEM
+
+where SYSTEM can have one of these forms:
+
+ OS
+ KERNEL-OS
+
+ See the file `config.sub' for the possible values of each field. If
+`config.sub' isn't included in this package, then this package doesn't
+need to know the machine type.
+
+ If you are _building_ compiler tools for cross-compiling, you should
+use the option `--target=TYPE' to select the type of system they will
+produce code for.
+
+ If you want to _use_ a cross compiler, that generates code for a
+platform different from the build platform, you should specify the
+"host" platform (i.e., that on which the generated programs will
+eventually be run) with `--host=TYPE'.
+
+Sharing Defaults
+================
+
+ If you want to set default values for `configure' scripts to share,
+you can create a site shell script called `config.site' that gives
+default values for variables like `CC', `cache_file', and `prefix'.
+`configure' looks for `PREFIX/share/config.site' if it exists, then
+`PREFIX/etc/config.site' if it exists. Or, you can set the
+`CONFIG_SITE' environment variable to the location of the site script.
+A warning: not all `configure' scripts look for a site script.
+
+Defining Variables
+==================
+
+ Variables not defined in a site shell script can be set in the
+environment passed to `configure'. However, some packages may run
+configure again during the build, and the customized values of these
+variables may be lost. In order to avoid this problem, you should set
+them in the `configure' command line, using `VAR=value'. For example:
+
+ ./configure CC=/usr/local2/bin/gcc
+
+causes the specified `gcc' to be used as the C compiler (unless it is
+overridden in the site shell script).
+
+Unfortunately, this technique does not work for `CONFIG_SHELL' due to
+an Autoconf bug. Until the bug is fixed you can use this workaround:
+
+ CONFIG_SHELL=/bin/bash /bin/bash ./configure CONFIG_SHELL=/bin/bash
+
+`configure' Invocation
+======================
+
+ `configure' recognizes the following options to control how it
+operates.
+
+`--help'
+`-h'
+ Print a summary of all of the options to `configure', and exit.
+
+`--help=short'
+`--help=recursive'
+ Print a summary of the options unique to this package's
+ `configure', and exit. The `short' variant lists options used
+ only in the top level, while the `recursive' variant lists options
+ also present in any nested packages.
+
+`--version'
+`-V'
+ Print the version of Autoconf used to generate the `configure'
+ script, and exit.
+
+`--cache-file=FILE'
+ Enable the cache: use and save the results of the tests in FILE,
+ traditionally `config.cache'. FILE defaults to `/dev/null' to
+ disable caching.
+
+`--config-cache'
+`-C'
+ Alias for `--cache-file=config.cache'.
+
+`--quiet'
+`--silent'
+`-q'
+ Do not print messages saying which checks are being made. To
+ suppress all normal output, redirect it to `/dev/null' (any error
+ messages will still be shown).
+
+`--srcdir=DIR'
+ Look for the package's source code in directory DIR. Usually
+ `configure' can determine that directory automatically.
+
+`--prefix=DIR'
+ Use DIR as the installation prefix. *note Installation Names::
+ for more details, including other options available for fine-tuning
+ the installation locations.
+
+`--no-create'
+`-n'
+ Run the configure checks, but stop before creating any output
+ files.
+
+`configure' also accepts some other, not widely useful, options. Run
+`configure --help' for more details.
diff --git a/src/wok/plugins/kimchi/Makefile.am b/src/wok/plugins/kimchi/Makefile.am
new file mode 100644
index 0000000..49c835e
--- /dev/null
+++ b/src/wok/plugins/kimchi/Makefile.am
@@ -0,0 +1,161 @@
+#
+# Kimchi
+#
+# Copyright IBM Corp, 2013
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+SUBDIRS = contrib control distros.d docs model po tests ui xmlutils
+
+kimchi_PYTHON = $(filter-out config.py, $(wildcard *.py))
+
+nodist_kimchi_PYTHON = config.py
+
+if WITH_SPICE
+WITH_SPICE=yes
+else
+WITH_SPICE=no
+endif
+
+wokdir = $(pythondir)/wok
+kimchidir = $(pythondir)/wok/plugins/kimchi
+
+confdir = $(sysconfdir)/wok/plugins.d
+dist_conf_DATA = kimchi.conf template.conf
+
+AUTOMAKE_OPTIONS = foreign
+
+ACLOCAL_AMFLAGS = --install -I m4
+
+EXTRA_DIST = \
+ config.rpath \
+ API.json \
+ autogen.sh \
+ COPYING.ASL2 \
+ COPYING.LGPL \
+ CONTRIBUTE.md \
+ VERSION \
+ build-aux/pkg-version \
+ config.py.in \
+ $(NULL)
+
+
+PEP8_BLACKLIST = *config.py,*i18n.py,*tests/test_config.py
+
+I18N_FILES = ./i18n.py \
+ $(NULL)
+
+check-local:
+ contrib/check_i18n.py $(I18N_FILES)
+ find . -path './.git' -prune -type f -o \
+ -name '*.py' -o -name '*.py.in' | xargs $(PYFLAKES) | \
+ while read LINE; do echo "$$LINE"; false; done
+
+ $(PEP8) --version
+ $(PEP8) --filename '*.py,*.py.in' --exclude="$(PEP8_BLACKLIST)" .
+
+
+# Link built mo files in the source tree to enable use of translations from
+# within the source tree
+all-local:
+ while read L && test -n "$$L"; do \
+ dir=mo/$$L/LC_MESSAGES ; \
+ $(MKDIR_P) $$dir ; \
+ ln -sf ../../../po/$$L.gmo $$dir/kimchi.mo ; \
+ done < po/LINGUAS
+
+do_substitution = \
+ sed -e 's,[@]prefix[@],$(prefix),g' \
+ -e 's,[@]datadir[@],$(datadir),g' \
+ -e 's,[@]sysconfdir[@],$(sysconfdir),g' \
+ -e 's,[@]localstatedir[@],$(localstatedir),g' \
+ -e 's,[@]pkgdatadir[@],$(pkgdatadir),g' \
+ -e 's,[@]wokdir[@],$(wokdir),g' \
+ -e 's,[@]kimchidir[@],$(kimchidir),g' \
+ -e 's,[@]kimchiversion[@],$(PACKAGE_VERSION),g' \
+ -e 's,[@]kimchirelease[@],$(PACKAGE_RELEASE),g' \
+ -e 's,[@]withspice[@],$(WITH_SPICE),g'
+
+config.py: config.py.in Makefile
+ $(do_substitution) < $(srcdir)/config.py.in > config.py
+
+
+#
+# Packaging helpers
+#
+
+install-deb: install
+ cp -R $(top_srcdir)/contrib/DEBIAN $(DESTDIR)/
+ mkdir -p $(DESTDIR)/var/lib/kimchi/vnc-tokens
+ mkdir -p $(DESTDIR)/var/lib/kimchi/debugreports
+ mkdir -p $(DESTDIR)/var/lib/kimchi/screenshots
+ mkdir -p $(DESTDIR)/var/lib/kimchi/isos
+
+
+deb: contrib/make-deb.sh
+ $(top_srcdir)/contrib/make-deb.sh
+
+kimchi.spec: contrib/kimchi.spec.fedora contrib/kimchi.spec.suse
+ @if test -e /etc/redhat-release; then \
+ ln -sf contrib/kimchi.spec.fedora $@ ; \
+ elif test -e /etc/SuSE-release; then \
+ ln -sf contrib/kimchi.spec.suse $@ ; \
+ else \
+ echo "Unable to select a spec file for RPM build" ; \
+ /bin/false ; \
+ fi
+
+rpm: dist kimchi.spec
+ $(MKDIR_P) rpm/BUILD rpm/RPMS rpm/SOURCES rpm/SPECS rpm/SRPMS
+ cp $(top_srcdir)/kimchi.spec rpm/SPECS/kimchi.spec
+ cp $(DIST_ARCHIVES) rpm/SOURCES
+ rpmbuild -ba --define "_topdir `pwd`/rpm" rpm/SPECS/kimchi.spec
+
+fedora-rpm: contrib/kimchi.spec.fedora
+ ln -sf contrib/kimchi.spec.fedora kimchi.spec
+ $(MAKE) rpm
+
+suse-rpm: contrib/kimchi.spec.suse
+ ln -sf contrib/kimchi.spec.suse kimchi.spec
+ $(MAKE) rpm
+
+ChangeLog:
+ @if test -d .git; then \
+ $(top_srcdir)/build-aux/genChangelog --release > $@; \
+ fi
+
+install-data-local:
+ $(MKDIR_P) $(DESTDIR)$(kimchidir)
+ $(INSTALL_DATA) API.json $(DESTDIR)$(kimchidir)/API.json
+ mkdir -p $(DESTDIR)/var/lib/kimchi/vnc-tokens
+ mkdir -p $(DESTDIR)/var/lib/kimchi/{debugreports,isos,screenshots}
+
+uninstall-local:
+ $(RM) $(DESTDIR)$(kimchidir)/API.json
+ $(RM) -rf $(DESTDIR)/var/lib/kimchi
+
+VERSION:
+ @if test -d .git; then \
+ git describe --abbrev=0 > $@; \
+ fi
+
+.PHONY: deb install-deb rpm fedora-rpm suse-rpm ChangeLog VERSION
+
+
+clean-local:
+ rm -rf mo rpm
+
+BUILT_SOURCES = config.py
+CLEANFILES = config.py kimchi.spec `find "$(top_srcdir)" -type f -name
"*.pyc" -print`
diff --git a/src/wok/plugins/kimchi/README.md b/src/wok/plugins/kimchi/README.md
new file mode 120000
index 0000000..0e01b43
--- /dev/null
+++ b/src/wok/plugins/kimchi/README.md
@@ -0,0 +1 @@
+docs/README.md
\ No newline at end of file
diff --git a/src/wok/plugins/kimchi/VERSION b/src/wok/plugins/kimchi/VERSION
new file mode 100644
index 0000000..bc80560
--- /dev/null
+++ b/src/wok/plugins/kimchi/VERSION
@@ -0,0 +1 @@
+1.5.0
diff --git a/src/wok/plugins/kimchi/__init__.py b/src/wok/plugins/kimchi/__init__.py
new file mode 100644
index 0000000..9330044
--- /dev/null
+++ b/src/wok/plugins/kimchi/__init__.py
@@ -0,0 +1,21 @@
+#
+# Project Kimchi
+#
+# Copyright IBM, Corp. 2013-2014
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+from root import KimchiRoot
+__all__ = [KimchiRoot]
diff --git a/src/wok/plugins/kimchi/autogen.sh b/src/wok/plugins/kimchi/autogen.sh
new file mode 100755
index 0000000..0f22dba
--- /dev/null
+++ b/src/wok/plugins/kimchi/autogen.sh
@@ -0,0 +1,21 @@
+#!/bin/bash
+
+aclocal
+automake --add-missing
+autoreconf
+
+if [ ! -f "configure" ]; then
+ echo "Failed to generate configure script. Check to make sure autoconf, "
+ echo "automake, and other build dependencies are properly installed."
+ exit 1
+fi
+
+if [ "x$1" == "x--system" ]; then
+ ./configure --prefix=/usr --sysconfdir=/etc --localstatedir=/var
+else
+ if [ $# -gt 0 ]; then
+ ./configure $@
+ else
+ ./configure --prefix=/usr/local
+ fi
+fi
diff --git a/src/wok/plugins/kimchi/build-aux/config.rpath
b/src/wok/plugins/kimchi/build-aux/config.rpath
new file mode 100644
index 0000000..17298f2
--- /dev/null
+++ b/src/wok/plugins/kimchi/build-aux/config.rpath
@@ -0,0 +1,672 @@
+#! /bin/sh
+# Output a system dependent set of variables, describing how to set the
+# run time search path of shared libraries in an executable.
+#
+# Copyright 1996-2010 Free Software Foundation, Inc.
+# Taken from GNU libtool, 2001
+# Originally by Gordon Matzigkeit <gord(a)gnu.ai.mit.edu>, 1996
+#
+# This file is free software; the Free Software Foundation gives
+# unlimited permission to copy and/or distribute it, with or without
+# modifications, as long as this notice is preserved.
+#
+# The first argument passed to this file is the canonical host specification,
+# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM
+# or
+# CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM
+# The environment variables CC, GCC, LDFLAGS, LD, with_gnu_ld
+# should be set by the caller.
+#
+# The set of defined variables is at the end of this script.
+
+# Known limitations:
+# - On IRIX 6.5 with CC="cc", the run time search patch must not be longer
+# than 256 bytes, otherwise the compiler driver will dump core. The only
+# known workaround is to choose shorter directory names for the build
+# directory and/or the installation directory.
+
+# All known linkers require a `.a' archive for static linking (except MSVC,
+# which needs '.lib').
+libext=a
+shrext=.so
+
+host="$1"
+host_cpu=`echo "$host" | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
+host_vendor=`echo "$host" | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
+host_os=`echo "$host" | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
+
+# Code taken from libtool.m4's _LT_CC_BASENAME.
+
+for cc_temp in $CC""; do
+ case $cc_temp in
+ compile | *[\\/]compile | ccache | *[\\/]ccache ) ;;
+ distcc | *[\\/]distcc | purify | *[\\/]purify ) ;;
+ \-*) ;;
+ *) break;;
+ esac
+done
+cc_basename=`echo "$cc_temp" | sed -e 's%^.*/%%'`
+
+# Code taken from libtool.m4's _LT_COMPILER_PIC.
+
+wl=
+if test "$GCC" = yes; then
+ wl='-Wl,'
+else
+ case "$host_os" in
+ aix*)
+ wl='-Wl,'
+ ;;
+ darwin*)
+ case $cc_basename in
+ xlc*)
+ wl='-Wl,'
+ ;;
+ esac
+ ;;
+ mingw* | cygwin* | pw32* | os2* | cegcc*)
+ ;;
+ hpux9* | hpux10* | hpux11*)
+ wl='-Wl,'
+ ;;
+ irix5* | irix6* | nonstopux*)
+ wl='-Wl,'
+ ;;
+ newsos6)
+ ;;
+ linux* | k*bsd*-gnu)
+ case $cc_basename in
+ ecc*)
+ wl='-Wl,'
+ ;;
+ icc* | ifort*)
+ wl='-Wl,'
+ ;;
+ lf95*)
+ wl='-Wl,'
+ ;;
+ pgcc | pgf77 | pgf90)
+ wl='-Wl,'
+ ;;
+ ccc*)
+ wl='-Wl,'
+ ;;
+ como)
+ wl='-lopt='
+ ;;
+ *)
+ case `$CC -V 2>&1 | sed 5q` in
+ *Sun\ C*)
+ wl='-Wl,'
+ ;;
+ esac
+ ;;
+ esac
+ ;;
+ osf3* | osf4* | osf5*)
+ wl='-Wl,'
+ ;;
+ rdos*)
+ ;;
+ solaris*)
+ wl='-Wl,'
+ ;;
+ sunos4*)
+ wl='-Qoption ld '
+ ;;
+ sysv4 | sysv4.2uw2* | sysv4.3*)
+ wl='-Wl,'
+ ;;
+ sysv4*MP*)
+ ;;
+ sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*)
+ wl='-Wl,'
+ ;;
+ unicos*)
+ wl='-Wl,'
+ ;;
+ uts4*)
+ ;;
+ esac
+fi
+
+# Code taken from libtool.m4's _LT_LINKER_SHLIBS.
+
+hardcode_libdir_flag_spec=
+hardcode_libdir_separator=
+hardcode_direct=no
+hardcode_minus_L=no
+
+case "$host_os" in
+ cygwin* | mingw* | pw32* | cegcc*)
+ # FIXME: the MSVC++ port hasn't been tested in a loooong time
+ # When not using gcc, we currently assume that we are using
+ # Microsoft Visual C++.
+ if test "$GCC" != yes; then
+ with_gnu_ld=no
+ fi
+ ;;
+ interix*)
+ # we just hope/assume this is gcc and not c89 (= MSVC++)
+ with_gnu_ld=yes
+ ;;
+ openbsd*)
+ with_gnu_ld=no
+ ;;
+esac
+
+ld_shlibs=yes
+if test "$with_gnu_ld" = yes; then
+ # Set some defaults for GNU ld with shared library support. These
+ # are reset later if shared libraries are not supported. Putting them
+ # here allows them to be overridden if necessary.
+ # Unlike libtool, we use -rpath here, not --rpath, since the documented
+ # option of GNU ld is called -rpath, not --rpath.
+ hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
+ case "$host_os" in
+ aix[3-9]*)
+ # On AIX/PPC, the GNU linker is very broken
+ if test "$host_cpu" != ia64; then
+ ld_shlibs=no
+ fi
+ ;;
+ amigaos*)
+ hardcode_libdir_flag_spec='-L$libdir'
+ hardcode_minus_L=yes
+ # Samuel A. Falvo II <kc5tja(a)dolphin.openprojects.net> reports
+ # that the semantics of dynamic libraries on AmigaOS, at least up
+ # to version 4, is to share data among multiple programs linked
+ # with the same dynamic library. Since this doesn't match the
+ # behavior of shared libraries on other platforms, we cannot use
+ # them.
+ ld_shlibs=no
+ ;;
+ beos*)
+ if $LD --help 2>&1 | grep ': supported targets:.* elf' >
/dev/null; then
+ :
+ else
+ ld_shlibs=no
+ fi
+ ;;
+ cygwin* | mingw* | pw32* | cegcc*)
+ # hardcode_libdir_flag_spec is actually meaningless, as there is
+ # no search path for DLLs.
+ hardcode_libdir_flag_spec='-L$libdir'
+ if $LD --help 2>&1 | grep 'auto-import' > /dev/null; then
+ :
+ else
+ ld_shlibs=no
+ fi
+ ;;
+ interix[3-9]*)
+ hardcode_direct=no
+ hardcode_libdir_flag_spec='${wl}-rpath,$libdir'
+ ;;
+ gnu* | linux* | k*bsd*-gnu)
+ if $LD --help 2>&1 | grep ': supported targets:.* elf' >
/dev/null; then
+ :
+ else
+ ld_shlibs=no
+ fi
+ ;;
+ netbsd*)
+ ;;
+ solaris*)
+ if $LD -v 2>&1 | grep 'BFD 2\.8' > /dev/null; then
+ ld_shlibs=no
+ elif $LD --help 2>&1 | grep ': supported targets:.* elf' >
/dev/null; then
+ :
+ else
+ ld_shlibs=no
+ fi
+ ;;
+ sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*)
+ case `$LD -v 2>&1` in
+ *\ [01].* | *\ 2.[0-9].* | *\ 2.1[0-5].*)
+ ld_shlibs=no
+ ;;
+ *)
+ if $LD --help 2>&1 | grep ': supported targets:.* elf' >
/dev/null; then
+ hardcode_libdir_flag_spec='`test -z "$SCOABSPATH" &&
echo ${wl}-rpath,$libdir`'
+ else
+ ld_shlibs=no
+ fi
+ ;;
+ esac
+ ;;
+ sunos4*)
+ hardcode_direct=yes
+ ;;
+ *)
+ if $LD --help 2>&1 | grep ': supported targets:.* elf' >
/dev/null; then
+ :
+ else
+ ld_shlibs=no
+ fi
+ ;;
+ esac
+ if test "$ld_shlibs" = no; then
+ hardcode_libdir_flag_spec=
+ fi
+else
+ case "$host_os" in
+ aix3*)
+ # Note: this linker hardcodes the directories in LIBPATH if there
+ # are no directories specified by -L.
+ hardcode_minus_L=yes
+ if test "$GCC" = yes; then
+ # Neither direct hardcoding nor static linking is supported with a
+ # broken collect2.
+ hardcode_direct=unsupported
+ fi
+ ;;
+ aix[4-9]*)
+ if test "$host_cpu" = ia64; then
+ # On IA64, the linker does run time linking by default, so we don't
+ # have to do anything special.
+ aix_use_runtimelinking=no
+ else
+ aix_use_runtimelinking=no
+ # Test if we are trying to use run time linking or normal
+ # AIX style linking. If -brtl is somewhere in LDFLAGS, we
+ # need to do runtime linking.
+ case $host_os in aix4.[23]|aix4.[23].*|aix[5-9]*)
+ for ld_flag in $LDFLAGS; do
+ if (test $ld_flag = "-brtl" || test $ld_flag =
"-Wl,-brtl"); then
+ aix_use_runtimelinking=yes
+ break
+ fi
+ done
+ ;;
+ esac
+ fi
+ hardcode_direct=yes
+ hardcode_libdir_separator=':'
+ if test "$GCC" = yes; then
+ case $host_os in aix4.[012]|aix4.[012].*)
+ collect2name=`${CC} -print-prog-name=collect2`
+ if test -f "$collect2name" && \
+ strings "$collect2name" | grep resolve_lib_name >/dev/null
+ then
+ # We have reworked collect2
+ :
+ else
+ # We have old collect2
+ hardcode_direct=unsupported
+ hardcode_minus_L=yes
+ hardcode_libdir_flag_spec='-L$libdir'
+ hardcode_libdir_separator=
+ fi
+ ;;
+ esac
+ fi
+ # Begin _LT_AC_SYS_LIBPATH_AIX.
+ echo 'int main () { return 0; }' > conftest.c
+ ${CC} ${LDFLAGS} conftest.c -o conftest
+ aix_libpath=`dump -H conftest 2>/dev/null | sed -n -e '/Import File
Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; }
+}'`
+ if test -z "$aix_libpath"; then
+ aix_libpath=`dump -HX64 conftest 2>/dev/null | sed -n -e '/Import File
Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; }
+}'`
+ fi
+ if test -z "$aix_libpath"; then
+ aix_libpath="/usr/lib:/lib"
+ fi
+ rm -f conftest.c conftest
+ # End _LT_AC_SYS_LIBPATH_AIX.
+ if test "$aix_use_runtimelinking" = yes; then
+
hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath"
+ else
+ if test "$host_cpu" = ia64; then
+ hardcode_libdir_flag_spec='${wl}-R $libdir:/usr/lib:/lib'
+ else
+
hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath"
+ fi
+ fi
+ ;;
+ amigaos*)
+ hardcode_libdir_flag_spec='-L$libdir'
+ hardcode_minus_L=yes
+ # see comment about different semantics on the GNU ld section
+ ld_shlibs=no
+ ;;
+ bsdi[45]*)
+ ;;
+ cygwin* | mingw* | pw32* | cegcc*)
+ # When not using gcc, we currently assume that we are using
+ # Microsoft Visual C++.
+ # hardcode_libdir_flag_spec is actually meaningless, as there is
+ # no search path for DLLs.
+ hardcode_libdir_flag_spec=' '
+ libext=lib
+ ;;
+ darwin* | rhapsody*)
+ hardcode_direct=no
+ if test "$GCC" = yes ; then
+ :
+ else
+ case $cc_basename in
+ xlc*)
+ ;;
+ *)
+ ld_shlibs=no
+ ;;
+ esac
+ fi
+ ;;
+ dgux*)
+ hardcode_libdir_flag_spec='-L$libdir'
+ ;;
+ freebsd1*)
+ ld_shlibs=no
+ ;;
+ freebsd2.2*)
+ hardcode_libdir_flag_spec='-R$libdir'
+ hardcode_direct=yes
+ ;;
+ freebsd2*)
+ hardcode_direct=yes
+ hardcode_minus_L=yes
+ ;;
+ freebsd* | dragonfly*)
+ hardcode_libdir_flag_spec='-R$libdir'
+ hardcode_direct=yes
+ ;;
+ hpux9*)
+ hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir'
+ hardcode_libdir_separator=:
+ hardcode_direct=yes
+ # hardcode_minus_L: Not really in the search PATH,
+ # but as the default location of the library.
+ hardcode_minus_L=yes
+ ;;
+ hpux10*)
+ if test "$with_gnu_ld" = no; then
+ hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir'
+ hardcode_libdir_separator=:
+ hardcode_direct=yes
+ # hardcode_minus_L: Not really in the search PATH,
+ # but as the default location of the library.
+ hardcode_minus_L=yes
+ fi
+ ;;
+ hpux11*)
+ if test "$with_gnu_ld" = no; then
+ hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir'
+ hardcode_libdir_separator=:
+ case $host_cpu in
+ hppa*64*|ia64*)
+ hardcode_direct=no
+ ;;
+ *)
+ hardcode_direct=yes
+ # hardcode_minus_L: Not really in the search PATH,
+ # but as the default location of the library.
+ hardcode_minus_L=yes
+ ;;
+ esac
+ fi
+ ;;
+ irix5* | irix6* | nonstopux*)
+ hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
+ hardcode_libdir_separator=:
+ ;;
+ netbsd*)
+ hardcode_libdir_flag_spec='-R$libdir'
+ hardcode_direct=yes
+ ;;
+ newsos6)
+ hardcode_direct=yes
+ hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
+ hardcode_libdir_separator=:
+ ;;
+ openbsd*)
+ if test -f /usr/libexec/ld.so; then
+ hardcode_direct=yes
+ if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test
"$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
+ hardcode_libdir_flag_spec='${wl}-rpath,$libdir'
+ else
+ case "$host_os" in
+ openbsd[01].* | openbsd2.[0-7] | openbsd2.[0-7].*)
+ hardcode_libdir_flag_spec='-R$libdir'
+ ;;
+ *)
+ hardcode_libdir_flag_spec='${wl}-rpath,$libdir'
+ ;;
+ esac
+ fi
+ else
+ ld_shlibs=no
+ fi
+ ;;
+ os2*)
+ hardcode_libdir_flag_spec='-L$libdir'
+ hardcode_minus_L=yes
+ ;;
+ osf3*)
+ hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
+ hardcode_libdir_separator=:
+ ;;
+ osf4* | osf5*)
+ if test "$GCC" = yes; then
+ hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
+ else
+ # Both cc and cxx compiler support -rpath directly
+ hardcode_libdir_flag_spec='-rpath $libdir'
+ fi
+ hardcode_libdir_separator=:
+ ;;
+ solaris*)
+ hardcode_libdir_flag_spec='-R$libdir'
+ ;;
+ sunos4*)
+ hardcode_libdir_flag_spec='-L$libdir'
+ hardcode_direct=yes
+ hardcode_minus_L=yes
+ ;;
+ sysv4)
+ case $host_vendor in
+ sni)
+ hardcode_direct=yes # is this really true???
+ ;;
+ siemens)
+ hardcode_direct=no
+ ;;
+ motorola)
+ hardcode_direct=no #Motorola manual says yes, but my tests say they lie
+ ;;
+ esac
+ ;;
+ sysv4.3*)
+ ;;
+ sysv4*MP*)
+ if test -d /usr/nec; then
+ ld_shlibs=yes
+ fi
+ ;;
+ sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[01].[10]* | unixware7* |
sco3.2v5.0.[024]*)
+ ;;
+ sysv5* | sco3.2v5* | sco5v6*)
+ hardcode_libdir_flag_spec='`test -z "$SCOABSPATH" && echo
${wl}-R,$libdir`'
+ hardcode_libdir_separator=':'
+ ;;
+ uts4*)
+ hardcode_libdir_flag_spec='-L$libdir'
+ ;;
+ *)
+ ld_shlibs=no
+ ;;
+ esac
+fi
+
+# Check dynamic linker characteristics
+# Code taken from libtool.m4's _LT_SYS_DYNAMIC_LINKER.
+# Unlike libtool.m4, here we don't care about _all_ names of the library, but
+# only about the one the linker finds when passed -lNAME. This is the last
+# element of library_names_spec in libtool.m4, or possibly two of them if the
+# linker has special search rules.
+library_names_spec= # the last element of library_names_spec in libtool.m4
+libname_spec='lib$name'
+case "$host_os" in
+ aix3*)
+ library_names_spec='$libname.a'
+ ;;
+ aix[4-9]*)
+ library_names_spec='$libname$shrext'
+ ;;
+ amigaos*)
+ library_names_spec='$libname.a'
+ ;;
+ beos*)
+ library_names_spec='$libname$shrext'
+ ;;
+ bsdi[45]*)
+ library_names_spec='$libname$shrext'
+ ;;
+ cygwin* | mingw* | pw32* | cegcc*)
+ shrext=.dll
+ library_names_spec='$libname.dll.a $libname.lib'
+ ;;
+ darwin* | rhapsody*)
+ shrext=.dylib
+ library_names_spec='$libname$shrext'
+ ;;
+ dgux*)
+ library_names_spec='$libname$shrext'
+ ;;
+ freebsd1*)
+ ;;
+ freebsd* | dragonfly*)
+ case "$host_os" in
+ freebsd[123]*)
+ library_names_spec='$libname$shrext$versuffix' ;;
+ *)
+ library_names_spec='$libname$shrext' ;;
+ esac
+ ;;
+ gnu*)
+ library_names_spec='$libname$shrext'
+ ;;
+ hpux9* | hpux10* | hpux11*)
+ case $host_cpu in
+ ia64*)
+ shrext=.so
+ ;;
+ hppa*64*)
+ shrext=.sl
+ ;;
+ *)
+ shrext=.sl
+ ;;
+ esac
+ library_names_spec='$libname$shrext'
+ ;;
+ interix[3-9]*)
+ library_names_spec='$libname$shrext'
+ ;;
+ irix5* | irix6* | nonstopux*)
+ library_names_spec='$libname$shrext'
+ case "$host_os" in
+ irix5* | nonstopux*)
+ libsuff= shlibsuff=
+ ;;
+ *)
+ case $LD in
+ *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ") libsuff=
shlibsuff= ;;
+ *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ")
libsuff=32 shlibsuff=N32 ;;
+ *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ") libsuff=64
shlibsuff=64 ;;
+ *) libsuff= shlibsuff= ;;
+ esac
+ ;;
+ esac
+ ;;
+ linux*oldld* | linux*aout* | linux*coff*)
+ ;;
+ linux* | k*bsd*-gnu)
+ library_names_spec='$libname$shrext'
+ ;;
+ knetbsd*-gnu)
+ library_names_spec='$libname$shrext'
+ ;;
+ netbsd*)
+ library_names_spec='$libname$shrext'
+ ;;
+ newsos6)
+ library_names_spec='$libname$shrext'
+ ;;
+ nto-qnx*)
+ library_names_spec='$libname$shrext'
+ ;;
+ openbsd*)
+ library_names_spec='$libname$shrext$versuffix'
+ ;;
+ os2*)
+ libname_spec='$name'
+ shrext=.dll
+ library_names_spec='$libname.a'
+ ;;
+ osf3* | osf4* | osf5*)
+ library_names_spec='$libname$shrext'
+ ;;
+ rdos*)
+ ;;
+ solaris*)
+ library_names_spec='$libname$shrext'
+ ;;
+ sunos4*)
+ library_names_spec='$libname$shrext$versuffix'
+ ;;
+ sysv4 | sysv4.3*)
+ library_names_spec='$libname$shrext'
+ ;;
+ sysv4*MP*)
+ library_names_spec='$libname$shrext'
+ ;;
+ sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*)
+ library_names_spec='$libname$shrext'
+ ;;
+ uts4*)
+ library_names_spec='$libname$shrext'
+ ;;
+esac
+
+sed_quote_subst='s/\(["`$\\]\)/\\\1/g'
+escaped_wl=`echo "X$wl" | sed -e 's/^X//' -e
"$sed_quote_subst"`
+shlibext=`echo "$shrext" | sed -e 's,^\.,,'`
+escaped_libname_spec=`echo "X$libname_spec" | sed -e 's/^X//' -e
"$sed_quote_subst"`
+escaped_library_names_spec=`echo "X$library_names_spec" | sed -e
's/^X//' -e "$sed_quote_subst"`
+escaped_hardcode_libdir_flag_spec=`echo "X$hardcode_libdir_flag_spec" | sed -e
's/^X//' -e "$sed_quote_subst"`
+
+LC_ALL=C sed -e 's/^\([a-zA-Z0-9_]*\)=/acl_cv_\1=/' <<EOF
+
+# How to pass a linker flag through the compiler.
+wl="$escaped_wl"
+
+# Static library suffix (normally "a").
+libext="$libext"
+
+# Shared library suffix (normally "so").
+shlibext="$shlibext"
+
+# Format of library name prefix.
+libname_spec="$escaped_libname_spec"
+
+# Library names that the linker finds when passed -lNAME.
+library_names_spec="$escaped_library_names_spec"
+
+# Flag to hardcode \$libdir into a binary during linking.
+# This must work even if \$libdir does not exist.
+hardcode_libdir_flag_spec="$escaped_hardcode_libdir_flag_spec"
+
+# Whether we need a single -rpath flag with a separated argument.
+hardcode_libdir_separator="$hardcode_libdir_separator"
+
+# Set to yes if using DIR/libNAME.so during linking hardcodes DIR into the
+# resulting binary.
+hardcode_direct="$hardcode_direct"
+
+# Set to yes if using the -LDIR flag during linking hardcodes DIR into the
+# resulting binary.
+hardcode_minus_L="$hardcode_minus_L"
+
+EOF
diff --git a/src/wok/plugins/kimchi/build-aux/genChangelog
b/src/wok/plugins/kimchi/build-aux/genChangelog
new file mode 100755
index 0000000..803f24e
--- /dev/null
+++ b/src/wok/plugins/kimchi/build-aux/genChangelog
@@ -0,0 +1,25 @@
+#!/bin/bash
+
+# This script is based on code from the Kandan project:
+#
https://github.com/kandanapp/kandan/blob/master/gen-changelog.sh
+
+echo "CHANGELOG"
+echo "========="
+echo
+git for-each-ref --sort='*authordate' --format='%(tag)' refs/tags | tac
|grep -v '^$' | while read TAG ; do
+ if [ $NEXT ]; then
+ echo "#### [$NEXT] ####"
+ elif [ "$1" != "--release" ]; then
+ echo "#### [Current] ####"
+ else
+ NEXT=$TAG
+ continue
+ fi
+ GIT_PAGER=cat git log --pretty=format:" * [%h] %<(78,trunc)%s (%an)"
$TAG..$NEXT
+ NEXT=$TAG
+ echo; echo
+done
+FIRST=$(git for-each-ref --sort='*authordate' --format='%(tag)' refs/tags
| head -1)
+
+echo "#### [$FIRST] ####"
+GIT_PAGER=cat git log --pretty=format:" * [%h] %<(78,trunc)%s (%an)" $FIRST
diff --git a/src/wok/plugins/kimchi/build-aux/pkg-version
b/src/wok/plugins/kimchi/build-aux/pkg-version
new file mode 100755
index 0000000..749cf6c
--- /dev/null
+++ b/src/wok/plugins/kimchi/build-aux/pkg-version
@@ -0,0 +1,59 @@
+#!/bin/sh
+#
+# Copyright 2008-2012 Red Hat, Inc.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+# tags and output versions:
+# - 4.9.0 => 4.9.0 (upstream clean)
+# - 4.9.0-1 => 4.9.0 (downstream clean)
+# - 4.9.0-2-g34e62f => 4.9.0 (upstream dirty)
+# - 4.9.0-1-2-g34e62f => 4.9.0 (downstream dirty)
+AWK_VERSION='
+ BEGIN { FS="-" }
+ /^[0-9]/ {
+ print $1
+ }'
+
+# tags and output releases:
+# - 4.9.0 => 0 (upstream clean)
+# - 4.9.0-1 => 1 (downstream clean)
+# - 4.9.0-2-g34e62f1 => 2.git34e62f1 (upstream dirty)
+# - 4.9.0-1-2-g34e62f1 => 1.2.git34e62f1 (downstream dirty)
+AWK_RELEASE='
+ BEGIN { FS="-"; OFS="." }
+ /^[0-9]/ {
+ if (NF == 1) print 0
+ else if (NF == 2) print $2
+ else if (NF == 3) print $2, "git" substr($3, 2)
+ else if (NF == 4) print $2, $3, "git" substr($4, 2)
+ }'
+
+if [ ! -d .git ]; then
+ PKG_VERSION=`cat VERSION`
+else
+ PKG_VERSION=`git describe --tags --match "[0-9]*" || cat VERSION`
+fi
+
+if test "x$1" = "x--full"; then
+ echo $PKG_VERSION | tr -d '[:space:]'
+elif test "x$1" = "x--version"; then
+ echo $PKG_VERSION | awk "$AWK_VERSION" | tr -cd '[:alnum:].'
+elif test "x$1" = "x--release"; then
+ echo $PKG_VERSION | awk "$AWK_RELEASE" | tr -cd '[:alnum:].'
+else
+ echo "usage: $0 [--full|--version|--release]"
+ exit 1
+fi
diff --git a/src/wok/plugins/kimchi/config.py.in b/src/wok/plugins/kimchi/config.py.in
new file mode 100644
index 0000000..6ae0ccd
--- /dev/null
+++ b/src/wok/plugins/kimchi/config.py.in
@@ -0,0 +1,144 @@
+#
+# Project Kimchi
+#
+# Copyright IBM, Corp. 2013-2015
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+#
+
+import libvirt
+import os
+import platform
+import threading
+
+from wok.config import CACHEEXPIRES, PluginConfig, PluginPaths
+from wok.xmlutils.utils import xpath_get_text
+
+kimchiLock = threading.Lock()
+
+__with_spice__ = "@withspice@"
+
+# Storage pool constant for read-only pool types
+READONLY_POOL_TYPE = ['iscsi', 'scsi', 'mpath']
+
+
+def get_distros_store():
+ return os.path.join(PluginPaths('kimchi').conf_dir, 'distros.d')
+
+
+def get_debugreports_path():
+ return os.path.join(PluginPaths('kimchi').state_dir, 'debugreports')
+
+
+def get_screenshot_path():
+ return os.path.join(PluginPaths('kimchi').state_dir, 'screenshots')
+
+
+def find_qemu_binary(find_emulator=False):
+ try:
+ connect = libvirt.open(None)
+ except Exception, e:
+ raise Exception("Unable to get qemu binary location: %s" % e)
+ try:
+ xml = connect.getCapabilities()
+
+ # On Little Endian system, the qemu binary is
+ # qemu-system-ppc64, not qemu-system-ppc64le as expected
+ arch = platform.machine()
+ if arch == "ppc64le":
+ arch = "ppc64"
+
+ if find_emulator:
+ expr = "/capabilities/guest/arch[@name='%s']\
+ /emulator" % arch
+ else:
+ expr = "/capabilities/guest/arch[@name='%s']\
+ /domain[@type='kvm']/emulator" % arch
+ res = xpath_get_text(xml, expr)
+ location = res[0]
+ except Exception, e:
+ raise Exception("Unable to get qemu binary location: %s" % e)
+ finally:
+ connect.close()
+ return location
+
+
+class KimchiPaths(PluginPaths):
+
+ def __init__(self):
+ super(KimchiPaths, self).__init__('kimchi')
+ self.spice_file = os.path.join(self.ui_dir,
+ 'spice-html5/pages/spice_auto.html')
+
+ if __with_spice__ == 'yes':
+ self.spice_dir = self.add_prefix('ui/spice-html5')
+ elif os.path.exists('@datadir@/spice-html5'):
+ self.spice_dir = '@datadir@/spice-html5'
+ else:
+ self.spice_dir = '/usr/share/spice-html5'
+
+ if os.path.exists('@datadir@/novnc'):
+ self.novnc_dir = '@datadir@/novnc'
+ else:
+ self.novnc_dir = '/usr/share/novnc'
+
+ if self.installed:
+ self.spice_css_file = os.path.join(self.spice_dir, 'spice.css')
+ else:
+ self.spice_css_file = os.path.join(self.spice_dir, 'css/spice.css')
+
+
+kimchiPaths = KimchiPaths()
+
+
+class KimchiConfig(PluginConfig):
+ def __init__(self):
+ super(KimchiConfig, self).__init__('kimchi')
+
+ static_config = {
+ '/novnc': {'type': 'dir',
+ 'path': kimchiPaths.novnc_dir},
+ '/spice-html5': {'type': 'dir',
+ 'path': kimchiPaths.spice_dir},
+ '/spice_auto.html': {'type': 'file',
+ 'path': kimchiPaths.spice_file},
+ '/spice-html5/spice.css': {'type': 'file',
+ 'path': kimchiPaths.spice_css_file}}
+
+ custom_config = {}
+ for uri, data in static_config.iteritems():
+ custom_config[uri] = {'tools.nocache.on': True,
+ 'tools.wokauth.on': True}
+ path = data['path']
+ if data['type'] == 'dir':
+ custom_config[uri].update({'tools.staticdir.on': True,
+ 'tools.staticdir.dir': path})
+ elif data['type'] == 'file':
+ custom_config[uri].update({'tools.staticfile.on': True,
+ 'tools.staticfile.filename': path})
+
+ for dirname in ('css', 'js', 'images'):
+ custom_config['/' + dirname] = {
+ 'tools.staticdir.on': True,
+ 'tools.staticdir.dir': os.path.join(kimchiPaths.ui_dir,
+ dirname),
+ 'tools.wokauth.on': False,
+ 'tools.nocache.on': False}
+ if dirname != 'images':
+ custom_config['/' + dirname].update({
+ 'tools.expires.on': True,
+ 'tools.expires.secs': CACHEEXPIRES})
+
+ self.update(custom_config)
diff --git a/src/wok/plugins/kimchi/config.rpath b/src/wok/plugins/kimchi/config.rpath
new file mode 100644
index 0000000..17298f2
--- /dev/null
+++ b/src/wok/plugins/kimchi/config.rpath
@@ -0,0 +1,672 @@
+#! /bin/sh
+# Output a system dependent set of variables, describing how to set the
+# run time search path of shared libraries in an executable.
+#
+# Copyright 1996-2010 Free Software Foundation, Inc.
+# Taken from GNU libtool, 2001
+# Originally by Gordon Matzigkeit <gord(a)gnu.ai.mit.edu>, 1996
+#
+# This file is free software; the Free Software Foundation gives
+# unlimited permission to copy and/or distribute it, with or without
+# modifications, as long as this notice is preserved.
+#
+# The first argument passed to this file is the canonical host specification,
+# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM
+# or
+# CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM
+# The environment variables CC, GCC, LDFLAGS, LD, with_gnu_ld
+# should be set by the caller.
+#
+# The set of defined variables is at the end of this script.
+
+# Known limitations:
+# - On IRIX 6.5 with CC="cc", the run time search patch must not be longer
+# than 256 bytes, otherwise the compiler driver will dump core. The only
+# known workaround is to choose shorter directory names for the build
+# directory and/or the installation directory.
+
+# All known linkers require a `.a' archive for static linking (except MSVC,
+# which needs '.lib').
+libext=a
+shrext=.so
+
+host="$1"
+host_cpu=`echo "$host" | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
+host_vendor=`echo "$host" | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
+host_os=`echo "$host" | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
+
+# Code taken from libtool.m4's _LT_CC_BASENAME.
+
+for cc_temp in $CC""; do
+ case $cc_temp in
+ compile | *[\\/]compile | ccache | *[\\/]ccache ) ;;
+ distcc | *[\\/]distcc | purify | *[\\/]purify ) ;;
+ \-*) ;;
+ *) break;;
+ esac
+done
+cc_basename=`echo "$cc_temp" | sed -e 's%^.*/%%'`
+
+# Code taken from libtool.m4's _LT_COMPILER_PIC.
+
+wl=
+if test "$GCC" = yes; then
+ wl='-Wl,'
+else
+ case "$host_os" in
+ aix*)
+ wl='-Wl,'
+ ;;
+ darwin*)
+ case $cc_basename in
+ xlc*)
+ wl='-Wl,'
+ ;;
+ esac
+ ;;
+ mingw* | cygwin* | pw32* | os2* | cegcc*)
+ ;;
+ hpux9* | hpux10* | hpux11*)
+ wl='-Wl,'
+ ;;
+ irix5* | irix6* | nonstopux*)
+ wl='-Wl,'
+ ;;
+ newsos6)
+ ;;
+ linux* | k*bsd*-gnu)
+ case $cc_basename in
+ ecc*)
+ wl='-Wl,'
+ ;;
+ icc* | ifort*)
+ wl='-Wl,'
+ ;;
+ lf95*)
+ wl='-Wl,'
+ ;;
+ pgcc | pgf77 | pgf90)
+ wl='-Wl,'
+ ;;
+ ccc*)
+ wl='-Wl,'
+ ;;
+ como)
+ wl='-lopt='
+ ;;
+ *)
+ case `$CC -V 2>&1 | sed 5q` in
+ *Sun\ C*)
+ wl='-Wl,'
+ ;;
+ esac
+ ;;
+ esac
+ ;;
+ osf3* | osf4* | osf5*)
+ wl='-Wl,'
+ ;;
+ rdos*)
+ ;;
+ solaris*)
+ wl='-Wl,'
+ ;;
+ sunos4*)
+ wl='-Qoption ld '
+ ;;
+ sysv4 | sysv4.2uw2* | sysv4.3*)
+ wl='-Wl,'
+ ;;
+ sysv4*MP*)
+ ;;
+ sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*)
+ wl='-Wl,'
+ ;;
+ unicos*)
+ wl='-Wl,'
+ ;;
+ uts4*)
+ ;;
+ esac
+fi
+
+# Code taken from libtool.m4's _LT_LINKER_SHLIBS.
+
+hardcode_libdir_flag_spec=
+hardcode_libdir_separator=
+hardcode_direct=no
+hardcode_minus_L=no
+
+case "$host_os" in
+ cygwin* | mingw* | pw32* | cegcc*)
+ # FIXME: the MSVC++ port hasn't been tested in a loooong time
+ # When not using gcc, we currently assume that we are using
+ # Microsoft Visual C++.
+ if test "$GCC" != yes; then
+ with_gnu_ld=no
+ fi
+ ;;
+ interix*)
+ # we just hope/assume this is gcc and not c89 (= MSVC++)
+ with_gnu_ld=yes
+ ;;
+ openbsd*)
+ with_gnu_ld=no
+ ;;
+esac
+
+ld_shlibs=yes
+if test "$with_gnu_ld" = yes; then
+ # Set some defaults for GNU ld with shared library support. These
+ # are reset later if shared libraries are not supported. Putting them
+ # here allows them to be overridden if necessary.
+ # Unlike libtool, we use -rpath here, not --rpath, since the documented
+ # option of GNU ld is called -rpath, not --rpath.
+ hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
+ case "$host_os" in
+ aix[3-9]*)
+ # On AIX/PPC, the GNU linker is very broken
+ if test "$host_cpu" != ia64; then
+ ld_shlibs=no
+ fi
+ ;;
+ amigaos*)
+ hardcode_libdir_flag_spec='-L$libdir'
+ hardcode_minus_L=yes
+ # Samuel A. Falvo II <kc5tja(a)dolphin.openprojects.net> reports
+ # that the semantics of dynamic libraries on AmigaOS, at least up
+ # to version 4, is to share data among multiple programs linked
+ # with the same dynamic library. Since this doesn't match the
+ # behavior of shared libraries on other platforms, we cannot use
+ # them.
+ ld_shlibs=no
+ ;;
+ beos*)
+ if $LD --help 2>&1 | grep ': supported targets:.* elf' >
/dev/null; then
+ :
+ else
+ ld_shlibs=no
+ fi
+ ;;
+ cygwin* | mingw* | pw32* | cegcc*)
+ # hardcode_libdir_flag_spec is actually meaningless, as there is
+ # no search path for DLLs.
+ hardcode_libdir_flag_spec='-L$libdir'
+ if $LD --help 2>&1 | grep 'auto-import' > /dev/null; then
+ :
+ else
+ ld_shlibs=no
+ fi
+ ;;
+ interix[3-9]*)
+ hardcode_direct=no
+ hardcode_libdir_flag_spec='${wl}-rpath,$libdir'
+ ;;
+ gnu* | linux* | k*bsd*-gnu)
+ if $LD --help 2>&1 | grep ': supported targets:.* elf' >
/dev/null; then
+ :
+ else
+ ld_shlibs=no
+ fi
+ ;;
+ netbsd*)
+ ;;
+ solaris*)
+ if $LD -v 2>&1 | grep 'BFD 2\.8' > /dev/null; then
+ ld_shlibs=no
+ elif $LD --help 2>&1 | grep ': supported targets:.* elf' >
/dev/null; then
+ :
+ else
+ ld_shlibs=no
+ fi
+ ;;
+ sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*)
+ case `$LD -v 2>&1` in
+ *\ [01].* | *\ 2.[0-9].* | *\ 2.1[0-5].*)
+ ld_shlibs=no
+ ;;
+ *)
+ if $LD --help 2>&1 | grep ': supported targets:.* elf' >
/dev/null; then
+ hardcode_libdir_flag_spec='`test -z "$SCOABSPATH" &&
echo ${wl}-rpath,$libdir`'
+ else
+ ld_shlibs=no
+ fi
+ ;;
+ esac
+ ;;
+ sunos4*)
+ hardcode_direct=yes
+ ;;
+ *)
+ if $LD --help 2>&1 | grep ': supported targets:.* elf' >
/dev/null; then
+ :
+ else
+ ld_shlibs=no
+ fi
+ ;;
+ esac
+ if test "$ld_shlibs" = no; then
+ hardcode_libdir_flag_spec=
+ fi
+else
+ case "$host_os" in
+ aix3*)
+ # Note: this linker hardcodes the directories in LIBPATH if there
+ # are no directories specified by -L.
+ hardcode_minus_L=yes
+ if test "$GCC" = yes; then
+ # Neither direct hardcoding nor static linking is supported with a
+ # broken collect2.
+ hardcode_direct=unsupported
+ fi
+ ;;
+ aix[4-9]*)
+ if test "$host_cpu" = ia64; then
+ # On IA64, the linker does run time linking by default, so we don't
+ # have to do anything special.
+ aix_use_runtimelinking=no
+ else
+ aix_use_runtimelinking=no
+ # Test if we are trying to use run time linking or normal
+ # AIX style linking. If -brtl is somewhere in LDFLAGS, we
+ # need to do runtime linking.
+ case $host_os in aix4.[23]|aix4.[23].*|aix[5-9]*)
+ for ld_flag in $LDFLAGS; do
+ if (test $ld_flag = "-brtl" || test $ld_flag =
"-Wl,-brtl"); then
+ aix_use_runtimelinking=yes
+ break
+ fi
+ done
+ ;;
+ esac
+ fi
+ hardcode_direct=yes
+ hardcode_libdir_separator=':'
+ if test "$GCC" = yes; then
+ case $host_os in aix4.[012]|aix4.[012].*)
+ collect2name=`${CC} -print-prog-name=collect2`
+ if test -f "$collect2name" && \
+ strings "$collect2name" | grep resolve_lib_name >/dev/null
+ then
+ # We have reworked collect2
+ :
+ else
+ # We have old collect2
+ hardcode_direct=unsupported
+ hardcode_minus_L=yes
+ hardcode_libdir_flag_spec='-L$libdir'
+ hardcode_libdir_separator=
+ fi
+ ;;
+ esac
+ fi
+ # Begin _LT_AC_SYS_LIBPATH_AIX.
+ echo 'int main () { return 0; }' > conftest.c
+ ${CC} ${LDFLAGS} conftest.c -o conftest
+ aix_libpath=`dump -H conftest 2>/dev/null | sed -n -e '/Import File
Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; }
+}'`
+ if test -z "$aix_libpath"; then
+ aix_libpath=`dump -HX64 conftest 2>/dev/null | sed -n -e '/Import File
Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; }
+}'`
+ fi
+ if test -z "$aix_libpath"; then
+ aix_libpath="/usr/lib:/lib"
+ fi
+ rm -f conftest.c conftest
+ # End _LT_AC_SYS_LIBPATH_AIX.
+ if test "$aix_use_runtimelinking" = yes; then
+
hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath"
+ else
+ if test "$host_cpu" = ia64; then
+ hardcode_libdir_flag_spec='${wl}-R $libdir:/usr/lib:/lib'
+ else
+
hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath"
+ fi
+ fi
+ ;;
+ amigaos*)
+ hardcode_libdir_flag_spec='-L$libdir'
+ hardcode_minus_L=yes
+ # see comment about different semantics on the GNU ld section
+ ld_shlibs=no
+ ;;
+ bsdi[45]*)
+ ;;
+ cygwin* | mingw* | pw32* | cegcc*)
+ # When not using gcc, we currently assume that we are using
+ # Microsoft Visual C++.
+ # hardcode_libdir_flag_spec is actually meaningless, as there is
+ # no search path for DLLs.
+ hardcode_libdir_flag_spec=' '
+ libext=lib
+ ;;
+ darwin* | rhapsody*)
+ hardcode_direct=no
+ if test "$GCC" = yes ; then
+ :
+ else
+ case $cc_basename in
+ xlc*)
+ ;;
+ *)
+ ld_shlibs=no
+ ;;
+ esac
+ fi
+ ;;
+ dgux*)
+ hardcode_libdir_flag_spec='-L$libdir'
+ ;;
+ freebsd1*)
+ ld_shlibs=no
+ ;;
+ freebsd2.2*)
+ hardcode_libdir_flag_spec='-R$libdir'
+ hardcode_direct=yes
+ ;;
+ freebsd2*)
+ hardcode_direct=yes
+ hardcode_minus_L=yes
+ ;;
+ freebsd* | dragonfly*)
+ hardcode_libdir_flag_spec='-R$libdir'
+ hardcode_direct=yes
+ ;;
+ hpux9*)
+ hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir'
+ hardcode_libdir_separator=:
+ hardcode_direct=yes
+ # hardcode_minus_L: Not really in the search PATH,
+ # but as the default location of the library.
+ hardcode_minus_L=yes
+ ;;
+ hpux10*)
+ if test "$with_gnu_ld" = no; then
+ hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir'
+ hardcode_libdir_separator=:
+ hardcode_direct=yes
+ # hardcode_minus_L: Not really in the search PATH,
+ # but as the default location of the library.
+ hardcode_minus_L=yes
+ fi
+ ;;
+ hpux11*)
+ if test "$with_gnu_ld" = no; then
+ hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir'
+ hardcode_libdir_separator=:
+ case $host_cpu in
+ hppa*64*|ia64*)
+ hardcode_direct=no
+ ;;
+ *)
+ hardcode_direct=yes
+ # hardcode_minus_L: Not really in the search PATH,
+ # but as the default location of the library.
+ hardcode_minus_L=yes
+ ;;
+ esac
+ fi
+ ;;
+ irix5* | irix6* | nonstopux*)
+ hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
+ hardcode_libdir_separator=:
+ ;;
+ netbsd*)
+ hardcode_libdir_flag_spec='-R$libdir'
+ hardcode_direct=yes
+ ;;
+ newsos6)
+ hardcode_direct=yes
+ hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
+ hardcode_libdir_separator=:
+ ;;
+ openbsd*)
+ if test -f /usr/libexec/ld.so; then
+ hardcode_direct=yes
+ if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test
"$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
+ hardcode_libdir_flag_spec='${wl}-rpath,$libdir'
+ else
+ case "$host_os" in
+ openbsd[01].* | openbsd2.[0-7] | openbsd2.[0-7].*)
+ hardcode_libdir_flag_spec='-R$libdir'
+ ;;
+ *)
+ hardcode_libdir_flag_spec='${wl}-rpath,$libdir'
+ ;;
+ esac
+ fi
+ else
+ ld_shlibs=no
+ fi
+ ;;
+ os2*)
+ hardcode_libdir_flag_spec='-L$libdir'
+ hardcode_minus_L=yes
+ ;;
+ osf3*)
+ hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
+ hardcode_libdir_separator=:
+ ;;
+ osf4* | osf5*)
+ if test "$GCC" = yes; then
+ hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
+ else
+ # Both cc and cxx compiler support -rpath directly
+ hardcode_libdir_flag_spec='-rpath $libdir'
+ fi
+ hardcode_libdir_separator=:
+ ;;
+ solaris*)
+ hardcode_libdir_flag_spec='-R$libdir'
+ ;;
+ sunos4*)
+ hardcode_libdir_flag_spec='-L$libdir'
+ hardcode_direct=yes
+ hardcode_minus_L=yes
+ ;;
+ sysv4)
+ case $host_vendor in
+ sni)
+ hardcode_direct=yes # is this really true???
+ ;;
+ siemens)
+ hardcode_direct=no
+ ;;
+ motorola)
+ hardcode_direct=no #Motorola manual says yes, but my tests say they lie
+ ;;
+ esac
+ ;;
+ sysv4.3*)
+ ;;
+ sysv4*MP*)
+ if test -d /usr/nec; then
+ ld_shlibs=yes
+ fi
+ ;;
+ sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[01].[10]* | unixware7* |
sco3.2v5.0.[024]*)
+ ;;
+ sysv5* | sco3.2v5* | sco5v6*)
+ hardcode_libdir_flag_spec='`test -z "$SCOABSPATH" && echo
${wl}-R,$libdir`'
+ hardcode_libdir_separator=':'
+ ;;
+ uts4*)
+ hardcode_libdir_flag_spec='-L$libdir'
+ ;;
+ *)
+ ld_shlibs=no
+ ;;
+ esac
+fi
+
+# Check dynamic linker characteristics
+# Code taken from libtool.m4's _LT_SYS_DYNAMIC_LINKER.
+# Unlike libtool.m4, here we don't care about _all_ names of the library, but
+# only about the one the linker finds when passed -lNAME. This is the last
+# element of library_names_spec in libtool.m4, or possibly two of them if the
+# linker has special search rules.
+library_names_spec= # the last element of library_names_spec in libtool.m4
+libname_spec='lib$name'
+case "$host_os" in
+ aix3*)
+ library_names_spec='$libname.a'
+ ;;
+ aix[4-9]*)
+ library_names_spec='$libname$shrext'
+ ;;
+ amigaos*)
+ library_names_spec='$libname.a'
+ ;;
+ beos*)
+ library_names_spec='$libname$shrext'
+ ;;
+ bsdi[45]*)
+ library_names_spec='$libname$shrext'
+ ;;
+ cygwin* | mingw* | pw32* | cegcc*)
+ shrext=.dll
+ library_names_spec='$libname.dll.a $libname.lib'
+ ;;
+ darwin* | rhapsody*)
+ shrext=.dylib
+ library_names_spec='$libname$shrext'
+ ;;
+ dgux*)
+ library_names_spec='$libname$shrext'
+ ;;
+ freebsd1*)
+ ;;
+ freebsd* | dragonfly*)
+ case "$host_os" in
+ freebsd[123]*)
+ library_names_spec='$libname$shrext$versuffix' ;;
+ *)
+ library_names_spec='$libname$shrext' ;;
+ esac
+ ;;
+ gnu*)
+ library_names_spec='$libname$shrext'
+ ;;
+ hpux9* | hpux10* | hpux11*)
+ case $host_cpu in
+ ia64*)
+ shrext=.so
+ ;;
+ hppa*64*)
+ shrext=.sl
+ ;;
+ *)
+ shrext=.sl
+ ;;
+ esac
+ library_names_spec='$libname$shrext'
+ ;;
+ interix[3-9]*)
+ library_names_spec='$libname$shrext'
+ ;;
+ irix5* | irix6* | nonstopux*)
+ library_names_spec='$libname$shrext'
+ case "$host_os" in
+ irix5* | nonstopux*)
+ libsuff= shlibsuff=
+ ;;
+ *)
+ case $LD in
+ *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ") libsuff=
shlibsuff= ;;
+ *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ")
libsuff=32 shlibsuff=N32 ;;
+ *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ") libsuff=64
shlibsuff=64 ;;
+ *) libsuff= shlibsuff= ;;
+ esac
+ ;;
+ esac
+ ;;
+ linux*oldld* | linux*aout* | linux*coff*)
+ ;;
+ linux* | k*bsd*-gnu)
+ library_names_spec='$libname$shrext'
+ ;;
+ knetbsd*-gnu)
+ library_names_spec='$libname$shrext'
+ ;;
+ netbsd*)
+ library_names_spec='$libname$shrext'
+ ;;
+ newsos6)
+ library_names_spec='$libname$shrext'
+ ;;
+ nto-qnx*)
+ library_names_spec='$libname$shrext'
+ ;;
+ openbsd*)
+ library_names_spec='$libname$shrext$versuffix'
+ ;;
+ os2*)
+ libname_spec='$name'
+ shrext=.dll
+ library_names_spec='$libname.a'
+ ;;
+ osf3* | osf4* | osf5*)
+ library_names_spec='$libname$shrext'
+ ;;
+ rdos*)
+ ;;
+ solaris*)
+ library_names_spec='$libname$shrext'
+ ;;
+ sunos4*)
+ library_names_spec='$libname$shrext$versuffix'
+ ;;
+ sysv4 | sysv4.3*)
+ library_names_spec='$libname$shrext'
+ ;;
+ sysv4*MP*)
+ library_names_spec='$libname$shrext'
+ ;;
+ sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*)
+ library_names_spec='$libname$shrext'
+ ;;
+ uts4*)
+ library_names_spec='$libname$shrext'
+ ;;
+esac
+
+sed_quote_subst='s/\(["`$\\]\)/\\\1/g'
+escaped_wl=`echo "X$wl" | sed -e 's/^X//' -e
"$sed_quote_subst"`
+shlibext=`echo "$shrext" | sed -e 's,^\.,,'`
+escaped_libname_spec=`echo "X$libname_spec" | sed -e 's/^X//' -e
"$sed_quote_subst"`
+escaped_library_names_spec=`echo "X$library_names_spec" | sed -e
's/^X//' -e "$sed_quote_subst"`
+escaped_hardcode_libdir_flag_spec=`echo "X$hardcode_libdir_flag_spec" | sed -e
's/^X//' -e "$sed_quote_subst"`
+
+LC_ALL=C sed -e 's/^\([a-zA-Z0-9_]*\)=/acl_cv_\1=/' <<EOF
+
+# How to pass a linker flag through the compiler.
+wl="$escaped_wl"
+
+# Static library suffix (normally "a").
+libext="$libext"
+
+# Shared library suffix (normally "so").
+shlibext="$shlibext"
+
+# Format of library name prefix.
+libname_spec="$escaped_libname_spec"
+
+# Library names that the linker finds when passed -lNAME.
+library_names_spec="$escaped_library_names_spec"
+
+# Flag to hardcode \$libdir into a binary during linking.
+# This must work even if \$libdir does not exist.
+hardcode_libdir_flag_spec="$escaped_hardcode_libdir_flag_spec"
+
+# Whether we need a single -rpath flag with a separated argument.
+hardcode_libdir_separator="$hardcode_libdir_separator"
+
+# Set to yes if using DIR/libNAME.so during linking hardcodes DIR into the
+# resulting binary.
+hardcode_direct="$hardcode_direct"
+
+# Set to yes if using the -LDIR flag during linking hardcodes DIR into the
+# resulting binary.
+hardcode_minus_L="$hardcode_minus_L"
+
+EOF
diff --git a/src/wok/plugins/kimchi/configure.ac b/src/wok/plugins/kimchi/configure.ac
new file mode 100644
index 0000000..adab45b
--- /dev/null
+++ b/src/wok/plugins/kimchi/configure.ac
@@ -0,0 +1,119 @@
+#
+# Kimchi
+#
+# Copyright IBM Corp, 2013-2015
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+AC_INIT([kimchi], [m4_esyscmd([./build-aux/pkg-version --version])])
+
+AC_SUBST([PACKAGE_VERSION],
+ [m4_esyscmd([./build-aux/pkg-version --version])])
+
+AC_SUBST([PACKAGE_RELEASE],
+ [m4_esyscmd([./build-aux/pkg-version --release])])
+
+# Testing for version and release
+AS_IF([test "x$PACKAGE_VERSION" = x],
+ AC_MSG_ERROR([package version not defined]))
+AS_IF([test "x$PACKAGE_RELEASE" = x],
+ AC_MSG_ERROR([package release not defined]))
+
+AC_CONFIG_AUX_DIR([build-aux])
+AM_INIT_AUTOMAKE([-Wno-portability])
+AM_PATH_PYTHON([2.6])
+AC_PATH_PROG([PEP8], [pep8], [/usr/bin/pep8])
+AC_PYTHON_MODULE([unittest])
+AC_SUBST([HAVE_PYMOD_UNITTEST])
+AC_SUBST([PYTHON_VERSION])
+AM_GNU_GETTEXT([external])
+AM_GNU_GETTEXT_VERSION([0.10])
+AC_PATH_PROG([CHEETAH], [cheetah], [/usr/bin/cheetah])
+
+# Checking for pyflakes
+AC_PATH_PROG([PYFLAKES], [pyflakes])
+if test "x$PYFLAKES" = "x"; then
+ AC_MSG_WARN([pyflakes not found])
+fi
+
+AC_ARG_ENABLE(
+ [sample],
+ [AS_HELP_STRING(
+ [--enable-sample],
+ [enable sample plugin @<:@default=no@:>@]
+ )],
+ ,
+ [enable_sample="no"]
+)
+
+if test "${enable_sample}" = "yes"; then
+AC_SUBST([ENABLE_SAMPLE], [True])
+else
+AC_SUBST([ENABLE_SAMPLE], [False])
+fi
+
+AC_ARG_WITH(
+ [spice-html5],
+ [AS_HELP_STRING([--with-spice-html5],
+ [Build Kimchi with spice-html5 @<:@default=no@:>@])],
+ ,
+ [with_spice_html5="no"]
+)
+AM_CONDITIONAL([WITH_SPICE], [test "x$with_spice_html5" = xyes])
+
+AC_CONFIG_FILES([
+ po/Makefile.in
+ po/gen-pot
+ Makefile
+ docs/Makefile
+ distros.d/Makefile
+ control/Makefile
+ control/vm/Makefile
+ model/Makefile
+ ui/Makefile
+ ui/config/Makefile
+ ui/css/Makefile
+ ui/images/Makefile
+ ui/images/theme-default/Makefile
+ ui/js/Makefile
+ ui/spice-html5/Makefile
+ ui/spice-html5/css/Makefile
+ ui/spice-html5/pages/Makefile
+ ui/spice-html5/thirdparty/Makefile
+ ui/pages/Makefile
+ ui/pages/help/Makefile
+ ui/pages/help/en_US/Makefile
+ ui/pages/help/de_DE/Makefile
+ ui/pages/help/es_ES/Makefile
+ ui/pages/help/fr_FR/Makefile
+ ui/pages/help/it_IT/Makefile
+ ui/pages/help/ja_JP/Makefile
+ ui/pages/help/ko_KR/Makefile
+ ui/pages/help/pt_BR/Makefile
+ ui/pages/help/ru_RU/Makefile
+ ui/pages/help/zh_CN/Makefile
+ ui/pages/help/zh_TW/Makefile
+ contrib/Makefile
+ contrib/DEBIAN/Makefile
+ contrib/DEBIAN/control
+ contrib/kimchi.spec.fedora
+ contrib/kimchi.spec.suse
+ tests/Makefile
+ xmlutils/Makefile
+],[
+ chmod +x po/gen-pot
+])
+
+AC_OUTPUT
diff --git a/src/wok/plugins/kimchi/contrib/DEBIAN/Makefile.am
b/src/wok/plugins/kimchi/contrib/DEBIAN/Makefile.am
new file mode 100644
index 0000000..ca89552
--- /dev/null
+++ b/src/wok/plugins/kimchi/contrib/DEBIAN/Makefile.am
@@ -0,0 +1,17 @@
+# Copyright IBM Corp, 2013
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+CLEANFILES = control
diff --git a/src/wok/plugins/kimchi/contrib/DEBIAN/control.in
b/src/wok/plugins/kimchi/contrib/DEBIAN/control.in
new file mode 100644
index 0000000..dc153d8
--- /dev/null
+++ b/src/wok/plugins/kimchi/contrib/DEBIAN/control.in
@@ -0,0 +1,30 @@
+Package: @PACKAGE_NAME@
+Version: @PACKAGE_VERSION@
+Section: base
+Priority: optional
+Architecture: all
+Depends: wok,
+ python-imaging,
+ python-configobj,
+ websockify,
+ novnc,
+ python-jsonschema (>= 1.3.0),
+ python-libvirt,
+ gettext,
+ libvirt-bin,
+ nfs-common,
+ qemu-kvm,
+ python-parted,
+ python-psutil (>= 0.6.0),
+ python-ethtool,
+ sosreport,
+ python-ipaddr,
+ python-lxml,
+ open-iscsi,
+ python-guestfs,
+ libguestfs-tools,
+ spice-html5
+Build-Depends: libxslt,
+ python-lxml
+Maintainer: Aline Manera <alinefm(a)br.ibm.com>
+Description: Kimchi web application
diff --git a/src/wok/plugins/kimchi/contrib/Makefile.am
b/src/wok/plugins/kimchi/contrib/Makefile.am
new file mode 100644
index 0000000..5001191
--- /dev/null
+++ b/src/wok/plugins/kimchi/contrib/Makefile.am
@@ -0,0 +1,34 @@
+# Copyright IBM Corp, 2013
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+SUBDIRS = DEBIAN
+
+EXTRA_DIST = \
+ check_i18n.py \
+ kimchi.spec.fedora.in \
+ make-deb.sh.in \
+ $(NULL)
+
+make-deb.sh: make-deb.sh.in $(top_builddir)/config.status
+ $(AM_V_GEN)sed \
+ -e 's|[@]PACKAGE_VERSION[@]|$(PACKAGE_VERSION)|g' \
+ -e 's|[@]PACKAGE_RELEASE[@]|$(PACKAGE_RELEASE)|g' \
+ < $< > $@-t && \
+ chmod a+x $@-t && \
+ mv $@-t $@
+BUILT_SOURCES = make-deb.sh
+
+CLEANFILES = kimchi.spec.fedora kimchi.spec.suse kimchi.spec make-deb.sh
diff --git a/src/wok/plugins/kimchi/contrib/check_i18n.py
b/src/wok/plugins/kimchi/contrib/check_i18n.py
new file mode 100755
index 0000000..6a2603c
--- /dev/null
+++ b/src/wok/plugins/kimchi/contrib/check_i18n.py
@@ -0,0 +1,82 @@
+#!/usr/bin/env python2
+#
+# Project Kimchi
+#
+# Copyright IBM, Corp. 2014-2015
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+import imp
+import os
+import re
+import sys
+
+
+# Match all conversion specifier with mapping key
+PATTERN = re.compile(r'''%\([^)]+\) # Mapping key
+ [#0\-+]? # Conversion flags (optional)
+ (\d+|\*)? # Minimum field width (optional)
+ (\.(\d+|\*))? # Precision (optional)
+ [lLh]? # Length modifier (optional)
+ [cdeEfFgGioursxX%] # Conversion type''',
+ re.VERBOSE)
+BAD_PATTERN = re.compile(r"%\([^)]*?\)")
+
+
+def load_i18n_module(i18nfile):
+ path = os.path.dirname(i18nfile)
+ mname = i18nfile.replace("/", "_").rstrip(".py")
+ mobj = imp.find_module("i18n", [path])
+ return imp.load_module(mname, *mobj)
+
+
+def check_string_formatting(messages):
+ for k, v in messages.iteritems():
+ if BAD_PATTERN.findall(PATTERN.sub(" ", v)):
+ print "bad i18n string formatting:"
+ print " %s: %s" % (k, v)
+ exit(1)
+
+
+def check_obsolete_messages(path, messages):
+ def find_message_key(path, k):
+ for root, dirs, files in os.walk(path):
+ for f in files:
+ fname = os.path.join(root, f)
+ if (not fname.endswith("i18n.py") and
fname.endswith(".py") or
+ fname.endswith(".json")):
+ with open(fname) as f:
+ string = "".join(f.readlines())
+ if k in string:
+ return True
+ return False
+
+ for k in messages.iterkeys():
+ if not find_message_key(path, k):
+ print " %s is obsolete, it is no longer in use" % k
+ exit(1)
+
+
+def main():
+ print "Checking for invalid i18n string..."
+ for f in sys.argv[1:]:
+ messages = load_i18n_module(f).messages
+ check_string_formatting(messages)
+ check_obsolete_messages(os.path.dirname(f), messages)
+ print "Checking for invalid i18n string successfully"
+
+
+if __name__ == '__main__':
+ main()
diff --git a/src/wok/plugins/kimchi/contrib/kimchi.spec.fedora.in
b/src/wok/plugins/kimchi/contrib/kimchi.spec.fedora.in
new file mode 100644
index 0000000..0db3d7e
--- /dev/null
+++ b/src/wok/plugins/kimchi/contrib/kimchi.spec.fedora.in
@@ -0,0 +1,119 @@
+Name: kimchi
+Version: @PACKAGE_VERSION@
+Release: @PACKAGE_RELEASE@%{?dist}
+Summary: Kimchi server application
+BuildRoot: %{_topdir}/BUILD/%{name}-%{version}-%{release}
+BuildArch: noarch
+Group: System Environment/Base
+License: LGPL/ASL2
+Source0: %{name}-%{version}.tar.gz
+Requires: wok
+Requires: qemu-kvm
+Requires: gettext
+Requires: libvirt
+Requires: libvirt-python
+Requires: libvirt-daemon-config-network
+Requires: python-websockify
+Requires: python-configobj
+Requires: novnc
+Requires: python-imaging
+Requires: pyparted
+Requires: python-psutil >= 0.6.0
+Requires: python-jsonschema >= 1.3.0
+Requires: python-ethtool
+Requires: sos
+Requires: python-ipaddr
+Requires: python-lxml
+Requires: nfs-utils
+Requires: iscsi-initiator-utils
+Requires: python-libguestfs
+Requires: libguestfs-tools
+BuildRequires: libxslt
+BuildRequires: python-lxml
+
+%if 0%{?rhel} >= 6 || 0%{?fedora} >= 19
+Requires: spice-html5
+%endif
+
+%if 0%{?fedora} >= 15 || 0%{?rhel} >= 7
+%global with_systemd 1
+%endif
+
+%if 0%{?rhel} == 6
+Requires: python-ordereddict
+Requires: python-imaging
+BuildRequires: python-unittest2
+%endif
+
+%description
+Web application to manage KVM/Qemu virtual machines
+
+
+%prep
+%setup
+
+
+%build
+%if 0%{?rhel} >= 6 || 0%{?fedora} >= 19
+%configure
+%else
+%configure --with-spice-html5
+%endif
+make
+
+
+%install
+rm -rf %{buildroot}
+make DESTDIR=%{buildroot} install
+
+
+%clean
+rm -rf $RPM_BUILD_ROOT
+
+%files
+%attr(-,root,root)
+%{python_sitelib}/wok/plugins/kimchi/*.py*
+%{python_sitelib}/wok/plugins/kimchi/control/*.py*
+%{python_sitelib}/wok/plugins/kimchi/control/vm/*.py*
+%{python_sitelib}/wok/plugins/kimchi/model/*.py*
+%{python_sitelib}/wok/plugins/kimchi/API.json
+%{python_sitelib}/wok/plugins/kimchi/
+%{_datadir}/kimchi/doc/API.md
+%{_datadir}/kimchi/doc/README.md
+%{_datadir}/kimchi/doc/README-federation.md
+%{_datadir}/kimchi/doc/kimchi-guest.png
+%{_datadir}/kimchi/doc/kimchi-templates.png
+%{_prefix}/share/locale/*/LC_MESSAGES/kimchi.mo
+%{_datadir}/wok/plugins/kimchi/ui/config/*.xml
+%{_datadir}/wok/plugins/kimchi/ui/
+%{_datadir}/wok/plugins/kimchi
+%{_sysconfdir}/wok/plugins.d/kimchi.conf
+%{_sysconfdir}/wok/plugins.d/template.conf
+%{_sysconfdir}/kimchi/distros.d/debian.json
+%{_sysconfdir}/kimchi/distros.d/fedora.json
+%{_sysconfdir}/kimchi/distros.d/opensuse.json
+%{_sysconfdir}/kimchi/distros.d/ubuntu.json
+%{_sysconfdir}/kimchi/distros.d/gentoo.json
+%{_sysconfdir}/kimchi/
+%{_sharedstatedir}/kimchi/debugreports/
+%{_sharedstatedir}/kimchi/isos/
+%{_sharedstatedir}/kimchi/screenshots/
+%{_sharedstatedir}/kimchi/vnc-tokens/
+%{_sharedstatedir}/kimchi/
+
+
+%changelog
+* Thu Jun 18 2015 Lucio Correia <luciojhc(a)linux.vnet.ibm.com> 1.6
+- Run kimchi as a plugin
+
+* Thu Feb 26 2015 Fr��d��ric Bonnard <frediz(a)linux.vnet.ibm.com> 1.4.0
+- Add man page for kimchid
+
+* Tue Feb 11 2014 Cr��stian Viana <vianac(a)linux.vnet.ibm.com> 1.1.0
+- Add help pages and XSLT dependency
+
+* Tue Jul 16 2013 Adam Litke <agl(a)us.ibm.com> 0.1.0-1
+- Adapted for autotools build
+
+* Thu Apr 04 2013 Aline Manera <alinefm(a)br.ibm.com> 0.0-1
+- First build
diff --git a/src/wok/plugins/kimchi/contrib/kimchi.spec.suse.in
b/src/wok/plugins/kimchi/contrib/kimchi.spec.suse.in
new file mode 100644
index 0000000..e466961
--- /dev/null
+++ b/src/wok/plugins/kimchi/contrib/kimchi.spec.suse.in
@@ -0,0 +1,107 @@
+Name: kimchi
+Version: @PACKAGE_VERSION@
+Release: @PACKAGE_RELEASE@%{?dist}
+Summary: Kimchi server application
+BuildRoot: %{_topdir}/BUILD/%{name}-%{version}-%{release}
+BuildArch: noarch
+Group: System Environment/Base
+License: LGPL/ASL2
+Source0: %{name}-%{version}.tar.gz
+Requires: wok
+Requires: kvm
+Requires: gettext-tools
+Requires: libvirt
+Requires: libvirt-python
+Requires: libvirt-daemon-config-network
+Requires: python-websockify
+Requires: python-configobj
+Requires: novnc
+Requires: python-imaging
+Requires: python-parted
+Requires: python-psutil >= 0.6.0
+Requires: python-jsonschema >= 1.3.0
+Requires: python-ethtool
+Requires: python-ipaddr
+Requires: python-lxml
+Requires: python-xml
+Requires: nfs-client
+Requires: open-iscsi
+Requires: python-libguestfs
+Requires: guestfs-tools
+BuildRequires: libxslt-tools
+BuildRequires: python-lxml
+
+%if 0%{?suse_version} == 1100
+Requires: python-ordereddict
+%endif
+
+%if 0%{?suse_version} > 1140
+%global with_systemd 1
+%endif
+
+%description
+Web application to manage KVM/Qemu virtual machines
+
+%prep
+%setup
+
+%build
+%configure --with-spice-html5
+make
+
+%install
+rm -rf %{buildroot}
+make DESTDIR=%{buildroot} install
+
+
+%clean
+rm -rf $RPM_BUILD_ROOT
+
+%files
+%attr(-,root,root)
+%{python_sitelib}/wok/plugins/kimchi/*.py*
+%{python_sitelib}/wok/plugins/kimchi/control/*.py*
+%{python_sitelib}/wok/plugins/kimchi/control/vm/*.py*
+%{python_sitelib}/wok/plugins/kimchi/model/*.py*
+%{python_sitelib}/wok/plugins/kimchi/API.json
+%{python_sitelib}/wok/plugins/kimchi/
+%{_datadir}/kimchi/doc/API.md
+%{_datadir}/kimchi/doc/README.md
+%{_datadir}/kimchi/doc/README-federation.md
+%{_datadir}/kimchi/doc/kimchi-guest.png
+%{_datadir}/kimchi/doc/kimchi-templates.png
+%{_prefix}/share/locale/*/LC_MESSAGES/kimchi.mo
+%{_datadir}/wok/plugins/kimchi/ui/config/*.xml
+%{_datadir}/wok/plugins/kimchi/ui/
+%{_datadir}/wok/plugins/kimchi
+%{_sysconfdir}/wok/plugins.d/kimchi.conf
+%{_sysconfdir}/wok/plugins.d/template.conf
+%{_sysconfdir}/kimchi/distros.d/debian.json
+%{_sysconfdir}/kimchi/distros.d/fedora.json
+%{_sysconfdir}/kimchi/distros.d/opensuse.json
+%{_sysconfdir}/kimchi/distros.d/ubuntu.json
+%{_sysconfdir}/kimchi/distros.d/gentoo.json
+%{_sysconfdir}/kimchi/
+%{_var}/lib/kimchi/debugreports/
+%{_var}/lib/kimchi/isos/
+%{_var}/lib/kimchi/screenshots/
+%{_var}/lib/kimchi/vnc-tokens/
+%{_var}/lib/kimchi/
+
+
+%changelog
+* Thu Jun 18 2015 Lucio Correia <luciojhc(a)linux.vnet.ibm.com> 1.6
+- Run kimchi as a plugin
+
+* Thu Feb 26 2015 Fr��d��ric Bonnard <frediz(a)linux.vnet.ibm.com> 1.4.0
+- Add man page for kimchid
+
+* Tue Feb 11 2014 Cr��stian Viana <vianac(a)linux.vnet.ibm.com> 1.1.0
+- Add help pages and XSLT dependency
+
+* Thu Jul 18 2013 Adam Litke <agl(a)us.ibm.com> 0.1.0-1
+- Adapted for autotools build
+- Split Suse and Fedora spec files
+
+* Thu Apr 04 2013 Aline Manera <alinefm(a)br.ibm.com> 0.0-1
+- First build
diff --git a/src/wok/plugins/kimchi/contrib/make-deb.sh.in
b/src/wok/plugins/kimchi/contrib/make-deb.sh.in
new file mode 100644
index 0000000..5a6e56a
--- /dev/null
+++ b/src/wok/plugins/kimchi/contrib/make-deb.sh.in
@@ -0,0 +1,15 @@
+#!/bin/bash
+
+VERSION="@PACKAGE_VERSION@"
+RELEASE="@PACKAGE_RELEASE@"
+
+if [ ! -f configure ]; then
+ echo "Please run this script from the top of the package tree"
+ exit 1
+fi
+
+TMPDIR=`mktemp -d`
+
+make DESTDIR=$TMPDIR install-deb
+dpkg-deb -b $TMPDIR kimchi-${VERSION}-${RELEASE}.noarch.deb
+rm -rf $TMPDIR
diff --git a/src/wok/plugins/kimchi/control/Makefile.am
b/src/wok/plugins/kimchi/control/Makefile.am
new file mode 100644
index 0000000..33118ca
--- /dev/null
+++ b/src/wok/plugins/kimchi/control/Makefile.am
@@ -0,0 +1,27 @@
+#
+# Kimchi
+#
+# Copyright IBM Corp, 2013
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+SUBDIRS = vm
+
+control_PYTHON = *.py
+
+controldir = $(pythondir)/wok/plugins/kimchi/control
+
+install-data-local:
+ $(MKDIR_P) $(DESTDIR)$(controldir)
diff --git a/src/wok/plugins/kimchi/control/__init__.py
b/src/wok/plugins/kimchi/control/__init__.py
new file mode 100644
index 0000000..4ad9459
--- /dev/null
+++ b/src/wok/plugins/kimchi/control/__init__.py
@@ -0,0 +1,26 @@
+#
+# Project Kimchi
+#
+# Copyright IBM, Corp. 2013-2014
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+import os
+
+
+from wok.control.utils import load_url_sub_node
+
+
+sub_nodes = load_url_sub_node(os.path.dirname(__file__), __name__)
diff --git a/src/wok/plugins/kimchi/control/config.py
b/src/wok/plugins/kimchi/control/config.py
new file mode 100644
index 0000000..15df68f
--- /dev/null
+++ b/src/wok/plugins/kimchi/control/config.py
@@ -0,0 +1,57 @@
+#
+# Project Kimchi
+#
+# Copyright IBM, Corp. 2013-2014
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+from wok.control.base import Collection, Resource
+from wok.control.utils import UrlSubNode
+
+
+@UrlSubNode("config")
+class Config(Resource):
+ def __init__(self, model, id=None):
+ super(Config, self).__init__(model, id)
+ self.capabilities = Capabilities(self.model)
+ self.distros = Distros(model)
+
+ @property
+ def data(self):
+ return self.info
+
+
+class Capabilities(Resource):
+ def __init__(self, model, id=None):
+ super(Capabilities, self).__init__(model, id)
+
+ @property
+ def data(self):
+ return self.info
+
+
+class Distros(Collection):
+ def __init__(self, model):
+ super(Distros, self).__init__(model)
+ self.resource = Distro
+
+
+class Distro(Resource):
+ def __init__(self, model, ident):
+ super(Distro, self).__init__(model, ident)
+
+ @property
+ def data(self):
+ return self.info
diff --git a/src/wok/plugins/kimchi/control/cpuinfo.py
b/src/wok/plugins/kimchi/control/cpuinfo.py
new file mode 100644
index 0000000..31f316c
--- /dev/null
+++ b/src/wok/plugins/kimchi/control/cpuinfo.py
@@ -0,0 +1,37 @@
+#
+# Project Kimchi
+#
+# Copyright IBM, Corp. 2014
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+
+from wok.control.base import Resource
+
+
+class CPUInfo(Resource):
+ def __init__(self, model):
+ super(CPUInfo, self).__init__(model)
+ self.admin_methods = ['GET']
+ self.role_key = 'host'
+ self.uri_fmt = "/host/cpuinfo"
+
+ @property
+ def data(self):
+ return {'threading_enabled': self.info['guest_threads_enabled'],
+ 'sockets': self.info['sockets'],
+ 'cores': self.info['cores_available'],
+ 'threads_per_core': self.info['threads_per_core']
+ }
diff --git a/src/wok/plugins/kimchi/control/debugreports.py
b/src/wok/plugins/kimchi/control/debugreports.py
new file mode 100644
index 0000000..b5a3072
--- /dev/null
+++ b/src/wok/plugins/kimchi/control/debugreports.py
@@ -0,0 +1,61 @@
+#
+# Project Kimchi
+#
+# Copyright IBM, Corp. 2013-2015
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+from wok.control.base import AsyncCollection, Resource
+from wok.control.utils import internal_redirect
+from wok.control.utils import UrlSubNode
+
+
+@UrlSubNode('debugreports', True)
+class DebugReports(AsyncCollection):
+ def __init__(self, model):
+ super(DebugReports, self).__init__(model)
+ self.resource = DebugReport
+ self.role_key = 'host'
+ self.admin_methods = ['GET', 'POST']
+
+ def _get_resources(self, filter_params):
+ res_list = super(DebugReports, self)._get_resources(filter_params)
+ return sorted(res_list, key=lambda x: x.data['time'], reverse=True)
+
+
+class DebugReport(Resource):
+ def __init__(self, model, ident):
+ super(DebugReport, self).__init__(model, ident)
+ self.role_key = 'host'
+ self.admin_methods = ['GET', 'PUT', 'POST']
+ self.uri_fmt = '/debugreports/%s'
+ self.content = DebugReportContent(model, ident)
+
+ @property
+ def data(self):
+ return {'name': self.ident,
+ 'uri': self.info['uri'],
+ 'time': self.info['ctime']}
+
+
+class DebugReportContent(Resource):
+ def __init__(self, model, ident):
+ super(DebugReportContent, self).__init__(model, ident)
+ self.role_key = 'host'
+ self.admin_methods = ['GET']
+
+ def get(self):
+ self.lookup()
+ raise internal_redirect(self.info['uri'])
diff --git a/src/wok/plugins/kimchi/control/groups.py
b/src/wok/plugins/kimchi/control/groups.py
new file mode 100644
index 0000000..649ff09
--- /dev/null
+++ b/src/wok/plugins/kimchi/control/groups.py
@@ -0,0 +1,28 @@
+#
+# Project Kimchi
+#
+# Copyright IBM, Corp. 2013-2014
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+from wok.control.base import SimpleCollection
+from wok.control.utils import UrlSubNode
+
+
+@UrlSubNode('groups', True)
+class Groups(SimpleCollection):
+ def __init__(self, model):
+ super(Groups, self).__init__(model)
+ self.role_key = 'guests'
diff --git a/src/wok/plugins/kimchi/control/host.py
b/src/wok/plugins/kimchi/control/host.py
new file mode 100644
index 0000000..0a40f1b
--- /dev/null
+++ b/src/wok/plugins/kimchi/control/host.py
@@ -0,0 +1,157 @@
+#
+# Project Kimchi
+#
+# Copyright IBM, Corp. 2013-2015
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+from wok.control.base import Collection, Resource, SimpleCollection
+from wok.control.utils import UrlSubNode
+from wok.exception import NotFoundError
+
+from cpuinfo import CPUInfo
+
+
+@UrlSubNode('host', True)
+class Host(Resource):
+ def __init__(self, model, id=None):
+ super(Host, self).__init__(model, id)
+ self.role_key = 'host'
+ self.admin_methods = ['GET', 'POST']
+ self.uri_fmt = '/host/%s'
+ self.reboot = self.generate_action_handler('reboot')
+ self.shutdown = self.generate_action_handler('shutdown')
+ self.stats = HostStats(self.model)
+ self.partitions = Partitions(self.model)
+ self.devices = Devices(self.model)
+ self.packagesupdate = PackagesUpdate(self.model)
+ self.repositories = Repositories(self.model)
+ self.swupdate = self.generate_action_handler_task('swupdate')
+ self.cpuinfo = CPUInfo(self.model)
+
+ @property
+ def data(self):
+ return self.info
+
+
+class HostStats(Resource):
+ def __init__(self, model, id=None):
+ super(HostStats, self).__init__(model, id)
+ self.role_key = 'host'
+ self.admin_methods = ['GET']
+ self.history = HostStatsHistory(self.model)
+
+ @property
+ def data(self):
+ return self.info
+
+
+class HostStatsHistory(Resource):
+ @property
+ def data(self):
+ return self.info
+
+
+class Partitions(Collection):
+ def __init__(self, model):
+ super(Partitions, self).__init__(model)
+ self.role_key = 'storage'
+ self.admin_methods = ['GET']
+ self.resource = Partition
+
+ # Defining get_resources in order to return list of partitions in UI
+ # sorted by their path
+ def _get_resources(self, flag_filter):
+ res_list = super(Partitions, self)._get_resources(flag_filter)
+ res_list = filter(lambda x: x.info['available'], res_list)
+ res_list.sort(key=lambda x: x.info['path'])
+ return res_list
+
+
+class Partition(Resource):
+ def __init__(self, model, id):
+ self.role_key = 'storage'
+ self.admin_methods = ['GET']
+ super(Partition, self).__init__(model, id)
+
+ @property
+ def data(self):
+ if not self.info['available']:
+ raise NotFoundError("KCHPART0001E", {'name':
self.info['name']})
+
+ return self.info
+
+
+class Devices(Collection):
+ def __init__(self, model):
+ super(Devices, self).__init__(model)
+ self.resource = Device
+
+
+class VMHolders(SimpleCollection):
+ def __init__(self, model, device_id):
+ super(VMHolders, self).__init__(model)
+ self.model_args = (device_id, )
+
+
+class Device(Resource):
+ def __init__(self, model, id):
+ super(Device, self).__init__(model, id)
+ self.vm_holders = VMHolders(self.model, id)
+
+ @property
+ def data(self):
+ return self.info
+
+
+class PackagesUpdate(Collection):
+ def __init__(self, model):
+ super(PackagesUpdate, self).__init__(model)
+ self.role_key = 'host'
+ self.admin_methods = ['GET']
+ self.resource = PackageUpdate
+
+
+class PackageUpdate(Resource):
+ def __init__(self, model, id=None):
+ super(PackageUpdate, self).__init__(model, id)
+ self.role_key = 'host'
+ self.admin_methods = ['GET']
+
+ @property
+ def data(self):
+ return self.info
+
+
+class Repositories(Collection):
+ def __init__(self, model):
+ super(Repositories, self).__init__(model)
+ self.role_key = 'host'
+ self.admin_methods = ['GET', 'POST']
+ self.resource = Repository
+
+
+class Repository(Resource):
+ def __init__(self, model, id):
+ super(Repository, self).__init__(model, id)
+ self.role_key = 'host'
+ self.admin_methods = ['GET', 'PUT', 'POST',
'DELETE']
+ self.uri_fmt = "/host/repositories/%s"
+ self.enable = self.generate_action_handler('enable')
+ self.disable = self.generate_action_handler('disable')
+
+ @property
+ def data(self):
+ return self.info
diff --git a/src/wok/plugins/kimchi/control/interfaces.py
b/src/wok/plugins/kimchi/control/interfaces.py
new file mode 100644
index 0000000..d698b7a
--- /dev/null
+++ b/src/wok/plugins/kimchi/control/interfaces.py
@@ -0,0 +1,46 @@
+#
+# Project Kimchi
+#
+# Copyright IBM, Corp. 2013-2014
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+from wok.control.base import Collection, Resource
+from wok.control.utils import UrlSubNode
+
+
+@UrlSubNode('interfaces', True)
+class Interfaces(Collection):
+ def __init__(self, model):
+ super(Interfaces, self).__init__(model)
+ self.role_key = 'network'
+ self.admin_methods = ['GET']
+ self.resource = Interface
+
+
+class Interface(Resource):
+ def __init__(self, model, ident):
+ super(Interface, self).__init__(model, ident)
+ self.role_key = 'network'
+ self.admin_methods = ['GET']
+ self.uri_fmt = "/interfaces/%s"
+
+ @property
+ def data(self):
+ return {'name': self.ident,
+ 'type': self.info['type'],
+ 'ipaddr': self.info['ipaddr'],
+ 'netmask': self.info['netmask'],
+ 'status': self.info['status']}
diff --git a/src/wok/plugins/kimchi/control/networks.py
b/src/wok/plugins/kimchi/control/networks.py
new file mode 100644
index 0000000..fd92111
--- /dev/null
+++ b/src/wok/plugins/kimchi/control/networks.py
@@ -0,0 +1,54 @@
+#
+# Project Kimchi
+#
+# Copyright IBM, Corp. 2013-2015
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+from wok.control.base import Collection, Resource
+from wok.control.utils import UrlSubNode
+
+
+@UrlSubNode('networks', True)
+class Networks(Collection):
+ def __init__(self, model):
+ super(Networks, self).__init__(model)
+ self.role_key = 'network'
+ self.admin_methods = ['POST']
+ self.resource = Network
+
+
+class Network(Resource):
+ def __init__(self, model, ident):
+ super(Network, self).__init__(model, ident)
+ self.role_key = 'network'
+ self.admin_methods = ['PUT', 'POST', 'DELETE']
+ self.uri_fmt = "/networks/%s"
+ self.activate = self.generate_action_handler('activate')
+ self.deactivate = self.generate_action_handler('deactivate',
+ destructive=True)
+
+ @property
+ def data(self):
+ return {'name': self.ident,
+ 'vms': self.info['vms'],
+ 'in_use': self.info['in_use'],
+ 'autostart': self.info['autostart'],
+ 'connection': self.info['connection'],
+ 'interface': self.info['interface'],
+ 'subnet': self.info['subnet'],
+ 'dhcp': self.info['dhcp'],
+ 'state': self.info['state'],
+ 'persistent': self.info['persistent']}
diff --git a/src/wok/plugins/kimchi/control/peers.py
b/src/wok/plugins/kimchi/control/peers.py
new file mode 100644
index 0000000..21e9f13
--- /dev/null
+++ b/src/wok/plugins/kimchi/control/peers.py
@@ -0,0 +1,29 @@
+#
+# Project Kimchi
+#
+# Copyright IBM, Corp. 2014
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+from wok.control.base import SimpleCollection
+from wok.control.utils import UrlSubNode
+
+
+@UrlSubNode("peers", True)
+class Peers(SimpleCollection):
+ def __init__(self, model):
+ super(Peers, self).__init__(model)
+ self.role_key = 'peers'
+ self.admin_methods = ['GET']
diff --git a/src/wok/plugins/kimchi/control/storagepools.py
b/src/wok/plugins/kimchi/control/storagepools.py
new file mode 100644
index 0000000..e5f264e
--- /dev/null
+++ b/src/wok/plugins/kimchi/control/storagepools.py
@@ -0,0 +1,116 @@
+#
+# Project Kimchi
+#
+# Copyright IBM, Corp. 2013-2015
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+import cherrypy
+
+from wok.control.base import Collection, Resource
+from wok.control.utils import get_class_name, model_fn
+from wok.control.utils import validate_params
+from wok.control.utils import UrlSubNode
+
+from ..model.storagepools import ISO_POOL_NAME
+from storagevolumes import IsoVolumes, StorageVolumes
+
+
+@UrlSubNode('storagepools', True)
+class StoragePools(Collection):
+ def __init__(self, model):
+ super(StoragePools, self).__init__(model)
+ self.role_key = 'storage'
+ self.admin_methods = ['POST']
+ self.resource = StoragePool
+ isos = IsoPool(model)
+ setattr(self, ISO_POOL_NAME, isos)
+
+ def create(self, params, *args):
+ try:
+ create = getattr(self.model, model_fn(self, 'create'))
+ except AttributeError:
+ error = 'Create is not allowed for %s' % get_class_name(self)
+ raise cherrypy.HTTPError(405, error)
+
+ validate_params(params, self, 'create')
+ args = self.model_args + [params]
+ name = create(*args)
+ args = self.resource_args + [name]
+ res = self.resource(self.model, *args)
+ resp = res.get()
+
+ if 'task_id' in res.data:
+ cherrypy.response.status = 202
+ else:
+ cherrypy.response.status = 201
+
+ return resp
+
+ def _get_resources(self, filter_params):
+ try:
+ res_list = super(StoragePools, self)._get_resources(filter_params)
+ # Append reserved pools
+ isos = getattr(self, ISO_POOL_NAME)
+ isos.lookup()
+ res_list.append(isos)
+ except AttributeError:
+ pass
+
+ return res_list
+
+
+class StoragePool(Resource):
+ def __init__(self, model, ident):
+ super(StoragePool, self).__init__(model, ident)
+ self.role_key = 'storage'
+ self.admin_methods = ['PUT', 'POST', 'DELETE']
+ self.uri_fmt = "/storagepools/%s"
+ self.activate = self.generate_action_handler('activate')
+ self.deactivate = self.generate_action_handler('deactivate',
+ destructive=True)
+ self.storagevolumes = StorageVolumes(self.model, ident)
+
+ @property
+ def data(self):
+ res = {'name': self.ident,
+ 'state': self.info['state'],
+ 'capacity': self.info['capacity'],
+ 'allocated': self.info['allocated'],
+ 'available': self.info['available'],
+ 'path': self.info['path'],
+ 'source': self.info['source'],
+ 'type': self.info['type'],
+ 'nr_volumes': self.info['nr_volumes'],
+ 'autostart': self.info['autostart'],
+ 'persistent': self.info['persistent']}
+
+ val = self.info.get('task_id')
+ if val:
+ res['task_id'] = val
+
+ return res
+
+
+class IsoPool(Resource):
+ def __init__(self, model):
+ super(IsoPool, self).__init__(model, ISO_POOL_NAME)
+ self.storagevolumes = IsoVolumes(self.model, ISO_POOL_NAME)
+
+ @property
+ def data(self):
+ return {'name': self.ident,
+ 'state': self.info['state'],
+ 'type': self.info['type']}
diff --git a/src/wok/plugins/kimchi/control/storageservers.py
b/src/wok/plugins/kimchi/control/storageservers.py
new file mode 100644
index 0000000..654ab47
--- /dev/null
+++ b/src/wok/plugins/kimchi/control/storageservers.py
@@ -0,0 +1,60 @@
+#
+# Project Kimchi
+#
+# Copyright IBM, Corp. 2014
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+from wok import template
+from wok.control.base import Collection, Resource
+from wok.control.utils import get_class_name, model_fn, UrlSubNode
+
+
+@UrlSubNode('storageservers', True)
+class StorageServers(Collection):
+ def __init__(self, model):
+ super(StorageServers, self).__init__(model)
+ self.role_key = 'storage'
+ self.admin_methods = ['GET']
+ self.resource = StorageServer
+
+
+class StorageServer(Resource):
+ def __init__(self, model, ident):
+ super(StorageServer, self).__init__(model, ident)
+ self.role_key = 'storage'
+ self.admin_methods = ['GET']
+ self.storagetargets = StorageTargets(self.model,
+ self.ident.decode("utf-8"))
+
+ @property
+ def data(self):
+ return self.info
+
+
+class StorageTargets(Collection):
+ def __init__(self, model, server):
+ super(StorageTargets, self).__init__(model)
+ self.role_key = 'storage'
+ self.admin_methods = ['GET']
+ self.server = server
+ self.resource_args = [self.server, ]
+ self.model_args = [self.server, ]
+
+ def get(self, filter_params):
+ res_list = []
+ get_list = getattr(self.model, model_fn(self, 'get_list'))
+ res_list = get_list(*self.model_args, **filter_params)
+ return template.render(get_class_name(self), res_list)
diff --git a/src/wok/plugins/kimchi/control/storagevolumes.py
b/src/wok/plugins/kimchi/control/storagevolumes.py
new file mode 100644
index 0000000..bbe6627
--- /dev/null
+++ b/src/wok/plugins/kimchi/control/storagevolumes.py
@@ -0,0 +1,83 @@
+#
+# Project Kimchi
+#
+# Copyright IBM, Corp. 2013-2015
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+from wok import template
+from wok.control.base import AsyncCollection, Collection, Resource
+from wok.control.utils import get_class_name, model_fn
+
+
+class StorageVolumes(AsyncCollection):
+ def __init__(self, model, pool):
+ super(StorageVolumes, self).__init__(model)
+ self.resource = StorageVolume
+ self.pool = pool
+ self.resource_args = [self.pool, ]
+ self.model_args = [self.pool, ]
+
+ def filter_data(self, resources, fields_filter):
+ # filter directory from storage volumes
+ fields_filter.update({'type': ['file', 'block',
'network']})
+ return super(StorageVolumes, self).filter_data(resources,
+ fields_filter)
+
+
+class StorageVolume(Resource):
+ def __init__(self, model, pool, ident):
+ super(StorageVolume, self).__init__(model, ident)
+ self.pool = pool
+ self.ident = ident
+ self.info = {}
+ self.model_args = [self.pool, self.ident]
+ self.uri_fmt = '/storagepools/%s/storagevolumes/%s'
+ self.resize = self.generate_action_handler('resize', ['size'])
+ self.wipe = self.generate_action_handler('wipe')
+ self.clone = self.generate_action_handler_task('clone')
+
+ @property
+ def data(self):
+ res = {'name': self.ident,
+ 'type': self.info['type'],
+ 'capacity': self.info['capacity'],
+ 'allocation': self.info['allocation'],
+ 'path': self.info['path'],
+ 'used_by': self.info['used_by'],
+ 'format': self.info['format']}
+
+ for key in ('os_version', 'os_distro', 'bootable',
'base'):
+ val = self.info.get(key)
+ if val:
+ res[key] = val
+
+ return res
+
+
+class IsoVolumes(Collection):
+ def __init__(self, model, pool):
+ super(IsoVolumes, self).__init__(model)
+ self.pool = pool
+
+ def get(self, filter_params):
+ res_list = []
+ try:
+ get_list = getattr(self.model, model_fn(self, 'get_list'))
+ res_list = get_list(*self.model_args)
+ except AttributeError:
+ pass
+
+ return template.render(get_class_name(self), res_list)
diff --git a/src/wok/plugins/kimchi/control/templates.py
b/src/wok/plugins/kimchi/control/templates.py
new file mode 100644
index 0000000..fc58815
--- /dev/null
+++ b/src/wok/plugins/kimchi/control/templates.py
@@ -0,0 +1,58 @@
+#
+# Project Kimchi
+#
+# Copyright IBM, Corp. 2013-2015
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+from wok.control.base import Collection, Resource
+from wok.control.utils import UrlSubNode
+
+
+@UrlSubNode('templates', True)
+class Templates(Collection):
+ def __init__(self, model):
+ super(Templates, self).__init__(model)
+ self.role_key = 'templates'
+ self.admin_methods = ['GET', 'POST']
+ self.resource = Template
+
+
+class Template(Resource):
+ def __init__(self, model, ident):
+ super(Template, self).__init__(model, ident)
+ self.role_key = 'templates'
+ self.admin_methods = ['PUT', 'POST', 'DELETE']
+ self.uri_fmt = "/templates/%s"
+ self.clone = self.generate_action_handler('clone')
+
+ @property
+ def data(self):
+ return {
+ 'name': self.ident,
+ 'icon': self.info['icon'],
+ 'invalid': self.info['invalid'],
+ 'os_distro': self.info['os_distro'],
+ 'os_version': self.info['os_version'],
+ 'cpus': self.info['cpus'],
+ 'memory': self.info['memory'],
+ 'cdrom': self.info.get('cdrom', None),
+ 'disks': self.info['disks'],
+ 'storagepool': self.info['storagepool'],
+ 'networks': self.info['networks'],
+ 'folder': self.info.get('folder', []),
+ 'graphics': self.info['graphics'],
+ 'cpu_info': self.info.get('cpu_info')
+ }
diff --git a/src/wok/plugins/kimchi/control/users.py
b/src/wok/plugins/kimchi/control/users.py
new file mode 100644
index 0000000..756a2f7
--- /dev/null
+++ b/src/wok/plugins/kimchi/control/users.py
@@ -0,0 +1,35 @@
+#
+# Project Kimchi
+#
+# Copyright IBM, Corp. 2013-2014
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+from wok.control.base import SimpleCollection
+from wok.control.utils import get_class_name, model_fn, UrlSubNode
+from wok.template import render
+
+
+@UrlSubNode('users', True)
+class Users(SimpleCollection):
+ def __init__(self, model):
+ super(Users, self).__init__(model)
+ self.role_key = 'guests'
+
+ def get(self, filter_params):
+ res_list = []
+ get_list = getattr(self.model, model_fn(self, 'get_list'))
+ res_list = get_list(*self.model_args, **filter_params)
+ return render(get_class_name(self), res_list)
diff --git a/src/wok/plugins/kimchi/control/vm/Makefile.am
b/src/wok/plugins/kimchi/control/vm/Makefile.am
new file mode 100644
index 0000000..b17c68a
--- /dev/null
+++ b/src/wok/plugins/kimchi/control/vm/Makefile.am
@@ -0,0 +1,26 @@
+#
+# Kimchi
+#
+# Copyright IBM Corp, 2013
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+
+vm_PYTHON = *.py
+
+vmdir = $(pythondir)/wok/plugins/kimchi/control/vm
+
+install-data-local:
+ $(MKDIR_P) $(DESTDIR)$(vmdir)
diff --git a/src/wok/plugins/kimchi/control/vm/__init__.py
b/src/wok/plugins/kimchi/control/vm/__init__.py
new file mode 100644
index 0000000..a311045
--- /dev/null
+++ b/src/wok/plugins/kimchi/control/vm/__init__.py
@@ -0,0 +1,26 @@
+#
+# Project Kimchi
+#
+# Copyright IBM, Corp. 2014
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+import os
+
+
+from wok.control.utils import load_url_sub_node
+
+
+sub_nodes = load_url_sub_node(os.path.dirname(__file__), __name__)
diff --git a/src/wok/plugins/kimchi/control/vm/hostdevs.py
b/src/wok/plugins/kimchi/control/vm/hostdevs.py
new file mode 100644
index 0000000..a43b9d8
--- /dev/null
+++ b/src/wok/plugins/kimchi/control/vm/hostdevs.py
@@ -0,0 +1,43 @@
+#
+# Project Kimchi
+#
+# Copyright IBM, Corp. 2014
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+from wok.control.base import Collection, Resource
+from wok.control.utils import UrlSubNode
+
+
+@UrlSubNode("hostdevs")
+class VMHostDevs(Collection):
+ def __init__(self, model, vmid):
+ super(VMHostDevs, self).__init__(model)
+ self.resource = VMHostDev
+ self.vmid = vmid
+ self.resource_args = [self.vmid, ]
+ self.model_args = [self.vmid, ]
+
+
+class VMHostDev(Resource):
+ def __init__(self, model, vmid, ident):
+ super(VMHostDev, self).__init__(model, ident)
+ self.vmid = vmid
+ self.ident = ident
+ self.model_args = [self.vmid, self.ident]
+
+ @property
+ def data(self):
+ return self.info
diff --git a/src/wok/plugins/kimchi/control/vm/ifaces.py
b/src/wok/plugins/kimchi/control/vm/ifaces.py
new file mode 100644
index 0000000..ac957fd
--- /dev/null
+++ b/src/wok/plugins/kimchi/control/vm/ifaces.py
@@ -0,0 +1,45 @@
+#
+# Project Kimchi
+#
+# Copyright IBM, Corp. 2014-2015
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+from wok.control.base import Collection, Resource
+from wok.control.utils import UrlSubNode
+
+
+@UrlSubNode("ifaces")
+class VMIfaces(Collection):
+ def __init__(self, model, vm):
+ super(VMIfaces, self).__init__(model)
+ self.resource = VMIface
+ self.vm = vm
+ self.resource_args = [self.vm, ]
+ self.model_args = [self.vm, ]
+
+
+class VMIface(Resource):
+ def __init__(self, model, vm, ident):
+ super(VMIface, self).__init__(model, ident)
+ self.vm = vm
+ self.ident = ident
+ self.info = {}
+ self.model_args = [self.vm, self.ident]
+ self.uri_fmt = '/vms/%s/ifaces/%s'
+
+ @property
+ def data(self):
+ return self.info
diff --git a/src/wok/plugins/kimchi/control/vm/snapshots.py
b/src/wok/plugins/kimchi/control/vm/snapshots.py
new file mode 100644
index 0000000..dd17b85
--- /dev/null
+++ b/src/wok/plugins/kimchi/control/vm/snapshots.py
@@ -0,0 +1,58 @@
+#
+# Project Kimchi
+#
+# Copyright IBM, Corp. 2014
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+from wok.control.base import AsyncCollection, Resource
+from wok.control.utils import UrlSubNode
+
+
+@UrlSubNode('snapshots')
+class VMSnapshots(AsyncCollection):
+ def __init__(self, model, vm):
+ super(VMSnapshots, self).__init__(model)
+ self.resource = VMSnapshot
+ self.vm = vm
+ self.resource_args = [self.vm, ]
+ self.model_args = [self.vm, ]
+ self.current = CurrentVMSnapshot(model, vm)
+
+
+class VMSnapshot(Resource):
+ def __init__(self, model, vm, ident):
+ super(VMSnapshot, self).__init__(model, ident)
+ self.vm = vm
+ self.ident = ident
+ self.model_args = [self.vm, self.ident]
+ self.uri_fmt = '/vms/%s/snapshots/%s'
+ self.revert = self.generate_action_handler('revert')
+
+ @property
+ def data(self):
+ return self.info
+
+
+class CurrentVMSnapshot(Resource):
+ def __init__(self, model, vm):
+ super(CurrentVMSnapshot, self).__init__(model)
+ self.vm = vm
+ self.model_args = [self.vm]
+ self.uri_fmt = '/vms/%s/snapshots/current'
+
+ @property
+ def data(self):
+ return self.info
diff --git a/src/wok/plugins/kimchi/control/vm/storages.py
b/src/wok/plugins/kimchi/control/vm/storages.py
new file mode 100644
index 0000000..f502caa
--- /dev/null
+++ b/src/wok/plugins/kimchi/control/vm/storages.py
@@ -0,0 +1,45 @@
+#
+# Project Kimchi
+#
+# Copyright IBM, Corp. 2014-2015
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+from wok.control.base import Collection, Resource
+from wok.control.utils import UrlSubNode
+
+
+@UrlSubNode("storages")
+class VMStorages(Collection):
+ def __init__(self, model, vm):
+ super(VMStorages, self).__init__(model)
+ self.resource = VMStorage
+ self.vm = vm
+ self.resource_args = [self.vm, ]
+ self.model_args = [self.vm, ]
+
+
+class VMStorage(Resource):
+ def __init__(self, model, vm, ident):
+ super(VMStorage, self).__init__(model, ident)
+ self.vm = vm
+ self.ident = ident
+ self.info = {}
+ self.model_args = [self.vm, self.ident]
+ self.uri_fmt = '/vms/%s/storages/%s'
+
+ @property
+ def data(self):
+ return self.info
diff --git a/src/wok/plugins/kimchi/control/vms.py
b/src/wok/plugins/kimchi/control/vms.py
new file mode 100644
index 0000000..858b23c
--- /dev/null
+++ b/src/wok/plugins/kimchi/control/vms.py
@@ -0,0 +1,67 @@
+#
+# Project Kimchi
+#
+# Copyright IBM, Corp. 2013-2015
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+from wok.control.base import AsyncCollection, Resource
+from wok.control.utils import internal_redirect, UrlSubNode
+
+from vm import sub_nodes
+
+
+@UrlSubNode('vms', True)
+class VMs(AsyncCollection):
+ def __init__(self, model):
+ super(VMs, self).__init__(model)
+ self.resource = VM
+ self.role_key = 'guests'
+ self.admin_methods = ['POST']
+
+
+class VM(Resource):
+ def __init__(self, model, ident):
+ super(VM, self).__init__(model, ident)
+ self.role_key = 'guests'
+ self.screenshot = VMScreenShot(model, ident)
+ self.uri_fmt = '/vms/%s'
+ for ident, node in sub_nodes.items():
+ setattr(self, ident, node(model, self.ident))
+ self.start = self.generate_action_handler('start')
+ self.poweroff = self.generate_action_handler('poweroff',
+ destructive=True)
+ self.shutdown = self.generate_action_handler('shutdown',
+ destructive=True)
+ self.reset = self.generate_action_handler('reset',
+ destructive=True)
+ self.connect = self.generate_action_handler('connect')
+ self.clone = self.generate_action_handler_task('clone')
+ self.suspend = self.generate_action_handler('suspend')
+ self.resume = self.generate_action_handler('resume')
+
+ @property
+ def data(self):
+ return self.info
+
+
+class VMScreenShot(Resource):
+ def __init__(self, model, ident):
+ super(VMScreenShot, self).__init__(model, ident)
+ self.role_key = 'guests'
+
+ def get(self):
+ self.lookup()
+ raise internal_redirect(self.info)
diff --git a/src/wok/plugins/kimchi/disks.py b/src/wok/plugins/kimchi/disks.py
new file mode 100644
index 0000000..eb40e3a
--- /dev/null
+++ b/src/wok/plugins/kimchi/disks.py
@@ -0,0 +1,196 @@
+#
+# Project Kimchi
+#
+# Copyright IBM, Corp. 2013-2015
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+import os.path
+import re
+import subprocess
+from parted import Device as PDevice
+from parted import Disk as PDisk
+
+from wok.exception import OperationFailed
+from wok.utils import wok_log
+
+
+def _get_dev_node_path(maj_min):
+ """ Returns device node path given the device number
'major:min' """
+
+ dm_name = "/sys/dev/block/%s/dm/name" % maj_min
+ if os.path.exists(dm_name):
+ with open(dm_name) as dm_f:
+ content = dm_f.read().rstrip('\n')
+ return "/dev/mapper/" + content
+
+ uevent = "/sys/dev/block/%s/uevent" % maj_min
+ with open(uevent) as ueventf:
+ content = ueventf.read()
+
+ data = dict(re.findall(r'(\S+)=(".*?"|\S+)',
content.replace("\n", " ")))
+
+ return "/dev/%s" % data["DEVNAME"]
+
+
+def _get_lsblk_devs(keys, devs=[]):
+ lsblk = subprocess.Popen(
+ ["lsblk", "-Pbo"] + [','.join(keys)] + devs,
+ stdout=subprocess.PIPE, stderr=subprocess.PIPE)
+ out, err = lsblk.communicate()
+ if lsblk.returncode != 0:
+ raise OperationFailed("KCHDISKS0001E", {'err': err})
+
+ return _parse_lsblk_output(out, keys)
+
+
+def _get_dev_major_min(name):
+ maj_min = None
+
+ keys = ["NAME", "MAJ:MIN"]
+ dev_list = _get_lsblk_devs(keys)
+
+ for dev in dev_list:
+ if dev['name'].split()[0] == name:
+ maj_min = dev['maj:min']
+ break
+ else:
+ raise OperationFailed("KCHDISKS0002E", {'device': name})
+
+ return maj_min
+
+
+def _is_dev_leaf(devNodePath):
+ try:
+ # By default, lsblk prints a device information followed by children
+ # device information
+ childrenCount = len(
+ _get_lsblk_devs(["NAME"], [devNodePath])) - 1
+ except OperationFailed as e:
+ # lsblk is known to fail on multipath devices
+ # Assume these devices contain children
+ wok_log.error(
+ "Error getting device info for %s: %s", devNodePath, e)
+ return False
+
+ return childrenCount == 0
+
+
+def _is_dev_extended_partition(devType, devNodePath):
+ if devType != 'part':
+ return False
+ diskPath = devNodePath.rstrip('0123456789')
+ device = PDevice(diskPath)
+ try:
+ extended_part = PDisk(device).getExtendedPartition()
+ except NotImplementedError as e:
+ wok_log.warning(
+ "Error getting extended partition info for dev %s type %s: %s",
+ devNodePath, devType, e.message)
+ # Treate disk with unsupported partiton table as if it does not
+ # contain extended partitions.
+ return False
+ if extended_part and extended_part.path == devNodePath:
+ return True
+ return False
+
+
+def _parse_lsblk_output(output, keys):
+ # output is on format key="value",
+ # where key can be NAME, TYPE, FSTYPE, SIZE, MOUNTPOINT, etc
+ lines = output.rstrip("\n").split("\n")
+ r = []
+ for line in lines:
+ d = {}
+ for key in keys:
+ expression = r"%s=\".*?\"" % key
+ match = re.search(expression, line)
+ field = match.group()
+ k, v = field.split('=', 1)
+ d[k.lower()] = v[1:-1]
+ r.append(d)
+ return r
+
+
+def _get_vgname(devNodePath):
+ """ Return volume group name of a physical volume. If the device node
path
+ is not a physical volume, return empty string. """
+ pvs = subprocess.Popen(
+ ["pvs", "--unbuffered", "--nameprefixes",
"--noheadings",
+ "-o", "vg_name", devNodePath],
+ stdout=subprocess.PIPE, stderr=subprocess.PIPE)
+ out, err = pvs.communicate()
+ if pvs.returncode != 0:
+ return ""
+
+ return re.findall(r"LVM2_VG_NAME='([^\']*)'", out)[0]
+
+
+def _is_available(name, devtype, fstype, mountpoint, majmin):
+ devNodePath = _get_dev_node_path(majmin)
+ # Only list unmounted and unformated and leaf and (partition or disk)
+ # leaf means a partition, a disk has no partition, or a disk not held
+ # by any multipath device. Physical volume belongs to no volume group
+ # is also listed. Extended partitions should not be listed.
+ if (devtype in ['part', 'disk', 'mpath'] and
+ fstype in ['', 'LVM2_member'] and
+ mountpoint == "" and
+ _get_vgname(devNodePath) == "" and
+ _is_dev_leaf(devNodePath) and
+ not _is_dev_extended_partition(devtype, devNodePath)):
+ return True
+ return False
+
+
+def get_partitions_names(check=False):
+ names = set()
+ keys = ["NAME", "TYPE", "FSTYPE",
"MOUNTPOINT", "MAJ:MIN"]
+ # output is on format key="value",
+ # where key can be NAME, TYPE, FSTYPE, MOUNTPOINT
+ for dev in _get_lsblk_devs(keys):
+ # split()[0] to avoid the second part of the name, after the
+ # whiteline
+ name = dev['name'].split()[0]
+ if check and not _is_available(name, dev['type'], dev['fstype'],
+ dev['mountpoint'],
dev['maj:min']):
+ continue
+ names.add(name)
+
+ return list(names)
+
+
+def get_partition_details(name):
+ majmin = _get_dev_major_min(name)
+ dev_path = _get_dev_node_path(majmin)
+
+ keys = ["TYPE", "FSTYPE", "SIZE",
"MOUNTPOINT"]
+ try:
+ dev = _get_lsblk_devs(keys, [dev_path])[0]
+ except OperationFailed as e:
+ wok_log.error(
+ "Error getting partition info for %s: %s", name, e)
+ return {}
+
+ dev['available'] = _is_available(name, dev['type'],
dev['fstype'],
+ dev['mountpoint'], majmin)
+ if dev['mountpoint']:
+ # Sometimes the mountpoint comes with [SWAP] or other
+ # info which is not an actual mount point. Filtering it
+ regexp = re.compile(r"\[.*\]")
+ if regexp.search(dev['mountpoint']) is not None:
+ dev['mountpoint'] = ''
+ dev['path'] = dev_path
+ dev['name'] = name
+ return dev
diff --git a/src/wok/plugins/kimchi/distroloader.py
b/src/wok/plugins/kimchi/distroloader.py
new file mode 100644
index 0000000..0032737
--- /dev/null
+++ b/src/wok/plugins/kimchi/distroloader.py
@@ -0,0 +1,67 @@
+#
+# Project Kimchi
+#
+# Copyright IBM, Corp. 2013-2015
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+#
+
+import glob
+import json
+import os
+
+
+from wok.exception import NotFoundError, OperationFailed
+from wok.utils import wok_log
+
+import config
+
+
+ARCHS = {'x86_64': ['x86_64', 'amd64', 'i686',
'x86', 'i386'],
+ 'amd64': ['x86_64', 'amd64', 'i686',
'x86', 'i386'],
+ 'ppc64': ['ppc', 'ppc64'],
+ 'ppc64le': ['ppc64', 'ppc64le']}
+
+
+class DistroLoader(object):
+
+ def __init__(self, location=None):
+ self.location = location or config.get_distros_store()
+
+ def _get_json_info(self, fname):
+ msg_args = {'filename': fname}
+ if not os.path.isfile(fname):
+ msg = "DistroLoader: failed to find distro file: %s" % fname
+ wok_log.error(msg)
+ raise NotFoundError("KCHDL0001E", msg_args)
+ try:
+ with open(fname) as f:
+ data = json.load(f)
+ return data
+ except ValueError:
+ msg = "DistroLoader: failed to parse distro file: %s" % fname
+ wok_log.error(msg)
+ raise OperationFailed("KCHDL0002E", msg_args)
+
+ def get(self):
+ arch_list = ARCHS.get(os.uname()[4])
+ all_json_files = glob.glob("%s/%s" % (self.location,
"*.json"))
+ distros = []
+ for f in all_json_files:
+ distros.extend(self._get_json_info(f))
+
+ # Return all remote ISOs arch not found
+ return dict([(distro['name'], distro) for distro in distros if
+ (arch_list is None or distro['os_arch'] in arch_list)])
diff --git a/src/wok/plugins/kimchi/distros.d/Makefile.am
b/src/wok/plugins/kimchi/distros.d/Makefile.am
new file mode 100644
index 0000000..684fe60
--- /dev/null
+++ b/src/wok/plugins/kimchi/distros.d/Makefile.am
@@ -0,0 +1,22 @@
+#
+# Kimchi
+#
+# Copyright IBM Corp, 2013
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+distrosdir = $(sysconfdir)/kimchi/distros.d
+
+dist_distros_DATA = *.json
diff --git a/src/wok/plugins/kimchi/distros.d/debian.json
b/src/wok/plugins/kimchi/distros.d/debian.json
new file mode 100644
index 0000000..5d6a313
--- /dev/null
+++ b/src/wok/plugins/kimchi/distros.d/debian.json
@@ -0,0 +1,9 @@
+[
+ {
+ "name": "debian-Wheezy",
+ "os_distro": "debian",
+ "os_arch": "x86_64",
+ "os_version": "7.7.0",
+ "path":
"http://caesar.acc.umu.se/debian-cd/7.7.0/amd64/iso-cd/debian-7.7.0-amd64-netinst.iso"
+ }
+]
diff --git a/src/wok/plugins/kimchi/distros.d/fedora.json
b/src/wok/plugins/kimchi/distros.d/fedora.json
new file mode 100644
index 0000000..bce72d6
--- /dev/null
+++ b/src/wok/plugins/kimchi/distros.d/fedora.json
@@ -0,0 +1,30 @@
+[
+ {
+ "name": "Fedora 20",
+ "os_distro": "fedora",
+ "os_arch": "x86_64",
+ "os_version": "20",
+ "path":
"http://fedora.mirrors.tds.net/pub/fedora/releases/20/Live/x86_64/Fedora-Live-Desktop-x86_64-20-1.iso"
+ },
+ {
+ "name": "Fedora 18 (PPC64)",
+ "os_distro": "fedora",
+ "os_arch": "ppc64",
+ "os_version": "18",
+ "path":
"http://mirrors.kernel.org/fedora-secondary/releases/18/Fedora/ppc64/iso/Fedora-18-ppc64-DVD.iso"
+ },
+ {
+ "name": "Fedora 19 (PPC64)",
+ "os_distro": "fedora",
+ "os_arch": "ppc64",
+ "os_version": "19",
+ "path":
"http://mirrors.kernel.org/fedora-secondary/releases/19/Fedora/ppc64/iso/Fedora-19-ppc64-DVD.iso"
+ },
+ {
+ "name": "Fedora 20 (PPC64)",
+ "os_distro": "fedora",
+ "os_arch": "ppc64",
+ "os_version": "20",
+ "path":
"http://mirrors.kernel.org/fedora-secondary/releases/20/Fedora/ppc64/iso/Fedora-20-ppc64-DVD.iso"
+ }
+]
diff --git a/src/wok/plugins/kimchi/distros.d/gentoo.json
b/src/wok/plugins/kimchi/distros.d/gentoo.json
new file mode 100644
index 0000000..2c0f012
--- /dev/null
+++ b/src/wok/plugins/kimchi/distros.d/gentoo.json
@@ -0,0 +1,9 @@
+[
+ {
+ "name": "gentoo-20141204",
+ "os_distro": "gentoo",
+ "os_arch": "x86_64",
+ "os_version": "20141204",
+ "path":
"http://distfiles.gentoo.org/releases/amd64/autobuilds/current-iso/install-amd64-minimal-20141204.iso"
+ }
+]
diff --git a/src/wok/plugins/kimchi/distros.d/opensuse.json
b/src/wok/plugins/kimchi/distros.d/opensuse.json
new file mode 100644
index 0000000..f51de97
--- /dev/null
+++ b/src/wok/plugins/kimchi/distros.d/opensuse.json
@@ -0,0 +1,23 @@
+[
+ {
+ "name": "opensuse-12.3",
+ "os_distro": "opensuse",
+ "os_arch": "x86_64",
+ "os_version": "12.3",
+ "path":
"http://suse.mirrors.tds.net/pub/opensuse/distribution/12.3/iso/openSUSE-12.3-DVD-x86_64.iso"
+ },
+ {
+ "name": "opensuse-13.1",
+ "os_distro": "opensuse",
+ "os_arch": "x86_64",
+ "os_version": "13.1",
+ "path":
"http://suse.mirrors.tds.net/pub/opensuse/distribution/13.1/iso/openSUSE-13.1-DVD-x86_64.iso"
+ },
+ {
+ "name": "opensuse-13.2",
+ "os_distro": "opensuse",
+ "os_arch": "x86_64",
+ "os_version": "13.2",
+ "path":
"http://suse.mirrors.tds.net/pub/opensuse/distribution/13.2/iso/openSUSE-13.2-DVD-x86_64.iso"
+ }
+]
diff --git a/src/wok/plugins/kimchi/distros.d/ubuntu.json
b/src/wok/plugins/kimchi/distros.d/ubuntu.json
new file mode 100644
index 0000000..161fbc8
--- /dev/null
+++ b/src/wok/plugins/kimchi/distros.d/ubuntu.json
@@ -0,0 +1,37 @@
+[
+ {
+ "name": "Ubuntu 13.04 (Raring Ringtail)",
+ "os_distro": "ubuntu",
+ "os_arch": "x86_64",
+ "os_version": "13.04",
+ "path":
"http://ubuntu-releases.cs.umn.edu/13.04/ubuntu-13.04-desktop-amd64.iso"
+ },
+ {
+ "name": "Ubuntu 13.10 (Saucy Salamander)",
+ "os_distro": "ubuntu",
+ "os_arch": "x86_64",
+ "os_version": "13.10",
+ "path":
"http://ubuntu-releases.cs.umn.edu/13.10/ubuntu-13.10-desktop-amd64.iso"
+ },
+ {
+ "name": "Ubuntu Server 14.04 LE (Trusty Tahr)",
+ "os_distro": "ubuntu",
+ "os_arch": "ppc64",
+ "os_version": "14.04",
+ "path":
"http://cdimages.ubuntu.com/releases/14.04/release/ubuntu-14.04-server-ppc64el.iso"
+ },
+ {
+ "name": "Ubuntu Server 14.04 LE (Trusty Tahr)",
+ "os_distro": "ubuntu",
+ "os_arch": "x86_64",
+ "os_version": "14.04",
+ "path":
"http://releases.ubuntu.com/14.04/ubuntu-14.04-desktop-amd64.iso"
+ },
+ {
+ "name": "Ubuntu Server 14.10 (Utopic Unicorn)",
+ "os_distro": "ubuntu",
+ "os_arch": "x86_64",
+ "os_version": "14.10",
+ "path":
"http://releases.ubuntu.com/14.10/ubuntu-14.10-desktop-amd64.iso"
+ }
+]
diff --git a/src/wok/plugins/kimchi/docs/API.md b/src/wok/plugins/kimchi/docs/API.md
new file mode 100644
index 0000000..fca424c
--- /dev/null
+++ b/src/wok/plugins/kimchi/docs/API.md
@@ -0,0 +1,1116 @@
+## Project Kimchi REST API Specification
+
+The Kimchi API provides all functionality to the application and may be used
+directly by external tools. In the following sections you will find the
+specification of all Collections and Resource types that are supported and the
+URIs where they can be accessed. In order to use the API effectively, please
+the following general conventions:
+
+* The **Content Type** of the API is JSON. When making HTTP requests to this
+ API you should specify the following headers:
+ * Accept: application/json
+ * Content-type: application/json
+* A **Collection** is a group of Resources of a given type.
+ * A **GET** request retrieves a list of summarized Resource representations
+ This summary *may* include all or some of the Resource properties but
+ *must* include a link to the full Resource representation.
+ * A **POST** request will create a new Resource in the Collection. The set
+ of Resource properties *must* be specified as a JSON object in the request
+ body.
+ * No other HTTP methods are supported for Collections
+* A **Resource** is a representation of a singular object in the API (eg.
+ Virtual Machine).
+ * A **GET** request retrieves the full Resource representation.
+ * A **DELETE** request will delete the Resource. This request *may* contain
+ a JSON object which specifies optional parameters.
+ * A **PUT** request is used to modify the properties of a Resource (eg.
+ Change the name of a Virtual Machine). This kind of request *must not*
+ alter the live state of the Resource. Only *actions* may alter live state.
+ * A **POST** request commits an *action* upon a Resource (eg. Start a
+ Virtual Machine). This request is made to a URI relative to the Resource
+ URI. Available *actions* are described within the *actions* property of a
+ Resource representation. The request body *must* contain a JSON object
+ which specifies parameters.
+* URIs begin with '/plugins/kimchi' to indicate the root of Kimchi plugin.
+ * Variable segments in the URI begin with a ':' and should replaced with the
+ appropriate resource identifier.
+
+### Collection: Virtual Machines
+
+**URI:** /plugins/kimchi/vms
+
+**Methods:**
+
+* **GET**: Retrieve a summarized list of all defined Virtual Machines
+* **POST**: Create a new Virtual Machine
+ * name *(optional)*: The name of the VM. Used to identify the VM in this
+ API. If omitted, a name will be chosen based on the template used.
+ * persistent: If 'true', vm will persist after a Power Off or host reboot.
+ All virtual machines created by Kimchi are persistent.
+ * template: The URI of a Template to use when building the VM
+ * storagepool *(optional)*: Assign a specific Storage Pool to the new VM
+ * graphics *(optional)*: Specify the graphics paramenter for this vm
+ * type: The type of graphics. It can be VNC or spice or None.
+ * vnc: Graphical display using the Virtual Network
+ Computing protocol
+ * spice: Graphical display using the Simple Protocol for
+ Independent Computing Environments
+ * null: Graphics is disabled or type not supported
+ * listen: The network which the vnc/spice server listens on.
+
+
+### Resource: Virtual Machine
+
+**URI:** /plugins/kimchi/vms/*:name*
+
+**Methods:**
+
+* **GET**: Retrieve the full description of a Virtual Machine
+ * name: The name of the VM. Used to identify the VM in this API
+ * state: Indicates the current state in the VM lifecycle
+ * running: The VM is powered on
+ * paused: The VMs virtual CPUs are paused
+ * shutoff: The VM is powered off
+ * stats: Virtual machine statistics:
+ * cpu_utilization: A number between 0 and 100 which indicates the
+ percentage of CPU utilization.
+ * net_throughput: Expresses total network throughput for reads and
+ writes across all virtual interfaces (kb/s).
+ * net_throughput_peak: The highest recent value of 'net_throughput'.
+ * io_throughput: Expresses the total IO throughput for reads and
+ writes across all virtual disks (kb/s).
+ * io_throughput_peak: The highest recent value of 'io_throughput'.
+ * uuid: UUID of the VM.
+ * memory: The amount of memory assigned to the VM (in MB)
+ * cpus: The number of CPUs assigned to the VM
+ * screenshot: A link to a recent capture of the screen in PNG format
+ * icon: A link to an icon that represents the VM
+ * graphics: A dict to show detail of VM graphics.
+ * type: The type of graphics. It can be VNC or spice or None.
+ * vnc: Graphical display using the Virtual Network
+ Computing protocol
+ * spice: Graphical display using the Simple Protocol for
+ Independent Computing Environments
+ * null: Graphics is disabled or type not supported
+ * listen: The network which the vnc/spice server listens on.
+ * port: The real port number of the graphics, vnc or spice. Users
+ can use this port to connect to the vm with general vnc/spice
+ clients.
+ * passwd: console password
+ * passwdValidTo: lifetime for the console password.
+ * users: A list of system users who have permission to access the VM.
+ Default is: empty (i.e. only root-users may access).
+ * groups: A list of system groups whose users have permission to access
+ the VM. Default is: empty (i.e. no groups given access).
+* **DELETE**: Remove the Virtual Machine
+* **PUT**: update the parameters of existed VM
+ * name: New name for this VM (only applied for shutoff VM)
+ * users: New list of system users.
+ * groups: New list of system groups.
+ * cpus: New number of virtual cpus for this VM (if VM is running, new value
+ will take effect in next reboot)
+ * memory: New amount of memory (MB) for this VM (if VM is running, new
+ value will take effect in next reboot)
+ * graphics: A dict to show detail of VM graphics.
+ * passwd *(optional)*: console password. When omitted a random password
+ willbe generated.
+ * passwdValidTo *(optional)*: lifetime for the console password. When
+ omitted the password will be valid just
+ for 30 seconds.
+
+* **POST**: *See Virtual Machine Actions*
+
+**Actions (POST):**
+
+* start: Power on a VM
+* poweroff: Power off a VM forcefully. Note this action may produce undesirable
+ results, for example unflushed disk cache in the guest.
+* shutdown: Shut down a VM graceful. This action issue shutdown request to guest.
+ And the guest will react this request. Note the guest OS may ignore
+ the request.
+* reset: Reset a VM immediately without the guest OS shutdown.
+ It emulates the power reset button on a machine. Note that there is a
+ risk of data loss caused by reset without the guest OS shutdown.
+* connect: Prepare the connection for spice or vnc
+
+* clone: Create a new VM identical to this VM. The new VM's name, UUID and
+ network MAC addresses will be generated automatically. Each existing
+ disks will be copied to a new volume in the same storage pool. If
+ there is no available space on that storage pool to hold the new
+ volume, it will be created on the pool 'default'. This action returns
+ a Task.
+
+* suspend: Suspend an active domain. The process is frozen without further
+ access to CPU resources and I/O but the memory used by the domain at
+ the hypervisor level will stay allocated.
+
+* resume: Resume a suspended domain. The process is restarted from the state
+ where it was frozen by calling "suspend".
+
+### Sub-resource: Virtual Machine Screenshot
+
+**URI:** /plugins/kimchi/vms/*:name*/screenshot
+
+Represents a snapshot of the Virtual Machine's primary monitor.
+
+**Methods:**
+
+* **GET**: Redirect to the latest screenshot of a Virtual Machine in PNG format
+
+
+### Sub-collection: Virtual Machine storages
+**URI:** /plugins/kimchi/vms/*:name*/storages
+* **GET**: Retrieve a summarized list of all storages of specified guest
+* **POST**: Attach a new storage or virtual drive to specified virtual machine.
+ * type: The type of the storage (currently support 'cdrom' and
'disk').
+ * path: Path of cdrom iso.
+ * pool: Storage pool which disk image file locate in.
+ * vol: Storage volume name of disk image.
+
+### Sub-resource: storage
+**URI:** /plugins/kimchi/vms/*:name*/storages/*:dev*
+* **GET**: Retrieve storage information
+ * dev: The name of the storage in the vm.
+ * type: The type of the storage (currently support 'cdrom' and
'disk').
+ * path: Path of cdrom iso or disk image file.
+ * bus: Bus type of disk attached.
+* **PUT**: Update storage information
+ * path: Path of cdrom iso. Can not be blank. Now just support cdrom type.
+* **DELETE**: Remove the storage.
+
+**Actions (POST):**
+
+
+### Sub-collection: Virtual Machine Passthrough Devices
+**URI:** /plugins/kimchi/vms/*:name*/hostdevs
+* **GET**: Retrieve a summarized list of all directly assigned host device of
+ specified guest.
+* **POST**: Directly assign a host device to guest.
+ * name: The name of the host device to be assigned to vm.
+
+### Sub-resource: Device
+**URI:** /plugins/kimchi/vms/*:name*/hostdevs/*:dev*
+* **GET**: Retrieve assigned device information
+ * name: The name of the assigned device.
+ * type: The type of the assigned device.
+* **DELETE**: Detach the host device from VM.
+
+### Sub-collection: Virtual Machine Snapshots
+**URI:** /plugins/kimchi/vms/*:name*/snapshots
+* **POST**: Create a new snapshot on a VM.
+ * name: The snapshot name (optional, defaults to a value based on the
+ current time).
+* **GET**: Retrieve a list of snapshots on a VM.
+
+### Sub-resource: Snapshot
+**URI:** /plugins/kimchi/vms/*:name*/snapshots/*:snapshot*
+* **GET**: Retrieve snapshot information.
+ * created: The time when the snapshot was created
+ (in seconds, since the epoch).
+ * name: The snapshot name.
+ * parent: The name of the parent snapshot, or an empty string if there is
+ no parent.
+ * state: The corresponding domain's state when the snapshot was created.
+* **DELETE**: Delete snapshot. If the snapshot has any children, they will be
+ merged automatically with the snapshot's parent.
+* **POST**: See "Snapshot actions (POST)"
+
+**Snapshot Actions (POST):**
+
+* revert: Revert the domain to the given snapshot.
+
+### Sub-resource: Current snapshot
+**URI:** /plugins/kimchi/vms/*:name*/snapshots/current
+* **GET**: Retrieve current snapshot information for the virtual machine.
+
+### Collection: Templates
+
+**URI:** /plugins/kimchi/templates
+
+**Methods:**
+
+* **GET**: Retrieve a summarized list of all defined Templates
+* **POST**: Create a new Template
+ * name: The name of the Template. Used to identify the Template in this API
+ * os_distro *(optional)*: The operating system distribution
+ * os_version *(optional)*: The version of the operating system distribution
+ * cpus *(optional)*: The number of CPUs assigned to the VM.
+ Default is 1, unlees specifying a cpu topology. In that case, cpus
+ will default to a product of the topology values (see cpu_info).
+ * memory *(optional)*: The amount of memory assigned to the VM.
+ Default is 1024M.
+ * cdrom *(optional)*: A volume name or URI to an ISO image.
+ * storagepool *(optional)*: URI of the storagepool.
+ Default is '/storagepools/default'
+ * networks *(optional)*: list of networks will be assigned to the new VM.
+ Default is '[default]'
+ * disks *(optional)*: An array of requested disks with the following optional fields
+ (either *size* or *volume* must be specified):
+ * index: The device index
+ * size: The device size in GB
+ * base: Base image of this disk
+
+ * graphics *(optional)*: The graphics paramenters of this template
+ * type: The type of graphics. It can be VNC or spice or None.
+ * vnc: Graphical display using the Virtual Network
+ Computing protocol
+ * spice: Graphical display using the Simple Protocol for
+ Independent Computing Environments
+ * null: Graphics is disabled or type not supported
+ * listen: The network which the vnc/spice server listens on.
+ * cpu_info *(optional)*: CPU-specific information.
+ * topology: Specify sockets, threads, and cores to run the virtual CPU
+ threads on.
+ All three are required in order to specify cpu topology.
+ * sockets - The number of sockets to use.
+ * cores - The number of cores per socket.
+ * threads - The number of threads per core.
+ If specifying both cpus and CPU topology, make sure cpus is
+ equal to the product of sockets, cores, and threads.
+
+### Sub-Collection: Virtual Machine Network Interfaces
+
+**URI:** /plugins/kimchi/vms/*:name*/ifaces
+
+Represents all network interfaces attached to a Virtual Machine.
+
+**Methods:**
+
+* **GET**: Retrieve a summarized list of all network interfaces attached to a Virtual
Machine.
+
+* **POST**: attach a network interface to VM
+ * model *(optional)*: model of emulated network interface card. It can be one of
these models:
+ ne2k_pci, i82551, i82557b, i82559er, rtl8139, e1000, pcnet and virtio.
+ When model is missing, libvirt will set 'rtl8139' as default value.
+ * network *(optional)*: the name of resource network, it is required when the
+ interface type is network.
+ * type: The type of VM network interface that libvirt supports.
+ Now kimchi just supports 'network' type.
+
+### Sub-Resource: Virtual Machine Network Interface
+
+**URI:** /plugins/kimchi/vms/*:name*/ifaces/*:mac*
+
+A interface represents available network interface on VM.
+
+**Methods:**
+
+* **GET**: Retrieve the full description of the VM network interface
+ * bridge *(optional)*: the name of resource bridge, only be available when the
+ interface type is bridge.
+ * mac: Media Access Control Address of the VM interface.
+ * model *(optional)*: model of emulated network interface card. It will be one of
these models:
+ ne2k_pci, i82551, i82557b, i82559er, rtl8139, e1000, pcnet and virtio.
+ * network *(optional)*: the name of resource network, only be available when the
+ interface type is network.
+ * type: The type of VM network interface that libvirt supports.
+ It will be one of these types: 'network', 'bridge',
'user','ethernet',
+ 'direct', 'hostdev', 'mcast', 'server' and
'client'.
+
+* **DELETE**: detach the network interface from VM
+
+* **PUT**: update the parameters of existing VM interface.
+ * model *(optional)*: model of emulated network interface card. It will be one of
these models:
+ ne2k_pci, i82551, i82557b, i82559er, rtl8139, e1000, pcnet and virtio.
+ This change is only on the persisted VM configuration.
+ * network *(optional)*: the name of resource network, only be available when the
+ interface type is network.
+ This change is on the active VM instance and persisted VM configuration.
+
+**Actions (POST):**
+
+*No actions defined*
+
+
+### Resource: Template
+
+**URI:** /plugins/kimchi/templates/*:name*
+
+**Methods:**
+
+* **GET**: Retrieve the full description of a Template
+ * name: A name for this template
+ * folder: A virtual path which can be used to organize Templates in a user
+ interface. The format is an array of path components.
+ * icon: A URI to a PNG image representing this template
+ * os_distro: The operating system distribution
+ * os_version: The version of the operating system distribution
+ * cpus: The number of CPUs assigned to the VM
+ * memory: The amount of memory assigned to the VM in the unit of MB
+ * cdrom: A volume name or URI to an ISO image
+ * storagepool: URI of the storagepool where template allocates vm storage.
+ * networks *(optional)*: list of networks will be assigned to the new VM.
+ * disks: An array of requested disks with the following optional fields
+ (either *size* or *volume* must be specified):
+ * index: The device index
+ * size: The device size in GB
+ * volume: A volume name that contains the initial disk contents
+ * format: Format of the image. Valid formats: bochs, cloop, cow, dmg, qcow,
qcow2, qed, raw, vmdk, vpc.
+ * graphics: A dict of graphics paramenters of this template
+ * type: The type of graphics. It can be VNC or spice or None.
+ * vnc: Graphical display using the Virtual Network
+ Computing protocol
+ * spice: Graphical display using the Simple Protocol for
+ Independent Computing Environments
+ * null: Graphics is disabled or type not supported
+ * listen: The network which the vnc/spice server listens on.
+ * invalid: A dict indicates which paramenters of this template are invalid.
+ * networks *(optional)*: An array of invalid network names.
+ * cdrom *(optional)*: An array of invalid cdrom names.
+ * disks *(optional)*: An array of invalid volume names.
+ * storagepools *(optional)*: An array of invalid storagepool names.
+
+* **DELETE**: Remove the Template
+* **POST**: *See Template Actions*
+* **PUT**: update the parameters of existed template
+ * name: A name for this template
+ * folder: A virtual path which can be used to organize Templates in the user
+ interface. The format is an array of path components.
+ * icon: A URI to a PNG image representing this template
+ * os_distro: The operating system distribution
+ * os_version: The version of the operating system distribution
+ * cpus: The number of CPUs assigned to the VM
+ * memory: The amount of memory assigned to the VM
+ * cdrom: A volume name or URI to an ISO image
+ * storagepool: URI of the storagepool where template allocates vm storage.
+ * networks *(optional)*: list of networks will be assigned to the new VM.
+ * disks: An array of requested disks with the following optional fields
+ (either *size* or *volume* must be specified):
+ * index: The device index
+ * size: The device size in GB
+ * volume: A volume name that contains the initial disk contents
+ * format: Format of the image. Valid formats: bochs, cloop, cow, dmg, qcow,
qcow2, qed, raw, vmdk, vpc.
+ * graphics *(optional)*: A dict of graphics paramenters of this template
+ * type: The type of graphics. It can be VNC or spice or None.
+ * vnc: Graphical display using the Virtual Network
+ Computing protocol
+ * spice: Graphical display using the Simple Protocol for
+ Independent Computing Environments
+ * null: Graphics is disabled or type not supported
+ * listen: The network which the vnc/spice server listens on.
+
+**Actions (POST):**
+
+* clone: clone a template from an existing template with different name.
+ It will provide a reasonable default name with "-cloneN" as suffix
+ for the new clone template. The "N" means the number of clone times.
+
+### Collection: Storage Pools
+
+**URI:** /plugins/kimchi/storagepools
+
+**Methods:**
+
+* **GET**: Retrieve a summarized list of all defined Storage Pools
+* **POST**: Create a new Storage Pool
+ * name: The name of the Storage Pool.
+ * type: The type of the defined Storage Pool.
+ Supported types: 'dir', 'kimchi-iso', 'netfs',
'logical', 'iscsi', 'scsi'
+ * path: The path of the defined Storage Pool.
+ For 'kimchi-iso' pool refers to targeted deep scan path.
+ Pool types: 'dir', 'kimchi-iso'.
+ * source: Dictionary containing source information of the pool.
+ * host: IP or hostname of server for a pool backed from a remote host.
+ Pool types: 'netfs', 'iscsi'.
+ * path: Export path on NFS server for NFS pool.
+ Pool types: 'netfs'.
+ * devices: Array of devices to be used in the Storage Pool
+ Pool types: 'logical'.
+ * target: Target IQN of an iSCSI pool.
+ Pool types: 'iscsi'.
+ * port *(optional)*: Listening port of a remote storage server.
+ Pool types: 'iscsi'.
+ * auth *(optional)*: Storage back-end authentication information.
+ Pool types: 'iscsi'.
+ * username: Login username of the iSCSI target.
+ * password: Login password of the iSCSI target.
+ * adapter_name: SCSI host name.
+
+### Resource: Storage Pool
+
+**URI:** /plugins/kimchi/storagepools/*:name*
+
+**Methods:**
+
+* **GET**: Retrieve the full description of a Storage Pool
+ * name: The name of the Storage Pool
+ Used to identify the Storage Pool in this API
+ 'kimchi_isos' is a reserved storage pool
+ which aggregates all ISO images
+ across all active storage pools into a single view.
+ * state: Indicates the current state of the Storage Pool
+ * active: The Storage Pool is ready for use
+ * inactive: The Storage Pool is not available
+ * path: The path of the defined Storage Pool
+ * type: The type of the Storage Pool
+ * capacity: The total space which can be used to store volumes
+ The unit is Bytes
+ * allocated: The amount of space which is being used to store volumes
+ The unit is Bytes
+ * available: Free space available for creating new volumes in the pool
+ * nr_volumes: The number of storage volumes for active pools, 0 for inactive pools
+ * autostart: Whether the storage pool will be enabled
+ automatically when the system boots
+ * persistent: True, when pool persist after a system reboot or be stopped.
+ All storage pools created by Kimchi are persistent.
+ * source: Source of the storage pool,
+ * addr: mount address of this storage pool(for 'netfs' pool)
+ * path: export path of this storage pool(for 'netfs' pool)
+
+* **PUT**: Set whether the Storage Pool should be enabled automatically when the
+ system boots
+ * autostart: Toggle the autostart flag of the VM. This flag sets whether
+ the Storage Pool should be enabled automatically when the
+ system boots
+ * disks: Adds one or more disks to the pool (for 'logical' pool only)
+* **DELETE**: Remove the Storage Pool
+* **POST**: *See Storage Pool Actions*
+
+**Actions (POST):**
+
+* activate: Activate an inactive Storage Pool
+* deactivate: Deactivate an active Storage Pool
+
+### Collection: Storage Volumes
+
+**URI:** /plugins/kimchi/storagepools/*:poolname*/storagevolumes
+
+**Methods:**
+
+* **GET**: Retrieve a summarized list of all defined Storage Volumes
+ in the defined Storage Pool
+* **POST**: Create a new Storage Volume in the Storage Pool
+ The return resource is a task resource * See Resource: Task *
+ Only one of 'capacity', 'url' can be specified.
+ * name: The name of the Storage Volume
+ * capacity: The total space which can be used to store volumes
+ The unit is bytes
+ * format: The format of the defined Storage Volume. Only used when creating
+ a storage volume with 'capacity'.
+ * upload: True to start an upload process. False, otherwise.
+ Only used when creating a storage volume 'capacity' parameter.
+ * file: File to be uploaded, passed through form data
+
+### Resource: Storage Volume
+
+**URI:** /plugins/kimchi/storagepools/*:poolname*/storagevolumes/*:name*
+
+**Methods:**
+
+* **GET**: Retrieve the full description of a Storage Volume
+ * name: The name of the Storage Volume
+ Used to identify the Storage Volume in this API
+ * type: The type of the Storage Volume
+ * capacity: The total space which can be used to store data
+ The unit is Bytes
+ * allocation: The amount of space which is being used to store data
+ The unit is Bytes
+ * format: The format of the file or volume
+ * path: Full path of the volume on the host filesystem.
+ * os_distro *(optional)*: os distribution of the volume, for iso volume only.
+ * os_version *(optional)*: os version of the volume, for iso volume only.
+ * bootable *(optional)*: True if iso image is bootable and not corrupted.
+ * used_by: Name of vms which use this volume.
+
+* **DELETE**: Remove the Storage Volume
+* **POST**: *See Storage Volume Actions*
+* **PUT**: Upload storage volume chunk
+ * chunk_size: Chunk size of the slice in Bytes.
+ * chunk: Actual data of uploaded file
+
+**Actions (POST):**
+
+* resize: Resize a Storage Volume
+ * size: resize the total space which can be used to store data
+ The unit is bytes
+* wipe: Wipe a Storage Volume
+* clone: Clone a Storage Volume.
+ * pool: The name of the destination pool (optional).
+ * name: The new storage volume name (optional).
+
+
+### Collection: Interfaces
+
+**URI:** /plugins/kimchi/interfaces
+
+**Methods:**
+
+* **GET**: Retrieve a summarized list of current Interfaces
+
+### Resource: Interface
+
+**URI:** /plugins/kimchi/interfaces/*:name*
+
+A interface represents available interface on host.
+
+**Methods:**
+
+* **GET**: Retrieve the full description of the Interface
+ * name: The name of the interface.
+ * status: The current status of the Interface.
+ * active: The interface is active.
+ * inactive: The interface is inactive.
+ * ipaddr: The ip address assigned to this interface in subnet.
+ * netmask: Is used to divide an IP address into subnets and specify the
+ networks available hosts
+ * type: The net device type of the interface.
+ * nic: Network interface controller that connects a computer to a
+ computer network
+ * vlan: A logical interface that represents a VLAN in all Layer 3
+ activities the unit may participate in
+ * bonding: The combination of network interfaces on one host for redundancy
+ and/or increased throughput.
+ * bridge: A network device that connects multiple network segments.
+
+* **POST**: *See Interface Actions*
+
+**Actions (POST):**
+
+*No actions defined*
+
+### Collection: Networks
+
+**URI:** /plugins/kimchi/networks
+
+**Methods:**
+
+* **GET**: Retrieve a summarized list of all defined Networks
+* **POST**: Create a new Network
+ * name: The name of the Network
+ * connection: Specifies how this network should be connected to the other
+ networks visible to this host.
+ * isolated: Create a private, isolated virtual network.
+ * nat: Outgoing traffic will be routed through the host.
+ * bridge: All traffic on this network will be bridged through the indicated
+ interface.
+ * subnet *(optional)*: Network segment in slash-separated format with ip address and
+ prefix or netmask used to create nat network.
+ * interface *(optional)*: The name of a network interface on the host.
+ For bridge network, the interface can be a bridge or nic/bonding
+ device.
+ * vlan_id *(optional)*: VLAN tagging ID for the bridge network.
+
+### Resource: Network
+
+**URI:** /plugins/kimchi/networks/*:name*
+
+**Methods:**
+
+* **GET**: Retrieve the full description of a Network
+ * name: The name of the Network
+ Used to identify the Network in this API
+ * state: Indicates the current state of the Network
+ * active: The Network is ready for use
+ * inactive: The Network is not available
+ * autostart: Network autostart onboot
+ * in_use: Indicates ('true') if some guest is attached to this network and
'false' otherwise.
+ * vms: all vms attached to this network
+ * subnet: Network segment in slash-separated format with ip address and prefix
+ * dhcp: DHCP services on the virtual network is enabled.
+ * start: start boundary of a pool of addresses to be provided to DHCP clients.
+ * end: end boundary of a pool of addresses to be provided to DHCP clients.
+ * connection: Specifies how this network should be connected to the other networks
+ visible to this host.
+ * isolated: A private, isolated virtual network.
+ The VMs attached to it can not be reached by the systems
+ outside of this network and vice versa.
+ * nat: Outgoing traffic will be routed through the host.
+ The VM attached to it will have internet access via the host but
+ other computers will not be able to connect to the VM.
+ * bridge: Aggregated Public Network.
+ The VM that joines this network is seen as a peer on this network
+ and it may offer network services such as HTTP or SSH.
+ * interface: The name of a bridge network interface on the host. All traffic
+ on this network will be bridged through the indicated interface.
+ The interface is a bridge or ethernet/bonding device.
+ * persistent: If 'true', network will persist after a system reboot or be
stopped.
+ All networks created by Kimchi are persistent.
+
+* **DELETE**: Remove the Network
+* **POST**: *See Network Actions*
+
+**Actions (POST):**
+
+* activate: Activate an inactive Network
+* deactivate: Deactivate an active Network
+
+
+### Resource: Configuration
+
+**URI:** /plugins/kimchi/config
+
+Contains information about the application environment and configuration.
+
+**Methods:**
+
+* **GET**: Retrieve configuration information
+ * display_proxy_port: Port for vnc and spice's websocket proxy to listen on
+ * version: The version of the kimchi service
+* **POST**: *See Configuration Actions*
+
+**Actions (POST):**
+
+*No actions defined*
+
+### Resource: Capabilities
+
+**URI:** /plugins/kimchi/config/capabilities
+
+Contains information about the host capabilities: iso streaming, screenshot
+creation.
+
+**Methods:**
+
+* **GET**: Retrieve capabilities information
+ * libvirt_stream_protocols: list of which network protocols are accepted
+ for iso streaming by libvirt
+ * qemu_spice: True, if QEMU supports Spice; False, otherwise
+ * qemu_stream: True, if QEMU supports ISO streaming; False, otherwise
+ * screenshot: True, if libvirt stream functionality can create screenshot
+ file without problems; False, otherwise or None if the functionality was
+ not tested yet
+ * system_report_tool: True if the is some debug report tool installed on
+ the system; False, otherwise.
+ * update_tool: True if there is a compatible package manager for the
+ system; False, otherwise
+ * repo_mngt_tool: 'deb', 'yum' or None - when the repository
management
+ tool is not identified
+ * federation: 'on' if federation feature is enabled, 'off'
otherwise.
+ * auth: authentication type, 'pam' and 'ldap' are supported.
+* **POST**: *See Configuration Actions*
+
+**Actions (POST):**
+
+*No actions defined*
+
+### Collection: Storage Servers
+
+**URI:** /plugins/kimchi/storageservers
+
+**Methods:**
+
+* **GET**: Retrieve a summarized list of used storage servers.
+ * Parameters:
+ * _target_type: Filter server list with given type, currently support
+ 'netfs' and 'iscsi'.
+
+### Resource: Storage Server
+
+**URI:** /plugins/kimchi/storageservers/*:host*
+
+**Methods:**
+
+* **GET**: Retrieve description of a Storage Server
+ * host: IP or host name of storage server
+ * port: port of storage server, only for "iscsi"
+
+### Collection: Storage Targets
+
+**URI:** /plugins/kimchi/storageservers/*:name*/storagetargets
+
+**Methods:**
+
+* **GET**: Retrieve a list of available storage targets.
+ * Parameters:
+ * _target_type: Filter target list with given type, currently support
+ 'netfs' and 'iscsi'.
+ * _server_port: Filter target list with given server port,
+ currently support 'iscsi'.
+ * Response: A list with storage targets information.
+ * host: IP or host name of storage server of this target.
+ * target_type: Type of storage target, supported: 'nfs'.
+ * target: Storage target path.
+
+### Collection: Distros
+
+**URI:** /plugins/kimchi/config/distros
+
+**Methods:**
+
+* **GET**: Retrieve a summarized list of all Distros
+
+### Resource: Distro
+
+**URI:** /plugins/kimchi/config/distros/*:name*
+
+Contains information about the OS distribution.
+
+**Methods:**
+
+* **GET**: Retrieve a OS distribution information.
+ * name: The name of the Distro.
+ * os_distro: The operating system distribution.
+ * os_version: The version of the operating system distribution.
+ * path: A URI to an ISO image.
+
+**Actions (POST):**
+
+*No actions defined*
+
+#### Collection: Debug Reports
+
+**URI:** /plugins/kimchi/debugreports
+
+**Methods:**
+
+* **GET**: Retrieve a summarized list of all available Debug Reports
+* **POST**: Create a new Debug Report. This POST method is different
+ from the other ones. The return resource is a task resource which
+ is identified by the url below
+ * task resource. * See Resource: Task *
+
+### Resource: Debug Report
+
+**URI:** /plugins/kimchi/debugreports/*:name*
+
+A Debug Report is an archive of logs and other information about the host that
+is used to diagnose and debug problems. The exact format and contents are
+specific to the low level collection tool being used.
+
+**Methods:**
+
+* **GET**: Retrieve the full description of Debug Report
+ * name: The debug report name used to identify the report
+ * uri: The URI path to download a debug report
+ * time: The time when the debug report is created
+
+* **PUT**: rename an existed debug report
+ * name: The new name for this debug report
+
+* **DELETE**: Remove the Debug Report
+ * name: The debug report name used to identify the report
+
+* **POST**: *See Debug Report Actions*
+
+**Actions (POST):**
+
+*No actions defined*
+
+### Sub-resource: Debug Report content
+
+**URI:** /plugins/kimchi/debugreports/*:name*/content
+
+It is the sub-resource of Debug Report and the client use it to get the real content
+of the Debug Report file from the server
+
+* **GET**: Retrieve the content of a Debug Report file
+
+**Actions (POST):**
+
+*No actions defined*
+
+### Resource: Host
+
+**URI:** /plugins/kimchi/host
+Contains information of host.
+
+**Methods:**
+
+* **GET**: Retrieve host static information
+ * memory: Total size of host physical memory
+ The unit is Bytes
+ * cpu_model: The model name of host CPU
+ * cpus: The number of online CPUs available on host
+ * os_distro: The OS distribution that runs on host
+ * os_version: The version of OS distribution
+ * os_codename: The code name of OS distribution
+
+* **POST**: *See Host Actions*
+
+**Actions (POST):**
+
+* reboot: Restart the host machine.
+ Only allowed if there is not vm running.
+* shutdown: Power off the host machine.
+ Only allowed if there is not vm running.
+* swupdate: Start the update of packages in background and return a Task resource
+ * task resource. * See Resource: Task *
+
+### Resource: Users
+
+**URI:** /plugins/kimchi/users
+List of available users.
+
+**Methods:**
+
+* **GET**: Retrieve list of available users.
+ * Parameters:
+ * _user_id: Validate whether user exists.
+ Essential for 'ldap' authentication.
+
+### Resource: Groups
+
+**URI:** /plugins/kimchi/groups
+List of available groups.
+
+**Methods:**
+
+* **GET**: Retrieve list of available groups, only support 'pam' authentication.
+
+### Resource: HostStats
+
+**URI:** /plugins/kimchi/host/stats
+
+Contains the host sample data.
+
+**Methods:**
+
+* **GET**: Retrieve host sample data
+ * cpu_utilization: A number between 0 and 100 which indicates the
+ percentage of CPU utilization.
+ * memory: memory statistics of host
+ * total: Total amount of memory. The unit is Bytes.
+ * free: The amount of memory left unused by the system. The unit is Bytes.
+ * buffers: The amount of memory used for file buffers. The unit is Bytes.
+ * cached: The amount of memory used as cache memory. The unit is Bytes.
+ * avail: The total amount of buffer, cache and free memory. The unit is Bytes.
+ * disk_read_rate: Expresses the total IO throughput for reads across
+ all disks (B/s).
+ * disk_write_rate: Expresses the total IO throughput for writes across
+ all disks (B/s).
+ * net_sent_rate: Expresses the total network throughput for writes across
+ all interfaces (B/s).
+ * net_recv_rate: Expresses the total network throughput for reads across
+ all interfaces (B/s).
+
+* **POST**: *See HostStats Actions*
+
+**Actions (POST):**
+
+*No actions defined*
+
+### Resource: HostStats
+
+**URI:** /plugins/kimchi/host/cpuinfo
+
+The cores and sockets of a hosts's CPU. Useful when sizing VMs to take
+advantages of the perforamance benefits of SMT (Power) or Hyper-Threading (Intel).
+
+**Methods:**
+
+* **GET**: Retreives the sockets, cores, and threads values.
+ * threading_enabled: Whether CPU topology is supported on this system.
+ * sockets: The number of total sockets on a system.
+ * cores: The total number of cores per socket.
+ * threads_per_core: The threads per core.
+
+**Actions (PUT):**
+
+*No actions defined*
+
+**Actions (POST):**
+
+*No actions defined*
+
+
+### Resource: HostStatsHistory
+
+**URI:** /plugins/kimchi/host/stats/history
+
+It is the sub-resource of Host Stats and the client uses it to get the host
+stats history
+
+**Methods:**
+
+* **GET**: Retrieve host sample data history
+ * cpu_utilization: CPU utilization history
+ * memory: Memory statistics history
+ * total: Total amount of memory. The unit is Bytes.
+ * free: The amount of memory left unused by the system. The unit is Bytes.
+ * buffers: The amount of memory used for file buffers. The unit is Bytes.
+ * cached: The amount of memory used as cache memory. The unit is Bytes.
+ * avail: The total amount of buffer, cache and free memory. The unit is Bytes.
+ * disk_read_rate: IO throughput for reads history
+ * disk_write_rate: IO throughput for writes history
+ * net_sent_rate: Network throughput for writes history
+ * net_recv_rate: Network throughput for reads history
+
+* **POST**: *See HostStatsHistory Actions*
+
+**Actions (POST):**
+
+*No actions defined*
+
+### Collection: Partitions
+
+**URI:** /plugins/kimchi/host/partitions
+
+**Methods:**
+
+* **GET**: Retrieves a detailed list of all partitions of the host.
+
+### Resource: Partition
+
+**URI:** /plugins/kimchi/host/partitions/*:name*
+
+**Methods:**
+
+* **GET**: Retrieve the description of a single Partition:
+ * name: The name of the partition. Used to identify it in this API
+ * path: The device path of this partition.
+ * type: The type of the partition:
+ * part: a standard partition
+ * lvm: a partition that belongs to a lvm
+ * fstype: The file system type of the partition
+ * size: The total size of the partition, in bytes
+ * mountpoint: If the partition is mounted, represents the mountpoint.
+ Otherwise blank.
+ * available: false, if the partition is in use by system; true, otherwise.
+
+### Collection: Devices
+
+**URI:** /plugins/kimchi/host/devices
+
+**Methods:**
+
+* **GET**: Retrieves list of host devices (Node Devices).
+ * Parameters:
+ * _cap: Filter node device list with given node device capability.
+ To list Fibre Channel SCSI Host devices, use "_cap=fc_host".
+ Other available values are "fc_host", "net",
"pci", "scsi",
+ "storage", "system", "usb" and
"usb_device".
+ * _passthrough: Filter devices eligible to be assigned to guest
+ directly. Possible values are "ture" and
"false".
+ * _passthrough_affected_by: Filter the affected devices in the same
+ group of a certain directly assigned device.
+ The value should be the name of a device.
+
+### Resource: Device
+
+**URI:** /plugins/kimchi/host/devices/*:name*
+
+**Methods:**
+
+* **GET**: Retrieve information of a single host device.
+ * device_type: Type of the device, supported types are "net",
"pci", "scsi",
+ "storage", "system", "usb" and
"usb_device".
+ * name: The name of the device.
+ * path: Path of device in sysfs.
+ * parent: The name of the parent parent device.
+ * adapter: Host adapter information of a "scsi_host" or "fc_host"
device.
+ * type: The capability type of the scsi_host device (fc_host, vport_ops).
+ * wwnn: The HBA Word Wide Node Name. Empty if pci device is not fc_host.
+ * wwpn: The HBA Word Wide Port Name. Empty if pci device is not fc_host.
+ * domain: Domain number of a "pci" device.
+ * bus: Bus number of a "pci" device.
+ * slot: Slot number of a "pci" device.
+ * function: Function number of a "pci" device.
+ * vendor: Vendor information of a "pci" device.
+ * id: Vendor id of a "pci" device.
+ * description: Vendor description of a "pci" device.
+ * product: Product information of a "pci" device.
+ * id: Product id of a "pci" device.
+ * description: Product description of a "pci" device.
+ * iommuGroup: IOMMU group number of a "pci" device. Would be None/null if
+ host does not enable IOMMU support.
+
+
+### Sub-collection: VMs with the device assigned.
+**URI:** /plugins/kimchi/host/devices/*:name*/vmholders
+* **GET**: Retrieve a summarized list of all VMs holding the device.
+
+### Sub-resource: VM holder
+**URI:** /plugins/kimchi/host/devices/*:name*/vmholders/*:vm*
+* **GET**: Retrieve information of the VM which is holding the device
+ * name: The name of the VM.
+ * state: The power state of the VM. Could be "running" and
"shutdown".
+
+
+### Collection: Host Packages Update
+
+**URI:** /plugins/kimchi/host/packagesupdate
+
+Contains the information and action of packages update in the host.
+
+**Methods:**
+
+* **GET**: Retrieves a list of all packages to be updated in the host:
+
+### Resource: Host Package Update
+
+**URI:** /plugins/kimchi/host/packagesupdate/*:name*
+
+Contains the information for a specific package to be updated.
+
+**Methods:**
+
+* **GET**: Retrieves a full description of a package:
+ * package_name: The name of the package to be updated
+ * arch: The architecture of the package
+ * version: The new version of the package
+ * repository: The repository name from where package will be downloaded
+
+### Collection: Host Repositories
+
+**URI:** /plugins/kimchi/host/repositories
+
+**Methods:**
+
+* **GET**: Retrieve a summarized list of all repositories available
+* **POST**: Add a new repository
+ * baseurl: URL to the repodata directory when "is_mirror" is false.
+Otherwise, it can be URL to the mirror system for YUM. Can be an
+http://, ftp:// or file:// URL.
+ * repo_id *(optional)*: Unique YUM repository ID
+ * config: A dictionary that contains specific data according to repository
+ type.
+ * repo_name *(optional)*: YUM Repository name
+ * mirrorlist *(optional)*: Specifies a URL to a file containing a
+ list of baseurls for YUM repository
+ * dist: Distribution to DEB repository
+ * comps *(optional)*: List of components to DEB repository
+
+### Resource: Repository
+
+**URI:** /plugins/kimchi/host/repositories/*:repo-id*
+
+**Methods:**
+
+* **GET**: Retrieve the full description of a Repository
+ * repo_id: Unique repository name for each repository, one word.
+ * baseurl: URL to the repodata directory when "is_mirror" is false.
+Otherwise, it can be URL to the mirror system for YUM. Can be an
+http://, ftp:// or file:// URL.
+ * enabled: True, when repository is enabled; False, otherwise
+ * config: A dictionary that contains specific data according to repository
+ type.
+ * repo_name: Human-readable string describing the YUM repository.
+ * mirrorlist: Specifies a URL to a file containing a list of baseurls
+ for YUM repository
+ * gpgcheck: True, to enable GPG signature verification; False, otherwise.
+ * gpgkey: URL pointing to the ASCII-armored GPG key file for the YUM
+ repository.
+ * dist: Distribution to DEB repository
+ * comps: List of components to DEB repository
+
+* **DELETE**: Remove the Repository
+* **POST**: *See Repository Actions*
+* **PUT**: update the parameters of existing Repository
+ * repo_id: Unique repository name for each repository, one word.
+ * baseurl: URL to the repodata directory when "is_mirror" is false.
+Otherwise, it can be URL to the mirror system for YUM. Can be an
+http://, ftp:// or file:// URL.
+ * config: A dictionary that contains specific data according to repository
+ type.
+ * repo_name: Human-readable string describing the YUM repository.
+ * mirrorlist: Specifies a URL to a file containing a list of baseurls
+ for YUM repository
+ * gpgcheck: True, to enable GPG signature verification; False, otherwise.
+ * gpgkey: URL pointing to the ASCII-armored GPG key file for the YUM
+ repository.
+ * dist: Distribution to DEB repository
+ * comps: List of components to DEB repository
+
+**Actions (POST):**
+
+* enable: Enable the Repository as package source
+* disable: Disable the Repository as package source
+
+### Collection: Peers
+
+**URI:** /plugins/kimchi/peers
+
+**Methods:**
+
+* **GET**: Return the list of Kimchi peers in the same network
+ (It uses openSLP for discovering)
diff --git a/src/wok/plugins/kimchi/docs/Makefile.am
b/src/wok/plugins/kimchi/docs/Makefile.am
new file mode 100644
index 0000000..679aa18
--- /dev/null
+++ b/src/wok/plugins/kimchi/docs/Makefile.am
@@ -0,0 +1,28 @@
+#
+# Kimchi
+#
+# Copyright IBM Corp, 2013
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+docdir = $(datadir)/kimchi/doc
+
+dist_doc_DATA = \
+ API.md \
+ README.md \
+ README-federation.md \
+ kimchi-guest.png \
+ kimchi-templates.png \
+ $(NULL)
diff --git a/src/wok/plugins/kimchi/docs/README-federation.md
b/src/wok/plugins/kimchi/docs/README-federation.md
new file mode 100644
index 0000000..c184f4f
--- /dev/null
+++ b/src/wok/plugins/kimchi/docs/README-federation.md
@@ -0,0 +1,60 @@
+Kimchi Project - Federation Feature
+===================================
+
+Federation feature is a Kimchi mechanism to discover Wok peers in the same
+network. It uses openSLP tool (
http://www.openslp.org/) to register and find Wok
+servers.
+
+By default this feature is disabled on Wok as it is not critical for KVM
+virtualization and requires additional software installation.
+
+To enable it, do the following:
+
+1. Install openslp and openslp-server rpm packages,
+ or install slpd and slptool deb packages.
+
+2. openSLP uses port 427 (UDP) and port 427 (TCP) so make sure to open those
+ ports in your firewall configuration
+
+ For system using firewalld, do:
+ sudo firewall-cmd --permanent --add-port=427/udp
+ sudo firewall-cmd --permanent --add-port=427/tcp
+ sudo firewall-cmd --reload
+
+ For openSUSE systems, do:
+ sudo /sbin/SuSEfirewall2 open EXT TCP 427
+ sudo /sbin/SuSEfirewall2 open EXT UDP 427
+
+ For system using iptables, do:
+ sudo iptables -A INPUT -p tcp --dport 427 -j ACCEPT
+ sudo iptables -A INPUT -p udp --dport 427 -j ACCEPT
+
+3. In addition to the openSLP ports, you also need to allow multicast in the
+ firewall configuration
+
+ For system using firewalld, do:
+ sudo firewall-cmd --direct --add-rule ipv4 filter INPUT 0 -s <subnet> -j ACCEPT
+
+ For openSUSE systems, do:
+ Add the subnet to the trusted networks listed on FW_TRUSTED_NETS in
+ /etc/sysconfig/SuSEfirewall2 file.
+ Make sure to restart /sbin/SuSEfirewall2 after modifying /etc/sysconfig/SuSEfirewall2
+
+ For system using iptables, do:
+ sudo iptables -A INPUT -s <subnet> -j ACCEPT
+
+4. Start slpd service and make sure it is up while running Wok
+ sudo service slpd start
+
+5. Enable federation on Wok by editing the /etc/wok/wok.conf file:
+
+ federation = on
+
+6. Then start Wok service
+ sudo service wokd start
+
+The Wok server will be registered on openSLP on server starting up and will
+be found by other Wok peers (with federation feature enabled) in the same
+network.
+
+Enjoy!
diff --git a/src/wok/plugins/kimchi/docs/README.md
b/src/wok/plugins/kimchi/docs/README.md
new file mode 100644
index 0000000..f400333
--- /dev/null
+++ b/src/wok/plugins/kimchi/docs/README.md
@@ -0,0 +1,247 @@
+Kimchi Project
+==============
+
+Kimchi is an HTML5 based management tool for KVM. It is designed to make it as
+easy as possible to get started with KVM and create your first guest.
+
+Kimchi runs as a Wok plugin. Wok runs as a daemon on the hypervisor host.
+
+Kimchi manages KVM guests through libvirt. The management interface is accessed
+over the web using a browser that supports HTML5.
+
+Browser Support
+===============
+Desktop Browser Support:
+-----------------------
+* **Internet Explorer:** IE9+
+* **Chrome:** Current-1 version
+* **Firefox:** Current-1 version Firefox 24ESR
+* **Safari:** Current-1 version
+* **Opera:** Current-1 version
+
+Mobile Browser Support:
+-----------------------
+* **Safari iOS:** Current-1 version
+* **Android Browser** Current-1 version
+
+Current-1 version denotes that we support the current stable version of the
+browser and the version that preceded it. For example, if the current version of
+a browser is 24.x, we support the 24.x and 23.x versions.This does not mean that
+kimchi cannot be used in other browsers, however, functionality and appearance
+may be diminished and we may not be able to provide support for any problems you
+find.
+
+Hypervisor Distro Support
+=========================
+
+Kimchi and Wok might run on any GNU/Linux distribution that meets the conditions
+described on the 'Getting Started' section below.
+
+The Kimchi community makes an effort to test it with the latest versions of
+Fedora, RHEL, OpenSuSe, and Ubuntu.
+
+Getting Started
+===============
+
+Install Dependencies
+--------------------
+
+**For fedora and RHEL:**
+
+ $ sudo yum install gcc make autoconf automake gettext-devel git \
+ python-cherrypy python-cheetah libvirt-python \
+ libvirt libvirt-daemon-config-network python-imaging \
+ PyPAM m2crypto python-jsonschema rpm-build \
+ qemu-kvm python-psutil python-ethtool sos \
+ python-ipaddr python-ldap python-lxml nfs-utils \
+ iscsi-initiator-utils libxslt pyparted nginx \
+ python-libguestfs libguestfs-tools python-websockify \
+ novnc spice-html5 python-configobj
+
+ # If using RHEL, install the following additional packages:
+ $ sudo yum install python-unittest2 python-ordereddict
+
+ # Restart libvirt to allow configuration changes to take effect
+ $ sudo service libvirtd restart
+
+ Packages version requirement:
+ python-psutil >= 0.6.0
+
+ # These dependencies are only required if you want to run the tests:
+ $ sudo yum install pyflakes python-pep8 python-requests
+
+*Note for RHEL users*: Some of the above packages are located in the Red Hat
+EPEL repositories. See
+[this
FAQ](http://fedoraproject.org/wiki/EPEL#How_can_I_use_these_extra_package...
+for more information on how to configure your system to access this repository.
+
+And for RHEL7 systems, you also need to subscribe to the "RHEL Server
Optional"
+channel at RHN Classic or Red Hat Satellite.
+
+**For debian:**
+
+ $ sudo apt-get install gcc make autoconf automake gettext git \
+ python-cherrypy3 python-cheetah python-libvirt \
+ libvirt-bin python-imaging python-configobj \
+ python-pam python-m2crypto python-jsonschema \
+ qemu-kvm libtool python-psutil python-ethtool \
+ sosreport python-ipaddr python-ldap \
+ python-lxml nfs-common open-iscsi lvm2 xsltproc \
+ python-parted nginx python-guestfs libguestfs-tools \
+ websockify novnc spice-html5
+
+ Packages version requirement:
+ python-jsonschema >= 1.3.0
+ python-psutil >= 0.6.0
+
+ # These dependencies are only required if you want to run the tests:
+ $ sudo apt-get install pep8 pyflakes python-requests
+
+**For openSUSE:**
+
+ $ sudo zypper install gcc make autoconf automake gettext-tools git \
+ python-CherryPy python-Cheetah libvirt-python \
+ libvirt libvirt-daemon-config-network python-pam \
+ python-imaging python-M2Crypto python-jsonschema \
+ rpm-build kvm python-psutil python-ethtool \
+ python-ipaddr python-ldap python-lxml nfs-client \
+ open-iscsi libxslt-tools python-xml python-parted \
+ nginx python-libguestfs python-configobj \
+ guestfs-tools python-websockify novnc
+
+ Packages version requirement:
+ python-psutil >= 0.6.0
+
+ # These dependencies are only required if you want to run the tests:
+ $ sudo zypper install python-pyflakes python-pep8 python-requests
+
+*Note for openSUSE users*: Some of the above packages are located in different
+openSUSE repositories. See
+[this
FAQ](http://download.opensuse.org/repositories/home:GRNET:synnefo/) for
+python-parted; and
+[this
FAQ](http://download.opensuse.org/repositories/systemsmanagement:/spacewa...
+for python-ethtool to get the correct repository based on your openSUSE version. And
+[this
FAQ](http://en.opensuse.org/SDB:Add_package_repositories) for more
+information on how configure your system to access this repository.
+
+Build and Install
+-----------------
+
+ Wok:
+ $ ./autogen.sh --system
+
+ $ make
+ $ sudo make install # Optional if running from the source tree
+
+
+ Kimchi:
+ $ cd plugins/kimchi
+
+ For openSUSE 13.1:
+ $ ./autogen.sh --with-spice-html5
+
+ Otherwise:
+ $ ./autogen.sh --system
+
+ $ make
+ $ sudo make install # Optional if running from the source tree
+
+Run
+---
+
+ $ sudo wokd --host=0.0.0.0
+
+If you cannot access Wok, take a look at these 2 points:
+
+1. Firewall
+Wok uses by default the ports 8000, 8001 and 64667. To allow incoming connections:
+
+ For system using firewalld, do:
+ sudo firewall-cmd --add-port=8000/tcp --permanent
+ sudo firewall-cmd --add-port=8001/tcp --permanent
+ sudo firewall-cmd --add-port=64667/tcp --permanent
+ sudo firewall-cmd --reload
+
+ For openSUSE systems, do:
+ sudo /sbin/SuSEfirewall2 open EXT TCP 8000
+ sudo /sbin/SuSEfirewall2 open EXT TCP 8001
+ sudo /sbin/SuSEfirewall2 open EXT TCP 64667
+
+ For system using iptables, do:
+ sudo iptables -A INPUT -p tcp --dport 8000 -j ACCEPT
+ sudo iptables -A INPUT -p tcp --dport 8001 -j ACCEPT
+ sudo iptables -A INPUT -p tcp --dport 64667 -j ACCEPT
+
+ Don't forget to correctly save the rules.
+
+
+2. SELinux
+Allow httpd_t context for Wok web server:
+
+ semanage permissive -a httpd_t
+
+
+Test
+----
+
+ $ cd plugins/kimchi
+ $ make check-local # check for i18n and formatting errors
+ $ sudo make check
+
+After all tests are executed, a summary will be displayed containing any
+errors/failures which might have occurred.
+
+Usage
+-----
+
+Connect your browser to
https://localhost:8001. You should see a screen like:
+
+![Wok Login Screen](/docs/kimchi-login.png)
+
+Wok uses PAM to authenticate users so you can log in with the same username
+and password that you would use to log in to the machine itself. Once logged in
+you will see a screen like:
+
+![Kimchi Guest View](/docs/kimchi-guest.png)
+
+This shows you the list of running guests including a live screenshot of
+the guest session. You can use the action buttons to shutdown the guests
+or connect to the display in a new window.
+
+To create a new guest, click on the "+" button in the upper right corner.
+In Kimchi, all guest creation is done through templates.
+
+You can view or modify templates by clicking on the Templates link in the
+top navigation bar.
+
+The template screen looks like:
+
+![Kimchi Template View](/docs/kimchi-templates.png)
+
+From this view, you can change the parameters of a template or create a
+new template using the "+" button in the upper right corner.
+
+To create a template, you need an ISO on your host or using remote one.
+If you are willing to use your own ISO, please copy it to out of box storage
+pool (default path is: /var/lib/kimchi/isos).
+
+Known Issues
+------------
+
+1. When you are using NFS as storage pool, check the nfs export path permission
+is configured as:
+ (1) export path need to be squashed as kvm gid and libvirt uid:
+ /my_export_path *(all_squash,anongid=<kvm-gid>,
anonuid=<libvirt-uid>,rw,sync)
+ So that root user can create volume with right user/group.
+ (2) Chown of export path as libvirt user, group as kvm group,
+ In order to make sure all mapped user can get into the mount point.
+
+Participating
+-------------
+
+All patches are sent through our mailing list hosted by oVirt. More
+information can be found at:
+
+https://github.com/kimchi-project/kimchi/wiki/Communications
+
+Patches should be sent using git-send-email to kimchi-devel(a)ovirt.org.
diff --git a/src/wok/plugins/kimchi/docs/kimchi-guest.png
b/src/wok/plugins/kimchi/docs/kimchi-guest.png
new file mode 100644
index 0000000000000000000000000000000000000000..2ec8fea930b71c0e03a40700d79c4bbb63bf54e6
GIT binary patch
literal 192281
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
P00000NkvXXu0mjf{F7R-
literal 0
HcmV?d00001
diff --git a/src/wok/plugins/kimchi/docs/kimchi-login.png
b/src/wok/plugins/kimchi/docs/kimchi-login.png
new file mode 100644
index 0000000000000000000000000000000000000000..66387fd70adebc3b20b9520974a127ea7faa52ac
GIT binary patch
literal 318041
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%0A&`9-9b?c>R2A
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⪼mDSr{tK2+EhOBG_{{`e&G
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
NOI8XjSt(%@^gj?LcDMil
literal 0
HcmV?d00001
diff --git a/src/wok/plugins/kimchi/docs/kimchi-templates.png
b/src/wok/plugins/kimchi/docs/kimchi-templates.png
new file mode 100644
index 0000000000000000000000000000000000000000..ca3ba585b02668de97015bdd9ec4af64265592bd
GIT binary patch
literal 329678
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%0Ad3dx|<q`n;0ZSQ(k06~bLzVbUVbpXVB!PYn
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ⅅOnbhWduq*EF?|q_xg7h<I
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⪻gYAy<i$*4^-X7~$4F9lRG_zXCwb
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
kbi{8Dx<
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�#jfNGR9ga5FKn
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
IM6N<$f~8PYD*ylh
literal 0
HcmV?d00001
diff --git a/src/wok/plugins/kimchi/i18n.py b/src/wok/plugins/kimchi/i18n.py
new file mode 100644
index 0000000..253f00d
--- /dev/null
+++ b/src/wok/plugins/kimchi/i18n.py
@@ -0,0 +1,335 @@
+#
+# Project Kimchi
+#
+# Copyright IBM, Corp. 2014-2015
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+import gettext
+
+_ = gettext.gettext
+
+
+messages = {
+ "KCHAPI0001E": _("Unknown parameter %(value)s"),
+
+ "KCHASYNC0003E": _("Timeout of %(seconds)s seconds expired while
running task '%(task)s."),
+
+ "KCHAUTH0004E": _("User %(user_id)s not found with given LDAP
settings."),
+
+ "KCHDEVS0001E": _('Unknown "_cap" specified'),
+ "KCHDEVS0002E": _('"_passthrough" should be "true"
or "false"'),
+ "KCHDEVS0003E": _('"_passthrough_affected_by" should be a
device name string'),
+
+ "KCHDISKS0001E": _("Error while getting block devices. Details:
%(err)s"),
+ "KCHDISKS0002E": _("Error while getting block device information for
%(device)s."),
+
+ "KCHDL0001E": _("Unable to find distro file: %(filename)s"),
+ "KCHDL0002E": _("Unable to parse distro file: %(filename)s. Make sure,
it is a JSON file."),
+
+ "KCHISCSI0001E": _("Unable to login to iSCSI host target %(portal)s.
Details: %(err)s"),
+ "KCHISCSI0002E": _("Unable to login to iSCSI host %(host)s target
%(target)s"),
+
+ "KCHISO0001E": _("Unable to find ISO file %(filename)s"),
+ "KCHISO0002E": _("The ISO file %(filename)s is not bootable"),
+ "KCHISO0003E": _("The ISO file %(filename)s does not have a valid El
Torito boot record"),
+ "KCHISO0004E": _("Invalid El Torito validation entry in ISO
%(filename)s"),
+ "KCHISO0005E": _("Invalid El Torito boot indicator in ISO
%(filename)s"),
+ "KCHISO0006E": _("Unexpected volume type for primary volume in ISO
%(filename)s"),
+ "KCHISO0007E": _("Bad format while reading volume descriptor in ISO
%(filename)s"),
+ "KCHISO0008E": _("The hypervisor doesn't have permission to use
this ISO %(filename)s. "
+ "Consider moving it under /var/lib/libvirt, or set the search
permission "
+ "to file access control lists for '%(user)s' user if
possible, or add the "
+ "'%(user)s' to the ISO path group, or (not recommended)
'chmod -R o+x 'path_to_iso'."
+ "Details: %(err)s" ),
+
+ "KCHIMG0001E": _("An error occurred when probing image OS
information."),
+ "KCHIMG0002E": _("No OS information found in given image."),
+ "KCHIMG0003E": _("Unable to read image file %(filename)s"),
+ "KCHIMG0004E": _("Image file must be an existing file on system.
%(filename)s is not a valid input."),
+
+ "KCHVM0001E": _("Virtual machine %(name)s already exists"),
+ "KCHVM0002E": _("Virtual machine %(name)s does not exist"),
+ "KCHVM0003E": _("Unable to rename virtual machine %(name)s. The name
%(new_name)s is already in use or the virtual machine is not powered off."),
+ "KCHVM0004E": _("Unable to retrieve screenshot for stopped virtual
machine %(name)s"),
+ "KCHVM0005E": _("Remote ISO image is not supported by this
server."),
+ "KCHVM0006E": _("Screenshot is not supported on virtual machine
%(name)s"),
+ "KCHVM0007E": _("Unable to create virtual machine %(name)s. Details:
%(err)s"),
+ "KCHVM0008E": _("Unable to update virtual machine %(name)s. Details:
%(err)s"),
+ "KCHVM0009E": _("Unable to retrieve virtual machine %(name)s. Details:
%(err)s"),
+ "KCHVM0010E": _("Unable to connect to powered off virtual machine
%(name)s."),
+ "KCHVM0011E": _("Virtual machine name must be a string without slashes
(/)"),
+ "KCHVM0012E": _("Invalid template URI %(value)s specified for virtual
machine"),
+ "KCHVM0013E": _("Invalid storage pool URI %(value)s specified for
virtual machine"),
+ "KCHVM0014E": _("Supported virtual machine graphics are Spice or
VNC"),
+ "KCHVM0015E": _("Graphics address to listen on must be IPv4 or
IPv6"),
+ "KCHVM0016E": _("Specify a template to create a virtual machine
from"),
+ "KCHVM0019E": _("Unable to start virtual machine %(name)s. Details:
%(err)s"),
+ "KCHVM0020E": _("Unable to power off virtual machine %(name)s.
Details: %(err)s"),
+ "KCHVM0021E": _("Unable to delete virtual machine %(name)s. Details:
%(err)s"),
+ "KCHVM0022E": _("Unable to reset virtual machine %(name)s. Details:
%(err)s"),
+ "KCHVM0023E": _("User name list must be an array"),
+ "KCHVM0024E": _("User name must be a string"),
+ "KCHVM0025E": _("Group name list must be an array"),
+ "KCHVM0026E": _("Group name must be a string"),
+ "KCHVM0027E": _("User(s) '%(users)s' do not exist"),
+ "KCHVM0028E": _("Group(s) '%(groups)s' do not exist"),
+ "KCHVM0029E": _("Unable to shutdown virtual machine %(name)s. Details:
%(err)s"),
+ "KCHVM0030E": _("Unable to get access metadata of virtual machine
%(name)s. Details: %(err)s"),
+ "KCHVM0031E": _("The guest console password must be a string."),
+ "KCHVM0032E": _("The life time for the guest console password must be
a number."),
+ "KCHVM0033E": _("Virtual machine '%(name)s' must be stopped
before cloning it."),
+ "KCHVM0034E": _("Insufficient disk space to clone virtual machine
'%(name)s'"),
+ "KCHVM0035E": _("Unable to clone VM '%(name)s'. Details:
%(err)s"),
+ "KCHVM0036E": _("Invalid operation for non-persistent virtual machine
%(name)s"),
+ "KCHVM0037E": _("Cannot suspend VM '%(name)s' because it is
not running."),
+ "KCHVM0038E": _("Unable to suspend VM '%(name)s'. Details:
%(err)s"),
+ "KCHVM0039E": _("Cannot resume VM '%(name)s' because it is not
paused."),
+ "KCHVM0040E": _("Unable to resume VM '%(name)s'. Details:
%(err)s"),
+ "KCHVM0041E": _("Memory assigned is higher then the maximum allowed in
the host."),
+ "KCHVM0042E": _("VM '%(name)s' does not support live memory
update. Update the memory with the machine offline to enable this feature."),
+ "KCHVM0043E": _("Only increase memory is allowed in active
VMs"),
+ "KCHVM0044E": _("For live memory update, new memory value must be
equal old memory value plus multiples of 1024 Mib"),
+ "KCHVM0045E": _("There are not enough free slots of 1024 Mib in the
guest."),
+ "KCHVM0046E": _("Host's libvirt version does not support memory
devices. Libvirt must be >= 1.2.14"),
+ "KCHVM0047E": _("Error attaching memory device. Details:
%(error)s"),
+
+ "KCHVMHDEV0001E": _("VM %(vmid)s does not contain directly assigned
host device %(dev_name)s."),
+ "KCHVMHDEV0002E": _("The host device %(dev_name)s is not allowed to
directly assign to VM."),
+ "KCHVMHDEV0003E": _("No IOMMU groups found. Host PCI pass through
needs IOMMU group to function correctly. "
+ "Please enable Intel VT-d or AMD IOMMU in your BIOS, then
verify the Kernel is compiled with IOMMU support. "
+ "For Intel CPU, add intel_iommu=on to your Kernel parameter
in /boot/grub2/grub.conf. "
+ "For AMD CPU, add iommu=pt iommu=1."),
+ "KCHVMHDEV0004E": _('"name" should be a device name
string'),
+ "KCHVMHDEV0005E": _('The device %(name)s is probably in use by the
host. Unable to attach it to the guest.'),
+
+ "KCHVMIF0001E": _("Interface %(iface)s does not exist in virtual
machine %(name)s"),
+ "KCHVMIF0002E": _("Network %(network)s specified for virtual machine
%(name)s does not exist"),
+ "KCHVMIF0004E": _("Supported virtual machine interfaces type is only
network"),
+ "KCHVMIF0005E": _("Network name for virtual machine interface must be
a string"),
+ "KCHVMIF0006E": _("Invalid network model card specified for virtual
machine interface"),
+ "KCHVMIF0007E": _("Specify type and network to add a new virtual
machine interface"),
+ "KCHVMIF0008E": _("MAC Address must respect this format
FF:FF:FF:FF:FF:FF"),
+ "KCHVMIF0009E": _("MAC Address %(mac)s already exists in virtual
machine %(name)s"),
+ "KCHVMIF0010E": _("Invalid MAC Address"),
+ "KCHVMIF0011E": _("Cannot change MAC address of a running virtual
machine"),
+
+ "KCHTMPL0001E": _("Template %(name)s already exists"),
+ "KCHTMPL0003E": _("Network '%(network)s' specified for
template %(template)s does not exist"),
+ "KCHTMPL0004E": _("Storage pool %(pool)s specified for template
%(template)s does not exist"),
+ "KCHTMPL0005E": _("Storage pool %(pool)s specified for template
%(template)s is not active"),
+ "KCHTMPL0006E": _("Invalid parameter '%(param)s' specified for
CDROM."),
+ "KCHTMPL0007E": _("Network %(network)s specified for template
%(template)s is not active"),
+ "KCHTMPL0008E": _("Template name must be a string"),
+ "KCHTMPL0009E": _("Template icon must be a path to the image"),
+ "KCHTMPL0010E": _("Template distribution must be a string"),
+ "KCHTMPL0011E": _("Template distribution version must be a
string"),
+ "KCHTMPL0012E": _("The number of CPUs must be an integer greater than
0"),
+ "KCHTMPL0013E": _("Amount of memory (MB) must be an integer greater
than 512"),
+ "KCHTMPL0014E": _("Template CDROM must be a local or remote ISO
file"),
+ "KCHTMPL0015E": _("Invalid storage pool URI %(value)s specified for
template"),
+ "KCHTMPL0016E": _("Specify an ISO image as CDROM or a base image to
create a template"),
+ "KCHTMPL0017E": _("All networks for the template must be specified in
a list."),
+ "KCHTMPL0018E": _("Specify a volume to a template when storage pool is
iSCSI or SCSI"),
+ "KCHTMPL0019E": _("The volume %(volume)s is not in storage pool
%(pool)s"),
+ "KCHTMPL0020E": _("Unable to create template due error:
%(err)s"),
+ "KCHTMPL0021E": _("Unable to delete template due error:
%(err)s"),
+ "KCHTMPL0022E": _("Disk size must be an integer greater than
1GB."),
+ "KCHTMPL0023E": _("Template base image must be a valid local image
file"),
+ "KCHTMPL0024E": _("Cannot identify base image %(path)s format"),
+ "KCHTMPL0025E": _("When specifying CPU topology, VCPUs must be a
product of sockets, cores, and threads."),
+ "KCHTMPL0026E": _("When specifying CPU topology, each element must be
an integer greater than zero."),
+ "KCHTMPL0027E": _("Invalid disk image format. Valid formats: bochs,
cloop, cow, dmg, qcow, qcow2, qed, raw, vmdk, vpc."),
+
+ "KCHPOOL0001E": _("Storage pool %(name)s already exists"),
+ "KCHPOOL0002E": _("Storage pool %(name)s does not exist"),
+ "KCHPOOL0004E": _("Specify %(item)s in order to create the storage
pool %(name)s"),
+ "KCHPOOL0005E": _("Unable to delete active storage pool
%(name)s"),
+ "KCHPOOL0006E": _("Unable to list storage pools. Details:
%(err)s"),
+ "KCHPOOL0007E": _("Unable to create storage pool %(name)s. Details:
%(err)s"),
+ "KCHPOOL0008E": _("Unable to get number of storage volumes in storage
pool %(name)s. Details: %(err)s"),
+ "KCHPOOL0009E": _("Unable to activate storage pool %(name)s. Details:
%(err)s"),
+ "KCHPOOL0010E": _("Unable to deactivate storage pool %(name)s.
Details: %(err)s"),
+ "KCHPOOL0011E": _("Unable to delete storage pool %(name)s. Details:
%(err)s"),
+ "KCHPOOL0012E": _("Unable to create NFS Pool as export path %(path)s
may block during mount"),
+ "KCHPOOL0013E": _("Unable to create NFS Pool as export path %(path)s
mount failed"),
+ "KCHPOOL0014E": _("Unsupported storage pool type: %(type)s"),
+ "KCHPOOL0015E": _("Error while retrieving storage pool XML to
%(pool)s"),
+ "KCHPOOL0016E": _("Storage pool name must be a string without slashes
(/)"),
+ "KCHPOOL0017E": _("Supported storage pool types are dir, netfs,
logical, iscsi, isci and kimchi-iso"),
+ "KCHPOOL0018E": _("Storage pool path must be a string"),
+ "KCHPOOL0019E": _("Storage pool host must be a IP or hostname"),
+ "KCHPOOL0020E": _("Storage pool device must be the absolute path to
the block device"),
+ "KCHPOOL0021E": _("Storage pool devices parameter must be a
list"),
+ "KCHPOOL0022E": _("Target IQN of an iSCSI pool must be a
string"),
+ "KCHPOOL0023E": _("Port of a remote storage server must be an integer
between 1 and 65535"),
+ "KCHPOOL0024E": _("iSCSI target username must be a string"),
+ "KCHPOOL0025E": _("iSCSI target password must be a string"),
+ "KCHPOOL0026E": _("Specify name and type to create a storage
pool"),
+ "KCHPOOL0027E": _("%(disk)s is not a valid disk/partition. Could not
add it to the pool %(pool)s."),
+ "KCHPOOL0028E": _("Unable to extend logical pool %(pool)s. Details:
%(err)s"),
+ "KCHPOOL0029E": _("The parameter disks only can be updated for logical
storage pool."),
+ "KCHPOOL0030E": _("The SCSI host adapter name must be a
string."),
+ "KCHPOOL0031E": _("The storage pool kimchi_isos is reserved for
internal use"),
+ "KCHPOOL0032E": _("Unable to activate NFS storage pool %(name)s. NFS
server %(server)s is unreachable."),
+ "KCHPOOL0033E": _("Unable to deactivate NFS storage pool %(name)s. NFS
server %(server)s is unreachable."),
+ "KCHPOOL0034E": _("Unable to deactivate pool %(name)s as it is
associated with some templates"),
+ "KCHPOOL0035E": _("Unable to delete pool %(name)s as it is associated
with some templates"),
+ "KCHPOOL0036E": _("A volume group named '%(name)s' already
exists. Please, choose another name to create the logical pool."),
+ "KCHPOOL0037E": _("Unable to update database with deep scan
information due error: %(err)s"),
+
+ "KCHVOL0001E": _("Storage volume %(name)s already exists"),
+ "KCHVOL0002E": _("Storage volume %(name)s does not exist in storage
pool %(pool)s"),
+ "KCHVOL0003E": _("Unable to create storage volume %(volume)s because
storage pool %(pool)s is not active"),
+ "KCHVOL0004E": _("Specify %(item)s in order to create storage volume
%(volume)s"),
+ "KCHVOL0006E": _("Unable to list storage volumes because storage pool
%(pool)s is not active"),
+ "KCHVOL0007E": _("Unable to create storage volume %(name)s in storage
pool %(pool)s. Details: %(err)s"),
+ "KCHVOL0008E": _("Unable to list storage volumes in storage pool
%(pool)s. Details: %(err)s"),
+ "KCHVOL0009E": _("Unable to wipe storage volumes %(name)s. Details:
%(err)s"),
+ "KCHVOL0010E": _("Unable to delete storage volume %(name)s. Details:
%(err)s"),
+ "KCHVOL0011E": _("Unable to resize storage volume %(name)s. Details:
%(err)s"),
+ "KCHVOL0012E": _("Storage type %(type)s does not support volume create
and delete"),
+ "KCHVOL0013E": _("Storage volume name must be a string"),
+ "KCHVOL0014E": _("Storage volume allocation must be an integer
number"),
+ "KCHVOL0015E": _("Storage volume format not supported. Valid formats:
bochs, cloop, cow, dmg, qcow, qcow2, qed, raw, vmdk, vpc."),
+ "KCHVOL0016E": _("Storage volume requires a volume name"),
+ "KCHVOL0017E": _("Unable to update database with storage volume
information due error: %(err)s"),
+ "KCHVOL0018E": _("Only one of parameter %(param)s can be
specified"),
+ "KCHVOL0019E": _("Create volume from %(param)s is not
supported"),
+ "KCHVOL0020E": _("Storage volume capacity must be an integer
number."),
+ "KCHVOL0021E": _("Storage volume URL must be http://, https://, ftp://
or ftps://."),
+ "KCHVOL0022E": _("Unable to access file %(url)s. Please, check
it."),
+ "KCHVOL0023E": _("Unable to clone storage volume '%(name)s' in
pool '%(pool)s'. Details: %(err)s"),
+ "KCHVOL0024E": _("Specify chunk data and its size to upload a
file."),
+ "KCHVOL0025E": _("In order to upload a storage volume, specify the
'upload' parameter."),
+ "KCHVOL0026E": _("Unable to upload chunk data as it does not match
with requested chunk size."),
+ "KCHVOL0027E": _("The storage volume %(vol)s is not under an upload
process."),
+ "KCHVOL0028E": _("The upload chunk data will exceed the storage volume
size."),
+ "KCHVOL0029E": _("Unable to upload chunk data to storage volume.
Details: %(err)s."),
+
+ "KCHIFACE0001E": _("Interface %(name)s does not exist"),
+
+ "KCHNET0001E": _("Network %(name)s already exists"),
+ "KCHNET0002E": _("Network %(name)s does not exist"),
+ "KCHNET0003E": _("Subnet %(subnet)s specified for network %(network)s
is not valid."),
+ "KCHNET0004E": _("Specify a network interface to create bridged
network %(name)s"),
+ "KCHNET0005E": _("Unable to delete active network %(name)s"),
+ "KCHNET0006E": _("Interface %(iface)s specified for network
%(network)s is already in use"),
+ "KCHNET0007E": _("Interface should be bare NIC, bonding or bridge
device."),
+ "KCHNET0008E": _("Unable to create network %(name)s. Details:
%(err)s"),
+ "KCHNET0009E": _("Unable to find a free IP address for network
'%(name)s'"),
+ "KCHNET0010E": _("The interface %(iface)s already exists."),
+ "KCHNET0011E": _("Network name must be a string without slashes (/) or
quotes (\")"),
+ "KCHNET0012E": _("Supported network types are isolated, NAT and
bridge"),
+ "KCHNET0013E": _("Network subnet must be a string with IP address and
prefix or netmask"),
+ "KCHNET0014E": _("Network interface must be a string"),
+ "KCHNET0015E": _("Network VLAN ID must be an integer between 1 and
4094"),
+ "KCHNET0016E": _("Specify name and type to create a Network"),
+ "KCHNET0017E": _("Unable to delete network %(name)s. There are some
virtual machines %(vms)s and/or templates linked to this network."),
+ "KCHNET0018E": _("Unable to deactivate network %(name)s. There are
some virtual machines %(vms)s and/or templates linked to this network."),
+ "KCHNET0019E": _("Bridge device %(name)s can not be the trunk device
of a VLAN."),
+ "KCHNET0020E": _("Failed to activate interface %(iface)s:
%(err)s."),
+ "KCHNET0021E": _("Failed to activate interface %(iface)s. Please check
the physical link status."),
+ "KCHNET0022E": _("Failed to start network %(name)s. Details:
%(err)s"),
+
+ "KCHDR0001E": _("Debug report %(name)s does not exist"),
+ "KCHDR0002E": _("Debug report tool not found in system"),
+ "KCHDR0003E": _("Unable to create debug report %(name)s. Details:
%(err)s."),
+ "KCHDR0004E": _("Can not find any debug report with the given name
%(name)s"),
+ "KCHDR0005E": _("Unable to generate debug report %(name)s. Details:
%(err)s"),
+ "KCHDR0006E": _("You should give a name for the debug report
file."),
+ "KCHDR0007E": _("Debug report name must be a string. Only letters,
digits, underscore ('_') and hyphen ('-') are allowed."),
+ "KCHDR0008E": _("The debug report with specified name
\"%(name)s\" already exists. Please use another one."),
+
+ "KCHSR0001E": _("Storage server %(server)s was not used by
Kimchi"),
+
+ "KCHDISTRO0001E": _("Distro '%(name)s' does not exist"),
+
+ "KCHPART0001E": _("Partition %(name)s does not exist in the
host"),
+
+ "KCHHOST0001E": _("Unable to shutdown host machine as there are
running virtual machines"),
+ "KCHHOST0002E": _("Unable to reboot host machine as there are running
virtual machines"),
+ "KCHHOST0003E": _("Node device '%(name)s' not found"),
+ "KCHHOST0004E": _("Conflicting flag filters specified."),
+
+ "KCHPKGUPD0001E": _("No packages marked for update"),
+ "KCHPKGUPD0002E": _("Package %(name)s is not marked to be
updated."),
+ "KCHPKGUPD0003E": _("Error while getting packages marked to be
updated. Details: %(err)s"),
+ "KCHPKGUPD0004E": _("There is no compatible package manager for this
system."),
+
+ "KCHUTILS0003E": _("Unable to choose a virtual machine name"),
+
+ "KCHVMSTOR0002E": _("Invalid storage type. Types supported:
'cdrom', 'disk'"),
+ "KCHVMSTOR0003E": _("The path '%(value)s' is not a valid
local/remote path for the device"),
+ "KCHVMSTOR0006E": _("Only CDROM path can be update."),
+ "KCHVMSTOR0007E": _("The storage device %(dev_name)s does not exist in
the virtual machine %(vm_name)s"),
+ "KCHVMSTOR0008E": _("Error while creating new storage device:
%(error)s"),
+ "KCHVMSTOR0009E": _("Error while updating storage device:
%(error)s"),
+ "KCHVMSTOR0010E": _("Error while removing storage device:
%(error)s"),
+ "KCHVMSTOR0011E": _("Do not support IDE device hot plug"),
+ "KCHVMSTOR0012E": _("Specify type and path or type and pool/volume to
add a new virtual machine disk"),
+ "KCHVMSTOR0013E": _("Specify path to update virtual machine
disk"),
+ "KCHVMSTOR0014E": _("Controller type %(type)s limitation of %(limit)s
devices reached"),
+ "KCHVMSTOR0015E": _("Cannot retrieve disk path information for given
pool/volume: %(error)s"),
+ "KCHVMSTOR0016E": _("Volume already in use by other virtual
machine."),
+ "KCHVMSTOR0017E": _("Only one of path or pool/volume can be specified
to add a new virtual machine disk"),
+ "KCHVMSTOR0018E": _("Volume chosen with format %(format)s does not fit
in the storage type %(type)s"),
+
+ "KCHREPOS0001E": _("YUM Repository ID must be one word only
string."),
+ "KCHREPOS0002E": _("Repository URL must be an http://, ftp:// or
file:// URL."),
+ "KCHREPOS0003E": _("Repository configuration is a dictionary with
specific values according to repository type."),
+ "KCHREPOS0004E": _("Distribution to DEB repository must be a
string"),
+ "KCHREPOS0005E": _("Components to DEB repository must be listed in a
array"),
+ "KCHREPOS0006E": _("Components to DEB repository must be a
string"),
+ "KCHREPOS0007E": _("Mirror list to repository must be a
string"),
+ "KCHREPOS0008E": _("YUM Repository name must be string."),
+ "KCHREPOS0009E": _("GPG check must be a boolean value."),
+ "KCHREPOS0010E": _("GPG key must be a URL pointing to the
ASCII-armored file."),
+ "KCHREPOS0011E": _("Could not update repository %(repo_id)s."),
+ "KCHREPOS0012E": _("Repository %(repo_id)s does not exist."),
+ "KCHREPOS0013E": _("Specify repository base URL, mirror list or
metalink in order to create or update a YUM repository."),
+ "KCHREPOS0014E": _("Repository management tool was not recognized for
your system."),
+ "KCHREPOS0015E": _("Repository %(repo_id)s is already
enabled."),
+ "KCHREPOS0016E": _("Repository %(repo_id)s is already
disabled."),
+ "KCHREPOS0017E": _("Could not remove repository %(repo_id)s."),
+ "KCHREPOS0018E": _("Could not write repository configuration file
%(repo_file)s"),
+ "KCHREPOS0019E": _("Specify repository distribution in order to create
a DEB repository."),
+ "KCHREPOS0020E": _("Could not enable repository %(repo_id)s."),
+ "KCHREPOS0021E": _("Could not disable repository %(repo_id)s."),
+ "KCHREPOS0022E": _("YUM Repository ID already exists"),
+ "KCHREPOS0023E": _("YUM Repository name must be a string"),
+ "KCHREPOS0024E": _("Unable to list repositories. Details:
'%(err)s'"),
+ "KCHREPOS0025E": _("Unable to retrieve repository information.
Details: '%(err)s'"),
+ "KCHREPOS0026E": _("Unable to add repository. Details:
'%(err)s'"),
+ "KCHREPOS0027E": _("Unable to remove repository. Details:
'%(err)s'"),
+ "KCHREPOS0028E": _("Configuration items: '%(items)s' are not
supported by repository manager"),
+ "KCHREPOS0029E": _("Repository metalink must be an http://, ftp:// or
file:// URL."),
+ "KCHREPOS0030E": _("Cannot specify mirrorlist and metalink at the same
time."),
+
+ "KCHSNAP0001E": _("Virtual machine '%(vm)s' must be stopped
before creating a snapshot of it."),
+ "KCHSNAP0002E": _("Unable to create snapshot '%(name)s' on
virtual machine '%(vm)s'. Details: %(err)s"),
+ "KCHSNAP0003E": _("Snapshot '%(name)s' does not exist on
virtual machine '%(vm)s'."),
+ "KCHSNAP0004E": _("Unable to retrieve snapshot '%(name)s' on
virtual machine '%(vm)s'. Details: %(err)s"),
+ "KCHSNAP0005E": _("Unable to list snapshots on virtual machine
'%(vm)s'. Details: %(err)s"),
+ "KCHSNAP0006E": _("Unable to delete snapshot '%(name)s' on
virtual machine '%(vm)s'. Details: %(err)s"),
+ "KCHSNAP0008E": _("Unable to retrieve current snapshot of virtual
machine '%(vm)s'. Details: %(err)s"),
+ "KCHSNAP0009E": _("Unable to revert virtual machine '%(vm)s'
to snapshot '%(name)s'. Details: %(err)s"),
+ "KCHSNAP0010E": _("Unable to create snapshot of virtual machine
'%(vm)s' because it contains a disk with format '%(format)s'; only
'qcow2' is supported."),
+
+ "KCHCPUINF0001E": _("The number of vCPUs is too large for this
system."),
+ "KCHCPUINF0002E": _("Invalid vCPU/topology combination."),
+ "KCHCPUINF0003E": _("This host (or current configuration) does not
allow CPU topology."),
+
+}
diff --git a/src/wok/plugins/kimchi/imageinfo.py b/src/wok/plugins/kimchi/imageinfo.py
new file mode 100644
index 0000000..8a22495
--- /dev/null
+++ b/src/wok/plugins/kimchi/imageinfo.py
@@ -0,0 +1,72 @@
+#
+# Kimchi
+#
+# Copyright IBM, Corp. 2014
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+import guestfs
+import json
+import os
+import sys
+
+from wok.exception import ImageFormatError, InvalidParameter, TimeoutExpired
+from wok.utils import run_command, wok_log
+
+
+def probe_img_info(path):
+ cmd = ["qemu-img", "info", "--output=json", path]
+ info = dict()
+ try:
+ out = run_command(cmd, 10)[0]
+ except TimeoutExpired:
+ wok_log.warning("Cannot decide format of base img %s", path)
+ return None
+
+ info = json.loads(out)
+ info['virtual-size'] = info['virtual-size'] >> 30
+ info['actual-size'] = info['actual-size'] >> 30
+ return info
+
+
+def probe_image(image_path):
+ if not os.path.isfile(image_path):
+ raise InvalidParameter("KCHIMG0004E", {'filename':
image_path})
+
+ if not os.access(image_path, os.R_OK):
+ raise ImageFormatError("KCHIMG0003E", {'filename':
image_path})
+
+ g = guestfs.GuestFS(python_return_dict=True)
+ g.add_drive_opts(image_path, readonly=1)
+ g.launch()
+
+ try:
+ roots = g.inspect_os()
+ except:
+ raise ImageFormatError("KCHIMG0001E")
+
+ if len(roots) == 0:
+ raise ImageFormatError("KCHIMG0002E")
+
+ for root in roots:
+ version = "%d.%d" % (g.inspect_get_major_version(root),
+ g.inspect_get_minor_version(root))
+ distro = "%s" % (g.inspect_get_distro(root))
+
+ return (distro, version)
+
+
+if __name__ == '__main__':
+ print probe_image(sys.argv[1])
diff --git a/src/wok/plugins/kimchi/iscsi.py b/src/wok/plugins/kimchi/iscsi.py
new file mode 100644
index 0000000..02886ac
--- /dev/null
+++ b/src/wok/plugins/kimchi/iscsi.py
@@ -0,0 +1,88 @@
+#
+# Project Kimchi
+#
+# Copyright IBM, Corp. 2014
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301USA
+
+import subprocess
+
+
+from wok.exception import OperationFailed
+
+
+class TargetClient(object):
+ def __init__(self, target, host, port=None, auth=None):
+ self.portal = host + ("" if port is None else ":%s" % port)
+ self.target = target
+ self.auth = auth
+ self.targetCmd = ['iscsiadm', '--mode', 'node',
'--targetname',
+ self.target, '--portal', self.portal]
+
+ def _update_db(self, Name, Value):
+ self._run_cmd(['--op=update', '--name', Name, '--value',
Value])
+
+ def _update_auth(self):
+ if self.auth is None:
+ items = (('node.session.auth.authmethod', 'None'),
+ ('node.session.auth.username', ''),
+ ('node.session.auth.password', ''))
+ else:
+ items = (('node.session.auth.authmethod', 'CHAP'),
+ ('node.session.auth.username',
self.auth['username']),
+ ('node.session.auth.password',
self.auth['password']))
+ for name, value in items:
+ self._update_db(name, value)
+
+ def _run_cmd(self, cmd):
+ iscsiadm = subprocess.Popen(
+ self.targetCmd + cmd,
+ stdout=subprocess.PIPE, stderr=subprocess.PIPE)
+ out, err = iscsiadm.communicate()
+ if iscsiadm.returncode != 0:
+ msg_args = {'portal': self.portal, 'err': err}
+ raise OperationFailed("KCHISCSI0001E", msg_args)
+ return out
+
+ def _discover(self):
+ iscsiadm = subprocess.Popen(
+ ['iscsiadm', '--mode', 'discovery', '--type',
'sendtargets',
+ '--portal', self.portal],
+ stdout=subprocess.PIPE, stderr=subprocess.PIPE)
+ out, err = iscsiadm.communicate()
+ if iscsiadm.returncode != 0:
+ msg_args = {'portal': self.portal, 'err': err}
+ raise OperationFailed("KCHISCSI0001E", msg_args)
+ return out
+
+ def _run_op(self, op):
+ self._run_cmd(['--' + op])
+
+ def login(self):
+ self._discover()
+ self._update_auth()
+ self._run_op('login')
+
+ def logout(self):
+ self._run_op('logout')
+
+ def validate(self):
+ try:
+ self.login()
+ except OperationFailed:
+ return False
+
+ self.logout()
+ return True
diff --git a/src/wok/plugins/kimchi/isoinfo.py b/src/wok/plugins/kimchi/isoinfo.py
new file mode 100644
index 0000000..8de6885
--- /dev/null
+++ b/src/wok/plugins/kimchi/isoinfo.py
@@ -0,0 +1,506 @@
+#
+# Project Kimchi
+#
+# Copyright IBM, Corp. 2013-2015
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+import contextlib
+import glob
+import os
+import platform
+import re
+import stat
+import struct
+import sys
+import urllib2
+
+
+from wok.exception import IsoFormatError
+from wok.utils import check_url_path, wok_log
+
+
+iso_dir = [
+ ##
+ # Portions of this data from libosinfo:
http://libosinfo.org/
+ #
+ # Each tuple has the following three members:
+ # Distro ID: Nickname for the distro or OS family
+ # Distro Version: A function or string that provides a specific version
+ # given a regular expression match on the volume id string
+ # Regular Expression: A regex to match against the ISO Volume ID
+ ##
+ ('openbsd', lambda m: m.group(2),
+ ('OpenBSD/(i386|amd64) (\d+\.\d+) Install CD')),
+ ('centos', lambda m: m.group(1),
+ ('CentOS_(\d+\.\d+)_Final')),
+ ('windows', '2000',
+ ('W2AFPP|SP1AFPP|SP2AFPP|YRMAFPP|ZRMAFPP|W2AOEM|SP1AOEM|SP2AOEM' +
+ '|YRMAOEM|ZRMAOEM|W2ASEL|SP2ASEL|W2SFPP|SP1SFPP|SP2SFPP|YRMSFPP' +
+ '|ZRMSFPP|W2SOEM|W2SOEM|SP1SOEM|SP2SOEM|YRMSOEM|ZRMSOEM|W2SSEL' +
+ '|SP2SSEL|W2PFPP|SP1PFPP|SP2PFPP|YRMPFPP|ZRMPFPP|W2POEM|SP1POEM' +
+ '|SP2POEM|YRMPOEM|ZRMPOEM|W2PSEL|SP2PSEL|W2PCCP|WIN2000|W2K_SP4')),
+ ('windows', 'xp',
+ ('WXPFPP|WXHFPP|WXPCCP|WXHCCP|WXPOEM|WXHOEM|WXPVOL|WXPEVL|XRMPFPP' +
+ '|XRMHFPP|XRMPCCP|XRMHCCP|XRMPOEM|XRMHOEM|XRMPVOL|XRMSD2|X1APFPP' +
+ '|X1AHFPP|X1APCCP|X1APCCP|X1AHCCP|X1APOEM|X1AHOEM|X1APVOL|VRMPFPP' +
+ '|VRMHFPP|VRMPCCP|VRMHCCP|VRMPOEM|VRMHOEM|VRMPVOL|VRMSD2|VX2PFPP' +
+ '|VX2HFPP|VX2PCCP|VX2HCCP|VX2POEM|VX2HOEM|VX2PRMFPP|VX2PVOL|GRTMUPD' +
+ '|GRTMPFPP|GRTMPRMFPP|GRTMHFPP|GRTMHKFPP|GRTMHKNFPP|GRTMHRMFPP' +
+ '|GRTMPOEM|GRTMHOEM|GRTMPVOL|GRTMPKNVOL|GRTMPKVOL|GRTMPRMVOL' +
+ '|MX2PFPP|MRMSD2|ARMPXFPP|ARMPXCCP|ARMPXOEM|ARMPXVOL|AX2PXCFPP' +
+ '|AX2PXFPP|NRMPIFPP')),
+ ('windows', '2003',
+ ('ARMECHK|ARMEVOL|ARMSVOL|ARMWVOL|ARMEEVL|ARMSEVL|ARMWEVL|ARMEOEM' +
+ '|ARMDOEM|ARMSOEM|ARMWOEM|ARMEFPP|ARMDFPP|ARMSFPP|ARMWFPP|NRMECHK' +
+ '|NRMEVOL|NRMSVOL|NRMWVOL|NRMEEVL|NRMSEVL|NRMWEVL|NRMEOEM|NRMDOEM' +
+ '|NRMSOEM|NRMWOEM|NRMEFPP|NRMDFPP|NRMSFPP|NRMSFPP|CRMSVOL|CRMSXVOL' +
+ '|BRMEVOL|BX2DVOL|ARMEEVL|BRMEEVL|CR0SP2|ARMEICHK|ARMEIFPP|ARMEIEVL' +
+ '|ARMEIOEM|ARMDIOEM|ARMEXFPP|ARMDFPP|ARMSXFPP|CR0SPX2|NRMEICHK' +
+ '|NRMEIFPP|NRMDIFPP|NRMEIOEM|NRMDIOEM|NRMEIVOL|NRMEIEVL|BRMEXVOL' +
+ '|BX2DXVOL|ARMEIFPP|CR0SPI2')),
+ ('windows', '2003r2',
+ ('CRMEFPP|CRMSFPP|CR0SCD2|CR0ECD2|BX2SFPP|BX2EFPP|BRMECD2FRE' +
+ '|BRMSCD2FRE|CRMEXFPP|CRMSXFPP|CR0SCD2X|CR0ECD2X|BX2SXFPP|BX2EXFPP' +
+ '|BRMECD2XFRE|BRMSCD2XFRE|CRMDVOL|CRMDXVOL')),
+ ('windows', '2008',
+ ('KRTMSVOL|KRTMSCHK|KRMWVOL|KRMSVOL|KRTMSXVOL|KRTMSXCHK|KRMWXVOL' +
+ '|KRMSXVOL')),
+ ('windows', '2008r2',
+ ('GRMSXVOL|GRMSXFRER|GRMSHXVOL|GRMSIAIVOL|SRVHPCR2')),
+ ('windows', 'vista',
+ ('FB1EVOL|LRMCFRE|FRTMBVOL|FRMBVOL|FRMEVOL|FB1EXVOL|LRMCXFRE' +
+ '|FRTMBXVOL|FRMBXVOL|FRMEXVOL|LRMEVOL|LRMEXVOL')),
+ ('windows', '7',
+ ('GRMCULFRER|GSP1RMCNPRFRER|GSP1RMCNULFRER|GSP1RMCULFRER' +
+ '|GSP1RMCPRFRER|GRMCENVOL|GRMCNENVOL|GRMCPRFRER|GSP1RMCPRVOL' +
+ '|GRMCULXFRER|GSP1RMCPRXFRER|GSP1RMCNHPXFRER|GRMCHPXFRER|GRMCXCHK' +
+ '|GSP1RMCENXVOL|GRMCENXVOL|GRMCNENXVOL|GRMCPRXFRER|GSP1RMCPRXVOL')),
+ ('windows', '8',
+ ('HB1_CCPA_X86FRE|HRM_CCSA_X86FRE|HRM_CCSA_X86CHK|HRM_CCSNA_X86CHK' +
+ '|HRM_CCSNA_X86FRE|HRM_CENA_X86FREV|HRM_CENA_X86CHKV' +
+ '|HRM_CENNA_X86FREV|HRM_CENNA_X86CHKV|HRM_CPRA_X86FREV' +
+ '|HRM_CPRNA_X86FREV|HB1_CCPA_X64FRE|HRM_CCSA_X64FRE' +
+ '|HRM_CCSA_X64CHK|HRM_CCSNA_X64FRE|HRM_CCSNA_X64CHK' +
+ '|HRM_CENNA_X64FREV|HRM_CENNA_X64CHKV|HRM_CENA_X64FREV' +
+ '|HRM_CENA_X64CHKV|HRM_CPRA_X64FREV|HRM_CPRNA_X64FREV')),
+ ('sles', '10', 'SLES10|SUSE-Linux-Enterprise-Server.001'),
+ ('sles', '11', 'SUSE_SLES-11-0-0'),
+ ('sles', '12', 'SLE-12'),
+ ('sles', lambda m: "11sp%s" % m.group(1),
'SLES-11-SP(\d+)'),
+ ('opensuse', lambda m: m.group(1), 'openSUSE[ -](\d+\.\d+)'),
+ ('opensuse', '11.1', 'SU1110.001'),
+ ('opensuse', '11.3',
+ 'openSUSE-DVD-i586-Build0702..001|openSUSE-DVD-x86_64.0702..001'),
+ ('opensuse', '11.4',
+ 'openSUSE-DVD-i586-Build0024|openSUSE-DVD-x86_640024'),
+ ('opensuse', '12.1',
+ 'openSUSE-DVD-i586-Build0039|openSUSE-DVD-x86_640039'),
+ ('opensuse', '12.2',
+ 'openSUSE-DVD-i586-Build0167|openSUSE-DVD-x86_640167'),
+ ('rhel', '4.8', 'RHEL/4-U8'),
+ ('rhel', lambda m: m.group(2), 'RHEL(-LE)?[_/-](\d+\.\d+)'),
+ ('debian', lambda m: m.group(1), 'Debian (\d+\.\d+)'),
+ ('ubuntu', lambda m: m.group(2), '[Uu]buntu(-Server)? (\d+\.\d+)'),
+ ('fedora', lambda m: m.group(1), 'Fedora[ -](\d+)'),
+ ('fedora', lambda m: m.group(1), 'Fedora.*-(\d+)-'),
+ ('gentoo', lambda m: m.group(1), 'Gentoo Linux \w+ (\d+)'),
+ ('powerkvm', 'live_cd', 'POWERKVM_LIVECD'),
+ ('arch', lambda m: m.group(1), 'ARCH_(\d+)'),
+]
+
+
+class IsoImage(object):
+ """
+ Scan an iso9660 image to extract the Volume ID and check for boot-ability
+
+ ISO-9660 specification:
+
http://www.ecma-international.org/publications/standards/Ecma-119.htm
+
+ El-Torito specification:
+
http://download.intel.com/support/motherboards/desktop/sb/specscdrom.pdf
+ """
+ SECTOR_SIZE = 2048
+ VOL_DESC = struct.Struct("=B5sBB32s32s")
+ EL_TORITO_BOOT_RECORD = struct.Struct("=B5sB32s32sI")
+ EL_TORITO_VALIDATION_ENTRY = struct.Struct("=BBH24sHBB")
+ EL_TORITO_BOOT_ENTRY = struct.Struct("=BBHBBHL20x")
+ # Path table info starting in ISO9660 offset 132. We force little
+ # endian byte order (the '<' sign) because Power systems can run on
+ # both.
+ # First int is path table size, next 4 bytes are discarded (it is
+ # the same info but in big endian) and next int is the location.
+ PATH_TABLE_SIZE_LOC = struct.Struct("<I 4s I")
+
+ def __init__(self, path):
+ self.path = path
+ self.remote = self._is_iso_remote()
+ self.volume_id = None
+ self.bootable = False
+ self._scan()
+
+ def _is_iso_remote(self):
+ if os.path.exists(self.path):
+ st_mode = os.stat(self.path).st_mode
+ if stat.S_ISREG(st_mode) or stat.S_ISBLK(st_mode):
+ return False
+
+ if check_url_path(self.path):
+ return True
+
+ raise IsoFormatError("KCHISO0001E", {'filename': self.path})
+
+ def probe(self):
+ if not self.bootable:
+ raise IsoFormatError("KCHISO0002E", {'filename':
self.path})
+
+ matcher = Matcher(self.volume_id)
+
+ for d, v, regex in iso_dir:
+ if matcher.search(regex):
+ distro = d
+ if hasattr(v, '__call__'):
+ version = v(matcher)
+ else:
+ version = v
+ return (distro, version)
+
+ msg = "probe_iso: Unable to identify ISO %s with Volume ID: %s"
+ wok_log.debug(msg, self.path, self.volume_id)
+
+ return ('unknown', 'unknown')
+
+ def _unpack(self, s, data):
+ return s.unpack(data[:s.size])
+
+ def _scan_el_torito(self, data):
+ """
+ Search the Volume Descriptor Table for an El Torito boot record. If
+ found, the boot record will provide a link to a boot catalogue. The
+ first entry in the boot catalogue is a validation entry. The next
+ entry contains the default boot entry. The default boot entry will
+ indicate whether the image is considered bootable.
+ """
+ vd_type = -1
+ for i in xrange(1, 4):
+ fmt = IsoImage.EL_TORITO_BOOT_RECORD
+ ptr = i * IsoImage.SECTOR_SIZE
+ tmp_data = data[ptr:ptr + fmt.size]
+ if len(tmp_data) < fmt.size:
+ return
+
+ (vd_type, vd_ident, vd_ver,
+ et_ident, pad0, boot_cat) = self._unpack(fmt, tmp_data)
+ if vd_type == 255: # Volume record terminator
+ return
+ if vd_type == 0: # Found El-Torito Boot Record
+ break
+ if not et_ident.startswith('EL TORITO SPECIFICATION'):
+ raise IsoFormatError("KCHISO0003E",
+ {'filename': self.path})
+
+ offset = IsoImage.SECTOR_SIZE * boot_cat
+ size = IsoImage.EL_TORITO_VALIDATION_ENTRY.size + \
+ IsoImage.EL_TORITO_BOOT_ENTRY.size
+ data = self._get_iso_data(offset, size)
+
+ fmt = IsoImage.EL_TORITO_VALIDATION_ENTRY
+ tmp_data = data[0:fmt.size]
+ ptr = fmt.size
+ (hdr_id, platform_id, pad0,
+ ident, csum, key55, keyAA) = self._unpack(fmt, tmp_data)
+ if key55 != 0x55 or keyAA != 0xaa:
+ raise IsoFormatError("KCHISO0004E",
+ {'filename': self.path})
+
+ fmt = IsoImage.EL_TORITO_BOOT_ENTRY
+ tmp_data = data[ptr:ptr + fmt.size]
+ (boot, media_type, load_seg, sys_type,
+ pad0, sectors, load_rba) = self._unpack(fmt, tmp_data)
+ if boot == 0x88:
+ self.bootable = True
+ elif boot == 0:
+ self.bootable = False
+ else:
+ raise IsoFormatError("KCHISO0005E",
+ {'filename': self.path})
+
+ def _scan_ppc(self):
+ """
+ PowerPC firmware does not use the conventional El Torito boot
+ specification. Instead, it looks for a file '/ppc/bootinfo.txt'
+ which contains boot information. A PPC image is bootable if
+ this file exists in the filesystem [1].
+
+ To detect if a PPC ISO is bootable, we could simply mount the
+ ISO and search for the boot file as we would with any other
+ file in the filesystem. We can also look for the boot file
+ searching byte by byte the ISO image. This is possible because
+ the PPC ISO image follows the ISO9660 standard [2]. Mounting
+ the ISO requires extra resources and it takes longer than
+ searching the image data, thus we chose the latter approach
+ in this code.
+
+ To locate a file we must access the Path Table, which contains
+ the records of all the directories in the ISO. After locating
+ the directory/subdirectory that contains the file, we access
+ the Directory Record to find it.
+
+
+ .. [1]
https://www.ibm.com/developerworks/community/wikis/home?\
+lang=en#!/wiki/W51a7ffcf4dfd_4b40_9d82_446ebc23c550/page/PowerLinux\
+%20Boot%20howto
+ .. [2]
http://wiki.osdev.org/ISO_9660
+ """
+
+ # To locate any file we must access the Path Table, which
+ # contains the records of all the directories in the ISO.
+ # ISO9660 dictates that the Path Table location information
+ # is at offset 132, inside the Primary Volume Descriptor,
+ # after the SystemArea (16*SECTOR_SIZE).
+ #
+ # In the Path table info we're forcing little endian byte
+ # order (the '<' sign) because Power systems can run on
+ # both.
+ #
+ # First int is path table size, next 4 bytes are discarded (it is
+ # the same info but in big endian) and next int is the location.
+ PATH_TABLE_LOC_OFFSET = 16 * IsoImage.SECTOR_SIZE + 132
+ PATH_TABLE_SIZE_LOC = struct.Struct("<I 4s I")
+
+ path_table_loc_data = self._get_iso_data(PATH_TABLE_LOC_OFFSET,
+ PATH_TABLE_SIZE_LOC.size)
+ path_size, unused, path_loc = self._unpack(PATH_TABLE_SIZE_LOC,
+ path_table_loc_data)
+ # Fetch the Path Table using location and size found above
+ path_table_offset = path_loc * IsoImage.SECTOR_SIZE
+ path_table_data = self._get_iso_data(path_table_offset, path_size)
+
+ # Loop inside the path table to find the directory 'ppc'.
+ # The contents of the registers are:
+ # - length of the directory identifier (1 byte)
+ # - extended attribute record length (1 byte)
+ # - location of directory register (4 bytes)
+ # - directory number of parent dir (2 bytes)
+ # - directory name (size varies according to length)
+ # - padding field - 1 byte if the length is odd, not present if even
+ DIR_NAMELEN_LOCATION_PARENT = struct.Struct("<B B I H")
+ dir_struct_size = DIR_NAMELEN_LOCATION_PARENT.size
+ i = 0
+ while i < path_size:
+ dir_data = path_table_data[i: i+dir_struct_size]
+ i += dir_struct_size
+ # We won't use the Extended Attribute Record
+ dir_namelen, unused, dir_loc, dir_parent = \
+ self._unpack(DIR_NAMELEN_LOCATION_PARENT, dir_data)
+ if dir_parent == 1:
+ # read the dir name using the namelen
+ dir_name = path_table_data[i: i+dir_namelen].rstrip()
+ if dir_name.lower() == 'ppc':
+ # stop searching, dir was found
+ break
+ # Need to consider the optional padding field as well
+ i += dir_namelen + dir_namelen % 2
+
+ if i > path_size:
+ # Didn't find the '/ppc' directory. ISO is not bootable.
+ self.bootable = False
+ return
+
+ # Get the 'ppc' directory record using 'dir_loc'.
+ ppc_dir_offset = dir_loc * IsoImage.SECTOR_SIZE
+
+ # We need to find the sector size of this dir entry. The
+ # size of the File Section is located 10 bytes after
+ # the dir location.
+ DIR_SIZE_FMT = struct.Struct("<10sI")
+ data = self._get_iso_data(ppc_dir_offset, DIR_SIZE_FMT.size)
+ unused, dir_size = self._unpack(DIR_SIZE_FMT, data)
+ # If the dir is in the middle of a sector, the sector is
+ # padded zero and won't be utilized. We need to round up
+ # the result
+ dir_sectorsize = dir_size / IsoImage.SECTOR_SIZE
+ if dir_size % IsoImage.SECTOR_SIZE:
+ dir_sectorsize += 1
+
+ # Fixed-size directory record fields:
+ # - length of directory record (1 byte)
+ # - extended attr. record length (1 byte)
+ # - location of extend in both-endian format (8 bytes)
+ # - data length (size of extend) in both-endian (8 bytes)
+ # - recording date and time (7 bytes)
+ # - file flags (1 byte)
+ # - file unit size interleaved (1 byte)
+ # - interleave gap size (1 byte)
+ # - volume sequence number (4 bytes)
+ # - length of file identifier (1 byte)
+ #
+ # Of all these fields, we will use only 3 of them, 'ignoring'
+ # 30 bytes total.
+ STATIC_DIR_RECORD_FMT = struct.Struct("<B 24s B 6s B")
+ static_rec_size = STATIC_DIR_RECORD_FMT.size
+
+ # Maximum offset possible of all the records of this directory
+ DIR_REC_MAX = ppc_dir_offset + dir_sectorsize*IsoImage.SECTOR_SIZE
+ # Max size of a given directory record
+ MAX_DIR_SIZE = 255
+ # Name of the boot file
+ BOOT_FILE_NAME = "bootinfo.txt"
+
+ # Loop until one of the following happens:
+ # - boot file is found
+ # - end of directory record listing for the 'ppc' dir
+ while ppc_dir_offset < DIR_REC_MAX:
+ record_data = self._get_iso_data(ppc_dir_offset, MAX_DIR_SIZE)
+ dir_rec_len, unused, file_flags, unused2, file_name_len = \
+ self._unpack(STATIC_DIR_RECORD_FMT, record_data)
+
+ # if dir_rec_len = 0, increment offset (skip the
+ # dir_rec_len byte) and continue the loop
+ if dir_rec_len == 0:
+ ppc_dir_offset += 1
+ continue
+
+ # Get filename of the file/dir we're at.
+ filename = record_data[static_rec_size:
+ static_rec_size + file_name_len].rstrip()
+ # The second bit of the file_flags indicate if this record
+ # is a directory.
+ if BOOT_FILE_NAME in filename.lower() and (file_flags & 2) != 1:
+ self.bootable = True
+ return
+
+ # Update offset and keep looking. There is a padding here
+ # if the length of the file identifier is EVEN.
+ padding = 0
+ if not file_name_len % 2:
+ padding = 1
+ ppc_dir_offset += dir_rec_len + padding
+ # If reached this point the file wasn't found = not bootable
+ self.bootable = False
+
+ def _scan_primary_vol(self, data):
+ """
+ Scan one sector for a Primary Volume Descriptor and extract the
+ Volume ID from the table
+ """
+ primary_vol_data = data[0: -1]
+ info = self._unpack(IsoImage.VOL_DESC, primary_vol_data)
+ (vd_type, vd_ident, vd_ver, pad0, sys_id, vol_id) = info
+ if vd_type != 1:
+ raise IsoFormatError("KCHISO0006E", {'filename':
self.path})
+ if vd_ident != 'CD001' or vd_ver != 1:
+ raise IsoFormatError("KCHISO0007E", {'filename':
self.path})
+ if vol_id.strip() == 'RED_HAT':
+ # Some RHEL ISO images store the infomation of volume id in the
+ # location of volume set id mistakenly.
+ self.volume_id = self._get_volume_set_id(data)
+ else:
+ self.volume_id = vol_id
+
+ def _get_volume_set_id(self, data):
+ # The index is picked from ISO-9660 specification.
+ return data[190: 318]
+
+ def _get_iso_data(self, offset, size):
+ if self.remote:
+ request = urllib2.Request(self.path)
+ range_header = "bytes=%d-%d" % (offset, offset + size - 1)
+ request.add_header("range", range_header)
+ with contextlib.closing(urllib2.urlopen(request)) as response:
+ data = response.read()
+ else:
+ with open(self.path) as fd:
+ fd.seek(offset)
+ data = fd.read(size)
+
+ return data
+
+ def _scan(self):
+ offset = 16 * IsoImage.SECTOR_SIZE
+ size = 4 * IsoImage.SECTOR_SIZE
+ data = self._get_iso_data(offset, size)
+ if len(data) < 2 * IsoImage.SECTOR_SIZE:
+ return
+
+ self._scan_primary_vol(data)
+ if platform.machine().startswith('ppc'):
+ self._scan_ppc()
+ else:
+ self._scan_el_torito(data)
+
+
+class Matcher(object):
+ """
+ Simple utility class to assist with matching a given string against a
+ series of regular expressions.
+ """
+ def __init__(self, matchstring):
+ self.matchstring = matchstring
+
+ def search(self, regex):
+ self.lastmatch = re.search(regex, self.matchstring)
+ return bool(self.lastmatch)
+
+ def group(self, num):
+ return self.lastmatch.group(num)
+
+
+def probe_iso(status_helper, params):
+ loc = params['path'].encode("utf-8")
+ updater = params['updater']
+ ignore = False
+ ignore_list = params.get('ignore_list', [])
+
+ def update_result(iso, ret):
+ path = os.path.abspath(iso) if os.path.isfile(iso) else iso
+ updater({'path': path, 'distro': ret[0], 'version':
ret[1]})
+
+ if os.path.isdir(loc):
+ for root, dirs, files in os.walk(loc):
+ for dir_name in ignore_list:
+ if root in glob.glob(dir_name):
+ ignore = True
+ break
+ if ignore:
+ ignore = False
+ continue
+ for name in files:
+ if not name.lower().endswith('.iso'):
+ continue
+ iso = os.path.join(root, name)
+ try:
+ iso_img = IsoImage(iso)
+ ret = iso_img.probe()
+ update_result(iso, ret)
+ except:
+ continue
+ else:
+ iso_img = IsoImage(loc)
+ ret = iso_img.probe()
+ update_result(loc, ret)
+
+ if status_helper is not None:
+ status_helper('', True)
+
+
+if __name__ == '__main__':
+ iso_list = []
+
+ def updater(iso_info):
+ iso_list.append(iso_info)
+
+ probe_iso(None, dict(path=sys.argv[1], updater=updater))
+ print iso_list
diff --git a/src/wok/plugins/kimchi/kimchi.conf b/src/wok/plugins/kimchi/kimchi.conf
new file mode 100644
index 0000000..1bf78e4
--- /dev/null
+++ b/src/wok/plugins/kimchi/kimchi.conf
@@ -0,0 +1,37 @@
+[wok]
+enable = True
+plugin_class = "KimchiRoot"
+uri = "/plugins/kimchi"
+extra_auth_api_class = "control.sub_nodes"
+
+[/]
+tools.trailing_slash.on = False
+request.methods_with_bodies = ('POST', 'PUT')
+tools.nocache.on = True
+tools.proxy.on = True
+tools.sessions.on = True
+tools.sessions.name = 'wok'
+tools.sessions.secure = True
+tools.sessions.httponly = True
+tools.sessions.locking = 'explicit'
+tools.sessions.storage_type = 'ram'
+tools.sessions.timeout = 10
+tools.wokauth.on = True
+
+[/data/screenshots]
+tools.staticdir.on = True
+tools.staticdir.dir = wok.config.PluginPaths('kimchi').state_dir +
'/screenshots'
+tools.nocache.on = False
+
+[/data/debugreports]
+tools.staticdir.on = True
+tools.staticdir.dir = wok.config.PluginPaths('kimchi').state_dir +
'/debugreports'
+tools.nocache.on = False
+tools.wokauth.on = True
+tools.staticdir.content_types = {'xz': 'application/x-xz'}
+
+[/help]
+tools.staticdir.on = True
+tools.staticdir.dir = wok.config.PluginPaths('kimchi').ui_dir +
'/pages/help'
+tools.nocache.on = True
+
diff --git a/src/wok/plugins/kimchi/kvmusertests.py
b/src/wok/plugins/kimchi/kvmusertests.py
new file mode 100644
index 0000000..35350d8
--- /dev/null
+++ b/src/wok/plugins/kimchi/kvmusertests.py
@@ -0,0 +1,79 @@
+# Project Kimchi
+#
+# Copyright IBM, Corp. 2014-2015
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+import libvirt
+import platform
+import psutil
+import threading
+
+
+from wok.rollbackcontext import RollbackContext
+
+KVMUSERTEST_VM_NAME = "KVMUSERTEST_VM"
+
+
+class UserTests(object):
+ SIMPLE_VM_XML = """
+ <domain type='kvm'>
+ <name>%(name)s</name>
+ <memory unit='KiB'>262144</memory>
+ <os>
+ <type arch='%(arch)s'>hvm</type>
+ <boot dev='hd'/>
+ </os>
+ </domain>"""
+ lock = threading.Lock()
+ user = None
+
+ @classmethod
+ def probe_user(cls):
+ with cls.lock:
+ if cls.user:
+ return cls.user
+
+ arch = 'ppc64' if platform.machine() == 'ppc64le' \
+ else platform.machine()
+
+ xml = cls.SIMPLE_VM_XML % {'name': KVMUSERTEST_VM_NAME, 'arch':
arch}
+
+ with RollbackContext() as rollback:
+ with cls.lock:
+ conn = libvirt.open(None)
+ rollback.prependDefer(conn.close)
+ f = libvirt.VIR_DOMAIN_START_AUTODESTROY
+ dom = conn.createXML(xml, flags=f)
+ rollback.prependDefer(dom.destroy)
+ filename = '/var/run/libvirt/qemu/%s.pid' % KVMUSERTEST_VM_NAME
+ with open(filename) as f:
+ pidStr = f.read()
+ p = psutil.Process(int(pidStr))
+
+ # bug fix #357
+ # in psutil 2.0 and above versions, username will be a method,
+ # not a string
+ if callable(p.username):
+ cls.user = p.username()
+ else:
+ cls.user = p.username
+
+ return cls.user
+
+
+if __name__ == '__main__':
+ ut = UserTests()
+ print ut.probe_user()
diff --git a/src/wok/plugins/kimchi/m4/ac_python_module.m4
b/src/wok/plugins/kimchi/m4/ac_python_module.m4
new file mode 100644
index 0000000..32b9d72
--- /dev/null
+++ b/src/wok/plugins/kimchi/m4/ac_python_module.m4
@@ -0,0 +1,30 @@
+dnl @synopsis AC_PYTHON_MODULE(modname[, fatal])
+dnl
+dnl Checks for Python module.
+dnl
+dnl If fatal is non-empty then absence of a module will trigger an
+dnl error.
+dnl
+dnl @category InstalledPackages
+dnl @author Andrew Collier <colliera(a)nu.ac.za>.
+dnl @version 2004-07-14
+dnl @license AllPermissive
+
+AC_DEFUN([AC_PYTHON_MODULE],[
+ AC_MSG_CHECKING(python module: $1)
+ python -c "import $1" 2>/dev/null
+ if test $? -eq 0;
+ then
+ AC_MSG_RESULT(yes)
+ eval AS_TR_CPP(HAVE_PYMOD_$1)=yes
+ else
+ AC_MSG_RESULT(no)
+ eval AS_TR_CPP(HAVE_PYMOD_$1)=no
+ #
+ if test -n "$2"
+ then
+ AC_MSG_ERROR(failed to find required module $1)
+ exit 1
+ fi
+ fi
+])
diff --git a/src/wok/plugins/kimchi/m4/gettext.m4 b/src/wok/plugins/kimchi/m4/gettext.m4
new file mode 100644
index 0000000..f84e6a5
--- /dev/null
+++ b/src/wok/plugins/kimchi/m4/gettext.m4
@@ -0,0 +1,383 @@
+# gettext.m4 serial 63 (gettext-0.18)
+dnl Copyright (C) 1995-2010 Free Software Foundation, Inc.
+dnl This file is free software; the Free Software Foundation
+dnl gives unlimited permission to copy and/or distribute it,
+dnl with or without modifications, as long as this notice is preserved.
+dnl
+dnl This file can can be used in projects which are not available under
+dnl the GNU General Public License or the GNU Library General Public
+dnl License but which still want to provide support for the GNU gettext
+dnl functionality.
+dnl Please note that the actual code of the GNU gettext library is covered
+dnl by the GNU Library General Public License, and the rest of the GNU
+dnl gettext package package is covered by the GNU General Public License.
+dnl They are *not* in the public domain.
+
+dnl Authors:
+dnl Ulrich Drepper <drepper(a)cygnus.com>, 1995-2000.
+dnl Bruno Haible <haible(a)clisp.cons.org>, 2000-2006, 2008-2010.
+
+dnl Macro to add for using GNU gettext.
+
+dnl Usage: AM_GNU_GETTEXT([INTLSYMBOL], [NEEDSYMBOL], [INTLDIR]).
+dnl INTLSYMBOL can be one of 'external', 'no-libtool',
'use-libtool'. The
+dnl default (if it is not specified or empty) is 'no-libtool'.
+dnl INTLSYMBOL should be 'external' for packages with no intl directory,
+dnl and 'no-libtool' or 'use-libtool' for packages with an intl
directory.
+dnl If INTLSYMBOL is 'use-libtool', then a libtool library
+dnl $(top_builddir)/intl/libintl.la will be created (shared and/or static,
+dnl depending on --{enable,disable}-{shared,static} and on the presence of
+dnl AM-DISABLE-SHARED). If INTLSYMBOL is 'no-libtool', a static library
+dnl $(top_builddir)/intl/libintl.a will be created.
+dnl If NEEDSYMBOL is specified and is 'need-ngettext', then GNU gettext
+dnl implementations (in libc or libintl) without the ngettext() function
+dnl will be ignored. If NEEDSYMBOL is specified and is
+dnl 'need-formatstring-macros', then GNU gettext implementations that
don't
+dnl support the ISO C 99 <inttypes.h> formatstring macros will be ignored.
+dnl INTLDIR is used to find the intl libraries. If empty,
+dnl the value `$(top_builddir)/intl/' is used.
+dnl
+dnl The result of the configuration is one of three cases:
+dnl 1) GNU gettext, as included in the intl subdirectory, will be compiled
+dnl and used.
+dnl Catalog format: GNU --> install in $(datadir)
+dnl Catalog extension: .mo after installation, .gmo in source tree
+dnl 2) GNU gettext has been found in the system's C library.
+dnl Catalog format: GNU --> install in $(datadir)
+dnl Catalog extension: .mo after installation, .gmo in source tree
+dnl 3) No internationalization, always use English msgid.
+dnl Catalog format: none
+dnl Catalog extension: none
+dnl If INTLSYMBOL is 'external', only cases 2 and 3 can occur.
+dnl The use of .gmo is historical (it was needed to avoid overwriting the
+dnl GNU format catalogs when building on a platform with an X/Open gettext),
+dnl but we keep it in order not to force irrelevant filename changes on the
+dnl maintainers.
+dnl
+AC_DEFUN([AM_GNU_GETTEXT],
+[
+ dnl Argument checking.
+ ifelse([$1], [], , [ifelse([$1], [external], , [ifelse([$1], [no-libtool], ,
[ifelse([$1], [use-libtool], ,
+ [errprint([ERROR: invalid first argument to AM_GNU_GETTEXT
+])])])])])
+ ifelse(ifelse([$1], [], [old])[]ifelse([$1], [no-libtool], [old]), [old],
+ [AC_DIAGNOSE([obsolete], [Use of AM_GNU_GETTEXT without [external] argument is
deprecated.])])
+ ifelse([$2], [], , [ifelse([$2], [need-ngettext], , [ifelse([$2],
[need-formatstring-macros], ,
+ [errprint([ERROR: invalid second argument to AM_GNU_GETTEXT
+])])])])
+ define([gt_included_intl],
+ ifelse([$1], [external],
+ ifdef([AM_GNU_GETTEXT_][INTL_SUBDIR], [yes], [no]),
+ [yes]))
+ define([gt_libtool_suffix_prefix], ifelse([$1], [use-libtool], [l], []))
+ gt_NEEDS_INIT
+ AM_GNU_GETTEXT_NEED([$2])
+
+ AC_REQUIRE([AM_PO_SUBDIRS])dnl
+ ifelse(gt_included_intl, yes, [
+ AC_REQUIRE([AM_INTL_SUBDIR])dnl
+ ])
+
+ dnl Prerequisites of AC_LIB_LINKFLAGS_BODY.
+ AC_REQUIRE([AC_LIB_PREPARE_PREFIX])
+ AC_REQUIRE([AC_LIB_RPATH])
+
+ dnl Sometimes libintl requires libiconv, so first search for libiconv.
+ dnl Ideally we would do this search only after the
+ dnl if test "$USE_NLS" = "yes"; then
+ dnl if { eval "gt_val=\$$gt_func_gnugettext_libc"; test
"$gt_val" != "yes"; }; then
+ dnl tests. But if configure.in invokes AM_ICONV after AM_GNU_GETTEXT
+ dnl the configure script would need to contain the same shell code
+ dnl again, outside any 'if'. There are two solutions:
+ dnl - Invoke AM_ICONV_LINKFLAGS_BODY here, outside any 'if'.
+ dnl - Control the expansions in more detail using AC_PROVIDE_IFELSE.
+ dnl Since AC_PROVIDE_IFELSE is only in autoconf >= 2.52 and not
+ dnl documented, we avoid it.
+ ifelse(gt_included_intl, yes, , [
+ AC_REQUIRE([AM_ICONV_LINKFLAGS_BODY])
+ ])
+
+ dnl Sometimes, on MacOS X, libintl requires linking with CoreFoundation.
+ gt_INTL_MACOSX
+
+ dnl Set USE_NLS.
+ AC_REQUIRE([AM_NLS])
+
+ ifelse(gt_included_intl, yes, [
+ BUILD_INCLUDED_LIBINTL=no
+ USE_INCLUDED_LIBINTL=no
+ ])
+ LIBINTL=
+ LTLIBINTL=
+ POSUB=
+
+ dnl Add a version number to the cache macros.
+ case " $gt_needs " in
+ *" need-formatstring-macros "*) gt_api_version=3 ;;
+ *" need-ngettext "*) gt_api_version=2 ;;
+ *) gt_api_version=1 ;;
+ esac
+ gt_func_gnugettext_libc="gt_cv_func_gnugettext${gt_api_version}_libc"
+ gt_func_gnugettext_libintl="gt_cv_func_gnugettext${gt_api_version}_libintl"
+
+ dnl If we use NLS figure out what method
+ if test "$USE_NLS" = "yes"; then
+ gt_use_preinstalled_gnugettext=no
+ ifelse(gt_included_intl, yes, [
+ AC_MSG_CHECKING([whether included gettext is requested])
+ AC_ARG_WITH([included-gettext],
+ [ --with-included-gettext use the GNU gettext library included here],
+ nls_cv_force_use_gnu_gettext=$withval,
+ nls_cv_force_use_gnu_gettext=no)
+ AC_MSG_RESULT([$nls_cv_force_use_gnu_gettext])
+
+ nls_cv_use_gnu_gettext="$nls_cv_force_use_gnu_gettext"
+ if test "$nls_cv_force_use_gnu_gettext" != "yes"; then
+ ])
+ dnl User does not insist on using GNU NLS library. Figure out what
+ dnl to use. If GNU gettext is available we use this. Else we have
+ dnl to fall back to GNU NLS library.
+
+ if test $gt_api_version -ge 3; then
+ gt_revision_test_code='
+#ifndef __GNU_GETTEXT_SUPPORTED_REVISION
+#define __GNU_GETTEXT_SUPPORTED_REVISION(major) ((major) == 0 ? 0 : -1)
+#endif
+changequote(,)dnl
+typedef int array [2 * (__GNU_GETTEXT_SUPPORTED_REVISION(0) >= 1) - 1];
+changequote([,])dnl
+'
+ else
+ gt_revision_test_code=
+ fi
+ if test $gt_api_version -ge 2; then
+ gt_expression_test_code=' + * ngettext ("", "",
0)'
+ else
+ gt_expression_test_code=
+ fi
+
+ AC_CACHE_CHECK([for GNU gettext in libc], [$gt_func_gnugettext_libc],
+ [AC_TRY_LINK([#include <libintl.h>
+$gt_revision_test_code
+extern int _nl_msg_cat_cntr;
+extern int *_nl_domain_bindings;],
+ [bindtextdomain ("", "");
+return * gettext ("")$gt_expression_test_code + _nl_msg_cat_cntr +
*_nl_domain_bindings],
+ [eval "$gt_func_gnugettext_libc=yes"],
+ [eval "$gt_func_gnugettext_libc=no"])])
+
+ if { eval "gt_val=\$$gt_func_gnugettext_libc"; test "$gt_val"
!= "yes"; }; then
+ dnl Sometimes libintl requires libiconv, so first search for libiconv.
+ ifelse(gt_included_intl, yes, , [
+ AM_ICONV_LINK
+ ])
+ dnl Search for libintl and define LIBINTL, LTLIBINTL and INCINTL
+ dnl accordingly. Don't use AC_LIB_LINKFLAGS_BODY([intl],[iconv])
+ dnl because that would add "-liconv" to LIBINTL and LTLIBINTL
+ dnl even if libiconv doesn't exist.
+ AC_LIB_LINKFLAGS_BODY([intl])
+ AC_CACHE_CHECK([for GNU gettext in libintl],
+ [$gt_func_gnugettext_libintl],
+ [gt_save_CPPFLAGS="$CPPFLAGS"
+ CPPFLAGS="$CPPFLAGS $INCINTL"
+ gt_save_LIBS="$LIBS"
+ LIBS="$LIBS $LIBINTL"
+ dnl Now see whether libintl exists and does not depend on libiconv.
+ AC_TRY_LINK([#include <libintl.h>
+$gt_revision_test_code
+extern int _nl_msg_cat_cntr;
+extern
+#ifdef __cplusplus
+"C"
+#endif
+const char *_nl_expand_alias (const char *);],
+ [bindtextdomain ("", "");
+return * gettext ("")$gt_expression_test_code + _nl_msg_cat_cntr +
*_nl_expand_alias ("")],
+ [eval "$gt_func_gnugettext_libintl=yes"],
+ [eval "$gt_func_gnugettext_libintl=no"])
+ dnl Now see whether libintl exists and depends on libiconv.
+ if { eval "gt_val=\$$gt_func_gnugettext_libintl"; test
"$gt_val" != yes; } && test -n "$LIBICONV"; then
+ LIBS="$LIBS $LIBICONV"
+ AC_TRY_LINK([#include <libintl.h>
+$gt_revision_test_code
+extern int _nl_msg_cat_cntr;
+extern
+#ifdef __cplusplus
+"C"
+#endif
+const char *_nl_expand_alias (const char *);],
+ [bindtextdomain ("", "");
+return * gettext ("")$gt_expression_test_code + _nl_msg_cat_cntr +
*_nl_expand_alias ("")],
+ [LIBINTL="$LIBINTL $LIBICONV"
+ LTLIBINTL="$LTLIBINTL $LTLIBICONV"
+ eval "$gt_func_gnugettext_libintl=yes"
+ ])
+ fi
+ CPPFLAGS="$gt_save_CPPFLAGS"
+ LIBS="$gt_save_LIBS"])
+ fi
+
+ dnl If an already present or preinstalled GNU gettext() is found,
+ dnl use it. But if this macro is used in GNU gettext, and GNU
+ dnl gettext is already preinstalled in libintl, we update this
+ dnl libintl. (Cf. the install rule in intl/Makefile.in.)
+ if { eval "gt_val=\$$gt_func_gnugettext_libc"; test "$gt_val"
= "yes"; } \
+ || { { eval "gt_val=\$$gt_func_gnugettext_libintl"; test
"$gt_val" = "yes"; } \
+ && test "$PACKAGE" != gettext-runtime \
+ && test "$PACKAGE" != gettext-tools; }; then
+ gt_use_preinstalled_gnugettext=yes
+ else
+ dnl Reset the values set by searching for libintl.
+ LIBINTL=
+ LTLIBINTL=
+ INCINTL=
+ fi
+
+ ifelse(gt_included_intl, yes, [
+ if test "$gt_use_preinstalled_gnugettext" != "yes"; then
+ dnl GNU gettext is not found in the C library.
+ dnl Fall back on included GNU gettext library.
+ nls_cv_use_gnu_gettext=yes
+ fi
+ fi
+
+ if test "$nls_cv_use_gnu_gettext" = "yes"; then
+ dnl Mark actions used to generate GNU NLS library.
+ BUILD_INCLUDED_LIBINTL=yes
+ USE_INCLUDED_LIBINTL=yes
+
LIBINTL="ifelse([$3],[],\${top_builddir}/intl,[$3])/libintl.[]gt_libtool_suffix_prefix[]a
$LIBICONV $LIBTHREAD"
+
LTLIBINTL="ifelse([$3],[],\${top_builddir}/intl,[$3])/libintl.[]gt_libtool_suffix_prefix[]a
$LTLIBICONV $LTLIBTHREAD"
+ LIBS=`echo " $LIBS " | sed -e 's/ -lintl / /' -e 's/^
//' -e 's/ $//'`
+ fi
+
+ CATOBJEXT=
+ if test "$gt_use_preinstalled_gnugettext" = "yes" \
+ || test "$nls_cv_use_gnu_gettext" = "yes"; then
+ dnl Mark actions to use GNU gettext tools.
+ CATOBJEXT=.gmo
+ fi
+ ])
+
+ if test -n "$INTL_MACOSX_LIBS"; then
+ if test "$gt_use_preinstalled_gnugettext" = "yes" \
+ || test "$nls_cv_use_gnu_gettext" = "yes"; then
+ dnl Some extra flags are needed during linking.
+ LIBINTL="$LIBINTL $INTL_MACOSX_LIBS"
+ LTLIBINTL="$LTLIBINTL $INTL_MACOSX_LIBS"
+ fi
+ fi
+
+ if test "$gt_use_preinstalled_gnugettext" = "yes" \
+ || test "$nls_cv_use_gnu_gettext" = "yes"; then
+ AC_DEFINE([ENABLE_NLS], [1],
+ [Define to 1 if translation of program messages to the user's native
language
+ is requested.])
+ else
+ USE_NLS=no
+ fi
+ fi
+
+ AC_MSG_CHECKING([whether to use NLS])
+ AC_MSG_RESULT([$USE_NLS])
+ if test "$USE_NLS" = "yes"; then
+ AC_MSG_CHECKING([where the gettext function comes from])
+ if test "$gt_use_preinstalled_gnugettext" = "yes"; then
+ if { eval "gt_val=\$$gt_func_gnugettext_libintl"; test
"$gt_val" = "yes"; }; then
+ gt_source="external libintl"
+ else
+ gt_source="libc"
+ fi
+ else
+ gt_source="included intl directory"
+ fi
+ AC_MSG_RESULT([$gt_source])
+ fi
+
+ if test "$USE_NLS" = "yes"; then
+
+ if test "$gt_use_preinstalled_gnugettext" = "yes"; then
+ if { eval "gt_val=\$$gt_func_gnugettext_libintl"; test
"$gt_val" = "yes"; }; then
+ AC_MSG_CHECKING([how to link with libintl])
+ AC_MSG_RESULT([$LIBINTL])
+ AC_LIB_APPENDTOVAR([CPPFLAGS], [$INCINTL])
+ fi
+
+ dnl For backward compatibility. Some packages may be using this.
+ AC_DEFINE([HAVE_GETTEXT], [1],
+ [Define if the GNU gettext() function is already present or preinstalled.])
+ AC_DEFINE([HAVE_DCGETTEXT], [1],
+ [Define if the GNU dcgettext() function is already present or preinstalled.])
+ fi
+
+ dnl We need to process the po/ directory.
+ POSUB=po
+ fi
+
+ ifelse(gt_included_intl, yes, [
+ dnl If this is used in GNU gettext we have to set BUILD_INCLUDED_LIBINTL
+ dnl to 'yes' because some of the testsuite requires it.
+ if test "$PACKAGE" = gettext-runtime || test "$PACKAGE" =
gettext-tools; then
+ BUILD_INCLUDED_LIBINTL=yes
+ fi
+
+ dnl Make all variables we use known to autoconf.
+ AC_SUBST([BUILD_INCLUDED_LIBINTL])
+ AC_SUBST([USE_INCLUDED_LIBINTL])
+ AC_SUBST([CATOBJEXT])
+
+ dnl For backward compatibility. Some configure.ins may be using this.
+ nls_cv_header_intl=
+ nls_cv_header_libgt=
+
+ dnl For backward compatibility. Some Makefiles may be using this.
+ DATADIRNAME=share
+ AC_SUBST([DATADIRNAME])
+
+ dnl For backward compatibility. Some Makefiles may be using this.
+ INSTOBJEXT=.mo
+ AC_SUBST([INSTOBJEXT])
+
+ dnl For backward compatibility. Some Makefiles may be using this.
+ GENCAT=gencat
+ AC_SUBST([GENCAT])
+
+ dnl For backward compatibility. Some Makefiles may be using this.
+ INTLOBJS=
+ if test "$USE_INCLUDED_LIBINTL" = yes; then
+ INTLOBJS="\$(GETTOBJS)"
+ fi
+ AC_SUBST([INTLOBJS])
+
+ dnl Enable libtool support if the surrounding package wishes it.
+ INTL_LIBTOOL_SUFFIX_PREFIX=gt_libtool_suffix_prefix
+ AC_SUBST([INTL_LIBTOOL_SUFFIX_PREFIX])
+ ])
+
+ dnl For backward compatibility. Some Makefiles may be using this.
+ INTLLIBS="$LIBINTL"
+ AC_SUBST([INTLLIBS])
+
+ dnl Make all documented variables known to autoconf.
+ AC_SUBST([LIBINTL])
+ AC_SUBST([LTLIBINTL])
+ AC_SUBST([POSUB])
+])
+
+
+dnl gt_NEEDS_INIT ensures that the gt_needs variable is initialized.
+m4_define([gt_NEEDS_INIT],
+[
+ m4_divert_text([DEFAULTS], [gt_needs=])
+ m4_define([gt_NEEDS_INIT], [])
+])
+
+
+dnl Usage: AM_GNU_GETTEXT_NEED([NEEDSYMBOL])
+AC_DEFUN([AM_GNU_GETTEXT_NEED],
+[
+ m4_divert_text([INIT_PREPARE], [gt_needs="$gt_needs $1"])
+])
+
+
+dnl Usage: AM_GNU_GETTEXT_VERSION([gettext-version])
+AC_DEFUN([AM_GNU_GETTEXT_VERSION], [])
diff --git a/src/wok/plugins/kimchi/m4/iconv.m4 b/src/wok/plugins/kimchi/m4/iconv.m4
new file mode 100644
index 0000000..e2041b9
--- /dev/null
+++ b/src/wok/plugins/kimchi/m4/iconv.m4
@@ -0,0 +1,214 @@
+# iconv.m4 serial 11 (gettext-0.18.1)
+dnl Copyright (C) 2000-2002, 2007-2010 Free Software Foundation, Inc.
+dnl This file is free software; the Free Software Foundation
+dnl gives unlimited permission to copy and/or distribute it,
+dnl with or without modifications, as long as this notice is preserved.
+
+dnl From Bruno Haible.
+
+AC_DEFUN([AM_ICONV_LINKFLAGS_BODY],
+[
+ dnl Prerequisites of AC_LIB_LINKFLAGS_BODY.
+ AC_REQUIRE([AC_LIB_PREPARE_PREFIX])
+ AC_REQUIRE([AC_LIB_RPATH])
+
+ dnl Search for libiconv and define LIBICONV, LTLIBICONV and INCICONV
+ dnl accordingly.
+ AC_LIB_LINKFLAGS_BODY([iconv])
+])
+
+AC_DEFUN([AM_ICONV_LINK],
+[
+ dnl Some systems have iconv in libc, some have it in libiconv (OSF/1 and
+ dnl those with the standalone portable GNU libiconv installed).
+ AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles
+
+ dnl Search for libiconv and define LIBICONV, LTLIBICONV and INCICONV
+ dnl accordingly.
+ AC_REQUIRE([AM_ICONV_LINKFLAGS_BODY])
+
+ dnl Add $INCICONV to CPPFLAGS before performing the following checks,
+ dnl because if the user has installed libiconv and not disabled its use
+ dnl via --without-libiconv-prefix, he wants to use it. The first
+ dnl AC_TRY_LINK will then fail, the second AC_TRY_LINK will succeed.
+ am_save_CPPFLAGS="$CPPFLAGS"
+ AC_LIB_APPENDTOVAR([CPPFLAGS], [$INCICONV])
+
+ AC_CACHE_CHECK([for iconv], [am_cv_func_iconv], [
+ am_cv_func_iconv="no, consider installing GNU libiconv"
+ am_cv_lib_iconv=no
+ AC_TRY_LINK([#include <stdlib.h>
+#include <iconv.h>],
+ [iconv_t cd = iconv_open("","");
+ iconv(cd,NULL,NULL,NULL,NULL);
+ iconv_close(cd);],
+ [am_cv_func_iconv=yes])
+ if test "$am_cv_func_iconv" != yes; then
+ am_save_LIBS="$LIBS"
+ LIBS="$LIBS $LIBICONV"
+ AC_TRY_LINK([#include <stdlib.h>
+#include <iconv.h>],
+ [iconv_t cd = iconv_open("","");
+ iconv(cd,NULL,NULL,NULL,NULL);
+ iconv_close(cd);],
+ [am_cv_lib_iconv=yes]
+ [am_cv_func_iconv=yes])
+ LIBS="$am_save_LIBS"
+ fi
+ ])
+ if test "$am_cv_func_iconv" = yes; then
+ AC_CACHE_CHECK([for working iconv], [am_cv_func_iconv_works], [
+ dnl This tests against bugs in AIX 5.1, HP-UX 11.11, Solaris 10.
+ am_save_LIBS="$LIBS"
+ if test $am_cv_lib_iconv = yes; then
+ LIBS="$LIBS $LIBICONV"
+ fi
+ AC_TRY_RUN([
+#include <iconv.h>
+#include <string.h>
+int main ()
+{
+ /* Test against AIX 5.1 bug: Failures are not distinguishable from successful
+ returns. */
+ {
+ iconv_t cd_utf8_to_88591 = iconv_open ("ISO8859-1", "UTF-8");
+ if (cd_utf8_to_88591 != (iconv_t)(-1))
+ {
+ static const char input[] = "\342\202\254"; /* EURO SIGN */
+ char buf[10];
+ const char *inptr = input;
+ size_t inbytesleft = strlen (input);
+ char *outptr = buf;
+ size_t outbytesleft = sizeof (buf);
+ size_t res = iconv (cd_utf8_to_88591,
+ (char **) &inptr, &inbytesleft,
+ &outptr, &outbytesleft);
+ if (res == 0)
+ return 1;
+ }
+ }
+ /* Test against Solaris 10 bug: Failures are not distinguishable from
+ successful returns. */
+ {
+ iconv_t cd_ascii_to_88591 = iconv_open ("ISO8859-1", "646");
+ if (cd_ascii_to_88591 != (iconv_t)(-1))
+ {
+ static const char input[] = "\263";
+ char buf[10];
+ const char *inptr = input;
+ size_t inbytesleft = strlen (input);
+ char *outptr = buf;
+ size_t outbytesleft = sizeof (buf);
+ size_t res = iconv (cd_ascii_to_88591,
+ (char **) &inptr, &inbytesleft,
+ &outptr, &outbytesleft);
+ if (res == 0)
+ return 1;
+ }
+ }
+#if 0 /* This bug could be worked around by the caller. */
+ /* Test against HP-UX 11.11 bug: Positive return value instead of 0. */
+ {
+ iconv_t cd_88591_to_utf8 = iconv_open ("utf8", "iso88591");
+ if (cd_88591_to_utf8 != (iconv_t)(-1))
+ {
+ static const char input[] = "\304rger mit b\366sen B\374bchen ohne
Augenma\337";
+ char buf[50];
+ const char *inptr = input;
+ size_t inbytesleft = strlen (input);
+ char *outptr = buf;
+ size_t outbytesleft = sizeof (buf);
+ size_t res = iconv (cd_88591_to_utf8,
+ (char **) &inptr, &inbytesleft,
+ &outptr, &outbytesleft);
+ if ((int)res > 0)
+ return 1;
+ }
+ }
+#endif
+ /* Test against HP-UX 11.11 bug: No converter from EUC-JP to UTF-8 is
+ provided. */
+ if (/* Try standardized names. */
+ iconv_open ("UTF-8", "EUC-JP") == (iconv_t)(-1)
+ /* Try IRIX, OSF/1 names. */
+ && iconv_open ("UTF-8", "eucJP") == (iconv_t)(-1)
+ /* Try AIX names. */
+ && iconv_open ("UTF-8", "IBM-eucJP") == (iconv_t)(-1)
+ /* Try HP-UX names. */
+ && iconv_open ("utf8", "eucJP") == (iconv_t)(-1))
+ return 1;
+ return 0;
+}], [am_cv_func_iconv_works=yes], [am_cv_func_iconv_works=no],
+ [case "$host_os" in
+ aix* | hpux*) am_cv_func_iconv_works="guessing no" ;;
+ *) am_cv_func_iconv_works="guessing yes" ;;
+ esac])
+ LIBS="$am_save_LIBS"
+ ])
+ case "$am_cv_func_iconv_works" in
+ *no) am_func_iconv=no am_cv_lib_iconv=no ;;
+ *) am_func_iconv=yes ;;
+ esac
+ else
+ am_func_iconv=no am_cv_lib_iconv=no
+ fi
+ if test "$am_func_iconv" = yes; then
+ AC_DEFINE([HAVE_ICONV], [1],
+ [Define if you have the iconv() function and it works.])
+ fi
+ if test "$am_cv_lib_iconv" = yes; then
+ AC_MSG_CHECKING([how to link with libiconv])
+ AC_MSG_RESULT([$LIBICONV])
+ else
+ dnl If $LIBICONV didn't lead to a usable library, we don't need $INCICONV
+ dnl either.
+ CPPFLAGS="$am_save_CPPFLAGS"
+ LIBICONV=
+ LTLIBICONV=
+ fi
+ AC_SUBST([LIBICONV])
+ AC_SUBST([LTLIBICONV])
+])
+
+dnl Define AM_ICONV using AC_DEFUN_ONCE for Autoconf >= 2.64, in order to
+dnl avoid warnings like
+dnl "warning: AC_REQUIRE: `AM_ICONV' was expanded before it was required".
+dnl This is tricky because of the way 'aclocal' is implemented:
+dnl - It requires defining an auxiliary macro whose name ends in AC_DEFUN.
+dnl Otherwise aclocal's initial scan pass would miss the macro definition.
+dnl - It requires a line break inside the AC_DEFUN_ONCE and AC_DEFUN expansions.
+dnl Otherwise aclocal would emit many "Use of uninitialized value $1"
+dnl warnings.
+m4_define([gl_iconv_AC_DEFUN],
+ m4_version_prereq([2.64],
+ [[AC_DEFUN_ONCE(
+ [$1], [$2])]],
+ [[AC_DEFUN(
+ [$1], [$2])]]))
+gl_iconv_AC_DEFUN([AM_ICONV],
+[
+ AM_ICONV_LINK
+ if test "$am_cv_func_iconv" = yes; then
+ AC_MSG_CHECKING([for iconv declaration])
+ AC_CACHE_VAL([am_cv_proto_iconv], [
+ AC_TRY_COMPILE([
+#include <stdlib.h>
+#include <iconv.h>
+extern
+#ifdef __cplusplus
+"C"
+#endif
+#if defined(__STDC__) || defined(__cplusplus)
+size_t iconv (iconv_t cd, char * *inbuf, size_t *inbytesleft, char * *outbuf, size_t
*outbytesleft);
+#else
+size_t iconv();
+#endif
+], [], [am_cv_proto_iconv_arg1=""],
[am_cv_proto_iconv_arg1="const"])
+ am_cv_proto_iconv="extern size_t iconv (iconv_t cd, $am_cv_proto_iconv_arg1
char * *inbuf, size_t *inbytesleft, char * *outbuf, size_t *outbytesleft);"])
+ am_cv_proto_iconv=`echo "[$]am_cv_proto_iconv" | tr -s ' ' | sed -e
's/( /(/'`
+ AC_MSG_RESULT([
+ $am_cv_proto_iconv])
+ AC_DEFINE_UNQUOTED([ICONV_CONST], [$am_cv_proto_iconv_arg1],
+ [Define as const if the declaration of iconv() needs const.])
+ fi
+])
diff --git a/src/wok/plugins/kimchi/m4/intlmacosx.m4
b/src/wok/plugins/kimchi/m4/intlmacosx.m4
new file mode 100644
index 0000000..dd91025
--- /dev/null
+++ b/src/wok/plugins/kimchi/m4/intlmacosx.m4
@@ -0,0 +1,51 @@
+# intlmacosx.m4 serial 3 (gettext-0.18)
+dnl Copyright (C) 2004-2010 Free Software Foundation, Inc.
+dnl This file is free software; the Free Software Foundation
+dnl gives unlimited permission to copy and/or distribute it,
+dnl with or without modifications, as long as this notice is preserved.
+dnl
+dnl This file can can be used in projects which are not available under
+dnl the GNU General Public License or the GNU Library General Public
+dnl License but which still want to provide support for the GNU gettext
+dnl functionality.
+dnl Please note that the actual code of the GNU gettext library is covered
+dnl by the GNU Library General Public License, and the rest of the GNU
+dnl gettext package package is covered by the GNU General Public License.
+dnl They are *not* in the public domain.
+
+dnl Checks for special options needed on MacOS X.
+dnl Defines INTL_MACOSX_LIBS.
+AC_DEFUN([gt_INTL_MACOSX],
+[
+ dnl Check for API introduced in MacOS X 10.2.
+ AC_CACHE_CHECK([for CFPreferencesCopyAppValue],
+ [gt_cv_func_CFPreferencesCopyAppValue],
+ [gt_save_LIBS="$LIBS"
+ LIBS="$LIBS -Wl,-framework -Wl,CoreFoundation"
+ AC_TRY_LINK([#include <CoreFoundation/CFPreferences.h>],
+ [CFPreferencesCopyAppValue(NULL, NULL)],
+ [gt_cv_func_CFPreferencesCopyAppValue=yes],
+ [gt_cv_func_CFPreferencesCopyAppValue=no])
+ LIBS="$gt_save_LIBS"])
+ if test $gt_cv_func_CFPreferencesCopyAppValue = yes; then
+ AC_DEFINE([HAVE_CFPREFERENCESCOPYAPPVALUE], [1],
+ [Define to 1 if you have the MacOS X function CFPreferencesCopyAppValue in the
CoreFoundation framework.])
+ fi
+ dnl Check for API introduced in MacOS X 10.3.
+ AC_CACHE_CHECK([for CFLocaleCopyCurrent], [gt_cv_func_CFLocaleCopyCurrent],
+ [gt_save_LIBS="$LIBS"
+ LIBS="$LIBS -Wl,-framework -Wl,CoreFoundation"
+ AC_TRY_LINK([#include <CoreFoundation/CFLocale.h>], [CFLocaleCopyCurrent();],
+ [gt_cv_func_CFLocaleCopyCurrent=yes],
+ [gt_cv_func_CFLocaleCopyCurrent=no])
+ LIBS="$gt_save_LIBS"])
+ if test $gt_cv_func_CFLocaleCopyCurrent = yes; then
+ AC_DEFINE([HAVE_CFLOCALECOPYCURRENT], [1],
+ [Define to 1 if you have the MacOS X function CFLocaleCopyCurrent in the
CoreFoundation framework.])
+ fi
+ INTL_MACOSX_LIBS=
+ if test $gt_cv_func_CFPreferencesCopyAppValue = yes || test
$gt_cv_func_CFLocaleCopyCurrent = yes; then
+ INTL_MACOSX_LIBS="-Wl,-framework -Wl,CoreFoundation"
+ fi
+ AC_SUBST([INTL_MACOSX_LIBS])
+])
diff --git a/src/wok/plugins/kimchi/m4/lib-ld.m4 b/src/wok/plugins/kimchi/m4/lib-ld.m4
new file mode 100644
index 0000000..ebb3052
--- /dev/null
+++ b/src/wok/plugins/kimchi/m4/lib-ld.m4
@@ -0,0 +1,110 @@
+# lib-ld.m4 serial 4 (gettext-0.18)
+dnl Copyright (C) 1996-2003, 2009-2010 Free Software Foundation, Inc.
+dnl This file is free software; the Free Software Foundation
+dnl gives unlimited permission to copy and/or distribute it,
+dnl with or without modifications, as long as this notice is preserved.
+
+dnl Subroutines of libtool.m4,
+dnl with replacements s/AC_/AC_LIB/ and s/lt_cv/acl_cv/ to avoid collision
+dnl with libtool.m4.
+
+dnl From libtool-1.4. Sets the variable with_gnu_ld to yes or no.
+AC_DEFUN([AC_LIB_PROG_LD_GNU],
+[AC_CACHE_CHECK([if the linker ($LD) is GNU ld], [acl_cv_prog_gnu_ld],
+[# I'd rather use --version here, but apparently some GNU ld's only accept -v.
+case `$LD -v 2>&1 </dev/null` in
+*GNU* | *'with BFD'*)
+ acl_cv_prog_gnu_ld=yes ;;
+*)
+ acl_cv_prog_gnu_ld=no ;;
+esac])
+with_gnu_ld=$acl_cv_prog_gnu_ld
+])
+
+dnl From libtool-1.4. Sets the variable LD.
+AC_DEFUN([AC_LIB_PROG_LD],
+[AC_ARG_WITH([gnu-ld],
+[ --with-gnu-ld assume the C compiler uses GNU ld [default=no]],
+test "$withval" = no || with_gnu_ld=yes, with_gnu_ld=no)
+AC_REQUIRE([AC_PROG_CC])dnl
+AC_REQUIRE([AC_CANONICAL_HOST])dnl
+# Prepare PATH_SEPARATOR.
+# The user is always right.
+if test "${PATH_SEPARATOR+set}" != set; then
+ echo "#! /bin/sh" >conf$$.sh
+ echo "exit 0" >>conf$$.sh
+ chmod +x conf$$.sh
+ if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then
+ PATH_SEPARATOR=';'
+ else
+ PATH_SEPARATOR=:
+ fi
+ rm -f conf$$.sh
+fi
+ac_prog=ld
+if test "$GCC" = yes; then
+ # Check if gcc -print-prog-name=ld gives a path.
+ AC_MSG_CHECKING([for ld used by GCC])
+ case $host in
+ *-*-mingw*)
+ # gcc leaves a trailing carriage return which upsets mingw
+ ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;;
+ *)
+ ac_prog=`($CC -print-prog-name=ld) 2>&5` ;;
+ esac
+ case $ac_prog in
+ # Accept absolute paths.
+ [[\\/]* | [A-Za-z]:[\\/]*)]
+ [re_direlt='/[^/][^/]*/\.\./']
+ # Canonicalize the path of ld
+ ac_prog=`echo $ac_prog| sed 's%\\\\%/%g'`
+ while echo $ac_prog | grep "$re_direlt" > /dev/null 2>&1; do
+ ac_prog=`echo $ac_prog| sed "s%$re_direlt%/%"`
+ done
+ test -z "$LD" && LD="$ac_prog"
+ ;;
+ "")
+ # If it fails, then pretend we aren't using GCC.
+ ac_prog=ld
+ ;;
+ *)
+ # If it is relative, then search for the first ld in PATH.
+ with_gnu_ld=unknown
+ ;;
+ esac
+elif test "$with_gnu_ld" = yes; then
+ AC_MSG_CHECKING([for GNU ld])
+else
+ AC_MSG_CHECKING([for non-GNU ld])
+fi
+AC_CACHE_VAL([acl_cv_path_LD],
+[if test -z "$LD"; then
+ IFS="${IFS= }"; ac_save_ifs="$IFS";
IFS="${IFS}${PATH_SEPARATOR-:}"
+ for ac_dir in $PATH; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f "$ac_dir/$ac_prog" || test -f
"$ac_dir/$ac_prog$ac_exeext"; then
+ acl_cv_path_LD="$ac_dir/$ac_prog"
+ # Check to see if the program is GNU ld. I'd rather use --version,
+ # but apparently some GNU ld's only accept -v.
+ # Break only if it was the GNU/non-GNU ld that we prefer.
+ case `"$acl_cv_path_LD" -v 2>&1 < /dev/null` in
+ *GNU* | *'with BFD'*)
+ test "$with_gnu_ld" != no && break ;;
+ *)
+ test "$with_gnu_ld" != yes && break ;;
+ esac
+ fi
+ done
+ IFS="$ac_save_ifs"
+else
+ acl_cv_path_LD="$LD" # Let the user override the test with a path.
+fi])
+LD="$acl_cv_path_LD"
+if test -n "$LD"; then
+ AC_MSG_RESULT([$LD])
+else
+ AC_MSG_RESULT([no])
+fi
+test -z "$LD" && AC_MSG_ERROR([no acceptable ld found in \$PATH])
+AC_LIB_PROG_LD_GNU
+])
diff --git a/src/wok/plugins/kimchi/m4/lib-link.m4
b/src/wok/plugins/kimchi/m4/lib-link.m4
new file mode 100644
index 0000000..c73bd8e
--- /dev/null
+++ b/src/wok/plugins/kimchi/m4/lib-link.m4
@@ -0,0 +1,774 @@
+# lib-link.m4 serial 21 (gettext-0.18)
+dnl Copyright (C) 2001-2010 Free Software Foundation, Inc.
+dnl This file is free software; the Free Software Foundation
+dnl gives unlimited permission to copy and/or distribute it,
+dnl with or without modifications, as long as this notice is preserved.
+
+dnl From Bruno Haible.
+
+AC_PREREQ([2.54])
+
+dnl AC_LIB_LINKFLAGS(name [, dependencies]) searches for libname and
+dnl the libraries corresponding to explicit and implicit dependencies.
+dnl Sets and AC_SUBSTs the LIB${NAME} and LTLIB${NAME} variables and
+dnl augments the CPPFLAGS variable.
+dnl Sets and AC_SUBSTs the LIB${NAME}_PREFIX variable to nonempty if libname
+dnl was found in ${LIB${NAME}_PREFIX}/$acl_libdirstem.
+AC_DEFUN([AC_LIB_LINKFLAGS],
+[
+ AC_REQUIRE([AC_LIB_PREPARE_PREFIX])
+ AC_REQUIRE([AC_LIB_RPATH])
+ pushdef([Name],[translit([$1],[./-], [___])])
+ pushdef([NAME],[translit([$1],[abcdefghijklmnopqrstuvwxyz./-],
+ [ABCDEFGHIJKLMNOPQRSTUVWXYZ___])])
+ AC_CACHE_CHECK([how to link with lib[]$1], [ac_cv_lib[]Name[]_libs], [
+ AC_LIB_LINKFLAGS_BODY([$1], [$2])
+ ac_cv_lib[]Name[]_libs="$LIB[]NAME"
+ ac_cv_lib[]Name[]_ltlibs="$LTLIB[]NAME"
+ ac_cv_lib[]Name[]_cppflags="$INC[]NAME"
+ ac_cv_lib[]Name[]_prefix="$LIB[]NAME[]_PREFIX"
+ ])
+ LIB[]NAME="$ac_cv_lib[]Name[]_libs"
+ LTLIB[]NAME="$ac_cv_lib[]Name[]_ltlibs"
+ INC[]NAME="$ac_cv_lib[]Name[]_cppflags"
+ LIB[]NAME[]_PREFIX="$ac_cv_lib[]Name[]_prefix"
+ AC_LIB_APPENDTOVAR([CPPFLAGS], [$INC]NAME)
+ AC_SUBST([LIB]NAME)
+ AC_SUBST([LTLIB]NAME)
+ AC_SUBST([LIB]NAME[_PREFIX])
+ dnl Also set HAVE_LIB[]NAME so that AC_LIB_HAVE_LINKFLAGS can reuse the
+ dnl results of this search when this library appears as a dependency.
+ HAVE_LIB[]NAME=yes
+ popdef([NAME])
+ popdef([Name])
+])
+
+dnl AC_LIB_HAVE_LINKFLAGS(name, dependencies, includes, testcode, [missing-message])
+dnl searches for libname and the libraries corresponding to explicit and
+dnl implicit dependencies, together with the specified include files and
+dnl the ability to compile and link the specified testcode. The missing-message
+dnl defaults to 'no' and may contain additional hints for the user.
+dnl If found, it sets and AC_SUBSTs HAVE_LIB${NAME}=yes and the LIB${NAME}
+dnl and LTLIB${NAME} variables and augments the CPPFLAGS variable, and
+dnl #defines HAVE_LIB${NAME} to 1. Otherwise, it sets and AC_SUBSTs
+dnl HAVE_LIB${NAME}=no and LIB${NAME} and LTLIB${NAME} to empty.
+dnl Sets and AC_SUBSTs the LIB${NAME}_PREFIX variable to nonempty if libname
+dnl was found in ${LIB${NAME}_PREFIX}/$acl_libdirstem.
+AC_DEFUN([AC_LIB_HAVE_LINKFLAGS],
+[
+ AC_REQUIRE([AC_LIB_PREPARE_PREFIX])
+ AC_REQUIRE([AC_LIB_RPATH])
+ pushdef([Name],[translit([$1],[./-], [___])])
+ pushdef([NAME],[translit([$1],[abcdefghijklmnopqrstuvwxyz./-],
+ [ABCDEFGHIJKLMNOPQRSTUVWXYZ___])])
+
+ dnl Search for lib[]Name and define LIB[]NAME, LTLIB[]NAME and INC[]NAME
+ dnl accordingly.
+ AC_LIB_LINKFLAGS_BODY([$1], [$2])
+
+ dnl Add $INC[]NAME to CPPFLAGS before performing the following checks,
+ dnl because if the user has installed lib[]Name and not disabled its use
+ dnl via --without-lib[]Name-prefix, he wants to use it.
+ ac_save_CPPFLAGS="$CPPFLAGS"
+ AC_LIB_APPENDTOVAR([CPPFLAGS], [$INC]NAME)
+
+ AC_CACHE_CHECK([for lib[]$1], [ac_cv_lib[]Name], [
+ ac_save_LIBS="$LIBS"
+ dnl If $LIB[]NAME contains some -l options, add it to the end of LIBS,
+ dnl because these -l options might require -L options that are present in
+ dnl LIBS. -l options benefit only from the -L options listed before it.
+ dnl Otherwise, add it to the front of LIBS, because it may be a static
+ dnl library that depends on another static library that is present in LIBS.
+ dnl Static libraries benefit only from the static libraries listed after
+ dnl it.
+ case " $LIB[]NAME" in
+ *" -l"*) LIBS="$LIBS $LIB[]NAME" ;;
+ *) LIBS="$LIB[]NAME $LIBS" ;;
+ esac
+ AC_TRY_LINK([$3], [$4],
+ [ac_cv_lib[]Name=yes],
+ [ac_cv_lib[]Name='m4_if([$5], [], [no], [[$5]])'])
+ LIBS="$ac_save_LIBS"
+ ])
+ if test "$ac_cv_lib[]Name" = yes; then
+ HAVE_LIB[]NAME=yes
+ AC_DEFINE([HAVE_LIB]NAME, 1, [Define if you have the lib][$1 library.])
+ AC_MSG_CHECKING([how to link with lib[]$1])
+ AC_MSG_RESULT([$LIB[]NAME])
+ else
+ HAVE_LIB[]NAME=no
+ dnl If $LIB[]NAME didn't lead to a usable library, we don't need
+ dnl $INC[]NAME either.
+ CPPFLAGS="$ac_save_CPPFLAGS"
+ LIB[]NAME=
+ LTLIB[]NAME=
+ LIB[]NAME[]_PREFIX=
+ fi
+ AC_SUBST([HAVE_LIB]NAME)
+ AC_SUBST([LIB]NAME)
+ AC_SUBST([LTLIB]NAME)
+ AC_SUBST([LIB]NAME[_PREFIX])
+ popdef([NAME])
+ popdef([Name])
+])
+
+dnl Determine the platform dependent parameters needed to use rpath:
+dnl acl_libext,
+dnl acl_shlibext,
+dnl acl_hardcode_libdir_flag_spec,
+dnl acl_hardcode_libdir_separator,
+dnl acl_hardcode_direct,
+dnl acl_hardcode_minus_L.
+AC_DEFUN([AC_LIB_RPATH],
+[
+ dnl Tell automake >= 1.10 to complain if config.rpath is missing.
+ m4_ifdef([AC_REQUIRE_AUX_FILE], [AC_REQUIRE_AUX_FILE([config.rpath])])
+ AC_REQUIRE([AC_PROG_CC]) dnl we use $CC, $GCC, $LDFLAGS
+ AC_REQUIRE([AC_LIB_PROG_LD]) dnl we use $LD, $with_gnu_ld
+ AC_REQUIRE([AC_CANONICAL_HOST]) dnl we use $host
+ AC_REQUIRE([AC_CONFIG_AUX_DIR_DEFAULT]) dnl we use $ac_aux_dir
+ AC_CACHE_CHECK([for shared library run path origin], [acl_cv_rpath], [
+ CC="$CC" GCC="$GCC" LDFLAGS="$LDFLAGS"
LD="$LD" with_gnu_ld="$with_gnu_ld" \
+ ${CONFIG_SHELL-/bin/sh} "$ac_aux_dir/config.rpath" "$host" >
conftest.sh
+ . ./conftest.sh
+ rm -f ./conftest.sh
+ acl_cv_rpath=done
+ ])
+ wl="$acl_cv_wl"
+ acl_libext="$acl_cv_libext"
+ acl_shlibext="$acl_cv_shlibext"
+ acl_libname_spec="$acl_cv_libname_spec"
+ acl_library_names_spec="$acl_cv_library_names_spec"
+ acl_hardcode_libdir_flag_spec="$acl_cv_hardcode_libdir_flag_spec"
+ acl_hardcode_libdir_separator="$acl_cv_hardcode_libdir_separator"
+ acl_hardcode_direct="$acl_cv_hardcode_direct"
+ acl_hardcode_minus_L="$acl_cv_hardcode_minus_L"
+ dnl Determine whether the user wants rpath handling at all.
+ AC_ARG_ENABLE([rpath],
+ [ --disable-rpath do not hardcode runtime library paths],
+ :, enable_rpath=yes)
+])
+
+dnl AC_LIB_FROMPACKAGE(name, package)
+dnl declares that libname comes from the given package. The configure file
+dnl will then not have a --with-libname-prefix option but a
+dnl --with-package-prefix option. Several libraries can come from the same
+dnl package. This declaration must occur before an AC_LIB_LINKFLAGS or similar
+dnl macro call that searches for libname.
+AC_DEFUN([AC_LIB_FROMPACKAGE],
+[
+ pushdef([NAME],[translit([$1],[abcdefghijklmnopqrstuvwxyz./-],
+ [ABCDEFGHIJKLMNOPQRSTUVWXYZ___])])
+ define([acl_frompackage_]NAME, [$2])
+ popdef([NAME])
+ pushdef([PACK],[$2])
+ pushdef([PACKUP],[translit(PACK,[abcdefghijklmnopqrstuvwxyz./-],
+ [ABCDEFGHIJKLMNOPQRSTUVWXYZ___])])
+ define([acl_libsinpackage_]PACKUP,
+ m4_ifdef([acl_libsinpackage_]PACKUP, [acl_libsinpackage_]PACKUP[[, ]],)[lib$1])
+ popdef([PACKUP])
+ popdef([PACK])
+])
+
+dnl AC_LIB_LINKFLAGS_BODY(name [, dependencies]) searches for libname and
+dnl the libraries corresponding to explicit and implicit dependencies.
+dnl Sets the LIB${NAME}, LTLIB${NAME} and INC${NAME} variables.
+dnl Also, sets the LIB${NAME}_PREFIX variable to nonempty if libname was found
+dnl in ${LIB${NAME}_PREFIX}/$acl_libdirstem.
+AC_DEFUN([AC_LIB_LINKFLAGS_BODY],
+[
+ AC_REQUIRE([AC_LIB_PREPARE_MULTILIB])
+ pushdef([NAME],[translit([$1],[abcdefghijklmnopqrstuvwxyz./-],
+ [ABCDEFGHIJKLMNOPQRSTUVWXYZ___])])
+ pushdef([PACK],[m4_ifdef([acl_frompackage_]NAME, [acl_frompackage_]NAME, lib[$1])])
+ pushdef([PACKUP],[translit(PACK,[abcdefghijklmnopqrstuvwxyz./-],
+ [ABCDEFGHIJKLMNOPQRSTUVWXYZ___])])
+ pushdef([PACKLIBS],[m4_ifdef([acl_frompackage_]NAME, [acl_libsinpackage_]PACKUP,
lib[$1])])
+ dnl Autoconf >= 2.61 supports dots in --with options.
+
pushdef([P_A_C_K],[m4_if(m4_version_compare(m4_defn([m4_PACKAGE_VERSION]),[2.61]),[-1],[translit(PACK,[.],[_])],PACK)])
+ dnl By default, look in $includedir and $libdir.
+ use_additional=yes
+ AC_LIB_WITH_FINAL_PREFIX([
+ eval additional_includedir=\"$includedir\"
+ eval additional_libdir=\"$libdir\"
+ ])
+ AC_ARG_WITH(P_A_C_K[-prefix],
+[[ --with-]]P_A_C_K[[-prefix[=DIR] search for ]PACKLIBS[ in DIR/include and DIR/lib
+ --without-]]P_A_C_K[[-prefix don't search for ]PACKLIBS[ in includedir and
libdir]],
+[
+ if test "X$withval" = "Xno"; then
+ use_additional=no
+ else
+ if test "X$withval" = "X"; then
+ AC_LIB_WITH_FINAL_PREFIX([
+ eval additional_includedir=\"$includedir\"
+ eval additional_libdir=\"$libdir\"
+ ])
+ else
+ additional_includedir="$withval/include"
+ additional_libdir="$withval/$acl_libdirstem"
+ if test "$acl_libdirstem2" != "$acl_libdirstem" \
+ && ! test -d "$withval/$acl_libdirstem"; then
+ additional_libdir="$withval/$acl_libdirstem2"
+ fi
+ fi
+ fi
+])
+ dnl Search the library and its dependencies in $additional_libdir and
+ dnl $LDFLAGS. Using breadth-first-seach.
+ LIB[]NAME=
+ LTLIB[]NAME=
+ INC[]NAME=
+ LIB[]NAME[]_PREFIX=
+ dnl HAVE_LIB${NAME} is an indicator that LIB${NAME}, LTLIB${NAME} have been
+ dnl computed. So it has to be reset here.
+ HAVE_LIB[]NAME=
+ rpathdirs=
+ ltrpathdirs=
+ names_already_handled=
+ names_next_round='$1 $2'
+ while test -n "$names_next_round"; do
+ names_this_round="$names_next_round"
+ names_next_round=
+ for name in $names_this_round; do
+ already_handled=
+ for n in $names_already_handled; do
+ if test "$n" = "$name"; then
+ already_handled=yes
+ break
+ fi
+ done
+ if test -z "$already_handled"; then
+ names_already_handled="$names_already_handled $name"
+ dnl See if it was already located by an earlier AC_LIB_LINKFLAGS
+ dnl or AC_LIB_HAVE_LINKFLAGS call.
+ uppername=`echo "$name" | sed -e
'y|abcdefghijklmnopqrstuvwxyz./-|ABCDEFGHIJKLMNOPQRSTUVWXYZ___|'`
+ eval value=\"\$HAVE_LIB$uppername\"
+ if test -n "$value"; then
+ if test "$value" = yes; then
+ eval value=\"\$LIB$uppername\"
+ test -z "$value" || LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+
}$value"
+ eval value=\"\$LTLIB$uppername\"
+ test -z "$value" || LTLIB[]NAME="${LTLIB[]NAME}${LTLIB[]NAME:+
}$value"
+ else
+ dnl An earlier call to AC_LIB_HAVE_LINKFLAGS has determined
+ dnl that this library doesn't exist. So just drop it.
+ :
+ fi
+ else
+ dnl Search the library lib$name in $additional_libdir and $LDFLAGS
+ dnl and the already constructed $LIBNAME/$LTLIBNAME.
+ found_dir=
+ found_la=
+ found_so=
+ found_a=
+ eval libname=\"$acl_libname_spec\" # typically: libname=lib$name
+ if test -n "$acl_shlibext"; then
+ shrext=".$acl_shlibext" # typically: shrext=.so
+ else
+ shrext=
+ fi
+ if test $use_additional = yes; then
+ dir="$additional_libdir"
+ dnl The same code as in the loop below:
+ dnl First look for a shared library.
+ if test -n "$acl_shlibext"; then
+ if test -f "$dir/$libname$shrext"; then
+ found_dir="$dir"
+ found_so="$dir/$libname$shrext"
+ else
+ if test "$acl_library_names_spec" =
'$libname$shrext$versuffix'; then
+ ver=`(cd "$dir" && \
+ for f in "$libname$shrext".*; do echo "$f";
done \
+ | sed -e "s,^$libname$shrext\\\\.,," \
+ | sort -t '.' -n -r -k1,1 -k2,2 -k3,3 -k4,4 -k5,5 \
+ | sed 1q ) 2>/dev/null`
+ if test -n "$ver" && test -f
"$dir/$libname$shrext.$ver"; then
+ found_dir="$dir"
+ found_so="$dir/$libname$shrext.$ver"
+ fi
+ else
+ eval library_names=\"$acl_library_names_spec\"
+ for f in $library_names; do
+ if test -f "$dir/$f"; then
+ found_dir="$dir"
+ found_so="$dir/$f"
+ break
+ fi
+ done
+ fi
+ fi
+ fi
+ dnl Then look for a static library.
+ if test "X$found_dir" = "X"; then
+ if test -f "$dir/$libname.$acl_libext"; then
+ found_dir="$dir"
+ found_a="$dir/$libname.$acl_libext"
+ fi
+ fi
+ if test "X$found_dir" != "X"; then
+ if test -f "$dir/$libname.la"; then
+ found_la="$dir/$libname.la"
+ fi
+ fi
+ fi
+ if test "X$found_dir" = "X"; then
+ for x in $LDFLAGS $LTLIB[]NAME; do
+ AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"])
+ case "$x" in
+ -L*)
+ dir=`echo "X$x" | sed -e 's/^X-L//'`
+ dnl First look for a shared library.
+ if test -n "$acl_shlibext"; then
+ if test -f "$dir/$libname$shrext"; then
+ found_dir="$dir"
+ found_so="$dir/$libname$shrext"
+ else
+ if test "$acl_library_names_spec" =
'$libname$shrext$versuffix'; then
+ ver=`(cd "$dir" && \
+ for f in "$libname$shrext".*; do echo
"$f"; done \
+ | sed -e "s,^$libname$shrext\\\\.,," \
+ | sort -t '.' -n -r -k1,1 -k2,2 -k3,3 -k4,4 -k5,5
\
+ | sed 1q ) 2>/dev/null`
+ if test -n "$ver" && test -f
"$dir/$libname$shrext.$ver"; then
+ found_dir="$dir"
+ found_so="$dir/$libname$shrext.$ver"
+ fi
+ else
+ eval library_names=\"$acl_library_names_spec\"
+ for f in $library_names; do
+ if test -f "$dir/$f"; then
+ found_dir="$dir"
+ found_so="$dir/$f"
+ break
+ fi
+ done
+ fi
+ fi
+ fi
+ dnl Then look for a static library.
+ if test "X$found_dir" = "X"; then
+ if test -f "$dir/$libname.$acl_libext"; then
+ found_dir="$dir"
+ found_a="$dir/$libname.$acl_libext"
+ fi
+ fi
+ if test "X$found_dir" != "X"; then
+ if test -f "$dir/$libname.la"; then
+ found_la="$dir/$libname.la"
+ fi
+ fi
+ ;;
+ esac
+ if test "X$found_dir" != "X"; then
+ break
+ fi
+ done
+ fi
+ if test "X$found_dir" != "X"; then
+ dnl Found the library.
+ LTLIB[]NAME="${LTLIB[]NAME}${LTLIB[]NAME:+ }-L$found_dir -l$name"
+ if test "X$found_so" != "X"; then
+ dnl Linking with a shared library. We attempt to hardcode its
+ dnl directory into the executable's runpath, unless it's the
+ dnl standard /usr/lib.
+ if test "$enable_rpath" = no \
+ || test "X$found_dir" = "X/usr/$acl_libdirstem" \
+ || test "X$found_dir" = "X/usr/$acl_libdirstem2";
then
+ dnl No hardcoding is needed.
+ LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$found_so"
+ else
+ dnl Use an explicit option to hardcode DIR into the resulting
+ dnl binary.
+ dnl Potentially add DIR to ltrpathdirs.
+ dnl The ltrpathdirs will be appended to $LTLIBNAME at the end.
+ haveit=
+ for x in $ltrpathdirs; do
+ if test "X$x" = "X$found_dir"; then
+ haveit=yes
+ break
+ fi
+ done
+ if test -z "$haveit"; then
+ ltrpathdirs="$ltrpathdirs $found_dir"
+ fi
+ dnl The hardcoding into $LIBNAME is system dependent.
+ if test "$acl_hardcode_direct" = yes; then
+ dnl Using DIR/libNAME.so during linking hardcodes DIR into the
+ dnl resulting binary.
+ LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$found_so"
+ else
+ if test -n "$acl_hardcode_libdir_flag_spec" && test
"$acl_hardcode_minus_L" = no; then
+ dnl Use an explicit option to hardcode DIR into the resulting
+ dnl binary.
+ LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$found_so"
+ dnl Potentially add DIR to rpathdirs.
+ dnl The rpathdirs will be appended to $LIBNAME at the end.
+ haveit=
+ for x in $rpathdirs; do
+ if test "X$x" = "X$found_dir"; then
+ haveit=yes
+ break
+ fi
+ done
+ if test -z "$haveit"; then
+ rpathdirs="$rpathdirs $found_dir"
+ fi
+ else
+ dnl Rely on "-L$found_dir".
+ dnl But don't add it if it's already contained in the
LDFLAGS
+ dnl or the already constructed $LIBNAME
+ haveit=
+ for x in $LDFLAGS $LIB[]NAME; do
+ AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"])
+ if test "X$x" = "X-L$found_dir"; then
+ haveit=yes
+ break
+ fi
+ done
+ if test -z "$haveit"; then
+ LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }-L$found_dir"
+ fi
+ if test "$acl_hardcode_minus_L" != no; then
+ dnl FIXME: Not sure whether we should use
+ dnl "-L$found_dir -l$name" or "-L$found_dir
$found_so"
+ dnl here.
+ LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$found_so"
+ else
+ dnl We cannot use $acl_hardcode_runpath_var and LD_RUN_PATH
+ dnl here, because this doesn't fit in flags passed to the
+ dnl compiler. So give up. No hardcoding. This affects only
+ dnl very old systems.
+ dnl FIXME: Not sure whether we should use
+ dnl "-L$found_dir -l$name" or "-L$found_dir
$found_so"
+ dnl here.
+ LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }-l$name"
+ fi
+ fi
+ fi
+ fi
+ else
+ if test "X$found_a" != "X"; then
+ dnl Linking with a static library.
+ LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$found_a"
+ else
+ dnl We shouldn't come here, but anyway it's good to have a
+ dnl fallback.
+ LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }-L$found_dir -l$name"
+ fi
+ fi
+ dnl Assume the include files are nearby.
+ additional_includedir=
+ case "$found_dir" in
+ */$acl_libdirstem | */$acl_libdirstem/)
+ basedir=`echo "X$found_dir" | sed -e 's,^X,,' -e
"s,/$acl_libdirstem/"'*$,,'`
+ if test "$name" = '$1'; then
+ LIB[]NAME[]_PREFIX="$basedir"
+ fi
+ additional_includedir="$basedir/include"
+ ;;
+ */$acl_libdirstem2 | */$acl_libdirstem2/)
+ basedir=`echo "X$found_dir" | sed -e 's,^X,,' -e
"s,/$acl_libdirstem2/"'*$,,'`
+ if test "$name" = '$1'; then
+ LIB[]NAME[]_PREFIX="$basedir"
+ fi
+ additional_includedir="$basedir/include"
+ ;;
+ esac
+ if test "X$additional_includedir" != "X"; then
+ dnl Potentially add $additional_includedir to $INCNAME.
+ dnl But don't add it
+ dnl 1. if it's the standard /usr/include,
+ dnl 2. if it's /usr/local/include and we are using GCC on Linux,
+ dnl 3. if it's already present in $CPPFLAGS or the already
+ dnl constructed $INCNAME,
+ dnl 4. if it doesn't exist as a directory.
+ if test "X$additional_includedir" != "X/usr/include";
then
+ haveit=
+ if test "X$additional_includedir" =
"X/usr/local/include"; then
+ if test -n "$GCC"; then
+ case $host_os in
+ linux* | gnu* | k*bsd*-gnu) haveit=yes;;
+ esac
+ fi
+ fi
+ if test -z "$haveit"; then
+ for x in $CPPFLAGS $INC[]NAME; do
+ AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"])
+ if test "X$x" = "X-I$additional_includedir";
then
+ haveit=yes
+ break
+ fi
+ done
+ if test -z "$haveit"; then
+ if test -d "$additional_includedir"; then
+ dnl Really add $additional_includedir to $INCNAME.
+ INC[]NAME="${INC[]NAME}${INC[]NAME:+
}-I$additional_includedir"
+ fi
+ fi
+ fi
+ fi
+ fi
+ dnl Look for dependencies.
+ if test -n "$found_la"; then
+ dnl Read the .la file. It defines the variables
+ dnl dlname, library_names, old_library, dependency_libs, current,
+ dnl age, revision, installed, dlopen, dlpreopen, libdir.
+ save_libdir="$libdir"
+ case "$found_la" in
+ */* | *\\*) . "$found_la" ;;
+ *) . "./$found_la" ;;
+ esac
+ libdir="$save_libdir"
+ dnl We use only dependency_libs.
+ for dep in $dependency_libs; do
+ case "$dep" in
+ -L*)
+ additional_libdir=`echo "X$dep" | sed -e
's/^X-L//'`
+ dnl Potentially add $additional_libdir to $LIBNAME and $LTLIBNAME.
+ dnl But don't add it
+ dnl 1. if it's the standard /usr/lib,
+ dnl 2. if it's /usr/local/lib and we are using GCC on Linux,
+ dnl 3. if it's already present in $LDFLAGS or the already
+ dnl constructed $LIBNAME,
+ dnl 4. if it doesn't exist as a directory.
+ if test "X$additional_libdir" !=
"X/usr/$acl_libdirstem" \
+ && test "X$additional_libdir" !=
"X/usr/$acl_libdirstem2"; then
+ haveit=
+ if test "X$additional_libdir" =
"X/usr/local/$acl_libdirstem" \
+ || test "X$additional_libdir" =
"X/usr/local/$acl_libdirstem2"; then
+ if test -n "$GCC"; then
+ case $host_os in
+ linux* | gnu* | k*bsd*-gnu) haveit=yes;;
+ esac
+ fi
+ fi
+ if test -z "$haveit"; then
+ haveit=
+ for x in $LDFLAGS $LIB[]NAME; do
+ AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"])
+ if test "X$x" = "X-L$additional_libdir";
then
+ haveit=yes
+ break
+ fi
+ done
+ if test -z "$haveit"; then
+ if test -d "$additional_libdir"; then
+ dnl Really add $additional_libdir to $LIBNAME.
+ LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+
}-L$additional_libdir"
+ fi
+ fi
+ haveit=
+ for x in $LDFLAGS $LTLIB[]NAME; do
+ AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"])
+ if test "X$x" = "X-L$additional_libdir";
then
+ haveit=yes
+ break
+ fi
+ done
+ if test -z "$haveit"; then
+ if test -d "$additional_libdir"; then
+ dnl Really add $additional_libdir to $LTLIBNAME.
+ LTLIB[]NAME="${LTLIB[]NAME}${LTLIB[]NAME:+
}-L$additional_libdir"
+ fi
+ fi
+ fi
+ fi
+ ;;
+ -R*)
+ dir=`echo "X$dep" | sed -e 's/^X-R//'`
+ if test "$enable_rpath" != no; then
+ dnl Potentially add DIR to rpathdirs.
+ dnl The rpathdirs will be appended to $LIBNAME at the end.
+ haveit=
+ for x in $rpathdirs; do
+ if test "X$x" = "X$dir"; then
+ haveit=yes
+ break
+ fi
+ done
+ if test -z "$haveit"; then
+ rpathdirs="$rpathdirs $dir"
+ fi
+ dnl Potentially add DIR to ltrpathdirs.
+ dnl The ltrpathdirs will be appended to $LTLIBNAME at the end.
+ haveit=
+ for x in $ltrpathdirs; do
+ if test "X$x" = "X$dir"; then
+ haveit=yes
+ break
+ fi
+ done
+ if test -z "$haveit"; then
+ ltrpathdirs="$ltrpathdirs $dir"
+ fi
+ fi
+ ;;
+ -l*)
+ dnl Handle this in the next round.
+ names_next_round="$names_next_round "`echo
"X$dep" | sed -e 's/^X-l//'`
+ ;;
+ *.la)
+ dnl Handle this in the next round. Throw away the .la's
+ dnl directory; it is already contained in a preceding -L
+ dnl option.
+ names_next_round="$names_next_round "`echo
"X$dep" | sed -e 's,^X.*/,,' -e 's,^lib,,' -e
's,\.la$,,'`
+ ;;
+ *)
+ dnl Most likely an immediate library name.
+ LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$dep"
+ LTLIB[]NAME="${LTLIB[]NAME}${LTLIB[]NAME:+ }$dep"
+ ;;
+ esac
+ done
+ fi
+ else
+ dnl Didn't find the library; assume it is in the system directories
+ dnl known to the linker and runtime loader. (All the system
+ dnl directories known to the linker should also be known to the
+ dnl runtime loader, otherwise the system is severely misconfigured.)
+ LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }-l$name"
+ LTLIB[]NAME="${LTLIB[]NAME}${LTLIB[]NAME:+ }-l$name"
+ fi
+ fi
+ fi
+ done
+ done
+ if test "X$rpathdirs" != "X"; then
+ if test -n "$acl_hardcode_libdir_separator"; then
+ dnl Weird platform: only the last -rpath option counts, the user must
+ dnl pass all path elements in one option. We can arrange that for a
+ dnl single library, but not when more than one $LIBNAMEs are used.
+ alldirs=
+ for found_dir in $rpathdirs; do
+
alldirs="${alldirs}${alldirs:+$acl_hardcode_libdir_separator}$found_dir"
+ done
+ dnl Note: acl_hardcode_libdir_flag_spec uses $libdir and $wl.
+ acl_save_libdir="$libdir"
+ libdir="$alldirs"
+ eval flag=\"$acl_hardcode_libdir_flag_spec\"
+ libdir="$acl_save_libdir"
+ LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$flag"
+ else
+ dnl The -rpath options are cumulative.
+ for found_dir in $rpathdirs; do
+ acl_save_libdir="$libdir"
+ libdir="$found_dir"
+ eval flag=\"$acl_hardcode_libdir_flag_spec\"
+ libdir="$acl_save_libdir"
+ LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$flag"
+ done
+ fi
+ fi
+ if test "X$ltrpathdirs" != "X"; then
+ dnl When using libtool, the option that works for both libraries and
+ dnl executables is -R. The -R options are cumulative.
+ for found_dir in $ltrpathdirs; do
+ LTLIB[]NAME="${LTLIB[]NAME}${LTLIB[]NAME:+ }-R$found_dir"
+ done
+ fi
+ popdef([P_A_C_K])
+ popdef([PACKLIBS])
+ popdef([PACKUP])
+ popdef([PACK])
+ popdef([NAME])
+])
+
+dnl AC_LIB_APPENDTOVAR(VAR, CONTENTS) appends the elements of CONTENTS to VAR,
+dnl unless already present in VAR.
+dnl Works only for CPPFLAGS, not for LIB* variables because that sometimes
+dnl contains two or three consecutive elements that belong together.
+AC_DEFUN([AC_LIB_APPENDTOVAR],
+[
+ for element in [$2]; do
+ haveit=
+ for x in $[$1]; do
+ AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"])
+ if test "X$x" = "X$element"; then
+ haveit=yes
+ break
+ fi
+ done
+ if test -z "$haveit"; then
+ [$1]="${[$1]}${[$1]:+ }$element"
+ fi
+ done
+])
+
+dnl For those cases where a variable contains several -L and -l options
+dnl referring to unknown libraries and directories, this macro determines the
+dnl necessary additional linker options for the runtime path.
+dnl AC_LIB_LINKFLAGS_FROM_LIBS([LDADDVAR], [LIBSVALUE], [USE-LIBTOOL])
+dnl sets LDADDVAR to linker options needed together with LIBSVALUE.
+dnl If USE-LIBTOOL evaluates to non-empty, linking with libtool is assumed,
+dnl otherwise linking without libtool is assumed.
+AC_DEFUN([AC_LIB_LINKFLAGS_FROM_LIBS],
+[
+ AC_REQUIRE([AC_LIB_RPATH])
+ AC_REQUIRE([AC_LIB_PREPARE_MULTILIB])
+ $1=
+ if test "$enable_rpath" != no; then
+ if test -n "$acl_hardcode_libdir_flag_spec" && test
"$acl_hardcode_minus_L" = no; then
+ dnl Use an explicit option to hardcode directories into the resulting
+ dnl binary.
+ rpathdirs=
+ next=
+ for opt in $2; do
+ if test -n "$next"; then
+ dir="$next"
+ dnl No need to hardcode the standard /usr/lib.
+ if test "X$dir" != "X/usr/$acl_libdirstem" \
+ && test "X$dir" != "X/usr/$acl_libdirstem2";
then
+ rpathdirs="$rpathdirs $dir"
+ fi
+ next=
+ else
+ case $opt in
+ -L) next=yes ;;
+ -L*) dir=`echo "X$opt" | sed -e 's,^X-L,,'`
+ dnl No need to hardcode the standard /usr/lib.
+ if test "X$dir" != "X/usr/$acl_libdirstem" \
+ && test "X$dir" !=
"X/usr/$acl_libdirstem2"; then
+ rpathdirs="$rpathdirs $dir"
+ fi
+ next= ;;
+ *) next= ;;
+ esac
+ fi
+ done
+ if test "X$rpathdirs" != "X"; then
+ if test -n ""$3""; then
+ dnl libtool is used for linking. Use -R options.
+ for dir in $rpathdirs; do
+ $1="${$1}${$1:+ }-R$dir"
+ done
+ else
+ dnl The linker is used for linking directly.
+ if test -n "$acl_hardcode_libdir_separator"; then
+ dnl Weird platform: only the last -rpath option counts, the user
+ dnl must pass all path elements in one option.
+ alldirs=
+ for dir in $rpathdirs; do
+
alldirs="${alldirs}${alldirs:+$acl_hardcode_libdir_separator}$dir"
+ done
+ acl_save_libdir="$libdir"
+ libdir="$alldirs"
+ eval flag=\"$acl_hardcode_libdir_flag_spec\"
+ libdir="$acl_save_libdir"
+ $1="$flag"
+ else
+ dnl The -rpath options are cumulative.
+ for dir in $rpathdirs; do
+ acl_save_libdir="$libdir"
+ libdir="$dir"
+ eval flag=\"$acl_hardcode_libdir_flag_spec\"
+ libdir="$acl_save_libdir"
+ $1="${$1}${$1:+ }$flag"
+ done
+ fi
+ fi
+ fi
+ fi
+ fi
+ AC_SUBST([$1])
+])
diff --git a/src/wok/plugins/kimchi/m4/lib-prefix.m4
b/src/wok/plugins/kimchi/m4/lib-prefix.m4
new file mode 100644
index 0000000..1601cea
--- /dev/null
+++ b/src/wok/plugins/kimchi/m4/lib-prefix.m4
@@ -0,0 +1,224 @@
+# lib-prefix.m4 serial 7 (gettext-0.18)
+dnl Copyright (C) 2001-2005, 2008-2010 Free Software Foundation, Inc.
+dnl This file is free software; the Free Software Foundation
+dnl gives unlimited permission to copy and/or distribute it,
+dnl with or without modifications, as long as this notice is preserved.
+
+dnl From Bruno Haible.
+
+dnl AC_LIB_ARG_WITH is synonymous to AC_ARG_WITH in autoconf-2.13, and
+dnl similar to AC_ARG_WITH in autoconf 2.52...2.57 except that is doesn't
+dnl require excessive bracketing.
+ifdef([AC_HELP_STRING],
+[AC_DEFUN([AC_LIB_ARG_WITH], [AC_ARG_WITH([$1],[[$2]],[$3],[$4])])],
+[AC_DEFUN([AC_][LIB_ARG_WITH], [AC_ARG_WITH([$1],[$2],[$3],[$4])])])
+
+dnl AC_LIB_PREFIX adds to the CPPFLAGS and LDFLAGS the flags that are needed
+dnl to access previously installed libraries. The basic assumption is that
+dnl a user will want packages to use other packages he previously installed
+dnl with the same --prefix option.
+dnl This macro is not needed if only AC_LIB_LINKFLAGS is used to locate
+dnl libraries, but is otherwise very convenient.
+AC_DEFUN([AC_LIB_PREFIX],
+[
+ AC_BEFORE([$0], [AC_LIB_LINKFLAGS])
+ AC_REQUIRE([AC_PROG_CC])
+ AC_REQUIRE([AC_CANONICAL_HOST])
+ AC_REQUIRE([AC_LIB_PREPARE_MULTILIB])
+ AC_REQUIRE([AC_LIB_PREPARE_PREFIX])
+ dnl By default, look in $includedir and $libdir.
+ use_additional=yes
+ AC_LIB_WITH_FINAL_PREFIX([
+ eval additional_includedir=\"$includedir\"
+ eval additional_libdir=\"$libdir\"
+ ])
+ AC_LIB_ARG_WITH([lib-prefix],
+[ --with-lib-prefix[=DIR] search for libraries in DIR/include and DIR/lib
+ --without-lib-prefix don't search for libraries in includedir and libdir],
+[
+ if test "X$withval" = "Xno"; then
+ use_additional=no
+ else
+ if test "X$withval" = "X"; then
+ AC_LIB_WITH_FINAL_PREFIX([
+ eval additional_includedir=\"$includedir\"
+ eval additional_libdir=\"$libdir\"
+ ])
+ else
+ additional_includedir="$withval/include"
+ additional_libdir="$withval/$acl_libdirstem"
+ fi
+ fi
+])
+ if test $use_additional = yes; then
+ dnl Potentially add $additional_includedir to $CPPFLAGS.
+ dnl But don't add it
+ dnl 1. if it's the standard /usr/include,
+ dnl 2. if it's already present in $CPPFLAGS,
+ dnl 3. if it's /usr/local/include and we are using GCC on Linux,
+ dnl 4. if it doesn't exist as a directory.
+ if test "X$additional_includedir" != "X/usr/include"; then
+ haveit=
+ for x in $CPPFLAGS; do
+ AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"])
+ if test "X$x" = "X-I$additional_includedir"; then
+ haveit=yes
+ break
+ fi
+ done
+ if test -z "$haveit"; then
+ if test "X$additional_includedir" = "X/usr/local/include";
then
+ if test -n "$GCC"; then
+ case $host_os in
+ linux* | gnu* | k*bsd*-gnu) haveit=yes;;
+ esac
+ fi
+ fi
+ if test -z "$haveit"; then
+ if test -d "$additional_includedir"; then
+ dnl Really add $additional_includedir to $CPPFLAGS.
+ CPPFLAGS="${CPPFLAGS}${CPPFLAGS:+ }-I$additional_includedir"
+ fi
+ fi
+ fi
+ fi
+ dnl Potentially add $additional_libdir to $LDFLAGS.
+ dnl But don't add it
+ dnl 1. if it's the standard /usr/lib,
+ dnl 2. if it's already present in $LDFLAGS,
+ dnl 3. if it's /usr/local/lib and we are using GCC on Linux,
+ dnl 4. if it doesn't exist as a directory.
+ if test "X$additional_libdir" != "X/usr/$acl_libdirstem"; then
+ haveit=
+ for x in $LDFLAGS; do
+ AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"])
+ if test "X$x" = "X-L$additional_libdir"; then
+ haveit=yes
+ break
+ fi
+ done
+ if test -z "$haveit"; then
+ if test "X$additional_libdir" =
"X/usr/local/$acl_libdirstem"; then
+ if test -n "$GCC"; then
+ case $host_os in
+ linux*) haveit=yes;;
+ esac
+ fi
+ fi
+ if test -z "$haveit"; then
+ if test -d "$additional_libdir"; then
+ dnl Really add $additional_libdir to $LDFLAGS.
+ LDFLAGS="${LDFLAGS}${LDFLAGS:+ }-L$additional_libdir"
+ fi
+ fi
+ fi
+ fi
+ fi
+])
+
+dnl AC_LIB_PREPARE_PREFIX creates variables acl_final_prefix,
+dnl acl_final_exec_prefix, containing the values to which $prefix and
+dnl $exec_prefix will expand at the end of the configure script.
+AC_DEFUN([AC_LIB_PREPARE_PREFIX],
+[
+ dnl Unfortunately, prefix and exec_prefix get only finally determined
+ dnl at the end of configure.
+ if test "X$prefix" = "XNONE"; then
+ acl_final_prefix="$ac_default_prefix"
+ else
+ acl_final_prefix="$prefix"
+ fi
+ if test "X$exec_prefix" = "XNONE"; then
+ acl_final_exec_prefix='${prefix}'
+ else
+ acl_final_exec_prefix="$exec_prefix"
+ fi
+ acl_save_prefix="$prefix"
+ prefix="$acl_final_prefix"
+ eval acl_final_exec_prefix=\"$acl_final_exec_prefix\"
+ prefix="$acl_save_prefix"
+])
+
+dnl AC_LIB_WITH_FINAL_PREFIX([statement]) evaluates statement, with the
+dnl variables prefix and exec_prefix bound to the values they will have
+dnl at the end of the configure script.
+AC_DEFUN([AC_LIB_WITH_FINAL_PREFIX],
+[
+ acl_save_prefix="$prefix"
+ prefix="$acl_final_prefix"
+ acl_save_exec_prefix="$exec_prefix"
+ exec_prefix="$acl_final_exec_prefix"
+ $1
+ exec_prefix="$acl_save_exec_prefix"
+ prefix="$acl_save_prefix"
+])
+
+dnl AC_LIB_PREPARE_MULTILIB creates
+dnl - a variable acl_libdirstem, containing the basename of the libdir, either
+dnl "lib" or "lib64" or "lib/64",
+dnl - a variable acl_libdirstem2, as a secondary possible value for
+dnl acl_libdirstem, either the same as acl_libdirstem or "lib/sparcv9" or
+dnl "lib/amd64".
+AC_DEFUN([AC_LIB_PREPARE_MULTILIB],
+[
+ dnl There is no formal standard regarding lib and lib64.
+ dnl On glibc systems, the current practice is that on a system supporting
+ dnl 32-bit and 64-bit instruction sets or ABIs, 64-bit libraries go under
+ dnl $prefix/lib64 and 32-bit libraries go under $prefix/lib. We determine
+ dnl the compiler's default mode by looking at the compiler's library search
+ dnl path. If at least one of its elements ends in /lib64 or points to a
+ dnl directory whose absolute pathname ends in /lib64, we assume a 64-bit ABI.
+ dnl Otherwise we use the default, namely "lib".
+ dnl On Solaris systems, the current practice is that on a system supporting
+ dnl 32-bit and 64-bit instruction sets or ABIs, 64-bit libraries go under
+ dnl $prefix/lib/64 (which is a symlink to either $prefix/lib/sparcv9 or
+ dnl $prefix/lib/amd64) and 32-bit libraries go under $prefix/lib.
+ AC_REQUIRE([AC_CANONICAL_HOST])
+ acl_libdirstem=lib
+ acl_libdirstem2=
+ case "$host_os" in
+ solaris*)
+ dnl See Solaris 10 Software Developer Collection > Solaris 64-bit
Developer's Guide > The Development Environment
+ dnl <
http://docs.sun.com/app/docs/doc/816-5138/dev-env?l=en&a=view>.
+ dnl "Portable Makefiles should refer to any library directories using the 64
symbolic link."
+ dnl But we want to recognize the sparcv9 or amd64 subdirectory also if the
+ dnl symlink is missing, so we set acl_libdirstem2 too.
+ AC_CACHE_CHECK([for 64-bit host], [gl_cv_solaris_64bit],
+ [AC_EGREP_CPP([sixtyfour bits], [
+#ifdef _LP64
+sixtyfour bits
+#endif
+ ], [gl_cv_solaris_64bit=yes], [gl_cv_solaris_64bit=no])
+ ])
+ if test $gl_cv_solaris_64bit = yes; then
+ acl_libdirstem=lib/64
+ case "$host_cpu" in
+ sparc*) acl_libdirstem2=lib/sparcv9 ;;
+ i*86 | x86_64) acl_libdirstem2=lib/amd64 ;;
+ esac
+ fi
+ ;;
+ *)
+ searchpath=`(LC_ALL=C $CC -print-search-dirs) 2>/dev/null | sed -n -e
's,^libraries: ,,p' | sed -e 's,^=,,'`
+ if test -n "$searchpath"; then
+ acl_save_IFS="${IFS= }"; IFS=":"
+ for searchdir in $searchpath; do
+ if test -d "$searchdir"; then
+ case "$searchdir" in
+ */lib64/ | */lib64 ) acl_libdirstem=lib64 ;;
+ */../ | */.. )
+ # Better ignore directories of this form. They are misleading.
+ ;;
+ *) searchdir=`cd "$searchdir" && pwd`
+ case "$searchdir" in
+ */lib64 ) acl_libdirstem=lib64 ;;
+ esac ;;
+ esac
+ fi
+ done
+ IFS="$acl_save_IFS"
+ fi
+ ;;
+ esac
+ test -n "$acl_libdirstem2" || acl_libdirstem2="$acl_libdirstem"
+])
diff --git a/src/wok/plugins/kimchi/m4/nls.m4 b/src/wok/plugins/kimchi/m4/nls.m4
new file mode 100644
index 0000000..003704c
--- /dev/null
+++ b/src/wok/plugins/kimchi/m4/nls.m4
@@ -0,0 +1,32 @@
+# nls.m4 serial 5 (gettext-0.18)
+dnl Copyright (C) 1995-2003, 2005-2006, 2008-2010 Free Software Foundation,
+dnl Inc.
+dnl This file is free software; the Free Software Foundation
+dnl gives unlimited permission to copy and/or distribute it,
+dnl with or without modifications, as long as this notice is preserved.
+dnl
+dnl This file can can be used in projects which are not available under
+dnl the GNU General Public License or the GNU Library General Public
+dnl License but which still want to provide support for the GNU gettext
+dnl functionality.
+dnl Please note that the actual code of the GNU gettext library is covered
+dnl by the GNU Library General Public License, and the rest of the GNU
+dnl gettext package package is covered by the GNU General Public License.
+dnl They are *not* in the public domain.
+
+dnl Authors:
+dnl Ulrich Drepper <drepper(a)cygnus.com>, 1995-2000.
+dnl Bruno Haible <haible(a)clisp.cons.org>, 2000-2003.
+
+AC_PREREQ([2.50])
+
+AC_DEFUN([AM_NLS],
+[
+ AC_MSG_CHECKING([whether NLS is requested])
+ dnl Default is enabled NLS
+ AC_ARG_ENABLE([nls],
+ [ --disable-nls do not use Native Language Support],
+ USE_NLS=$enableval, USE_NLS=yes)
+ AC_MSG_RESULT([$USE_NLS])
+ AC_SUBST([USE_NLS])
+])
diff --git a/src/wok/plugins/kimchi/m4/po.m4 b/src/wok/plugins/kimchi/m4/po.m4
new file mode 100644
index 0000000..8bc921d
--- /dev/null
+++ b/src/wok/plugins/kimchi/m4/po.m4
@@ -0,0 +1,449 @@
+# po.m4 serial 17 (gettext-0.18)
+dnl Copyright (C) 1995-2010 Free Software Foundation, Inc.
+dnl This file is free software; the Free Software Foundation
+dnl gives unlimited permission to copy and/or distribute it,
+dnl with or without modifications, as long as this notice is preserved.
+dnl
+dnl This file can can be used in projects which are not available under
+dnl the GNU General Public License or the GNU Library General Public
+dnl License but which still want to provide support for the GNU gettext
+dnl functionality.
+dnl Please note that the actual code of the GNU gettext library is covered
+dnl by the GNU Library General Public License, and the rest of the GNU
+dnl gettext package package is covered by the GNU General Public License.
+dnl They are *not* in the public domain.
+
+dnl Authors:
+dnl Ulrich Drepper <drepper(a)cygnus.com>, 1995-2000.
+dnl Bruno Haible <haible(a)clisp.cons.org>, 2000-2003.
+
+AC_PREREQ([2.50])
+
+dnl Checks for all prerequisites of the po subdirectory.
+AC_DEFUN([AM_PO_SUBDIRS],
+[
+ AC_REQUIRE([AC_PROG_MAKE_SET])dnl
+ AC_REQUIRE([AC_PROG_INSTALL])dnl
+ AC_REQUIRE([AC_PROG_MKDIR_P])dnl defined by autoconf
+ AC_REQUIRE([AM_NLS])dnl
+
+ dnl Release version of the gettext macros. This is used to ensure that
+ dnl the gettext macros and po/Makefile.in.in are in sync.
+ AC_SUBST([GETTEXT_MACRO_VERSION], [0.18])
+
+ dnl Perform the following tests also if --disable-nls has been given,
+ dnl because they are needed for "make dist" to work.
+
+ dnl Search for GNU msgfmt in the PATH.
+ dnl The first test excludes Solaris msgfmt and early GNU msgfmt versions.
+ dnl The second test excludes FreeBSD msgfmt.
+ AM_PATH_PROG_WITH_TEST(MSGFMT, msgfmt,
+ [$ac_dir/$ac_word --statistics /dev/null >&]AS_MESSAGE_LOG_FD[ 2>&1
&&
+ (if $ac_dir/$ac_word --statistics /dev/null 2>&1 >/dev/null | grep usage
>/dev/null; then exit 1; else exit 0; fi)],
+ :)
+ AC_PATH_PROG([GMSGFMT], [gmsgfmt], [$MSGFMT])
+
+ dnl Test whether it is GNU msgfmt >= 0.15.
+changequote(,)dnl
+ case `$MSGFMT --version | sed 1q | sed -e 's,^[^0-9]*,,'` in
+ '' | 0.[0-9] | 0.[0-9].* | 0.1[0-4] | 0.1[0-4].*) MSGFMT_015=: ;;
+ *) MSGFMT_015=$MSGFMT ;;
+ esac
+changequote([,])dnl
+ AC_SUBST([MSGFMT_015])
+changequote(,)dnl
+ case `$GMSGFMT --version | sed 1q | sed -e 's,^[^0-9]*,,'` in
+ '' | 0.[0-9] | 0.[0-9].* | 0.1[0-4] | 0.1[0-4].*) GMSGFMT_015=: ;;
+ *) GMSGFMT_015=$GMSGFMT ;;
+ esac
+changequote([,])dnl
+ AC_SUBST([GMSGFMT_015])
+
+ dnl Search for GNU xgettext 0.12 or newer in the PATH.
+ dnl The first test excludes Solaris xgettext and early GNU xgettext versions.
+ dnl The second test excludes FreeBSD xgettext.
+ AM_PATH_PROG_WITH_TEST(XGETTEXT, xgettext,
+ [$ac_dir/$ac_word --omit-header --copyright-holder= --msgid-bugs-address= /dev/null
>&]AS_MESSAGE_LOG_FD[ 2>&1 &&
+ (if $ac_dir/$ac_word --omit-header --copyright-holder= --msgid-bugs-address=
/dev/null 2>&1 >/dev/null | grep usage >/dev/null; then exit 1; else exit 0;
fi)],
+ :)
+ dnl Remove leftover from FreeBSD xgettext call.
+ rm -f messages.po
+
+ dnl Test whether it is GNU xgettext >= 0.15.
+changequote(,)dnl
+ case `$XGETTEXT --version | sed 1q | sed -e 's,^[^0-9]*,,'` in
+ '' | 0.[0-9] | 0.[0-9].* | 0.1[0-4] | 0.1[0-4].*) XGETTEXT_015=: ;;
+ *) XGETTEXT_015=$XGETTEXT ;;
+ esac
+changequote([,])dnl
+ AC_SUBST([XGETTEXT_015])
+
+ dnl Search for GNU msgmerge 0.11 or newer in the PATH.
+ AM_PATH_PROG_WITH_TEST(MSGMERGE, msgmerge,
+ [$ac_dir/$ac_word --update -q /dev/null /dev/null >&]AS_MESSAGE_LOG_FD[
2>&1], :)
+
+ dnl Installation directories.
+ dnl Autoconf >= 2.60 defines localedir. For older versions of autoconf, we
+ dnl have to define it here, so that it can be used in po/Makefile.
+ test -n "$localedir" || localedir='${datadir}/locale'
+ AC_SUBST([localedir])
+
+ dnl Support for AM_XGETTEXT_OPTION.
+ test -n "${XGETTEXT_EXTRA_OPTIONS+set}" || XGETTEXT_EXTRA_OPTIONS=
+ AC_SUBST([XGETTEXT_EXTRA_OPTIONS])
+
+ AC_CONFIG_COMMANDS([po-directories], [[
+ for ac_file in $CONFIG_FILES; do
+ # Support "outfile[:infile[:infile...]]"
+ case "$ac_file" in
+ *:*) ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;;
+ esac
+ # PO directories have a Makefile.in generated from Makefile.in.in.
+ case "$ac_file" in */Makefile.in)
+ # Adjust a relative srcdir.
+ ac_dir=`echo "$ac_file"|sed 's%/[^/][^/]*$%%'`
+ ac_dir_suffix="/`echo "$ac_dir"|sed 's%^\./%%'`"
+ ac_dots=`echo "$ac_dir_suffix"|sed 's%/[^/]*%../%g'`
+ # In autoconf-2.13 it is called $ac_given_srcdir.
+ # In autoconf-2.50 it is called $srcdir.
+ test -n "$ac_given_srcdir" || ac_given_srcdir="$srcdir"
+ case "$ac_given_srcdir" in
+ .) top_srcdir=`echo $ac_dots|sed 's%/$%%'` ;;
+ /*) top_srcdir="$ac_given_srcdir" ;;
+ *) top_srcdir="$ac_dots$ac_given_srcdir" ;;
+ esac
+ # Treat a directory as a PO directory if and only if it has a
+ # POTFILES.in file. This allows packages to have multiple PO
+ # directories under different names or in different locations.
+ if test -f "$ac_given_srcdir/$ac_dir/POTFILES.in"; then
+ rm -f "$ac_dir/POTFILES"
+ test -n "$as_me" && echo "$as_me: creating
$ac_dir/POTFILES" || echo "creating $ac_dir/POTFILES"
+ cat "$ac_given_srcdir/$ac_dir/POTFILES.in" | sed -e "/^#/d"
-e "/^[ ]*\$/d" -e "s,.*, $top_srcdir/& \\\\," | sed -e
"\$s/\(.*\) \\\\/\1/" > "$ac_dir/POTFILES"
+ POMAKEFILEDEPS="POTFILES.in"
+ # ALL_LINGUAS, POFILES, UPDATEPOFILES, DUMMYPOFILES, GMOFILES depend
+ # on $ac_dir but don't depend on user-specified configuration
+ # parameters.
+ if test -f "$ac_given_srcdir/$ac_dir/LINGUAS"; then
+ # The LINGUAS file contains the set of available languages.
+ if test -n "$OBSOLETE_ALL_LINGUAS"; then
+ test -n "$as_me" && echo "$as_me: setting
ALL_LINGUAS in configure.in is obsolete" || echo "setting ALL_LINGUAS in
configure.in is obsolete"
+ fi
+ ALL_LINGUAS_=`sed -e "/^#/d" -e "s/#.*//"
"$ac_given_srcdir/$ac_dir/LINGUAS"`
+ # Hide the ALL_LINGUAS assigment from automake < 1.5.
+ eval 'ALL_LINGUAS''=$ALL_LINGUAS_'
+ POMAKEFILEDEPS="$POMAKEFILEDEPS LINGUAS"
+ else
+ # The set of available languages was given in configure.in.
+ # Hide the ALL_LINGUAS assigment from automake < 1.5.
+ eval 'ALL_LINGUAS''=$OBSOLETE_ALL_LINGUAS'
+ fi
+ # Compute POFILES
+ # as $(foreach lang, $(ALL_LINGUAS), $(srcdir)/$(lang).po)
+ # Compute UPDATEPOFILES
+ # as $(foreach lang, $(ALL_LINGUAS), $(lang).po-update)
+ # Compute DUMMYPOFILES
+ # as $(foreach lang, $(ALL_LINGUAS), $(lang).nop)
+ # Compute GMOFILES
+ # as $(foreach lang, $(ALL_LINGUAS), $(srcdir)/$(lang).gmo)
+ case "$ac_given_srcdir" in
+ .) srcdirpre= ;;
+ *) srcdirpre='$(srcdir)/' ;;
+ esac
+ POFILES=
+ UPDATEPOFILES=
+ DUMMYPOFILES=
+ GMOFILES=
+ for lang in $ALL_LINGUAS; do
+ POFILES="$POFILES $srcdirpre$lang.po"
+ UPDATEPOFILES="$UPDATEPOFILES $lang.po-update"
+ DUMMYPOFILES="$DUMMYPOFILES $lang.nop"
+ GMOFILES="$GMOFILES $srcdirpre$lang.gmo"
+ done
+ # CATALOGS depends on both $ac_dir and the user's LINGUAS
+ # environment variable.
+ INST_LINGUAS=
+ if test -n "$ALL_LINGUAS"; then
+ for presentlang in $ALL_LINGUAS; do
+ useit=no
+ if test "%UNSET%" != "$LINGUAS"; then
+ desiredlanguages="$LINGUAS"
+ else
+ desiredlanguages="$ALL_LINGUAS"
+ fi
+ for desiredlang in $desiredlanguages; do
+ # Use the presentlang catalog if desiredlang is
+ # a. equal to presentlang, or
+ # b. a variant of presentlang (because in this case,
+ # presentlang can be used as a fallback for messages
+ # which are not translated in the desiredlang catalog).
+ case "$desiredlang" in
+ "$presentlang"*) useit=yes;;
+ esac
+ done
+ if test $useit = yes; then
+ INST_LINGUAS="$INST_LINGUAS $presentlang"
+ fi
+ done
+ fi
+ CATALOGS=
+ if test -n "$INST_LINGUAS"; then
+ for lang in $INST_LINGUAS; do
+ CATALOGS="$CATALOGS $lang.gmo"
+ done
+ fi
+ test -n "$as_me" && echo "$as_me: creating
$ac_dir/Makefile" || echo "creating $ac_dir/Makefile"
+ sed -e "/^POTFILES =/r $ac_dir/POTFILES" -e "/^# Makevars/r
$ac_given_srcdir/$ac_dir/Makevars" -e "s|@POFILES@|$POFILES|g" -e
"s|@UPDATEPOFILES@|$UPDATEPOFILES|g" -e
"s|@DUMMYPOFILES@|$DUMMYPOFILES|g" -e "s|@GMOFILES@|$GMOFILES|g" -e
"s|@CATALOGS@|$CATALOGS|g" -e "s|@POMAKEFILEDEPS@|$POMAKEFILEDEPS|g"
"$ac_dir/Makefile.in" > "$ac_dir/Makefile"
+ for f in "$ac_given_srcdir/$ac_dir"/Rules-*; do
+ if test -f "$f"; then
+ case "$f" in
+ *.orig | *.bak | *~) ;;
+ *) cat "$f" >> "$ac_dir/Makefile" ;;
+ esac
+ fi
+ done
+ fi
+ ;;
+ esac
+ done]],
+ [# Capture the value of obsolete ALL_LINGUAS because we need it to compute
+ # POFILES, UPDATEPOFILES, DUMMYPOFILES, GMOFILES, CATALOGS. But hide it
+ # from automake < 1.5.
+ eval 'OBSOLETE_ALL_LINGUAS''="$ALL_LINGUAS"'
+ # Capture the value of LINGUAS because we need it to compute CATALOGS.
+ LINGUAS="${LINGUAS-%UNSET%}"
+ ])
+])
+
+dnl Postprocesses a Makefile in a directory containing PO files.
+AC_DEFUN([AM_POSTPROCESS_PO_MAKEFILE],
+[
+ # When this code is run, in config.status, two variables have already been
+ # set:
+ # - OBSOLETE_ALL_LINGUAS is the value of LINGUAS set in configure.in,
+ # - LINGUAS is the value of the environment variable LINGUAS at configure
+ # time.
+
+changequote(,)dnl
+ # Adjust a relative srcdir.
+ ac_dir=`echo "$ac_file"|sed 's%/[^/][^/]*$%%'`
+ ac_dir_suffix="/`echo "$ac_dir"|sed 's%^\./%%'`"
+ ac_dots=`echo "$ac_dir_suffix"|sed 's%/[^/]*%../%g'`
+ # In autoconf-2.13 it is called $ac_given_srcdir.
+ # In autoconf-2.50 it is called $srcdir.
+ test -n "$ac_given_srcdir" || ac_given_srcdir="$srcdir"
+ case "$ac_given_srcdir" in
+ .) top_srcdir=`echo $ac_dots|sed 's%/$%%'` ;;
+ /*) top_srcdir="$ac_given_srcdir" ;;
+ *) top_srcdir="$ac_dots$ac_given_srcdir" ;;
+ esac
+
+ # Find a way to echo strings without interpreting backslash.
+ if test "X`(echo '\t') 2>/dev/null`" = 'X\t'; then
+ gt_echo='echo'
+ else
+ if test "X`(printf '%s\n' '\t') 2>/dev/null`" =
'X\t'; then
+ gt_echo='printf %s\n'
+ else
+ echo_func () {
+ cat <<EOT
+$*
+EOT
+ }
+ gt_echo='echo_func'
+ fi
+ fi
+
+ # A sed script that extracts the value of VARIABLE from a Makefile.
+ sed_x_variable='
+# Test if the hold space is empty.
+x
+s/P/P/
+x
+ta
+# Yes it was empty. Look if we have the expected variable definition.
+/^[ ]*VARIABLE[ ]*=/{
+ # Seen the first line of the variable definition.
+ s/^[ ]*VARIABLE[ ]*=//
+ ba
+}
+bd
+:a
+# Here we are processing a line from the variable definition.
+# Remove comment, more precisely replace it with a space.
+s/#.*$/ /
+# See if the line ends in a backslash.
+tb
+:b
+s/\\$//
+# Print the line, without the trailing backslash.
+p
+tc
+# There was no trailing backslash. The end of the variable definition is
+# reached. Clear the hold space.
+s/^.*$//
+x
+bd
+:c
+# A trailing backslash means that the variable definition continues in the
+# next line. Put a nonempty string into the hold space to indicate this.
+s/^.*$/P/
+x
+:d
+'
+changequote([,])dnl
+
+ # Set POTFILES to the value of the Makefile variable POTFILES.
+ sed_x_POTFILES=`$gt_echo "$sed_x_variable" | sed -e '/^ *#/d' -e
's/VARIABLE/POTFILES/g'`
+ POTFILES=`sed -n -e "$sed_x_POTFILES" < "$ac_file"`
+ # Compute POTFILES_DEPS as
+ # $(foreach file, $(POTFILES), $(top_srcdir)/$(file))
+ POTFILES_DEPS=
+ for file in $POTFILES; do
+ POTFILES_DEPS="$POTFILES_DEPS "'$(top_srcdir)/'"$file"
+ done
+ POMAKEFILEDEPS=""
+
+ if test -n "$OBSOLETE_ALL_LINGUAS"; then
+ test -n "$as_me" && echo "$as_me: setting ALL_LINGUAS in
configure.in is obsolete" || echo "setting ALL_LINGUAS in configure.in is
obsolete"
+ fi
+ if test -f "$ac_given_srcdir/$ac_dir/LINGUAS"; then
+ # The LINGUAS file contains the set of available languages.
+ ALL_LINGUAS_=`sed -e "/^#/d" -e "s/#.*//"
"$ac_given_srcdir/$ac_dir/LINGUAS"`
+ POMAKEFILEDEPS="$POMAKEFILEDEPS LINGUAS"
+ else
+ # Set ALL_LINGUAS to the value of the Makefile variable LINGUAS.
+ sed_x_LINGUAS=`$gt_echo "$sed_x_variable" | sed -e '/^ *#/d' -e
's/VARIABLE/LINGUAS/g'`
+ ALL_LINGUAS_=`sed -n -e "$sed_x_LINGUAS" < "$ac_file"`
+ fi
+ # Hide the ALL_LINGUAS assigment from automake < 1.5.
+ eval 'ALL_LINGUAS''=$ALL_LINGUAS_'
+ # Compute POFILES
+ # as $(foreach lang, $(ALL_LINGUAS), $(srcdir)/$(lang).po)
+ # Compute UPDATEPOFILES
+ # as $(foreach lang, $(ALL_LINGUAS), $(lang).po-update)
+ # Compute DUMMYPOFILES
+ # as $(foreach lang, $(ALL_LINGUAS), $(lang).nop)
+ # Compute GMOFILES
+ # as $(foreach lang, $(ALL_LINGUAS), $(srcdir)/$(lang).gmo)
+ # Compute PROPERTIESFILES
+ # as $(foreach lang, $(ALL_LINGUAS), $(top_srcdir)/$(DOMAIN)_$(lang).properties)
+ # Compute CLASSFILES
+ # as $(foreach lang, $(ALL_LINGUAS), $(top_srcdir)/$(DOMAIN)_$(lang).class)
+ # Compute QMFILES
+ # as $(foreach lang, $(ALL_LINGUAS), $(srcdir)/$(lang).qm)
+ # Compute MSGFILES
+ # as $(foreach lang, $(ALL_LINGUAS), $(srcdir)/$(frob $(lang)).msg)
+ # Compute RESOURCESDLLFILES
+ # as $(foreach lang, $(ALL_LINGUAS), $(srcdir)/$(frob
$(lang))/$(DOMAIN).resources.dll)
+ case "$ac_given_srcdir" in
+ .) srcdirpre= ;;
+ *) srcdirpre='$(srcdir)/' ;;
+ esac
+ POFILES=
+ UPDATEPOFILES=
+ DUMMYPOFILES=
+ GMOFILES=
+ PROPERTIESFILES=
+ CLASSFILES=
+ QMFILES=
+ MSGFILES=
+ RESOURCESDLLFILES=
+ for lang in $ALL_LINGUAS; do
+ POFILES="$POFILES $srcdirpre$lang.po"
+ UPDATEPOFILES="$UPDATEPOFILES $lang.po-update"
+ DUMMYPOFILES="$DUMMYPOFILES $lang.nop"
+ GMOFILES="$GMOFILES $srcdirpre$lang.gmo"
+ PROPERTIESFILES="$PROPERTIESFILES
\$(top_srcdir)/\$(DOMAIN)_$lang.properties"
+ CLASSFILES="$CLASSFILES \$(top_srcdir)/\$(DOMAIN)_$lang.class"
+ QMFILES="$QMFILES $srcdirpre$lang.qm"
+ frobbedlang=`echo $lang | sed -e 's/\..*$//' -e
'y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/'`
+ MSGFILES="$MSGFILES $srcdirpre$frobbedlang.msg"
+ frobbedlang=`echo $lang | sed -e 's/_/-/g' -e 's/^sr-CS/sr-SP/' -e
's/@latin$/-Latn/' -e 's/@cyrillic$/-Cyrl/' -e
's/^sr-SP$/sr-SP-Latn/' -e 's/^uz-UZ$/uz-UZ-Latn/'`
+ RESOURCESDLLFILES="$RESOURCESDLLFILES
$srcdirpre$frobbedlang/\$(DOMAIN).resources.dll"
+ done
+ # CATALOGS depends on both $ac_dir and the user's LINGUAS
+ # environment variable.
+ INST_LINGUAS=
+ if test -n "$ALL_LINGUAS"; then
+ for presentlang in $ALL_LINGUAS; do
+ useit=no
+ if test "%UNSET%" != "$LINGUAS"; then
+ desiredlanguages="$LINGUAS"
+ else
+ desiredlanguages="$ALL_LINGUAS"
+ fi
+ for desiredlang in $desiredlanguages; do
+ # Use the presentlang catalog if desiredlang is
+ # a. equal to presentlang, or
+ # b. a variant of presentlang (because in this case,
+ # presentlang can be used as a fallback for messages
+ # which are not translated in the desiredlang catalog).
+ case "$desiredlang" in
+ "$presentlang"*) useit=yes;;
+ esac
+ done
+ if test $useit = yes; then
+ INST_LINGUAS="$INST_LINGUAS $presentlang"
+ fi
+ done
+ fi
+ CATALOGS=
+ JAVACATALOGS=
+ QTCATALOGS=
+ TCLCATALOGS=
+ CSHARPCATALOGS=
+ if test -n "$INST_LINGUAS"; then
+ for lang in $INST_LINGUAS; do
+ CATALOGS="$CATALOGS $lang.gmo"
+ JAVACATALOGS="$JAVACATALOGS \$(DOMAIN)_$lang.properties"
+ QTCATALOGS="$QTCATALOGS $lang.qm"
+ frobbedlang=`echo $lang | sed -e 's/\..*$//' -e
'y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/'`
+ TCLCATALOGS="$TCLCATALOGS $frobbedlang.msg"
+ frobbedlang=`echo $lang | sed -e 's/_/-/g' -e 's/^sr-CS/sr-SP/' -e
's/@latin$/-Latn/' -e 's/@cyrillic$/-Cyrl/' -e
's/^sr-SP$/sr-SP-Latn/' -e 's/^uz-UZ$/uz-UZ-Latn/'`
+ CSHARPCATALOGS="$CSHARPCATALOGS $frobbedlang/\$(DOMAIN).resources.dll"
+ done
+ fi
+
+ sed -e "s|@POTFILES_DEPS@|$POTFILES_DEPS|g" -e
"s|@POFILES@|$POFILES|g" -e "s|@UPDATEPOFILES@|$UPDATEPOFILES|g" -e
"s|@DUMMYPOFILES@|$DUMMYPOFILES|g" -e "s|@GMOFILES@|$GMOFILES|g" -e
"s|@PROPERTIESFILES@|$PROPERTIESFILES|g" -e
"s|@CLASSFILES@|$CLASSFILES|g" -e "s|@QMFILES@|$QMFILES|g" -e
"s|@MSGFILES@|$MSGFILES|g" -e
"s|@RESOURCESDLLFILES@|$RESOURCESDLLFILES|g" -e
"s|@CATALOGS@|$CATALOGS|g" -e "s|@JAVACATALOGS@|$JAVACATALOGS|g" -e
"s|@QTCATALOGS@|$QTCATALOGS|g" -e "s|@TCLCATALOGS@|$TCLCATALOGS|g" -e
"s|@CSHARPCATALOGS@|$CSHARPCATALOGS|g" -e 's,^#distdir:,distdir:,' <
"$ac_file" > "$ac_file.tmp"
+ if grep -l '@TCLCATALOGS@' "$ac_file" > /dev/null; then
+ # Add dependencies that cannot be formulated as a simple suffix rule.
+ for lang in $ALL_LINGUAS; do
+ frobbedlang=`echo $lang | sed -e 's/\..*$//' -e
'y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/'`
+ cat >> "$ac_file.tmp" <<EOF
+$frobbedlang.msg: $lang.po
+ @echo "\$(MSGFMT) -c --tcl -d \$(srcdir) -l $lang $srcdirpre$lang.po"; \
+ \$(MSGFMT) -c --tcl -d "\$(srcdir)" -l $lang $srcdirpre$lang.po || { rm -f
"\$(srcdir)/$frobbedlang.msg"; exit 1; }
+EOF
+ done
+ fi
+ if grep -l '@CSHARPCATALOGS@' "$ac_file" > /dev/null; then
+ # Add dependencies that cannot be formulated as a simple suffix rule.
+ for lang in $ALL_LINGUAS; do
+ frobbedlang=`echo $lang | sed -e 's/_/-/g' -e 's/^sr-CS/sr-SP/' -e
's/@latin$/-Latn/' -e 's/@cyrillic$/-Cyrl/' -e
's/^sr-SP$/sr-SP-Latn/' -e 's/^uz-UZ$/uz-UZ-Latn/'`
+ cat >> "$ac_file.tmp" <<EOF
+$frobbedlang/\$(DOMAIN).resources.dll: $lang.po
+ @echo "\$(MSGFMT) -c --csharp -d \$(srcdir) -l $lang $srcdirpre$lang.po -r
\$(DOMAIN)"; \
+ \$(MSGFMT) -c --csharp -d "\$(srcdir)" -l $lang $srcdirpre$lang.po -r
"\$(DOMAIN)" || { rm -f "\$(srcdir)/$frobbedlang.msg"; exit 1; }
+EOF
+ done
+ fi
+ if test -n "$POMAKEFILEDEPS"; then
+ cat >> "$ac_file.tmp" <<EOF
+Makefile: $POMAKEFILEDEPS
+EOF
+ fi
+ mv "$ac_file.tmp" "$ac_file"
+])
+
+dnl Initializes the accumulator used by AM_XGETTEXT_OPTION.
+AC_DEFUN([AM_XGETTEXT_OPTION_INIT],
+[
+ XGETTEXT_EXTRA_OPTIONS=
+])
+
+dnl Registers an option to be passed to xgettext in the po subdirectory.
+AC_DEFUN([AM_XGETTEXT_OPTION],
+[
+ AC_REQUIRE([AM_XGETTEXT_OPTION_INIT])
+ XGETTEXT_EXTRA_OPTIONS="$XGETTEXT_EXTRA_OPTIONS $1"
+])
diff --git a/src/wok/plugins/kimchi/m4/progtest.m4
b/src/wok/plugins/kimchi/m4/progtest.m4
new file mode 100644
index 0000000..2d804ac
--- /dev/null
+++ b/src/wok/plugins/kimchi/m4/progtest.m4
@@ -0,0 +1,92 @@
+# progtest.m4 serial 6 (gettext-0.18)
+dnl Copyright (C) 1996-2003, 2005, 2008-2010 Free Software Foundation, Inc.
+dnl This file is free software; the Free Software Foundation
+dnl gives unlimited permission to copy and/or distribute it,
+dnl with or without modifications, as long as this notice is preserved.
+dnl
+dnl This file can can be used in projects which are not available under
+dnl the GNU General Public License or the GNU Library General Public
+dnl License but which still want to provide support for the GNU gettext
+dnl functionality.
+dnl Please note that the actual code of the GNU gettext library is covered
+dnl by the GNU Library General Public License, and the rest of the GNU
+dnl gettext package package is covered by the GNU General Public License.
+dnl They are *not* in the public domain.
+
+dnl Authors:
+dnl Ulrich Drepper <drepper(a)cygnus.com>, 1996.
+
+AC_PREREQ([2.50])
+
+# Search path for a program which passes the given test.
+
+dnl AM_PATH_PROG_WITH_TEST(VARIABLE, PROG-TO-CHECK-FOR,
+dnl TEST-PERFORMED-ON-FOUND_PROGRAM [, VALUE-IF-NOT-FOUND [, PATH]])
+AC_DEFUN([AM_PATH_PROG_WITH_TEST],
+[
+# Prepare PATH_SEPARATOR.
+# The user is always right.
+if test "${PATH_SEPARATOR+set}" != set; then
+ echo "#! /bin/sh" >conf$$.sh
+ echo "exit 0" >>conf$$.sh
+ chmod +x conf$$.sh
+ if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then
+ PATH_SEPARATOR=';'
+ else
+ PATH_SEPARATOR=:
+ fi
+ rm -f conf$$.sh
+fi
+
+# Find out how to test for executable files. Don't use a zero-byte file,
+# as systems may use methods other than mode bits to determine executability.
+cat >conf$$.file <<_ASEOF
+#! /bin/sh
+exit 0
+_ASEOF
+chmod +x conf$$.file
+if test -x conf$$.file >/dev/null 2>&1; then
+ ac_executable_p="test -x"
+else
+ ac_executable_p="test -f"
+fi
+rm -f conf$$.file
+
+# Extract the first word of "$2", so it can be a program name with args.
+set dummy $2; ac_word=[$]2
+AC_MSG_CHECKING([for $ac_word])
+AC_CACHE_VAL([ac_cv_path_$1],
+[case "[$]$1" in
+ [[\\/]]* | ?:[[\\/]]*)
+ ac_cv_path_$1="[$]$1" # Let the user override the test with a path.
+ ;;
+ *)
+ ac_save_IFS="$IFS"; IFS=$PATH_SEPARATOR
+ for ac_dir in ifelse([$5], , $PATH, [$5]); do
+ IFS="$ac_save_IFS"
+ test -z "$ac_dir" && ac_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if $ac_executable_p "$ac_dir/$ac_word$ac_exec_ext"; then
+ echo "$as_me: trying $ac_dir/$ac_word..." >&AS_MESSAGE_LOG_FD
+ if [$3]; then
+ ac_cv_path_$1="$ac_dir/$ac_word$ac_exec_ext"
+ break 2
+ fi
+ fi
+ done
+ done
+ IFS="$ac_save_IFS"
+dnl If no 4th arg is given, leave the cache variable unset,
+dnl so AC_PATH_PROGS will keep looking.
+ifelse([$4], , , [ test -z "[$]ac_cv_path_$1" &&
ac_cv_path_$1="$4"
+])dnl
+ ;;
+esac])dnl
+$1="$ac_cv_path_$1"
+if test ifelse([$4], , [-n "[$]$1"], ["[$]$1" != "$4"]);
then
+ AC_MSG_RESULT([$][$1])
+else
+ AC_MSG_RESULT([no])
+fi
+AC_SUBST([$1])dnl
+])
diff --git a/src/wok/plugins/kimchi/mockmodel.py b/src/wok/plugins/kimchi/mockmodel.py
new file mode 100644
index 0000000..b269c26
--- /dev/null
+++ b/src/wok/plugins/kimchi/mockmodel.py
@@ -0,0 +1,627 @@
+#
+# Project Kimchi
+#
+# Copyright IBM, Corp. 2013-2015
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+import libvirt
+import lxml.etree as ET
+import os
+import random
+import time
+from lxml import objectify
+from lxml.builder import E
+
+from wok.exception import NotFoundError, OperationFailed
+from wok.objectstore import ObjectStore
+from wok.utils import add_task, get_next_clone_name, wok_log
+from wok.xmlutils.utils import xml_item_update
+
+import config
+import imageinfo
+import osinfo
+from model import cpuinfo
+from model.debugreports import DebugReportsModel
+from model.host import DeviceModel
+from model.libvirtstoragepool import IscsiPoolDef, NetfsPoolDef
+from model.libvirtstoragepool import StoragePoolDef
+from model.model import Model
+from model.storagepools import StoragePoolModel
+from model.storagevolumes import StorageVolumeModel, StorageVolumesModel
+from model.templates import LibvirtVMTemplate
+from model.users import PAMUsersModel
+from model.groups import PAMGroupsModel
+from vmtemplate import VMTemplate
+
+
+fake_user = {'root': 'letmein!'}
+mockmodel_defaults = {
+ 'storagepool': '/plugins/kimchi/storagepools/default-pool',
+ 'domain': 'test', 'arch': 'i686'
+}
+
+
+class MockModel(Model):
+ _mock_vms = {}
+ _mock_snapshots = {}
+ _XMLDesc = libvirt.virDomain.XMLDesc
+ _defineXML = libvirt.virConnect.defineXML
+ _undefineDomain = libvirt.virDomain.undefine
+ _libvirt_get_vol_path = LibvirtVMTemplate._get_volume_path
+
+ def __init__(self, objstore_loc=None):
+ # Override osinfo.defaults to ajust the values according to
+ # test:///default driver
+ defaults = dict(osinfo.defaults)
+ defaults.update(mockmodel_defaults)
+ osinfo.defaults = dict(defaults)
+
+ self._mock_devices = MockDevices()
+ self._mock_partitions = MockPartitions()
+ self._mock_storagevolumes = MockStorageVolumes()
+ self._mock_swupdate = MockSoftwareUpdate()
+ self._mock_repositories = MockRepositories()
+
+ cpuinfo.get_topo_capabilities = \
+ MockModel.get_topo_capabilities
+ libvirt.virConnect.defineXML = MockModel.domainDefineXML
+ libvirt.virDomain.XMLDesc = MockModel.domainXMLDesc
+ libvirt.virDomain.undefine = MockModel.undefineDomain
+ libvirt.virDomain.attachDeviceFlags = MockModel.attachDeviceFlags
+ libvirt.virDomain.detachDeviceFlags = MockModel.detachDeviceFlags
+ libvirt.virDomain.updateDeviceFlags = MockModel.updateDeviceFlags
+ libvirt.virStorageVol.resize = MockModel.volResize
+ libvirt.virStorageVol.wipePattern = MockModel.volWipePattern
+
+ IscsiPoolDef.prepare = NetfsPoolDef.prepare = StoragePoolDef.prepare
+
+ PAMUsersModel.auth_type = 'fake'
+ PAMGroupsModel.auth_type = 'fake'
+
+ super(MockModel, self).__init__('test:///default', objstore_loc)
+ self.objstore_loc = objstore_loc
+ self.objstore = ObjectStore(objstore_loc)
+
+ # The MockModel methods are instantiated on runtime according to Model
+ # and BaseModel
+ # Because that a normal method override will not work here
+ # Instead of that we also need to do the override on runtime
+ for method in dir(self):
+ if method.startswith('_mock_'):
+ mock_method = getattr(self, method)
+ if not callable(mock_method):
+ continue
+
+ m = method[6:]
+ model_method = getattr(self, m)
+ setattr(self, '_model_' + m, model_method)
+ setattr(self, m, mock_method)
+
+ DeviceModel.lookup = self._mock_device_lookup
+ StoragePoolModel._update_lvm_disks = self._update_lvm_disks
+ StorageVolumesModel.get_list = self._mock_storagevolumes_get_list
+ StorageVolumeModel.doUpload = self._mock_storagevolume_doUpload
+ DebugReportsModel._gen_debugreport_file = self._gen_debugreport_file
+ LibvirtVMTemplate._get_volume_path = self._get_volume_path
+ VMTemplate.get_iso_info = self._probe_image
+ imageinfo.probe_image = self._probe_image
+
+ def reset(self):
+ MockModel._mock_vms = {}
+ MockModel._mock_snapshots = {}
+ self._mock_swupdate = MockSoftwareUpdate()
+ self._mock_repositories = MockRepositories()
+
+ if hasattr(self, 'objstore'):
+ self.objstore = ObjectStore(self.objstore_loc)
+
+ params = {'vms': [u'test'], 'templates': [],
+ 'networks': [u'default'], 'storagepools':
[u'default-pool']}
+
+ for res, items in params.iteritems():
+ resources = getattr(self, '%s_get_list' % res)()
+ for i in resources:
+ if i in items:
+ continue
+
+ try:
+ getattr(self, '%s_deactivate' % res[:-1])(i)
+ except:
+ pass
+
+ getattr(self, '%s_delete' % res[:-1])(i)
+
+ volumes = self.storagevolumes_get_list('default-pool')
+ for v in volumes:
+ self.storagevolume_delete('default-pool', v)
+
+ @staticmethod
+ def get_topo_capabilities(conn):
+ # The libvirt test driver doesn't return topology.
+ xml = "<topology sockets='1' cores='2'
threads='2'/>"
+ return ET.fromstring(xml)
+
+ @staticmethod
+ def domainDefineXML(conn, xml):
+ name = objectify.fromstring(xml).name.text
+ try:
+ dom = conn.lookupByName(name)
+ if not dom.isActive():
+ MockModel._mock_vms[name] = xml
+ except:
+ pass
+
+ return MockModel._defineXML(conn, xml)
+
+ @staticmethod
+ def domainXMLDesc(dom, flags=0):
+ return MockModel._mock_vms.get(dom.name(),
+ MockModel._XMLDesc(dom, flags))
+
+ @staticmethod
+ def undefineDomain(dom):
+ name = dom.name()
+ if name in MockModel._mock_vms.keys():
+ del MockModel._mock_vms[dom.name()]
+ return MockModel._undefineDomain(dom)
+
+ @staticmethod
+ def attachDeviceFlags(dom, xml, flags=0):
+ old_xml = dom.XMLDesc(libvirt.VIR_DOMAIN_XML_SECURE)
+ root = objectify.fromstring(old_xml)
+ dev = objectify.fromstring(xml)
+ root.devices.append(dev)
+
+ MockModel._mock_vms[dom.name()] = ET.tostring(root, encoding="utf-8")
+
+ @staticmethod
+ def _get_device_node(dom, xml):
+ xpath_map = {'disk': 'target',
+ 'interface': 'mac',
+ 'graphics': 'listen'}
+
+ dev = objectify.fromstring(xml)
+ dev_id = dev.find(xpath_map[dev.tag]).items()
+
+ dev_filter = ''
+ for key, value in dev_id:
+ dev_filter += "[@%s='%s']" % (key, value)
+
+ old_xml = dom.XMLDesc(libvirt.VIR_DOMAIN_XML_SECURE)
+ root = objectify.fromstring(old_xml)
+ devices = root.devices
+
+ dev = devices.find("./%s/%s%s/.." % (dev.tag, xpath_map[dev.tag],
+ dev_filter))
+
+ return (root, dev)
+
+ @staticmethod
+ def detachDeviceFlags(dom, xml, flags=0):
+ root, dev = MockModel._get_device_node(dom, xml)
+ root.devices.remove(dev)
+
+ MockModel._mock_vms[dom.name()] = ET.tostring(root, encoding="utf-8")
+
+ @staticmethod
+ def updateDeviceFlags(dom, xml, flags=0):
+ root, old_dev = MockModel._get_device_node(dom, xml)
+ root.devices.replace(old_dev, objectify.fromstring(xml))
+ MockModel._mock_vms[dom.name()] = ET.tostring(root, encoding="utf-8")
+
+ @staticmethod
+ def volResize(vol, size, flags=0):
+ new_xml = xml_item_update(vol.XMLDesc(0), './capacity', str(size))
+ vol.delete(0)
+ pool = vol.storagePoolLookupByVolume()
+ pool.createXML(new_xml)
+
+ @staticmethod
+ def volWipePattern(vol, algorithm, flags=0):
+ new_xml = xml_item_update(vol.XMLDesc(0), './allocation', '0')
+ vol.delete(0)
+ pool = vol.storagePoolLookupByVolume()
+ pool.createXML(new_xml)
+
+ def _probe_image(self, path):
+ return ('unknown', 'unknown')
+
+ def _get_volume_path(self, pool, vol):
+ pool_info = self.storagepool_lookup(pool)
+ if pool_info['type'] == 'scsi':
+ return self._mock_storagevolumes.scsi_volumes[vol]['path']
+
+ return MockModel._libvirt_get_vol_path(pool, vol)
+
+ def _gen_debugreport_file(self, name):
+ return add_task('/plugins/kimchi/debugreports/%s' % name,
+ self._create_log, self.objstore, name)
+
+ def _create_log(self, cb, name):
+ path = config.get_debugreports_path()
+ tmpf = os.path.join(path, name + '.tmp')
+ realf = os.path.join(path, name + '.txt')
+ length = random.randint(1000, 10000)
+ with open(tmpf, 'w') as fd:
+ while length:
+ fd.write('I am logged')
+ length = length - 1
+ os.rename(tmpf, realf)
+ cb("OK", True)
+
+ def _update_lvm_disks(self, pool_name, disks):
+ conn = self.conn.get()
+ pool = conn.storagePoolLookupByName(pool_name.encode('utf-8'))
+ xml = pool.XMLDesc(0)
+
+ root = ET.fromstring(xml)
+ source = root.xpath('./source')[0]
+
+ for d in disks:
+ dev = E.device(path=d)
+ source.append(dev)
+
+ conn.storagePoolDefineXML(ET.tostring(root), 0)
+
+ def _mock_host_shutdown(self, *name):
+ wok_log.info("The host system will be shutted down")
+
+ def _mock_host_reboot(self, *name):
+ wok_log.info("The host system will be rebooted")
+
+ def _mock_storagevolumes_create(self, pool, params):
+ vol_source = ['url', 'capacity']
+ index_list = list(i for i in range(len(vol_source))
+ if vol_source[i] in params)
+ create_param = vol_source[index_list[0]]
+ name = params.get('name')
+ if name is None and create_param == 'url':
+ params['name'] = os.path.basename(params['url'])
+ del params['url']
+ params['capacity'] = 1024
+
+ return self._model_storagevolumes_create(pool, params)
+
+ def _mock_storagevolumes_get_list(self, pool):
+ pool_info = self.storagepool_lookup(pool)
+ if pool_info['type'] == 'scsi':
+ return self._mock_storagevolumes.scsi_volumes.keys()
+
+ return self._model_storagevolumes_get_list(pool)
+
+ def _mock_storagevolume_lookup(self, pool, vol):
+ pool_info = self.storagepool_lookup(pool)
+ if pool_info['type'] == 'scsi':
+ return self._mock_storagevolumes.scsi_volumes[vol]
+
+ return self._model_storagevolume_lookup(pool, vol)
+
+ def _mock_storagevolume_doUpload(self, cb, vol, offset, data, data_size):
+ vol_path = vol.path()
+
+ # MockModel does not create the storage volume as a file
+ # So create it to do the file upload
+ if offset == 0:
+ dirname = os.path.dirname(vol_path)
+ if not os.path.exists(dirname):
+ os.makedirs(dirname)
+ open(vol_path, 'w').close()
+
+ try:
+ with open(vol_path, 'a') as fd:
+ fd.seek(offset)
+ fd.write(data)
+ except Exception, e:
+ os.remove(vol_path)
+ cb('', False)
+ raise OperationFailed("KCHVOL0029E", {"err": e.message})
+
+ def _mock_partitions_get_list(self):
+ return self._mock_partitions.partitions.keys()
+
+ def _mock_partition_lookup(self, name):
+ return self._mock_partitions.partitions[name]
+
+ def _mock_devices_get_list(self, _cap=None, _passthrough=None,
+ _passthrough_affected_by=None):
+ if _cap is None:
+ return self._mock_devices.devices.keys()
+
+ if _cap == 'fc_host':
+ _cap = 'scsi_host'
+
+ return [dev['name'] for dev in self._mock_devices.devices.values()
+ if dev['device_type'] == _cap]
+
+ def _mock_device_lookup(self, dev_name):
+ return self._mock_devices.devices[dev_name]
+
+ def _mock_packagesupdate_get_list(self):
+ return self._mock_swupdate.pkgs.keys()
+
+ def _mock_packageupdate_lookup(self, pkg_name):
+ return self._mock_swupdate.pkgs[pkg_name]
+
+ def _mock_host_swupdate(self, args=None):
+ task_id = add_task('/plugins/kimchi/host/swupdate',
+ self._mock_swupdate.doUpdate, self.objstore)
+ return self.task_lookup(task_id)
+
+ def _mock_repositories_get_list(self):
+ return self._mock_repositories.repos.keys()
+
+ def _mock_repositories_create(self, params):
+ # Create a repo_id if not given by user. The repo_id will follow
+ # the format kimchi_repo_<integer>, where integer is the number of
+ # seconds since the Epoch (January 1st, 1970), in UTC.
+ repo_id = params.get('repo_id', None)
+ if repo_id is None:
+ repo_id = "kimchi_repo_%s" % str(int(time.time() * 1000))
+ params.update({'repo_id': repo_id})
+
+ config = params.get('config', {})
+ info = {'repo_id': repo_id,
+ 'baseurl': params['baseurl'],
+ 'enabled': True,
+ 'config': {'repo_name': config.get('repo_name',
repo_id),
+ 'gpgkey': config.get('gpgkey', []),
+ 'gpgcheck': True,
+ 'mirrorlist': params.get('mirrorlist',
'')}}
+ self._mock_repositories.repos[repo_id] = info
+ return repo_id
+
+ def _mock_repository_lookup(self, repo_id):
+ return self._mock_repositories.repos[repo_id]
+
+ def _mock_repository_delete(self, repo_id):
+ del self._mock_repositories.repos[repo_id]
+
+ def _mock_repository_enable(self, repo_id):
+ self._mock_repositories.repos[repo_id]['enabled'] = True
+
+ def _mock_repository_disable(self, repo_id):
+ self._mock_repositories.repos[repo_id]['enabled'] = False
+
+ def _mock_repository_update(self, repo_id, params):
+ self._mock_repositories.repos[repo_id].update(params)
+ return repo_id
+
+ def _mock_vm_clone(self, name):
+ new_name = get_next_clone_name(self.vms_get_list(), name)
+ snapshots = MockModel._mock_snapshots.get(name, [])
+ MockModel._mock_snapshots[new_name] = snapshots
+ return self._model_vm_clone(name)
+
+ def _mock_vmsnapshots_create(self, vm_name, params):
+ name = params.get('name', unicode(int(time.time())))
+ params = {'vm_name': vm_name, 'name': name}
+ taskid = add_task(u'/plugins/kimchi/vms/%s/snapshots/%s' %
+ (vm_name, name), self._vmsnapshots_create_task,
+ self.objstore, params)
+ return self.task_lookup(taskid)
+
+ def _vmsnapshots_create_task(self, cb, params):
+ vm_name = params['vm_name']
+ name = params['name']
+ parent = u''
+
+ snapshots = MockModel._mock_snapshots.get(vm_name, [])
+ for sn in snapshots:
+ if sn.current:
+ sn.current = False
+ parent = sn.name
+
+ snapshots.append(MockVMSnapshot(name, {'parent': parent}))
+ MockModel._mock_snapshots[vm_name] = snapshots
+
+ cb('OK', True)
+
+ def _mock_vmsnapshots_get_list(self, vm_name):
+ snapshots = MockModel._mock_snapshots.get(vm_name, [])
+ return sorted([snap.name for snap in snapshots])
+
+ def _mock_currentvmsnapshot_lookup(self, vm_name):
+ for sn in MockModel._mock_snapshots.get(vm_name, []):
+ if sn.current:
+ return sn.info
+
+ def _mock_vmsnapshot_lookup(self, vm_name, name):
+ for sn in MockModel._mock_snapshots.get(vm_name, []):
+ if sn.name == name:
+ return sn.info
+
+ raise NotFoundError('KCHSNAP0003E', {'name': name, 'vm':
vm_name})
+
+ def _mock_vmsnapshot_delete(self, vm_name, name):
+ snapshots = MockModel._mock_snapshots.get(vm_name, [])
+ for sn in snapshots:
+ if sn.name == name:
+ del snapshots[snapshots.index(sn)]
+
+ MockModel._mock_snapshots[vm_name] = snapshots
+
+ def _mock_vmsnapshot_revert(self, vm_name, name):
+ snapshots = MockModel._mock_snapshots.get(vm_name, [])
+ for sn in snapshots:
+ if sn.current:
+ sn.current = False
+
+ for sn in snapshots:
+ if sn.name == name:
+ sn.current = True
+
+
+class MockStorageVolumes(object):
+ def __init__(self):
+ base_path = "/dev/disk/by-path/pci-0000:0e:00.0-fc-0x20-lun"
+ self.scsi_volumes = {'unit:0:0:1': {'capacity': 1024,
+ 'format': 'unknown',
+ 'allocation': 512,
+ 'type': 'block',
+ 'path': base_path + '1',
+ 'used_by': []},
+ 'unit:0:0:2': {'capacity': 2048,
+ 'format': 'unknown',
+ 'allocation': 512,
+ 'type': 'block',
+ 'path': base_path + '2',
+ 'used_by': []}}
+
+
+class MockPartitions(object):
+ def __init__(self):
+ self.partitions = {"vdx": {"available": True,
"name": "vdx",
+ "fstype": "", "path":
"/dev/vdx",
+ "mountpoint": "",
"type": "disk",
+ "size": "2147483648"},
+ "vdz": {"available": True,
"name": "vdz",
+ "fstype": "", "path":
"/dev/vdz",
+ "mountpoint": "",
"type": "disk",
+ "size": "2147483648"}}
+
+
+class MockDevices(object):
+ def __init__(self):
+ self.devices = {
+ 'computer': {'device_type': 'system',
+ 'firmware': {'release_date':
'01/01/2012',
+ 'vendor': 'LENOVO',
+ 'version': 'XXXXX (X.XX )'},
+ 'hardware': {'serial': 'PXXXXX',
+ 'uuid':
+ '9d660370-820f-4241-8731-5a60c97e8aa6',
+ 'vendor': 'LENOVO',
+ 'version': 'ThinkPad T420'},
+ 'name': 'computer',
+ 'parent': None,
+ 'product': '4180XXX'},
+ 'pci_0000_03_00_0': {'bus': 3,
+ 'device_type': 'pci',
+ 'domain': 0,
+ 'driver': {'name': 'iwlwifi'},
+ 'function': 0,
+ 'iommuGroup': 7,
+ 'name': 'pci_0000_03_00_0',
+ 'parent': 'computer',
+ 'path':
+ '/sys/devices/pci0000:00/0000:03:00.0',
+ 'product': {
+ 'description':
+ 'Centrino Advanced-N 6205 [Taylor Peak]',
+ 'id': '0x0085'},
+ 'slot': 0,
+ 'vendor': {'description': 'Intel
Corporation',
+ 'id': '0x8086'}},
+ 'pci_0000_0d_00_0': {'bus': 13,
+ 'device_type': 'pci',
+ 'domain': 0,
+ 'driver': {'name':
'sdhci-pci'},
+ 'function': 0,
+ 'iommuGroup': 7,
+ 'name': 'pci_0000_0d_00_0',
+ 'parent': 'computer',
+ 'path':
+ '/sys/devices/pci0000:00/0000:0d:00.0',
+ 'product': {'description':
+ 'PCIe SDXC/MMC Host Controller',
+ 'id': '0xe823'},
+ 'slot': 0,
+ 'vendor': {'description': 'Ricoh Co
Ltd',
+ 'id': '0x1180'}},
+ 'scsi_host0': {'adapter': {'fabric_wwn':
'37df6c1efa1b4388',
+ 'type': 'fc_host',
+ 'wwnn': 'efb6563f06434a98',
+ 'wwpn': '742f32073aab45d7'},
+ 'device_type': 'scsi_host',
+ 'host': 0,
+ 'name': 'scsi_host0',
+ 'parent': 'computer',
+ 'path':
'/sys/devices/pci0000:00/0000:40:00.0/0'},
+ 'scsi_host1': {'adapter': {'fabric_wwn':
'542efa5dced34123',
+ 'type': 'fc_host',
+ 'wwnn': 'b7433a40c9b84092',
+ 'wwpn': '25c1f485ae42497f'},
+ 'device_type': 'scsi_host',
+ 'host': 0,
+ 'name': 'scsi_host1',
+ 'parent': 'computer',
+ 'path':
'/sys/devices/pci0000:00/0000:40:00.0/1'},
+ 'scsi_host2': {'adapter': {'fabric_wwn':
'5c373c334c20478d',
+ 'type': 'fc_host',
+ 'wwnn': 'f2030bec4a254e6b',
+ 'wwpn': '07dbca4164d44096'},
+ 'device_type': 'scsi_host',
+ 'host': 0,
+ 'name': 'scsi_host2',
+ 'parent': 'computer',
+ 'path':
'/sys/devices/pci0000:00/0000:40:00.0/2'}}
+
+
+class MockSoftwareUpdate(object):
+ def __init__(self):
+ self.pkgs = {
+ 'udevmountd': {'repository': 'openSUSE-13.1-Update',
+ 'version': '0.81.5-14.1',
+ 'arch': 'x86_64',
+ 'package_name': 'udevmountd'},
+ 'sysconfig-network': {'repository':
'openSUSE-13.1-Extras',
+ 'version': '0.81.5-14.1',
+ 'arch': 'x86_64',
+ 'package_name': 'sysconfig-network'},
+ 'libzypp': {'repository': 'openSUSE-13.1-Update',
+ 'version': '13.9.0-10.1',
+ 'arch': 'noarch',
+ 'package_name': 'libzypp'}}
+ self._num2update = 3
+
+ def doUpdate(self, cb, params):
+ msgs = []
+ for pkg in self.pkgs.keys():
+ msgs.append("Updating package %s" % pkg)
+ cb('\n'.join(msgs))
+ time.sleep(1)
+
+ time.sleep(2)
+ msgs.append("All packages updated")
+ cb('\n'.join(msgs), True)
+
+ # After updating all packages any package should be listed to be
+ # updated, so reset self._packages
+ self.pkgs = {}
+
+
+class MockRepositories(object):
+ def __init__(self):
+ self.repos = {"kimchi_repo_1392167832":
+ {"repo_id": "kimchi_repo_1392167832",
+ "enabled": True,
+ "baseurl": "http://www.fedora.org",
+ "config": {"repo_name":
"kimchi_repo_1392167832",
+ "gpgkey": [],
+ "gpgcheck": True,
+ "mirrorlist": ""}}}
+
+
+class MockVMSnapshot(object):
+ def __init__(self, name, params={}):
+ self.name = name
+ self.current = True
+
+ self.info = {'created': params.get('created',
+ unicode(int(time.time()))),
+ 'name': name,
+ 'parent': params.get('parent', u''),
+ 'state': params.get('state', u'shutoff')}
diff --git a/src/wok/plugins/kimchi/model/Makefile.am
b/src/wok/plugins/kimchi/model/Makefile.am
new file mode 100644
index 0000000..f4f4750
--- /dev/null
+++ b/src/wok/plugins/kimchi/model/Makefile.am
@@ -0,0 +1,25 @@
+#
+# Kimchi
+#
+# Copyright IBM Corp, 2013
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+model_PYTHON = *.py
+
+modeldir = $(pythondir)/wok/plugins/kimchi/model
+
+install-data-local:
+ $(MKDIR_P) $(DESTDIR)$(modeldir)
diff --git a/src/wok/plugins/kimchi/model/__init__.py
b/src/wok/plugins/kimchi/model/__init__.py
new file mode 100644
index 0000000..ca7ede4
--- /dev/null
+++ b/src/wok/plugins/kimchi/model/__init__.py
@@ -0,0 +1,18 @@
+#
+# Project Kimchi
+#
+# Copyright IBM, Corp. 2014
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
diff --git a/src/wok/plugins/kimchi/model/config.py
b/src/wok/plugins/kimchi/model/config.py
new file mode 100644
index 0000000..464ffae
--- /dev/null
+++ b/src/wok/plugins/kimchi/model/config.py
@@ -0,0 +1,176 @@
+#
+# Project Kimchi
+#
+# Copyright IBM, Corp. 2014-2015
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+import cherrypy
+from multiprocessing.pool import ThreadPool
+
+from wok.basemodel import Singleton
+from wok.config import config as kconfig
+from wok.config import get_version
+from wok.exception import NotFoundError
+from wok.utils import check_url_path, run_command, wok_log
+
+from ..config import find_qemu_binary
+from ..distroloader import DistroLoader
+from ..repositories import Repositories
+from ..screenshot import VMScreenshot
+from ..swupdate import SoftwareUpdate
+from debugreports import DebugReportsModel
+from featuretests import FeatureTests, FEATURETEST_POOL_NAME
+from featuretests import FEATURETEST_VM_NAME
+
+
+class ConfigModel(object):
+ def __init__(self, **kargs):
+ pass
+
+ def lookup(self, name):
+ proxy_port = kconfig.get('display', 'display_proxy_port')
+ return {'display_proxy_port': proxy_port,
+ 'version': get_version()}
+
+
+class CapabilitiesModel(object):
+ __metaclass__ = Singleton
+
+ def __init__(self, **kargs):
+ self.conn = kargs['conn']
+ self.qemu_stream = False
+ self.libvirt_stream_protocols = []
+ self.fc_host_support = False
+ self.metadata_support = False
+ self.kernel_vfio = False
+ self.mem_hotplug_support = False
+
+ # Subscribe function to set host capabilities to be run when cherrypy
+ # server is up
+ # It is needed because some features tests depends on the server
+ cherrypy.engine.subscribe('start', self._set_capabilities)
+
+ # Subscribe function to clean any Kimchi leftovers
+ cherrypy.engine.subscribe('stop', self._clean_leftovers)
+
+ def _clean_leftovers(self):
+ conn = self.conn.get()
+ FeatureTests.disable_libvirt_error_logging()
+ try:
+ dom = conn.lookupByName(FEATURETEST_VM_NAME)
+ dom.undefine()
+ except Exception:
+ # Any exception can be ignored here
+ pass
+
+ try:
+ pool = conn.storagePoolLookupByName(FEATURETEST_POOL_NAME)
+ pool.undefine()
+ except Exception:
+ # Any exception can be ignored here
+ pass
+
+ FeatureTests.enable_libvirt_error_logging()
+
+ def _set_capabilities(self):
+ wok_log.info("*** Running feature tests ***")
+ conn = self.conn.get()
+ self.qemu_stream = FeatureTests.qemu_supports_iso_stream()
+ self.nfs_target_probe = FeatureTests.libvirt_support_nfs_probe(conn)
+ self.fc_host_support = FeatureTests.libvirt_support_fc_host(conn)
+ self.metadata_support = FeatureTests.has_metadata_support(conn)
+ self.kernel_vfio = FeatureTests.kernel_support_vfio()
+ self.mem_hotplug_support = FeatureTests.has_mem_hotplug_support(conn)
+
+ self.libvirt_stream_protocols = []
+ for p in ['http', 'https', 'ftp', 'ftps',
'tftp']:
+ if FeatureTests.libvirt_supports_iso_stream(conn, p):
+ self.libvirt_stream_protocols.append(p)
+
+ wok_log.info("*** Feature tests completed ***")
+ _set_capabilities.priority = 90
+
+ def _qemu_support_spice(self):
+ qemu_path = find_qemu_binary(find_emulator=True)
+ out, err, rc = run_command(['ldd', qemu_path])
+ if rc != 0:
+ wok_log.error('Failed to find qemu binary dependencies: %s',
+ err)
+ return False
+ for line in out.split('\n'):
+ if line.lstrip().startswith('libspice-server.so'):
+ return True
+ return False
+
+ def lookup(self, *ident):
+ report_tool = DebugReportsModel.get_system_report_tool()
+ try:
+ SoftwareUpdate()
+ except Exception:
+ update_tool = False
+ else:
+ update_tool = True
+
+ try:
+ repo = Repositories()
+ except Exception:
+ repo_mngt_tool = None
+ else:
+ repo_mngt_tool = repo._pkg_mnger.TYPE
+
+ return {'libvirt_stream_protocols': self.libvirt_stream_protocols,
+ 'qemu_spice': self._qemu_support_spice(),
+ 'qemu_stream': self.qemu_stream,
+ 'screenshot': VMScreenshot.get_stream_test_result(),
+ 'system_report_tool': bool(report_tool),
+ 'update_tool': update_tool,
+ 'repo_mngt_tool': repo_mngt_tool,
+ 'federation': kconfig.get("server",
"federation"),
+ 'auth': kconfig.get("authentication",
"method"),
+ 'kernel_vfio': self.kernel_vfio,
+ 'nm_running': FeatureTests.is_nm_running(),
+ 'mem_hotplug_support': self.mem_hotplug_support
+ }
+
+
+class DistrosModel(object):
+ def __init__(self, **kargs):
+ distroloader = DistroLoader()
+ self.distros = distroloader.get()
+
+ def get_list(self):
+ def validate_distro(distro):
+ if check_url_path(distro['path']):
+ return distro['name']
+
+ n_processes = len(self.distros.keys())
+ pool = ThreadPool(processes=n_processes)
+ map_res = pool.map_async(validate_distro, self.distros.values())
+ pool.close()
+ pool.join()
+ res = list(set(map_res.get()) - set([None]))
+ return sorted(res)
+
+
+class DistroModel(object):
+ def __init__(self, **kargs):
+ self._distros = DistrosModel()
+
+ def lookup(self, name):
+ try:
+ return self._distros.distros[name]
+ except KeyError:
+ raise NotFoundError("KCHDISTRO0001E", {'name': name})
diff --git a/src/wok/plugins/kimchi/model/cpuinfo.py
b/src/wok/plugins/kimchi/model/cpuinfo.py
new file mode 100644
index 0000000..299e445
--- /dev/null
+++ b/src/wok/plugins/kimchi/model/cpuinfo.py
@@ -0,0 +1,126 @@
+#
+# Project Kimchi
+#
+# Copyright IBM, Corp. 2014-2015
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+import platform
+from xml.etree import ElementTree as ET
+
+from wok.exception import InvalidParameter, InvalidOperation
+from wok.utils import run_command, wok_log
+
+
+ARCH = 'power' if platform.machine().startswith('ppc') else
'x86'
+
+
+def get_topo_capabilities(connect):
+ """
+ This helper function exists solely to be overridden for
+ mockmodel tests. Since other modules use getCapabilies(),
+ it can't be overridden directly.
+ """
+ xml = connect.getCapabilities()
+ capabilities = ET.fromstring(xml)
+ return
capabilities.find('host').find('cpu').find('topology')
+
+
+class CPUInfoModel(object):
+ """
+ Get information about a CPU for hyperthreading (on x86)
+ or SMT (on POWER) for logic when creating templates and VMs.
+ """
+
+ def __init__(self, **kargs):
+ self.guest_threads_enabled = False
+ self.sockets = 0
+ self.cores_present = 0
+ self.cores_available = 0
+ self.cores_per_socket = 0
+ self.threads_per_core = 0
+ self.max_threads = 0
+
+ self.conn = kargs['conn']
+ libvirt_topology = None
+ try:
+ connect = self.conn.get()
+ libvirt_topology = get_topo_capabilities(connect)
+ except Exception as e:
+ wok_log.info("Unable to get CPU topology capabilities: %s"
+ % e.message)
+ return
+ if libvirt_topology is None:
+ wok_log.info("cpu_info topology not supported.")
+ return
+
+ if ARCH == 'power':
+ # IBM PowerPC
+ self.guest_threads_enabled = True
+ out, error, rc = run_command(['ppc64_cpu', '--smt'])
+ if rc or 'on' in out:
+ # SMT has to be disabled for guest to use threads as CPUs.
+ # rc is always zero, whether SMT is off or on.
+ self.guest_threads_enabled = False
+ out, error, rc = run_command(['ppc64_cpu',
'--cores-present'])
+ if not rc:
+ self.cores_present = int(out.split()[-1])
+ out, error, rc = run_command(['ppc64_cpu', '--cores-on'])
+ if not rc:
+ self.cores_available = int(out.split()[-1])
+ out, error, rc = run_command(['ppc64_cpu',
'--threads-per-core'])
+ if not rc:
+ self.threads_per_core = int(out.split()[-1])
+ self.sockets = self.cores_present/self.threads_per_core
+ if self.sockets == 0:
+ self.sockets = 1
+ self.cores_per_socket = self.cores_present/self.sockets
+ else:
+ # Intel or AMD
+ self.guest_threads_enabled = True
+ self.sockets = int(libvirt_topology.get('sockets'))
+ self.cores_per_socket = int(libvirt_topology.get('cores'))
+ self.cores_present = self.cores_per_socket * self.sockets
+ self.cores_available = self.cores_present
+ self.threads_per_core = int(libvirt_topology.get('threads'))
+
+ def lookup(self, ident):
+ return {
+ 'guest_threads_enabled': self.guest_threads_enabled,
+ 'sockets': self.sockets,
+ 'cores_per_socket': self.cores_per_socket,
+ 'cores_present': self.cores_present,
+ 'cores_available': self.cores_available,
+ 'threads_per_core': self.threads_per_core,
+ }
+
+ def check_topology(self, vcpus, topology):
+ """
+ param vcpus: should be an integer
+ param iso_path: the path of the guest ISO
+ param topology: {'sockets': x, 'cores': x, 'threads':
x}
+ """
+ sockets = topology['sockets']
+ cores = topology['cores']
+ threads = topology['threads']
+
+ if not self.guest_threads_enabled:
+ raise InvalidOperation("KCHCPUINF0003E")
+ if vcpus != sockets * cores * threads:
+ raise InvalidParameter("KCHCPUINF0002E")
+ if vcpus > self.cores_available * self.threads_per_core:
+ raise InvalidParameter("KCHCPUINF0001E")
+ if threads > self.threads_per_core:
+ raise InvalidParameter("KCHCPUINF0002E")
diff --git a/src/wok/plugins/kimchi/model/debugreports.py
b/src/wok/plugins/kimchi/model/debugreports.py
new file mode 100644
index 0000000..48e6b26
--- /dev/null
+++ b/src/wok/plugins/kimchi/model/debugreports.py
@@ -0,0 +1,213 @@
+#
+# Project Kimchi
+#
+# Copyright IBM, Corp. 2014-2015
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+import fnmatch
+import glob
+import logging
+import os
+import shutil
+import subprocess
+import time
+
+from wok.exception import InvalidParameter, NotFoundError, OperationFailed
+from wok.exception import WokException
+from wok.utils import add_task, wok_log
+from wok.utils import run_command
+from wok.model.tasks import TaskModel
+
+from .. import config
+
+
+class DebugReportsModel(object):
+ def __init__(self, **kargs):
+ self.objstore = kargs['objstore']
+ self.task = TaskModel(**kargs)
+
+ def create(self, params):
+ ident = params.get('name').strip()
+ # Generate a name with time and millisec precision, if necessary
+ if ident is None or ident == "":
+ ident = 'report-' + str(int(time.time() * 1000))
+ else:
+ if ident in self.get_list():
+ raise InvalidParameter("KCHDR0008E", {"name":
ident})
+ taskid = self._gen_debugreport_file(ident)
+ return self.task.lookup(taskid)
+
+ def get_list(self):
+ path = config.get_debugreports_path()
+ file_pattern = os.path.join(path, '*.*')
+ file_lists = glob.glob(file_pattern)
+ file_lists = [os.path.split(file)[1] for file in file_lists]
+ name_lists = [file.split('.', 1)[0] for file in file_lists]
+
+ return name_lists
+
+ def _gen_debugreport_file(self, name):
+ gen_cmd = self.get_system_report_tool()
+
+ if gen_cmd is not None:
+ return add_task('/plugins/kimchi/debugreports/%s' % name, gen_cmd,
+ self.objstore, name)
+
+ raise OperationFailed("KCHDR0002E")
+
+ @staticmethod
+ def sosreport_generate(cb, name):
+ def log_error(e):
+ log = logging.getLogger('Model')
+ log.warning('Exception in generating debug file: %s', e)
+
+ try:
+ command = ['sosreport', '--batch', '--name=%s' %
name]
+ output, error, retcode = run_command(command)
+
+ if retcode != 0:
+ raise OperationFailed("KCHDR0003E", {'name': name,
+ 'err': retcode})
+
+ # SOSREPORT might create file in /tmp or /var/tmp
+ # FIXME: The right way should be passing the tar.xz file directory
+ # though the parameter '--tmp-dir', but it is failing in Fedora 20
+ patterns = ['/tmp/sosreport-%s-*',
'/var/tmp/sosreport-%s-*']
+ reports = []
+ reportFile = None
+ for p in patterns:
+ reports = reports + [f for f in glob.glob(p % name)]
+ for f in reports:
+ if not fnmatch.fnmatch(f, '*.md5'):
+ reportFile = f
+ break
+ # Some error in sosreport happened
+ if reportFile is None:
+ wok_log.error('Debug report file not found. See sosreport '
+ 'output for detail:\n%s', output)
+ fname = (patterns[0] % name).split('/')[-1]
+ raise OperationFailed('KCHDR0004E', {'name': fname})
+
+ md5_report_file = reportFile + '.md5'
+ report_file_extension = '.' + reportFile.split('.', 1)[1]
+ path = config.get_debugreports_path()
+ target = os.path.join(path, name + report_file_extension)
+ # Moving report
+ msg = 'Moving debug report file "%s" to "%s"' %
(reportFile,
+ target)
+ wok_log.info(msg)
+ shutil.move(reportFile, target)
+ # Deleting md5
+ msg = 'Deleting report md5 file: "%s"' % (md5_report_file)
+ wok_log.info(msg)
+ with open(md5_report_file) as f:
+ md5 = f.read().strip()
+ wok_log.info('Md5 file content: "%s"', md5)
+ os.remove(md5_report_file)
+ cb('OK', True)
+ return
+
+ except WokException as e:
+ log_error(e)
+ raise
+
+ except OSError as e:
+ log_error(e)
+ raise
+
+ except Exception, e:
+ # No need to call cb to update the task status here.
+ # The task object will catch the exception raised here
+ # and update the task status there
+ log_error(e)
+ raise OperationFailed("KCHDR0005E", {'name': name,
'err': e})
+
+ @staticmethod
+ def get_system_report_tool():
+ # Please add new possible debug report command here
+ # and implement the report generating function
+ # based on the new report command
+ report_tools = ({'cmd': 'sosreport --help',
+ 'fn': DebugReportsModel.sosreport_generate},)
+
+ # check if the command can be found by shell one by one
+ for helper_tool in report_tools:
+ try:
+ retcode = subprocess.call(helper_tool['cmd'], shell=True,
+ stdout=subprocess.PIPE,
+ stderr=subprocess.PIPE)
+ if retcode == 0:
+ return helper_tool['fn']
+ except Exception, e:
+ wok_log.info('Exception running command: %s', e)
+
+ return None
+
+
+class DebugReportModel(object):
+ def __init__(self, **kargs):
+ pass
+
+ def lookup(self, name):
+ path = config.get_debugreports_path()
+ file_pattern = os.path.join(path, name)
+ file_pattern = file_pattern + '.*'
+ try:
+ file_target = glob.glob(file_pattern)[0]
+ except IndexError:
+ raise NotFoundError("KCHDR0001E", {'name': name})
+
+ ctime = os.stat(file_target).st_mtime
+ ctime = time.strftime("%Y-%m-%d-%H:%M:%S", time.localtime(ctime))
+ file_target = os.path.split(file_target)[-1]
+ file_target = os.path.join("plugins/kimchi/data/debugreports",
+ file_target)
+ return {'uri': file_target,
+ 'ctime': ctime}
+
+ def update(self, name, params):
+ path = config.get_debugreports_path()
+ file_pattern = os.path.join(path, name + '.*')
+ try:
+ file_source = glob.glob(file_pattern)[0]
+ except IndexError:
+ raise NotFoundError("KCHDR0001E", {'name': name})
+
+ file_target = file_source.replace(name, params['name'])
+ if os.path.isfile(file_target):
+ raise InvalidParameter('KCHDR0008E', {'name':
params['name']})
+
+ shutil.move(file_source, file_target)
+ wok_log.info('%s renamed to %s' % (file_source, file_target))
+ return params['name']
+
+ def delete(self, name):
+ path = config.get_debugreports_path()
+ file_pattern = os.path.join(path, name + '.*')
+ try:
+ file_target = glob.glob(file_pattern)[0]
+ except IndexError:
+ raise NotFoundError("KCHDR0001E", {'name': name})
+
+ os.remove(file_target)
+
+
+class DebugReportContentModel(object):
+ def __init__(self, **kargs):
+ self._debugreport = DebugReportModel()
+
+ def lookup(self, name):
+ return self._debugreport.lookup(name)
diff --git a/src/wok/plugins/kimchi/model/diskutils.py
b/src/wok/plugins/kimchi/model/diskutils.py
new file mode 100644
index 0000000..350e6eb
--- /dev/null
+++ b/src/wok/plugins/kimchi/model/diskutils.py
@@ -0,0 +1,75 @@
+#
+# Project Kimchi
+#
+# Copyright IBM, Corp. 2014-2015
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+from wok.exception import OperationFailed, NotFoundError
+from wok.utils import wok_log
+
+from ..xmlutils.disk import get_vm_disk_info, get_vm_disks
+from vms import VMModel, VMsModel
+
+"""
+ Functions that multiple storage-related models (e.g. VMStoragesModel,
+ VolumesModel) will need.
+"""
+
+
+def get_disk_used_by(objstore, conn, path):
+ try:
+ with objstore as session:
+ try:
+ used_by = session.get('storagevolume', path)['used_by']
+ except (KeyError, NotFoundError):
+ wok_log.info('Volume %s not found in obj store.' % path)
+ used_by = []
+ # try to find this volume in existing vm
+ vms_list = VMsModel.get_vms(conn)
+ for vm in vms_list:
+ dom = VMModel.get_vm(vm, conn)
+ storages = get_vm_disks(dom)
+ for disk in storages.keys():
+ d_info = get_vm_disk_info(dom, disk)
+ if path == d_info['path']:
+ used_by.append(vm)
+ try:
+ session.store('storagevolume', path,
+ {'used_by': used_by})
+ except Exception as e:
+ # Let the exception be raised. If we allow disks'
+ # used_by to be out of sync, data corruption could
+ # occour if a disk is added to two guests
+ # unknowingly.
+ wok_log.error('Unable to store storage volume id in'
+ ' objectstore due error: %s',
+ e.message)
+ raise OperationFailed('KCHVOL0017E',
+ {'err': e.message})
+ except Exception as e:
+ # This exception is going to catch errors returned by 'with',
+ # specially ones generated by 'session.store'. It is outside
+ # to avoid conflict with the __exit__ function of 'with'
+ raise OperationFailed('KCHVOL0017E', {'err': e.message})
+ return used_by
+
+
+def set_disk_used_by(objstore, path, new_used_by):
+ try:
+ with objstore as session:
+ session.store('storagevolume', path, {'used_by':
new_used_by})
+ except Exception as e:
+ raise OperationFailed('KCHVOL0017E', {'err': e.message})
diff --git a/src/wok/plugins/kimchi/model/featuretests.py
b/src/wok/plugins/kimchi/model/featuretests.py
new file mode 100644
index 0000000..c53d1aa
--- /dev/null
+++ b/src/wok/plugins/kimchi/model/featuretests.py
@@ -0,0 +1,259 @@
+#
+# Project Kimchi
+#
+# Copyright IBM, Corp. 2013-2015
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+import cherrypy
+import libvirt
+import lxml.etree as ET
+import platform
+import subprocess
+from lxml.builder import E
+
+from wok.rollbackcontext import RollbackContext
+from wok.utils import run_command, servermethod, wok_log
+
+
+FEATURETEST_VM_NAME = "FEATURETEST_VM"
+FEATURETEST_POOL_NAME = "FEATURETEST_POOL"
+
+ISO_STREAM_XML = """
+<domain type='%(domain)s'>
+ <name>%(name)s</name>
+ <memory unit='KiB'>1048576</memory>
+ <os>
+ <type arch='%(arch)s'>hvm</type>
+ <boot dev='cdrom'/>
+ </os>
+ <devices>
+ <disk type='network' device='cdrom'>
+ <driver name='qemu' type='raw'/>
+ <source protocol='%(protocol)s'
name='/url/path/to/iso/file'>
+ <host name='host.name' port='1234'/>
+ </source>
+ <target dev='hdc' bus='ide'/>
+ <readonly/>
+ <alias name='ide0-1-0'/>
+ <address type='drive' controller='0' bus='1'
target='0' unit='0'/>
+ </disk>
+ </devices>
+</domain>"""
+
+SIMPLE_VM_XML = """
+<domain type='%(domain)s'>
+ <name>%(name)s</name>
+ <memory unit='KiB'>10240</memory>
+ <os>
+ <type arch='%(arch)s'>hvm</type>
+ <boot dev='hd'/>
+ </os>
+</domain>"""
+
+MAXMEM_VM_XML = """
+<domain type='%(domain)s'>
+ <name>%(name)s</name>
+ <maxMemory slots='1' unit='KiB'>20480</maxMemory>
+ <memory unit='KiB'>10240</memory>
+ <os>
+ <type arch='%(arch)s'>hvm</type>
+ <boot dev='hd'/>
+ </os>
+</domain>"""
+
+DEV_MEM_XML = """
+<memory model='dimm'>
+ <target>
+ <size unit='KiB'>10240</size>
+ <node>0</node>
+ </target>
+</memory>"""
+
+SCSI_FC_XML = """
+<pool type='scsi'>
+ <name>%(name)s</name>
+ <source>
+ <adapter type='fc_host' wwnn='1234567890abcdef'
wwpn='abcdef1234567890'/>
+ </source>
+ <target>
+ <path>/dev/disk/by-path</path>
+ </target>
+</pool>
+"""
+
+
+class FeatureTests(object):
+
+ @staticmethod
+ def disable_libvirt_error_logging():
+ def libvirt_errorhandler(userdata, error):
+ # A libvirt error handler to ignore annoying messages in stderr
+ pass
+
+ # Filter functions are enable only in production env
+ if cherrypy.config.get('environment') != 'production':
+ return
+ # Register the error handler to hide libvirt error in stderr
+ libvirt.registerErrorHandler(f=libvirt_errorhandler, ctx=None)
+
+ @staticmethod
+ def enable_libvirt_error_logging():
+ # Filter functions are enable only in production env
+ if cherrypy.config.get('environment') != 'production':
+ return
+ # Unregister the error handler
+ libvirt.registerErrorHandler(f=None, ctx=None)
+
+ @staticmethod
+ def libvirt_supports_iso_stream(conn, protocol):
+ conn_type = conn.getType().lower()
+ domain_type = 'test' if conn_type == 'test' else 'kvm'
+ arch = 'i686' if conn_type == 'test' else platform.machine()
+ arch = 'ppc64' if arch == 'ppc64le' else arch
+ xml = ISO_STREAM_XML % {'name': FEATURETEST_VM_NAME,
+ 'domain': domain_type, 'protocol':
protocol,
+ 'arch': arch}
+ try:
+ FeatureTests.disable_libvirt_error_logging()
+ dom = conn.defineXML(xml)
+ dom.undefine()
+ return True
+ except libvirt.libvirtError, e:
+ wok_log.error(e.message)
+ return False
+ finally:
+ FeatureTests.enable_libvirt_error_logging()
+
+ @staticmethod
+ def libvirt_support_nfs_probe(conn):
+ def _get_xml():
+ obj = E.source(E.host(name='localhost'),
E.format(type='nfs'))
+ xml = ET.tostring(obj)
+ return xml
+ try:
+ FeatureTests.disable_libvirt_error_logging()
+ conn.findStoragePoolSources('netfs', _get_xml(), 0)
+ except libvirt.libvirtError as e:
+ wok_log.error(e.message)
+ if e.get_error_code() == 38:
+ # if libvirt cannot find showmount,
+ # it returns 38--general system call failure
+ return False
+ finally:
+ FeatureTests.enable_libvirt_error_logging()
+
+ return True
+
+ @staticmethod
+ @servermethod
+ def qemu_supports_iso_stream():
+ host = cherrypy.server.socket_host
+ port = cherrypy.server.socket_port
+ cmd = "qemu-io -r http://%s:%d/images/icon-fedora.png \
+ -c 'read -v 0 512'" % (host, port)
+ proc = subprocess.Popen(cmd, stdout=subprocess.PIPE,
+ stderr=subprocess.PIPE, shell=True)
+ stdout, stderr = proc.communicate()
+ return len(stderr) == 0
+
+ @staticmethod
+ def libvirt_support_fc_host(conn):
+ try:
+ FeatureTests.disable_libvirt_error_logging()
+ pool = None
+ pool_xml = SCSI_FC_XML % {'name': FEATURETEST_POOL_NAME}
+ pool = conn.storagePoolDefineXML(pool_xml, 0)
+ except libvirt.libvirtError as e:
+ if e.get_error_code() == 27:
+ # Libvirt requires adapter name, not needed when supports to FC
+ return False
+ finally:
+ FeatureTests.enable_libvirt_error_logging()
+ pool is None or pool.undefine()
+ return True
+
+ @staticmethod
+ def has_metadata_support(conn):
+ KIMCHI_META_URL = "https://github.com/kimchi-project/kimchi/"
+ KIMCHI_NAMESPACE = "kimchi"
+ with RollbackContext() as rollback:
+ FeatureTests.disable_libvirt_error_logging()
+ rollback.prependDefer(FeatureTests.enable_libvirt_error_logging)
+ conn_type = conn.getType().lower()
+ domain_type = 'test' if conn_type == 'test' else
'kvm'
+ arch = 'i686' if conn_type == 'test' else platform.machine()
+ arch = 'ppc64' if arch == 'ppc64le' else arch
+ dom = conn.defineXML(SIMPLE_VM_XML % {'name': FEATURETEST_VM_NAME,
+ 'domain': domain_type,
+ 'arch': arch})
+ rollback.prependDefer(dom.undefine)
+ try:
+ dom.setMetadata(libvirt.VIR_DOMAIN_METADATA_ELEMENT,
+ "<metatest/>", KIMCHI_NAMESPACE,
+ KIMCHI_META_URL,
+ flags=libvirt.VIR_DOMAIN_AFFECT_CURRENT)
+ return True
+ except libvirt.libvirtError:
+ return False
+
+ @staticmethod
+ def kernel_support_vfio():
+ out, err, rc = run_command(['modprobe', 'vfio-pci'])
+ if rc != 0:
+ wok_log.warning("Unable to load Kernal module vfio-pci.")
+ return False
+ return True
+
+ @staticmethod
+ def is_nm_running():
+ '''Tries to determine whether NetworkManager is
running.'''
+
+ out, err, rc = run_command(['nmcli', 'dev', 'status'])
+ if rc != 0:
+ return False
+
+ return True
+
+ @staticmethod
+ def has_mem_hotplug_support(conn):
+ '''
+ A memory device can be hot-plugged or hot-unplugged since libvirt
+ version 1.2.14.
+ '''
+ # Libvirt < 1.2.14 does not support memory devices, so firstly, check
+ # its version, then try to attach a device. These steps avoid errors
+ # with Libvirt 'test' driver for KVM
+ version = 1000000*1 + 1000*2 + 14
+ if libvirt.getVersion() < version:
+ return False
+
+ with RollbackContext() as rollback:
+ FeatureTests.disable_libvirt_error_logging()
+ rollback.prependDefer(FeatureTests.enable_libvirt_error_logging)
+ conn_type = conn.getType().lower()
+ domain_type = 'test' if conn_type == 'test' else
'kvm'
+ arch = 'i686' if conn_type == 'test' else platform.machine()
+ arch = 'ppc64' if arch == 'ppc64le' else arch
+ dom = conn.defineXML(MAXMEM_VM_XML % {'name': FEATURETEST_VM_NAME,
+ 'domain': domain_type,
+ 'arch': arch})
+ rollback.prependDefer(dom.undefine)
+ try:
+ dom.attachDeviceFlags(DEV_MEM_XML,
+ libvirt.VIR_DOMAIN_MEM_CONFIG)
+ return True
+ except libvirt.libvirtError:
+ return False
diff --git a/src/wok/plugins/kimchi/model/groups.py
b/src/wok/plugins/kimchi/model/groups.py
new file mode 100644
index 0000000..fc63d68
--- /dev/null
+++ b/src/wok/plugins/kimchi/model/groups.py
@@ -0,0 +1,67 @@
+#
+# Project Kimchi
+#
+# Copyright IBM, Corp. 2014
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+import grp
+
+from wok.config import config
+
+
+class GroupsModel(object):
+ def __init__(self, **args):
+ auth_type = config.get("authentication", "method")
+ for klass in GroupsModel.__subclasses__():
+ if auth_type == klass.auth_type:
+ self.grp = klass(**args)
+
+ def get_list(self, **args):
+ if hasattr(self.grp, '_get_list'):
+ return self.grp._get_list(**args)
+ else:
+ return list()
+
+ def validate(self, gid):
+ return self.grp._validate(gid)
+
+
+class PAMGroupsModel(GroupsModel):
+ auth_type = 'pam'
+
+ def __init__(self, **kargs):
+ pass
+
+ def _get_list(self):
+ return sorted([group.gr_name
+ for group in grp.getgrall()])
+
+ def _validate(self, gid):
+ try:
+ grp.getgrnam(gid)
+ except KeyError:
+ return False
+ return True
+
+
+class LDAPGroupsModel(GroupsModel):
+ auth_type = 'ldap'
+
+ def __init__(self, **kargs):
+ pass
+
+ def _validate(self, gid):
+ return False
diff --git a/src/wok/plugins/kimchi/model/host.py b/src/wok/plugins/kimchi/model/host.py
new file mode 100644
index 0000000..75d4de0
--- /dev/null
+++ b/src/wok/plugins/kimchi/model/host.py
@@ -0,0 +1,476 @@
+#
+# Project Kimchi
+#
+# Copyright IBM, Corp. 2014-2015
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+import libvirt
+import os
+import platform
+import psutil
+import time
+from cherrypy.process.plugins import BackgroundTask
+from collections import defaultdict
+
+from wok.basemodel import Singleton
+from wok.exception import InvalidOperation, InvalidParameter
+from wok.exception import NotFoundError, OperationFailed
+from wok.utils import add_task, wok_log
+from wok.xmlutils.utils import xpath_get_text
+from wok.model.tasks import TaskModel
+
+import hostdev
+from .. import disks
+from .. import netinfo
+from ..repositories import Repositories
+from ..swupdate import SoftwareUpdate
+from config import CapabilitiesModel
+from vms import DOM_STATE_MAP
+
+
+HOST_STATS_INTERVAL = 1
+
+
+class HostModel(object):
+ def __init__(self, **kargs):
+ self.conn = kargs['conn']
+ self.objstore = kargs['objstore']
+ self.task = TaskModel(**kargs)
+ self.host_info = self._get_host_info()
+
+ def _get_ppc_cpu_info(self):
+ res = {}
+ with open('/proc/cpuinfo') as f:
+ for line in f.xreadlines():
+ # Parse CPU, CPU's revision and CPU's clock information
+ for key in ['cpu', 'revision', 'clock']:
+ if key in line:
+ info = line.split(':')[1].strip()
+ if key == 'clock':
+ value = float(info.split('MHz')[0].strip()) / 1000
+ else:
+ value = info.split('(')[0].strip()
+ res[key] = value
+
+ # Power machines show, for each cpu/core, a block with
+ # all cpu information. Here we control the scan of the
+ # necessary information (1st block provides
+ # everything), skipping the function when find all
+ # information.
+ if len(res.keys()) == 3:
+ return "%(cpu)s (%(revision)s) @ %(clock)s GHz\
+ " % res
+
+ return ""
+
+ def _get_host_info(self):
+ res = {}
+ if platform.machine().startswith('ppc'):
+ res['cpu_model'] = self._get_ppc_cpu_info()
+ else:
+ with open('/proc/cpuinfo') as f:
+ for line in f.xreadlines():
+ if "model name" in line:
+ res['cpu_model'] = line.split(':')[1].strip()
+ break
+
+ res['cpus'] = 0
+ res['memory'] = 0L
+
+ # Include IBM PowerKVM name to supported distro names
+ _sup_distros = platform._supported_dists + ('ibm_powerkvm',)
+ # 'fedora' '17' 'Beefy Miracle'
+ distro, version, codename = platform.linux_distribution(
+ supported_dists=_sup_distros)
+ res['os_distro'] = distro
+ res['os_version'] = version
+ res['os_codename'] = unicode(codename, "utf-8")
+
+ return res
+
+ def lookup(self, *name):
+ cpus = psutil.NUM_CPUS
+
+ # psutil is unstable on how to get the number of
+ # cpus, different versions call it differently
+ if hasattr(psutil, 'cpu_count'):
+ cpus = psutil.cpu_count()
+
+ elif hasattr(psutil, '_psplatform'):
+ for method_name in ['_get_num_cpus', 'get_num_cpus']:
+
+ method = getattr(psutil._psplatform, method_name, None)
+ if method is not None:
+ cpus = method()
+ break
+
+ self.host_info['cpus'] = cpus
+ self.host_info['memory'] = psutil.phymem_usage().total
+ return self.host_info
+
+ def swupdate(self, *name):
+ try:
+ swupdate = SoftwareUpdate()
+ except:
+ raise OperationFailed('KCHPKGUPD0004E')
+
+ pkgs = swupdate.getNumOfUpdates()
+ if pkgs == 0:
+ raise OperationFailed('KCHPKGUPD0001E')
+
+ wok_log.debug('Host is going to be updated.')
+ taskid = add_task('/plugins/kimchi/host/swupdate', swupdate.doUpdate,
+ self.objstore, None)
+ return self.task.lookup(taskid)
+
+ def shutdown(self, args=None):
+ # Check for running vms before shutdown
+ running_vms = self._get_vms_list_by_state('running')
+ if len(running_vms) > 0:
+ raise OperationFailed("KCHHOST0001E")
+
+ wok_log.info('Host is going to shutdown.')
+ os.system('shutdown -h now')
+
+ def reboot(self, args=None):
+ # Find running VMs
+ running_vms = self._get_vms_list_by_state('running')
+ if len(running_vms) > 0:
+ raise OperationFailed("KCHHOST0002E")
+
+ wok_log.info('Host is going to reboot.')
+ os.system('reboot')
+
+ def _get_vms_list_by_state(self, state):
+ conn = self.conn.get()
+ return [dom.name().decode('utf-8')
+ for dom in conn.listAllDomains(0)
+ if (DOM_STATE_MAP[dom.info()[0]]) == state]
+
+
+class HostStatsModel(object):
+ __metaclass__ = Singleton
+
+ def __init__(self, **kargs):
+ self.host_stats = defaultdict(list)
+ self.host_stats_thread = BackgroundTask(HOST_STATS_INTERVAL,
+ self._update_host_stats)
+ self.host_stats_thread.start()
+
+ def lookup(self, *name):
+ return {'cpu_utilization':
self.host_stats['cpu_utilization'][-1],
+ 'memory': self.host_stats['memory'][-1],
+ 'disk_read_rate': self.host_stats['disk_read_rate'][-1],
+ 'disk_write_rate':
self.host_stats['disk_write_rate'][-1],
+ 'net_recv_rate': self.host_stats['net_recv_rate'][-1],
+ 'net_sent_rate': self.host_stats['net_sent_rate'][-1]}
+
+ def _update_host_stats(self):
+ preTimeStamp = self.host_stats['timestamp']
+ timestamp = time.time()
+ # FIXME when we upgrade psutil, we can get uptime by psutil.uptime
+ # we get uptime by float(open("/proc/uptime").readline().split()[0])
+ # and calculate the first io_rate after the OS started.
+ with open("/proc/uptime") as time_f:
+ seconds = (timestamp - preTimeStamp if preTimeStamp else
+ float(time_f.readline().split()[0]))
+
+ self.host_stats['timestamp'] = timestamp
+ self._get_host_disk_io_rate(seconds)
+ self._get_host_network_io_rate(seconds)
+
+ self._get_percentage_host_cpu_usage()
+ self._get_host_memory_stats()
+
+ # store only 60 stats (1 min)
+ for key, value in self.host_stats.iteritems():
+ if isinstance(value, list):
+ if len(value) == 60:
+ self.host_stats[key] = value[10:]
+
+ def _get_percentage_host_cpu_usage(self):
+ # This is cpu usage producer. This producer will calculate the usage
+ # at an interval of HOST_STATS_INTERVAL.
+ # The psutil.cpu_percent works as non blocking.
+ # psutil.cpu_percent maintains a cpu time sample.
+ # It will update the cpu time sample when it is called.
+ # So only this producer can call psutil.cpu_percent in kimchi.
+ self.host_stats['cpu_utilization'].append(psutil.cpu_percent(None))
+
+ def _get_host_memory_stats(self):
+ virt_mem = psutil.virtual_memory()
+ # available:
+ # the actual amount of available memory that can be given
+ # instantly to processes that request more memory in bytes; this
+ # is calculated by summing different memory values depending on
+ # the platform (e.g. free + buffers + cached on Linux)
+ memory_stats = {'total': virt_mem.total,
+ 'free': virt_mem.free,
+ 'cached': virt_mem.cached,
+ 'buffers': virt_mem.buffers,
+ 'avail': virt_mem.available}
+ self.host_stats['memory'].append(memory_stats)
+
+ def _get_host_disk_io_rate(self, seconds):
+ disk_read_bytes = self.host_stats['disk_read_bytes']
+ disk_write_bytes = self.host_stats['disk_write_bytes']
+ prev_read_bytes = disk_read_bytes[-1] if disk_read_bytes else 0
+ prev_write_bytes = disk_write_bytes[-1] if disk_write_bytes else 0
+
+ disk_io = psutil.disk_io_counters(False)
+ read_bytes = disk_io.read_bytes
+ write_bytes = disk_io.write_bytes
+
+ rd_rate = int(float(read_bytes - prev_read_bytes) / seconds + 0.5)
+ wr_rate = int(float(write_bytes - prev_write_bytes) / seconds + 0.5)
+
+ self.host_stats['disk_read_rate'].append(rd_rate)
+ self.host_stats['disk_write_rate'].append(wr_rate)
+ self.host_stats['disk_read_bytes'].append(read_bytes)
+ self.host_stats['disk_write_bytes'].append(write_bytes)
+
+ def _get_host_network_io_rate(self, seconds):
+ net_recv_bytes = self.host_stats['net_recv_bytes']
+ net_sent_bytes = self.host_stats['net_sent_bytes']
+ prev_recv_bytes = net_recv_bytes[-1] if net_recv_bytes else 0
+ prev_sent_bytes = net_sent_bytes[-1] if net_sent_bytes else 0
+
+ net_ios = psutil.network_io_counters(True)
+ recv_bytes = 0
+ sent_bytes = 0
+ for key in set(netinfo.nics() +
+ netinfo.wlans()) & set(net_ios.iterkeys()):
+ recv_bytes = recv_bytes + net_ios[key].bytes_recv
+ sent_bytes = sent_bytes + net_ios[key].bytes_sent
+
+ rx_rate = int(float(recv_bytes - prev_recv_bytes) / seconds + 0.5)
+ tx_rate = int(float(sent_bytes - prev_sent_bytes) / seconds + 0.5)
+
+ self.host_stats['net_recv_rate'].append(rx_rate)
+ self.host_stats['net_sent_rate'].append(tx_rate)
+ self.host_stats['net_recv_bytes'].append(recv_bytes)
+ self.host_stats['net_sent_bytes'].append(sent_bytes)
+
+
+class HostStatsHistoryModel(object):
+ def __init__(self, **kargs):
+ self.history = HostStatsModel(**kargs)
+
+ def lookup(self, *name):
+ return {'cpu_utilization':
self.history.host_stats['cpu_utilization'],
+ 'memory': self.history.host_stats['memory'],
+ 'disk_read_rate':
self.history.host_stats['disk_read_rate'],
+ 'disk_write_rate':
self.history.host_stats['disk_write_rate'],
+ 'net_recv_rate':
self.history.host_stats['net_recv_rate'],
+ 'net_sent_rate':
self.history.host_stats['net_sent_rate']}
+
+
+class PartitionsModel(object):
+ def __init__(self, **kargs):
+ pass
+
+ def get_list(self):
+ result = disks.get_partitions_names()
+ return result
+
+
+class PartitionModel(object):
+ def __init__(self, **kargs):
+ pass
+
+ def lookup(self, name):
+ return disks.get_partition_details(name)
+
+
+class DevicesModel(object):
+ def __init__(self, **kargs):
+ self.conn = kargs['conn']
+ self.caps = CapabilitiesModel(**kargs)
+ self.cap_map = \
+ {'net': libvirt.VIR_CONNECT_LIST_NODE_DEVICES_CAP_NET,
+ 'pci': libvirt.VIR_CONNECT_LIST_NODE_DEVICES_CAP_PCI_DEV,
+ 'scsi': libvirt.VIR_CONNECT_LIST_NODE_DEVICES_CAP_SCSI,
+ 'scsi_host': libvirt.VIR_CONNECT_LIST_NODE_DEVICES_CAP_SCSI_HOST,
+ 'storage': libvirt.VIR_CONNECT_LIST_NODE_DEVICES_CAP_STORAGE,
+ 'usb_device': libvirt.VIR_CONNECT_LIST_NODE_DEVICES_CAP_USB_DEV,
+ 'usb':
+ libvirt.VIR_CONNECT_LIST_NODE_DEVICES_CAP_USB_INTERFACE}
+ # TODO: when no longer supporting Libvirt < 1.0.5 distros
+ # (like RHEL6) remove this verification and insert the
+ # key 'fc_host' with the libvirt variable in the hash
+ # declaration above.
+ try:
+ self.cap_map['fc_host'] = \
+ libvirt.VIR_CONNECT_LIST_NODE_DEVICES_CAP_FC_HOST
+ except AttributeError:
+ self.cap_map['fc_host'] = None
+
+ def get_list(self, _cap=None, _passthrough=None,
+ _passthrough_affected_by=None):
+ if _passthrough_affected_by is not None:
+ # _passthrough_affected_by conflicts with _cap and _passthrough
+ if (_cap, _passthrough) != (None, None):
+ raise InvalidParameter("KCHHOST0004E")
+ return sorted(
+ self._get_passthrough_affected_devs(_passthrough_affected_by))
+
+ if _cap == 'fc_host':
+ dev_names = self._get_devices_fc_host()
+ else:
+ dev_names = self._get_devices_with_capability(_cap)
+
+ if _passthrough is not None and _passthrough.lower() == 'true':
+ conn = self.conn.get()
+ passthrough_names = [
+ dev['name'] for dev in hostdev.get_passthrough_dev_infos(conn)]
+ dev_names = list(set(dev_names) & set(passthrough_names))
+
+ dev_names.sort()
+ return dev_names
+
+ def _get_devices_with_capability(self, cap):
+ conn = self.conn.get()
+ if cap is None:
+ cap_flag = 0
+ else:
+ cap_flag = self.cap_map.get(cap)
+ if cap_flag is None:
+ return []
+ return [name.name() for name in conn.listAllDevices(cap_flag)]
+
+ def _get_passthrough_affected_devs(self, dev_name):
+ conn = self.conn.get()
+ info = DeviceModel(conn=self.conn).lookup(dev_name)
+ affected = hostdev.get_affected_passthrough_devices(conn, info)
+ return [dev_info['name'] for dev_info in affected]
+
+ def _get_devices_fc_host(self):
+ conn = self.conn.get()
+ # Libvirt < 1.0.5 does not support fc_host capability
+ if not self.caps.fc_host_support:
+ ret = []
+ scsi_hosts = self._get_devices_with_capability('scsi_host')
+ for host in scsi_hosts:
+ xml = conn.nodeDeviceLookupByName(host).XMLDesc(0)
+ path = '/device/capability/capability/@type'
+ if 'fc_host' in xpath_get_text(xml, path):
+ ret.append(host)
+ return ret
+ # Double verification to catch the case where the libvirt
+ # supports fc_host but does not, for some reason, recognize
+ # the libvirt.VIR_CONNECT_LIST_NODE_DEVICES_CAP_FC_HOST
+ # attribute.
+ if not self.cap_map['fc_host']:
+ return conn.listDevices('fc_host', 0)
+ return self._get_devices_with_capability('fc_host')
+
+
+class DeviceModel(object):
+ def __init__(self, **kargs):
+ self.conn = kargs['conn']
+
+ def lookup(self, nodedev_name):
+ conn = self.conn.get()
+ try:
+ dev = conn.nodeDeviceLookupByName(nodedev_name)
+ except:
+ raise NotFoundError('KCHHOST0003E', {'name': nodedev_name})
+ return hostdev.get_dev_info(dev)
+
+
+class PackagesUpdateModel(object):
+ def __init__(self, **kargs):
+ try:
+ self.host_swupdate = SoftwareUpdate()
+ except:
+ self.host_swupdate = None
+
+ def get_list(self):
+ if self.host_swupdate is None:
+ raise OperationFailed('KCHPKGUPD0004E')
+
+ return self.host_swupdate.getUpdates()
+
+
+class PackageUpdateModel(object):
+ def __init__(self, **kargs):
+ pass
+
+ def lookup(self, name):
+ try:
+ swupdate = SoftwareUpdate()
+ except Exception:
+ raise OperationFailed('KCHPKGUPD0004E')
+
+ return swupdate.getUpdate(name)
+
+
+class RepositoriesModel(object):
+ def __init__(self, **kargs):
+ try:
+ self.host_repositories = Repositories()
+ except:
+ self.host_repositories = None
+
+ def get_list(self):
+ if self.host_repositories is None:
+ raise InvalidOperation('KCHREPOS0014E')
+
+ return sorted(self.host_repositories.getRepositories())
+
+ def create(self, params):
+ if self.host_repositories is None:
+ raise InvalidOperation('KCHREPOS0014E')
+
+ return self.host_repositories.addRepository(params)
+
+
+class RepositoryModel(object):
+ def __init__(self, **kargs):
+ try:
+ self._repositories = Repositories()
+ except:
+ self._repositories = None
+
+ def lookup(self, repo_id):
+ if self._repositories is None:
+ raise InvalidOperation('KCHREPOS0014E')
+
+ return self._repositories.getRepository(repo_id)
+
+ def enable(self, repo_id):
+ if self._repositories is None:
+ raise InvalidOperation('KCHREPOS0014E')
+
+ return self._repositories.enableRepository(repo_id)
+
+ def disable(self, repo_id):
+ if self._repositories is None:
+ raise InvalidOperation('KCHREPOS0014E')
+
+ return self._repositories.disableRepository(repo_id)
+
+ def update(self, repo_id, params):
+ if self._repositories is None:
+ raise InvalidOperation('KCHREPOS0014E')
+
+ return self._repositories.updateRepository(repo_id, params)
+
+ def delete(self, repo_id):
+ if self._repositories is None:
+ raise InvalidOperation('KCHREPOS0014E')
+
+ return self._repositories.removeRepository(repo_id)
diff --git a/src/wok/plugins/kimchi/model/hostdev.py
b/src/wok/plugins/kimchi/model/hostdev.py
new file mode 100644
index 0000000..31211c7
--- /dev/null
+++ b/src/wok/plugins/kimchi/model/hostdev.py
@@ -0,0 +1,324 @@
+#
+# Kimchi
+#
+# Copyright IBM, Corp. 2014
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+import os
+from pprint import pformat
+from pprint import pprint
+
+from wok.utils import wok_log
+from wok.xmlutils.utils import dictize
+
+from libvirtconnection import LibvirtConnection
+
+
+def _get_all_host_dev_infos(libvirt_conn):
+ node_devs = libvirt_conn.listAllDevices(0)
+ return [get_dev_info(node_dev) for node_dev in node_devs]
+
+
+def _get_dev_info_tree(dev_infos):
+ devs = dict([(dev_info['name'], dev_info) for dev_info in dev_infos])
+ root = None
+ for dev_info in dev_infos:
+ if dev_info['parent'] is None:
+ root = dev_info
+ continue
+
+ try:
+ parent = devs[dev_info['parent']]
+ except KeyError:
+ wok_log.error('Parent %s of device %s does not exist.',
+ dev_info['parent'], dev_info['name'])
+ continue
+
+ try:
+ children = parent['children']
+ except KeyError:
+ parent['children'] = [dev_info]
+ else:
+ children.append(dev_info)
+ return root
+
+
+def _is_pci_qualified(pci_dev):
+ # PCI bridge is not suitable to passthrough
+ # KVM does not support passthrough graphic card now
+ blacklist_classes = (0x030000, 0x060000)
+
+ with open(os.path.join(pci_dev['path'], 'class')) as f:
+ pci_class = int(f.readline().strip(), 16)
+
+ if pci_class & 0xff0000 in blacklist_classes:
+ return False
+
+ return True
+
+
+def get_passthrough_dev_infos(libvirt_conn):
+ ''' Get devices eligible to be passed through to VM. '''
+
+ def is_eligible(dev):
+ return dev['device_type'] in ('usb_device', 'scsi') or \
+ (dev['device_type'] == 'pci' and _is_pci_qualified(dev))
+
+ dev_infos = _get_all_host_dev_infos(libvirt_conn)
+
+ return [dev_info for dev_info in dev_infos if is_eligible(dev_info)]
+
+
+def _get_same_iommugroup_devices(dev_infos, device_info):
+ dev_dict = dict([(dev_info['name'], dev_info) for dev_info in dev_infos])
+
+ def get_iommu_group(dev_info):
+ # Find out the iommu group of a given device.
+ # Child device belongs to the same iommu group as the parent device.
+ try:
+ return dev_info['iommuGroup']
+ except KeyError:
+ pass
+
+ parent = dev_info['parent']
+ while parent is not None:
+ try:
+ parent_info = dev_dict[parent]
+ except KeyError:
+ wok_log.error("Parent %s of device %s does not exist",
+ parent, dev_info['name'])
+ break
+
+ try:
+ iommuGroup = parent_info['iommuGroup']
+ except KeyError:
+ pass
+ else:
+ return iommuGroup
+
+ parent = parent_info['parent']
+
+ return None
+
+ iommu_group = get_iommu_group(device_info)
+
+ if iommu_group is None:
+ return []
+
+ return [dev_info for dev_info in dev_infos
+ if dev_info['name'] != device_info['name'] and
+ get_iommu_group(dev_info) == iommu_group]
+
+
+def _get_children_devices(dev_infos, device_info):
+ def get_children_recursive(parent):
+ try:
+ children = parent['children']
+ except KeyError:
+ return []
+
+ result = []
+ for child in children:
+ result.append(child)
+ result.extend(get_children_recursive(child))
+
+ return result
+
+ # Annotate every the dev_info element with children information
+ _get_dev_info_tree(dev_infos)
+
+ for dev_info in dev_infos:
+ if dev_info['name'] == device_info['name']:
+ return get_children_recursive(dev_info)
+
+ return []
+
+
+def get_affected_passthrough_devices(libvirt_conn, passthrough_dev):
+ dev_infos = _get_all_host_dev_infos(libvirt_conn)
+
+ group_devices = _get_same_iommugroup_devices(dev_infos, passthrough_dev)
+ if not group_devices:
+ # On host without iommu group support, the affected devices should
+ # at least include all children devices
+ group_devices.extend(_get_children_devices(dev_infos, passthrough_dev))
+
+ return group_devices
+
+
+def get_dev_info(node_dev):
+ ''' Parse the node device XML string into dict according to
+
http://libvirt.org/formatnode.html.
+
+ scsi_generic is not documented in libvirt official website. Try to
+ parse scsi_generic according to the following libvirt path series.
+
https://www.redhat.com/archives/libvir-list/2013-June/msg00014.html
+
+ scsi_target is not documented in libvirt official website. Try to
+ parse scsi_target according to the libvirt commit db19834a0a.
+ '''
+
+ xmlstr = node_dev.XMLDesc(0)
+ info = dictize(xmlstr)['device']
+ dev_type = info['capability'].pop('type')
+ info['device_type'] = dev_type
+ cap_dict = info.pop('capability')
+ info.update(cap_dict)
+ info['parent'] = node_dev.parent()
+
+ if dev_type in ('scsi', 'scsi_generic', 'scsi_target',
'system', 'usb'):
+ return info
+
+ if dev_type in ('net', 'pci', 'scsi_host', 'storage',
'usb_device'):
+ return globals()['_get_%s_dev_info' % dev_type](info)
+
+ wok_log.error("Unknown device type: %s", dev_type)
+ return info
+
+
+def _get_net_dev_info(info):
+ cap = info.pop('capability')
+ links = {"80203": "IEEE 802.3", "80211": "IEEE
802.11"}
+ link_raw = cap['type']
+ info['link_type'] = links.get(link_raw, link_raw)
+
+ return info
+
+
+def _get_pci_dev_info(info):
+ for k in ('vendor', 'product'):
+ try:
+ description = info[k].pop('pyval')
+ except KeyError:
+ description = None
+ info[k]['description'] = description
+ if 'path' not in info:
+ # Old libvirt does not provide syspath info
+ info['path'] = \
+ "/sys/bus/pci/devices/" \
+ "%(domain)04x:%(bus)02x:%(slot)02x.%(function)01x" % {
+ 'domain': info['domain'], 'bus':
info['bus'],
+ 'slot': info['slot'], 'function':
info['function']}
+ try:
+ info['iommuGroup'] = int(info['iommuGroup']['number'])
+ except KeyError:
+ # Old libvirt does not provide syspath info, figure it out ourselves
+ iommu_link = os.path.join(info['path'], 'iommu_group')
+ if os.path.exists(iommu_link):
+ iommu_path = os.path.realpath(iommu_link)
+ try:
+ info['iommuGroup'] = int(iommu_path.rsplit('/', 1)[1])
+ except (ValueError, IndexError):
+ # No IOMMU group support at all.
+ pass
+ else:
+ # No IOMMU group support at all.
+ pass
+ return info
+
+
+def _get_scsi_host_dev_info(info):
+ try:
+ cap_info = info.pop('capability')
+ except KeyError:
+ # kimchi.model.libvirtstoragepool.ScsiPoolDef assumes
+ # info['adapter']['type'] always exists.
+ info['adapter'] = {'type': ''}
+ return info
+ if isinstance(cap_info, list):
+ info['adapter'] = {}
+ for cap in cap_info:
+ if cap['type'] == 'vport_ops':
+ del cap['type']
+ info['adapter']['vport_ops'] = cap
+ else:
+ info['adapter'].update(cap)
+ else:
+ info['adapter'] = cap_info
+ return info
+
+
+def _get_storage_dev_info(info):
+ try:
+ cap_info = info.pop('capability')
+ except KeyError:
+ return info
+
+ if cap_info['type'] == 'removable':
+ cap_info['available'] = bool(cap_info.pop('media_available'))
+ if cap_info['available']:
+ for k in ('size', 'label'):
+ try:
+ cap_info[k] = cap_info.pop('media_' + k)
+ except KeyError:
+ cap_info[k] = None
+ info['media'] = cap_info
+ return info
+
+
+def _get_usb_device_dev_info(info):
+ for k in ('vendor', 'product'):
+ try:
+ info[k]['description'] = info[k].pop('pyval')
+ except KeyError:
+ # Some USB devices don't provide vendor/product description.
+ pass
+ return info
+
+
+# For test and debug
+def _print_host_dev_tree(libvirt_conn):
+ dev_infos = _get_all_host_dev_infos(libvirt_conn)
+ root = _get_dev_info_tree(dev_infos)
+ if root is None:
+ print "No device found"
+ return
+ print '-----------------'
+ print '\n'.join(_format_dev_node(root))
+
+
+def _format_dev_node(node):
+ try:
+ children = node['children']
+ del node['children']
+ except KeyError:
+ children = []
+
+ lines = []
+ lines.extend([' ~' + line for line in pformat(node).split('\n')])
+
+ count = len(children)
+ for i, child in enumerate(children):
+ if count == 1:
+ lines.append(' \-----------------')
+ else:
+ lines.append(' +-----------------')
+ clines = _format_dev_node(child)
+ if i == count - 1:
+ p = ' '
+ else:
+ p = ' |'
+ lines.extend([p + cline for cline in clines])
+ lines.append('')
+
+ return lines
+
+
+if __name__ == '__main__':
+ libvirt_conn = LibvirtConnection('qemu:///system').get()
+ _print_host_dev_tree(libvirt_conn)
+ print 'Eligible passthrough devices:'
+ pprint(get_passthrough_dev_infos(libvirt_conn))
diff --git a/src/wok/plugins/kimchi/model/interfaces.py
b/src/wok/plugins/kimchi/model/interfaces.py
new file mode 100644
index 0000000..149afe3
--- /dev/null
+++ b/src/wok/plugins/kimchi/model/interfaces.py
@@ -0,0 +1,44 @@
+#
+# Project Kimchi
+#
+# Copyright IBM, Corp. 2014
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+from wok.exception import NotFoundError
+
+from .. import netinfo
+from networks import NetworksModel
+
+
+class InterfacesModel(object):
+ def __init__(self, **kargs):
+ self.conn = kargs['conn']
+ self.networks = NetworksModel(**kargs)
+
+ def get_list(self):
+ return list(set(netinfo.all_favored_interfaces()) -
+ set(self.networks.get_all_networks_interfaces()))
+
+
+class InterfaceModel(object):
+ def __init__(self, **kargs):
+ pass
+
+ def lookup(self, name):
+ try:
+ return netinfo.get_interface_info(name)
+ except ValueError:
+ raise NotFoundError("KCHIFACE0001E", {'name': name})
diff --git a/src/wok/plugins/kimchi/model/libvirtconnection.py
b/src/wok/plugins/kimchi/model/libvirtconnection.py
new file mode 100644
index 0000000..73f3dcf
--- /dev/null
+++ b/src/wok/plugins/kimchi/model/libvirtconnection.py
@@ -0,0 +1,136 @@
+#
+# Project Kimchi
+#
+# Copyright IBM, Corp. 2014
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+import cherrypy
+import libvirt
+import threading
+import time
+
+from wok.utils import wok_log
+
+
+class LibvirtConnection(object):
+ _connections = {}
+ _connectionLock = threading.Lock()
+
+ def __init__(self, uri):
+ self.uri = uri
+ if self.uri not in LibvirtConnection._connections:
+ LibvirtConnection._connections[self.uri] = {}
+ self._connections = LibvirtConnection._connections[self.uri]
+ self.wrappables = self.get_wrappable_objects()
+
+ def get_wrappable_objects(self):
+ """
+ When a wrapped function returns an instance of another libvirt object,
+ we also want to wrap that object so we can catch errors that happen
+ when calling its methods.
+ """
+ objs = []
+ for name in ('virDomain', 'virDomainSnapshot',
'virInterface',
+ 'virNWFilter', 'virNetwork',
'virNodeDevice', 'virSecret',
+ 'virStoragePool', 'virStorageVol',
'virStream'):
+ try:
+ attr = getattr(libvirt, name)
+ except AttributeError:
+ pass
+ objs.append(attr)
+ return tuple(objs)
+
+ def get(self, conn_id=0):
+ """
+ Return current connection to libvirt or open a new one. Wrap all
+ callable libvirt methods so we can catch connection errors and handle
+ them by restarting the server.
+ """
+ def wrapMethod(f):
+ def wrapper(*args, **kwargs):
+ try:
+ ret = f(*args, **kwargs)
+ return ret
+ except libvirt.libvirtError as e:
+ edom = e.get_error_domain()
+ ecode = e.get_error_code()
+ EDOMAINS = (libvirt.VIR_FROM_REMOTE,
+ libvirt.VIR_FROM_RPC)
+ ECODES = (libvirt.VIR_ERR_SYSTEM_ERROR,
+ libvirt.VIR_ERR_INTERNAL_ERROR,
+ libvirt.VIR_ERR_NO_CONNECT,
+ libvirt.VIR_ERR_INVALID_CONN)
+ if edom in EDOMAINS and ecode in ECODES:
+ wok_log.error('Connection to libvirt broken. '
+ 'Recycling. ecode: %d edom: %d' %
+ (ecode, edom))
+ with LibvirtConnection._connectionLock:
+ self._connections[conn_id] = None
+ raise
+ wrapper.__name__ = f.__name__
+ wrapper.__doc__ = f.__doc__
+ return wrapper
+
+ with LibvirtConnection._connectionLock:
+ conn = self._connections.get(conn_id)
+ if not conn:
+ retries = 5
+ while True:
+ retries = retries - 1
+ try:
+ conn = libvirt.open(self.uri)
+ break
+ except libvirt.libvirtError:
+ wok_log.error('Unable to connect to libvirt.')
+ if not retries:
+ wok_log.error("Unable to establish connection "
+ "with libvirt. Please check "
+ "your libvirt URI which is often "
+ "defined in "
+ "/etc/libvirt/libvirt.conf")
+ cherrypy.engine.stop()
+ exit(1)
+ time.sleep(2)
+
+ for name in dir(libvirt.virConnect):
+ method = getattr(conn, name)
+ if callable(method) and not name.startswith('_'):
+ setattr(conn, name, wrapMethod(method))
+
+ for cls in self.wrappables:
+ for name in dir(cls):
+ method = getattr(cls, name)
+ if callable(method) and not name.startswith('_'):
+ setattr(cls, name, wrapMethod(method))
+
+ self._connections[conn_id] = conn
+ # In case we're running into troubles with keeping the
+ # connections alive we should place here:
+ # conn.setKeepAlive(interval=5, count=3)
+ # However the values need to be considered wisely to not affect
+ # hosts which are hosting a lot of virtual machines
+ return conn
+
+ def isQemuURI(self):
+ """
+ This method will return True or Value when the system libvirt
+ URI is a qemu based URI. For example:
+ qemu:///system or qemu+tcp://someipaddress/system
+ """
+ if self.get().getURI().startswith('qemu'):
+ return True
+ else:
+ return False
diff --git a/src/wok/plugins/kimchi/model/libvirtstoragepool.py
b/src/wok/plugins/kimchi/model/libvirtstoragepool.py
new file mode 100644
index 0000000..b22856b
--- /dev/null
+++ b/src/wok/plugins/kimchi/model/libvirtstoragepool.py
@@ -0,0 +1,264 @@
+#
+# Project Kimchi
+#
+# Copyright IBM, Corp. 2014
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+import libvirt
+import lxml.etree as ET
+import os
+import tempfile
+from lxml.builder import E
+
+from wok.exception import InvalidParameter, OperationFailed, TimeoutExpired
+from wok.rollbackcontext import RollbackContext
+from wok.utils import parse_cmd_output, run_command, wok_log
+
+from ..iscsi import TargetClient
+
+
+class StoragePoolDef(object):
+ @classmethod
+ def create(cls, poolArgs):
+ for klass in cls.__subclasses__():
+ if poolArgs['type'] == klass.poolType:
+ return klass(poolArgs)
+ raise OperationFailed("KCHPOOL0014E", {'type':
poolArgs['type']})
+
+ def __init__(self, poolArgs):
+ self.poolArgs = poolArgs
+
+ def prepare(self, conn):
+ ''' Validate pool arguments and perform preparations. Operation
which
+ would cause side effect should be put here. Subclasses can optionally
+ override this method, or it always succeeds by default. '''
+ pass
+
+ @property
+ def xml(self):
+ ''' Subclasses have to override this method to actually generate the
+ storage pool XML definition. Should cause no side effect and be
+ idempotent'''
+ # TODO: When add new pool type, should also add the related test in
+ # tests/test_storagepool.py
+ raise OperationFailed("KCHPOOL0015E", {'pool': self})
+
+
+class DirPoolDef(StoragePoolDef):
+ poolType = 'dir'
+
+ @property
+ def xml(self):
+ # Required parameters
+ # name:
+ # type:
+ # path:
+ pool = E.pool(type='dir')
+ pool.append(E.name(self.poolArgs['name']))
+ pool.append(E.target(E.path(self.poolArgs['path'])))
+ return ET.tostring(pool, encoding='unicode', pretty_print=True)
+
+
+class NetfsPoolDef(StoragePoolDef):
+ poolType = 'netfs'
+
+ def __init__(self, poolArgs):
+ super(NetfsPoolDef, self).__init__(poolArgs)
+ self.path = '/var/lib/kimchi/nfs_mount/' + self.poolArgs['name']
+
+ def prepare(self, conn):
+ mnt_point = tempfile.mkdtemp(dir='/tmp')
+ export_path = "%s:%s" % (
+ self.poolArgs['source']['host'],
self.poolArgs['source']['path'])
+ mount_cmd = ["mount", "-o",
'soft,timeo=100,retrans=3,retry=0',
+ export_path, mnt_point]
+ umount_cmd = ["umount", "-f", export_path]
+ mounted = False
+ # Due to an NFS bug (See Red Hat BZ 1023059), NFSv4 exports may take
+ # 10-15 seconds to mount the first time.
+ cmd_timeout = 15
+
+ with RollbackContext() as rollback:
+ rollback.prependDefer(os.rmdir, mnt_point)
+ try:
+ run_command(mount_cmd, cmd_timeout)
+ rollback.prependDefer(run_command, umount_cmd, cmd_timeout)
+ except TimeoutExpired:
+ raise InvalidParameter("KCHPOOL0012E", {'path':
export_path})
+ with open("/proc/mounts", "rb") as f:
+ rawMounts = f.read()
+ output_items = ['dev_path', 'mnt_point', 'type']
+ mounts = parse_cmd_output(rawMounts, output_items)
+ for item in mounts:
+ if 'dev_path' in item and item['dev_path'] ==
export_path:
+ mounted = True
+
+ if not mounted:
+ raise InvalidParameter("KCHPOOL0013E", {'path':
export_path})
+
+ @property
+ def xml(self):
+ # Required parameters
+ # name:
+ # type:
+ # source[host]:
+ # source[path]:
+ pool = E.pool(type='netfs')
+ pool.append(E.name(self.poolArgs['name']))
+
+ source = E.source()
+ source.append(E.host(name=self.poolArgs['source']['host']))
+ source.append(E.dir(path=self.poolArgs['source']['path']))
+
+ pool.append(source)
+ pool.append(E.target(E.path(self.path)))
+ return ET.tostring(pool, encoding='unicode', pretty_print=True)
+
+
+class LogicalPoolDef(StoragePoolDef):
+ poolType = 'logical'
+
+ def __init__(self, poolArgs):
+ super(LogicalPoolDef, self).__init__(poolArgs)
+ self.path = '/dev/' + self.poolArgs['name']
+
+ @property
+ def xml(self):
+ # Required parameters
+ # name:
+ # type:
+ # source[devices]:
+ pool = E.pool(type='logical')
+ pool.append(E.name(self.poolArgs['name']))
+
+ source = E.source()
+ for device_path in self.poolArgs['source']['devices']:
+ source.append(E.device(path=device_path))
+
+ pool.append(source)
+ pool.append(E.target(E.path(self.path)))
+ return ET.tostring(pool, encoding='unicode', pretty_print=True)
+
+
+class ScsiPoolDef(StoragePoolDef):
+ poolType = 'scsi'
+
+ def prepare(self, conn=None):
+ tmp_name = self.poolArgs['source']['name']
+ self.poolArgs['source']['name'] =
tmp_name.replace('scsi_', '')
+ # fc_host adapters type are only available in libvirt >= 1.0.5
+ if not self.poolArgs['fc_host_support']:
+ self.poolArgs['source']['adapter']['type'] =
'scsi_host'
+ msg = "Libvirt version <= 1.0.5. Setting SCSI host name as
'%s'; "\
+ "setting SCSI adapter type as 'scsi_host'; "\
+ "ignoring wwnn and wwpn." % tmp_name
+ wok_log.info(msg)
+ # Path for Fibre Channel scsi hosts
+ self.poolArgs['path'] = '/dev/disk/by-path'
+ if not self.poolArgs['source']['adapter']['type']:
+ self.poolArgs['source']['adapter']['type'] =
'scsi_host'
+
+ @property
+ def xml(self):
+ # Required parameters
+ # name:
+ # source[adapter][type]:
+ # source[name]:
+ # source[adapter][wwnn]:
+ # source[adapter][wwpn]:
+ # path:
+ pool = E.pool(type='scsi')
+ pool.append(E.name(self.poolArgs['name']))
+
+ adapter =
E.adapter(type=self.poolArgs['source']['adapter']['type'])
+ adapter.set('name', self.poolArgs['source']['name'])
+ adapter.set('wwnn',
self.poolArgs['source']['adapter']['wwnn'])
+ adapter.set('wwpn',
self.poolArgs['source']['adapter']['wwpn'])
+
+ pool.append(E.source(adapter))
+ pool.append(E.target(E.path(self.poolArgs['path'])))
+ return ET.tostring(pool, encoding='unicode', pretty_print=True)
+
+
+class IscsiPoolDef(StoragePoolDef):
+ poolType = 'iscsi'
+
+ def prepare(self, conn):
+ source = self.poolArgs['source']
+ if not TargetClient(**source).validate():
+ msg_args = {'host': source['host'], 'target':
source['target']}
+ raise OperationFailed("KCHISCSI0002E", msg_args)
+ self._prepare_auth(conn)
+
+ def _prepare_auth(self, conn):
+ try:
+ auth = self.poolArgs['source']['auth']
+ except KeyError:
+ return
+
+ try:
+ virSecret = conn.secretLookupByUsage(
+ libvirt.VIR_SECRET_USAGE_TYPE_ISCSI, self.poolArgs['name'])
+ except libvirt.libvirtError:
+ secret = E.secret(ephemeral='no', private='yes')
+
+ description = E.description('Secret for iSCSI storage pool %s' %
+ self.poolArgs['name'])
+ secret.append(description)
+ secret.append(E.auth(type='chap',
username=auth['username']))
+
+ usage = E.usage(type='iscsi')
+ usage.append(E.target(self.poolArgs['name']))
+ secret.append(usage)
+ virSecret = conn.secretDefineXML(ET.tostring(secret))
+
+ virSecret.setValue(auth['password'])
+
+ @property
+ def xml(self):
+ # Required parameters
+ # name:
+ # type:
+ # source[host]:
+ # source[target]:
+ #
+ # Optional parameters
+ # source[port]:
+ pool = E.pool(type='iscsi')
+ pool.append(E.name(self.poolArgs['name']))
+
+ host = E.host(name=self.poolArgs['source']['host'])
+ port = self.poolArgs['source'].get('port')
+ if port is not None:
+ host.set('port', str(port))
+
+ source = E.source(host)
+ source.append(E.device(path=self.poolArgs['source']['target']))
+
+ source_auth = self.poolArgs['source'].get('auth')
+ if source_auth is not None:
+ auth = E.auth(type='chap')
+ auth.set('username', source_auth['username'])
+
+ secret = E.secret(type='iscsi')
+ secret.set('usage', self.poolArgs['name'])
+ auth.append(secret)
+
+ source.append(auth)
+
+ pool.append(source)
+ pool.append(E.target(E.path('/dev/disk/by-id')))
+ return ET.tostring(pool, encoding='unicode', pretty_print=True)
diff --git a/src/wok/plugins/kimchi/model/model.py
b/src/wok/plugins/kimchi/model/model.py
new file mode 100644
index 0000000..0c94f63
--- /dev/null
+++ b/src/wok/plugins/kimchi/model/model.py
@@ -0,0 +1,52 @@
+#
+# Project Kimchi
+#
+# Copyright IBM, Corp. 2014-2015
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+import inspect
+import os
+
+from wok.basemodel import BaseModel
+from wok.objectstore import ObjectStore
+from wok.utils import import_module, listPathModules
+
+from libvirtconnection import LibvirtConnection
+
+
+class Model(BaseModel):
+ def __init__(self, libvirt_uri=None, objstore_loc=None):
+
+ self.objstore = ObjectStore(objstore_loc)
+ self.conn = LibvirtConnection(libvirt_uri)
+ kargs = {'objstore': self.objstore, 'conn': self.conn}
+
+ this = os.path.basename(__file__)
+ this_mod = os.path.splitext(this)[0]
+
+ models = []
+ for mod_name in listPathModules(os.path.dirname(__file__)):
+ if mod_name.startswith("_") or mod_name == this_mod:
+ continue
+
+ module = import_module('plugins.kimchi.model.' + mod_name)
+ members = inspect.getmembers(module, inspect.isclass)
+ for cls_name, instance in members:
+ if inspect.getmodule(instance) == module:
+ if cls_name.endswith('Model'):
+ models.append(instance(**kargs))
+
+ return super(Model, self).__init__(models)
diff --git a/src/wok/plugins/kimchi/model/networks.py
b/src/wok/plugins/kimchi/model/networks.py
new file mode 100644
index 0000000..b579865
--- /dev/null
+++ b/src/wok/plugins/kimchi/model/networks.py
@@ -0,0 +1,382 @@
+#
+# Project Kimchi
+#
+# Copyright IBM, Corp. 2014-2015
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+import ipaddr
+import libvirt
+import sys
+import time
+from xml.sax.saxutils import escape
+
+from wok.config import PluginPaths
+from wok.exception import InvalidOperation, InvalidParameter
+from wok.exception import MissingParameter, NotFoundError, OperationFailed
+from wok.rollbackcontext import RollbackContext
+from wok.utils import run_command, wok_log
+from wok.xmlutils.utils import xpath_get_text
+
+from .. import netinfo
+from .. import network as knetwork
+from ..osinfo import defaults as tmpl_defaults
+from ..xmlutils.network import create_vlan_tagged_bridge_xml
+from ..xmlutils.network import to_network_xml
+
+
+KIMCHI_BRIDGE_PREFIX = 'kb'
+
+
+class NetworksModel(object):
+ def __init__(self, **kargs):
+ self.conn = kargs['conn']
+ if self.conn.isQemuURI():
+ self._check_default_networks()
+
+ def _check_default_networks(self):
+ networks = list(set(tmpl_defaults['networks']))
+ conn = self.conn.get()
+
+ error_msg = ("Please, check the configuration in %s/template.conf to "
+ "ensure it lists only valid networks." %
+ PluginPaths('kimchi').conf_dir)
+
+ for net_name in networks:
+ try:
+ net = conn.networkLookupByName(net_name)
+ except libvirt.libvirtError, e:
+ msg = "Fatal: Unable to find network %s."
+ wok_log.error(msg, net_name)
+ wok_log.error(error_msg)
+ wok_log.error("Details: %s", e.message)
+ sys.exit(1)
+
+ if net.isActive() == 0:
+ try:
+ net.create()
+ except libvirt.libvirtError as e:
+ msg = "Fatal: Unable to activate network %s."
+ wok_log.error(msg, net_name)
+ wok_log.error(error_msg)
+ wok_log.error("Details: %s", e.message)
+ sys.exit(1)
+
+ def create(self, params):
+ conn = self.conn.get()
+ name = params['name']
+ if name in self.get_list():
+ raise InvalidOperation("KCHNET0001E", {'name': name})
+
+ connection = params["connection"]
+ # set forward mode, isolated do not need forward
+ if connection != 'isolated':
+ params['forward'] = {'mode': connection}
+
+ # set subnet, bridge network do not need subnet
+ if connection in ["nat", 'isolated']:
+ self._set_network_subnet(params)
+
+ # only bridge network need bridge(linux bridge) or interface(macvtap)
+ if connection == 'bridge':
+ self._set_network_bridge(params)
+
+ params['name'] = escape(params['name'])
+ xml = to_network_xml(**params)
+
+ try:
+ network = conn.networkDefineXML(xml.encode("utf-8"))
+ network.setAutostart(True)
+ except libvirt.libvirtError as e:
+ raise OperationFailed("KCHNET0008E",
+ {'name': name, 'err':
e.get_error_message()})
+
+ return name
+
+ def get_list(self):
+ conn = self.conn.get()
+ names = conn.listNetworks() + conn.listDefinedNetworks()
+ return sorted(map(lambda x: x.decode('utf-8'), names))
+
+ def _get_available_address(self, addr_pools=[]):
+ invalid_addrs = []
+ for net_name in self.get_list():
+ network = NetworkModel.get_network(self.conn.get(), net_name)
+ xml = network.XMLDesc(0)
+ subnet = NetworkModel.get_network_from_xml(xml)['subnet']
+ subnet and invalid_addrs.append(ipaddr.IPNetwork(subnet))
+ addr_pools = addr_pools if addr_pools else knetwork.PrivateNets
+ return knetwork.get_one_free_network(invalid_addrs, addr_pools)
+
+ def _set_network_subnet(self, params):
+ netaddr = params.get('subnet', '')
+ # lookup a free network address for nat and isolated automatically
+ if not netaddr:
+ netaddr = self._get_available_address()
+ if not netaddr:
+ raise OperationFailed("KCHNET0009E", {'name':
params['name']})
+
+ try:
+ ip = ipaddr.IPNetwork(netaddr)
+ except ValueError:
+ raise InvalidParameter("KCHNET0003E", {'subent': netaddr,
+ 'network':
params['name']})
+
+ if ip.ip == ip.network:
+ ip.ip = ip.ip + 1
+
+ dhcp_start = str(ip.ip + ip.numhosts / 2)
+ dhcp_end = str(ip.ip + ip.numhosts - 2)
+ params.update({'net': str(ip),
+ 'dhcp': {'range': {'start': dhcp_start,
+ 'end': dhcp_end}}})
+
+ def _ensure_iface_up(self, iface):
+ if netinfo.operstate(iface) != 'up':
+ _, err, rc = run_command(['ip', 'link', 'set',
'dev', iface, 'up'])
+ if rc != 0:
+ raise OperationFailed("KCHNET0020E",
+ {'iface': iface, 'err': err})
+ # Add a delay to wait for the link change takes into effect.
+ for i in range(10):
+ time.sleep(1)
+ if netinfo.operstate(iface) == 'up':
+ break
+ else:
+ raise OperationFailed("KCHNET0021E", {'iface': iface})
+
+ def _set_network_bridge(self, params):
+ try:
+ iface = params['interface']
+ if iface in self.get_all_networks_interfaces():
+ msg_args = {'iface': iface, 'network':
params['name']}
+ raise InvalidParameter("KCHNET0006E", msg_args)
+ except KeyError:
+ raise MissingParameter("KCHNET0004E", {'name':
params['name']})
+
+ self._ensure_iface_up(iface)
+ if netinfo.is_bridge(iface):
+ if 'vlan_id' in params:
+ raise InvalidParameter('KCHNET0019E', {'name': iface})
+ params['bridge'] = iface
+ elif netinfo.is_bare_nic(iface) or netinfo.is_bonding(iface):
+ if params.get('vlan_id') is None:
+ params['forward']['dev'] = iface
+ else:
+ params['bridge'] = \
+ self._create_vlan_tagged_bridge(str(iface),
+ str(params['vlan_id']))
+ else:
+ raise InvalidParameter("KCHNET0007E")
+
+ def get_all_networks_interfaces(self):
+ net_names = self.get_list()
+ interfaces = []
+ for name in net_names:
+ conn = self.conn.get()
+ network = conn.networkLookupByName(name.encode("utf-8"))
+ xml = network.XMLDesc(0)
+ net_dict = NetworkModel.get_network_from_xml(xml)
+ forward = net_dict['forward']
+ (forward['mode'] == 'bridge' and forward['interface']
and
+ interfaces.append(forward['interface'][0]) is None or
+ interfaces.extend(forward['interface'] + forward['pf']))
+ net_dict['bridge'] and interfaces.append(net_dict['bridge'])
+ return interfaces
+
+ def _create_vlan_tagged_bridge(self, interface, vlan_id):
+ # Truncate the interface name if it exceeds 8 characters to make sure
+ # the length of bridge name is less than 15 (its maximum value).
+ br_name = KIMCHI_BRIDGE_PREFIX + interface[-8:] + '-' + vlan_id
+ br_xml = create_vlan_tagged_bridge_xml(br_name, interface, vlan_id)
+ conn = self.conn.get()
+
+ bridges = []
+ for net in conn.listAllNetworks():
+ # Bridged networks do not have a bridge name
+ # So in those cases, libvirt raises an error when trying to get
+ # the bridge name
+ try:
+ bridges.append(net.bridgeName())
+ except libvirt.libvirtError, e:
+ wok_log.error(e.message)
+
+ if br_name in bridges:
+ raise InvalidOperation("KCHNET0010E", {'iface': br_name})
+
+ with RollbackContext() as rollback:
+ try:
+ vlan_tagged_br = conn.interfaceDefineXML(br_xml, 0)
+ rollback.prependDefer(vlan_tagged_br.destroy)
+ vlan_tagged_br.create(0)
+ except libvirt.libvirtError as e:
+ raise OperationFailed(e.message)
+ else:
+ return br_name
+
+
+class NetworkModel(object):
+ def __init__(self, **kargs):
+ self.conn = kargs['conn']
+ self.objstore = kargs['objstore']
+
+ def lookup(self, name):
+ network = self.get_network(self.conn.get(), name)
+ xml = network.XMLDesc(0)
+ net_dict = self.get_network_from_xml(xml)
+ subnet = net_dict['subnet']
+ dhcp = net_dict['dhcp']
+ forward = net_dict['forward']
+ interface = net_dict['bridge']
+
+ connection = forward['mode'] or "isolated"
+ # FIXME, if we want to support other forward mode well.
+ if connection == 'bridge':
+ # macvtap bridge
+ interface = interface or forward['interface'][0]
+ # exposing the network on linux bridge or macvtap interface
+ interface_subnet = knetwork.get_dev_netaddr(interface)
+ subnet = subnet if subnet else interface_subnet
+
+ # libvirt use format 192.168.0.1/24, standard should be 192.168.0.0/24
+ #
http://www.ovirt.org/File:Issue3.png
+ if subnet:
+ subnet = ipaddr.IPNetwork(subnet)
+ subnet = "%s/%s" % (subnet.network, subnet.prefixlen)
+
+ return {'connection': connection,
+ 'interface': interface,
+ 'subnet': subnet,
+ 'dhcp': dhcp,
+ 'vms': self._get_vms_attach_to_a_network(name),
+ 'in_use': self._is_network_in_use(name),
+ 'autostart': network.autostart() == 1,
+ 'state': network.isActive() and "active" or
"inactive",
+ 'persistent': True if network.isPersistent() else False}
+
+ def _is_network_in_use(self, name):
+ # All the networks listed as default in template.conf file should not
+ # be deactivate or deleted. Otherwise, we will allow user create
+ # inconsistent templates from scratch
+ if name in tmpl_defaults['networks']:
+ return True
+
+ vms = self._get_vms_attach_to_a_network(name)
+ return bool(vms) or self._is_network_used_by_template(name)
+
+ def _is_network_used_by_template(self, network):
+ with self.objstore as session:
+ templates = session.get_list('template')
+ for tmpl in templates:
+ tmpl_net = session.get('template', tmpl)['networks']
+ if network in tmpl_net:
+ return True
+ return False
+
+ def _get_vms_attach_to_a_network(self, network, filter="all"):
+ DOM_STATE_MAP = {'nostate': 0, 'running': 1, 'blocked':
2,
+ 'paused': 3, 'shutdown': 4, 'shutoff':
5,
+ 'crashed': 6}
+ state = DOM_STATE_MAP.get(filter)
+ vms = []
+ conn = self.conn.get()
+ for dom in conn.listAllDomains(0):
+ networks = self._vm_get_networks(dom)
+ if network.encode('utf-8') in networks and \
+ (state is None or state == dom.state(0)[0]):
+ vms.append(dom.name())
+ return vms
+
+ def _vm_get_networks(self, dom):
+ xml = dom.XMLDesc(0)
+ xpath =
"/domain/devices/interface[@type='network']/source/@network"
+ return xpath_get_text(xml, xpath)
+
+ def activate(self, name):
+ network = self.get_network(self.conn.get(), name)
+ try:
+ network.create()
+ except libvirt.libvirtError, e:
+ raise OperationFailed('KCHNET0022E', {'name': name,
+ 'err': e.message})
+
+ def deactivate(self, name):
+ if self._is_network_in_use(name):
+ vms = self._get_vms_attach_to_a_network(name)
+ vms.sort()
+ raise InvalidOperation("KCHNET0018E", {'name': name,
+ 'vms': ',
'.join(vms)})
+
+ network = self.get_network(self.conn.get(), name)
+ network.destroy()
+
+ def delete(self, name):
+ if self._is_network_in_use(name):
+ vms = self._get_vms_attach_to_a_network(name)
+ vms.sort()
+ raise InvalidOperation("KCHNET0017E", {'name': name,
+ 'vms': ',
'.join(vms)})
+
+ network = self.get_network(self.conn.get(), name)
+ if network.isActive():
+ raise InvalidOperation("KCHNET0005E", {'name': name})
+
+ self._remove_vlan_tagged_bridge(network)
+ network.undefine()
+
+ @staticmethod
+ def get_network(conn, name):
+ name = name.encode("utf-8")
+ try:
+ return conn.networkLookupByName(name)
+ except libvirt.libvirtError:
+ raise NotFoundError("KCHNET0002E", {'name': name})
+
+ @staticmethod
+ def get_network_from_xml(xml):
+ address = xpath_get_text(xml, "/network/ip/@address")
+ address = address and address[0] or ''
+ netmask = xpath_get_text(xml, "/network/ip/@netmask")
+ netmask = netmask and netmask[0] or ''
+ net = address and netmask and "/".join([address, netmask]) or
''
+
+ dhcp_start = xpath_get_text(xml, "/network/ip/dhcp/range/@start")
+ dhcp_start = dhcp_start and dhcp_start[0] or ''
+ dhcp_end = xpath_get_text(xml, "/network/ip/dhcp/range/@end")
+ dhcp_end = dhcp_end and dhcp_end[0] or ''
+ dhcp = {'start': dhcp_start, 'end': dhcp_end}
+
+ forward_mode = xpath_get_text(xml, "/network/forward/@mode")
+ forward_mode = forward_mode and forward_mode[0] or ''
+ forward_if = xpath_get_text(xml, "/network/forward/interface/@dev")
+ forward_pf = xpath_get_text(xml, "/network/forward/pf/@dev")
+ bridge = xpath_get_text(xml, "/network/bridge/@name")
+ bridge = bridge and bridge[0] or ''
+ return {'subnet': net, 'dhcp': dhcp, 'bridge': bridge,
+ 'forward': {'mode': forward_mode,
+ 'interface': forward_if,
+ 'pf': forward_pf}}
+
+ def _remove_vlan_tagged_bridge(self, network):
+ try:
+ bridge = network.bridgeName()
+ except libvirt.libvirtError:
+ pass
+ else:
+ if bridge.startswith(KIMCHI_BRIDGE_PREFIX):
+ conn = self.conn.get()
+ iface = conn.interfaceLookupByName(bridge)
+ iface.isActive() and iface.destroy(0)
+ iface.undefine()
diff --git a/src/wok/plugins/kimchi/model/peers.py
b/src/wok/plugins/kimchi/model/peers.py
new file mode 100644
index 0000000..7577364
--- /dev/null
+++ b/src/wok/plugins/kimchi/model/peers.py
@@ -0,0 +1,72 @@
+#
+# Project Kimchi
+#
+# Copyright IBM, Corp. 2014-2015
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+import cherrypy
+import re
+import socket
+
+from wok.config import config
+from wok.utils import run_command, wok_log
+
+
+class PeersModel(object):
+ def __init__(self, **kargs):
+ # check federation feature is enabled on Kimchi server
+ if config.get("server", "federation") == "off":
+ return
+
+ # register server on openslp
+ hostname = socket.getfqdn(config.get("server", "host"))
+ port = config.get("server", "ssl_port")
+ self.url = hostname + ":" + port
+
+ cmd = ["slptool", "register",
+ "service:wokd://%s" % self.url]
+ out, error, ret = run_command(cmd)
+ if out and len(out) != 0:
+ wok_log.error("Unable to register server on openSLP."
+ " Details: %s" % out)
+ cherrypy.engine.subscribe('exit', self._peer_deregister)
+
+ def _peer_deregister(self):
+ cmd = ["slptool", "deregister",
+ "service:wokd://%s" % self.url]
+ out, error, ret = run_command(cmd)
+ if out and len(out) != 0:
+ wok_log.error("Unable to deregister server on openSLP."
+ " Details: %s" % out)
+
+ def get_list(self):
+ # check federation feature is enabled on Kimchi server
+ if config.get("server", "federation") == "off":
+ return []
+
+ cmd = ["slptool", "findsrvs", "service:wokd"]
+ out, error, ret = run_command(cmd)
+ if ret != 0:
+ return []
+
+ peers = []
+ for server in out.strip().split("\n"):
+ match = re.match("service:wokd://(.*?),.*", server)
+ peer = match.group(1)
+ if peer != self.url:
+ peers.append("https://" + peer)
+
+ return peers
diff --git a/src/wok/plugins/kimchi/model/storagepools.py
b/src/wok/plugins/kimchi/model/storagepools.py
new file mode 100644
index 0000000..0db2ef4
--- /dev/null
+++ b/src/wok/plugins/kimchi/model/storagepools.py
@@ -0,0 +1,490 @@
+#
+# Project Kimchi
+#
+# Copyright IBM, Corp. 2014-2015
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+import libvirt
+import lxml.etree as ET
+import sys
+from lxml.builder import E
+
+from wok.config import config, PluginPaths
+from wok.exception import InvalidOperation, MissingParameter
+from wok.exception import NotFoundError, OperationFailed
+from wok.utils import add_task, run_command, wok_log
+from wok.xmlutils.utils import xpath_get_text
+
+from ..osinfo import defaults as tmpl_defaults
+from ..scan import Scanner
+from ..utils import pool_name_from_uri
+from config import CapabilitiesModel
+from host import DeviceModel
+from libvirtstoragepool import StoragePoolDef
+
+
+ISO_POOL_NAME = u'kimchi_isos'
+
+POOL_STATE_MAP = {0: 'inactive',
+ 1: 'initializing',
+ 2: 'active',
+ 3: 'degraded',
+ 4: 'inaccessible'}
+
+# Types of pools supported
+STORAGE_SOURCES = {'netfs': {'addr': '/pool/source/host/@name',
+ 'path': '/pool/source/dir/@path'},
+ 'iscsi': {'addr': '/pool/source/host/@name',
+ 'port': '/pool/source/host/@port',
+ 'path': '/pool/source/device/@path'},
+ 'scsi': {'adapter_type':
'/pool/source/adapter/@type',
+ 'adapter_name':
'/pool/source/adapter/@name',
+ 'wwnn': '/pool/source/adapter/@wwnn',
+ 'wwpn': '/pool/source/adapter/@wwpn'}}
+
+
+class StoragePoolsModel(object):
+ def __init__(self, **kargs):
+ self.conn = kargs['conn']
+ self.objstore = kargs['objstore']
+ self.scanner = Scanner(self._clean_scan)
+ self.scanner.delete()
+ self.caps = CapabilitiesModel(**kargs)
+ self.device = DeviceModel(**kargs)
+
+ if self.conn.isQemuURI():
+ self._check_default_pools()
+
+ def _check_default_pools(self):
+ pools = {}
+
+ default_pool = tmpl_defaults['storagepool']
+ default_pool = default_pool.split('/')[-1]
+
+ pools[default_pool] = {}
+ if default_pool == 'default':
+ pools[default_pool] = {'path': '/var/lib/libvirt/images'}
+
+ if config.get("server", "create_iso_pool") ==
"true":
+ pools['ISO'] = {'path': '/var/lib/kimchi/isos'}
+
+ error_msg = ("Please, check the configuration in %s/template.conf to "
+ "ensure it has a valid storage pool." %
+ PluginPaths('kimchi').conf_dir)
+
+ conn = self.conn.get()
+ for pool_name in pools:
+ try:
+ pool = conn.storagePoolLookupByName(pool_name)
+ except libvirt.libvirtError, e:
+ pool_path = pools[pool_name].get('path')
+ if pool_path is None:
+ msg = "Fatal: Unable to find storage pool %s. " +
error_msg
+ wok_log.error(msg % pool_name)
+ wok_log.error("Details: %s", e.message)
+ sys.exit(1)
+
+ # Try to create the pool
+ pool = E.pool(E.name(pool_name), type='dir')
+ pool.append(E.target(E.path(pool_path)))
+ xml = ET.tostring(pool)
+ try:
+ pool = conn.storagePoolDefineXML(xml, 0)
+ except libvirt.libvirtError, e:
+ msg = "Fatal: Unable to create storage pool %s. "
+ msg += error_msg
+ wok_log.error(msg % pool_name)
+ wok_log.error("Details: %s", e.message)
+ sys.exit(1)
+
+ # Build and set autostart value to pool
+ # Ignore error as the pool was already successfully created
+ try:
+ # Add build step to make sure target directory created
+ # The build process may fail when the pool directory
+ # already exists on system
+ pool.build(libvirt.VIR_STORAGE_POOL_BUILD_NEW)
+ pool.setAutostart(1)
+ except:
+ pass
+
+ if pool.isActive() == 0:
+ try:
+ pool.create(0)
+ except libvirt.libvirtError, e:
+ msg = "Fatal: Unable to craete storage pool %s. "
+ msg += error_msg
+ wok_log.error(msg % pool_name)
+ wok_log.error("Details: %s", e.message)
+ sys.exit(1)
+
+ def get_list(self):
+ try:
+ conn = self.conn.get()
+ names = conn.listStoragePools()
+ names += conn.listDefinedStoragePools()
+ return sorted(map(lambda x: x.decode('utf-8'), names))
+ except libvirt.libvirtError as e:
+ raise OperationFailed("KCHPOOL0006E",
+ {'err': e.get_error_message()})
+
+ def create(self, params):
+ task_id = None
+ conn = self.conn.get()
+ try:
+ name = params['name']
+ if name == ISO_POOL_NAME:
+ raise InvalidOperation("KCHPOOL0031E")
+
+ # The user may want to create a logical pool with the same name
+ # used before but a volume group will already exist with this name
+ # So check the volume group does not exist to create the pool
+ if params['type'] == 'logical':
+ vgdisplay_cmd = ['vgdisplay', name.encode('utf-8')]
+ output, error, returncode = run_command(vgdisplay_cmd)
+ # From vgdisplay error codes:
+ # 1 error reading VGDA
+ # 2 volume group doesn't exist
+ # 3 not all physical volumes of volume group online
+ # 4 volume group not found
+ # 5 no volume groups found at all
+ # 6 error reading VGDA from lvmtab
+ if returncode not in [2, 4, 5]:
+ raise InvalidOperation("KCHPOOL0036E", {'name':
name})
+
+ if params['type'] == 'kimchi-iso':
+ task_id = self._do_deep_scan(params)
+
+ if params['type'] == 'scsi':
+ adapter_name = params['source']['adapter_name']
+ extra_params = self.device.lookup(adapter_name)
+ # Adds name, adapter_type, wwpn and wwnn to source information
+ params['source'].update(extra_params)
+ params['fc_host_support'] = self.caps.fc_host_support
+
+ poolDef = StoragePoolDef.create(params)
+ poolDef.prepare(conn)
+ xml = poolDef.xml.encode("utf-8")
+ except KeyError, item:
+ raise MissingParameter("KCHPOOL0004E",
+ {'item': str(item), 'name': name})
+
+ if name in self.get_list():
+ raise InvalidOperation("KCHPOOL0001E", {'name': name})
+
+ try:
+ if task_id:
+ # Create transient pool for deep scan
+ conn.storagePoolCreateXML(xml, 0)
+ return name
+
+ pool = conn.storagePoolDefineXML(xml, 0)
+ except libvirt.libvirtError as e:
+ wok_log.error("Problem creating Storage Pool: %s", e)
+ raise OperationFailed("KCHPOOL0007E",
+ {'name': name, 'err':
e.get_error_message()})
+
+ # Build and set autostart value to pool
+ # Ignore error as the pool was already successfully created
+ # The build process fails when the pool directory already exists
+ try:
+ if params['type'] in ['logical', 'dir',
'netfs', 'scsi']:
+ pool.build(libvirt.VIR_STORAGE_POOL_BUILD_NEW)
+ pool.setAutostart(1)
+ else:
+ pool.setAutostart(0)
+ except:
+ pass
+
+ if params['type'] == 'netfs':
+ output, error, returncode = run_command(['setsebool', '-P',
+ 'virt_use_nfs=1'])
+ if error or returncode:
+ wok_log.error("Unable to set virt_use_nfs=1. If you use "
+ "SELinux, this may prevent NFS pools from "
+ "being used.")
+ return name
+
+ def _clean_scan(self, pool_name):
+ try:
+ conn = self.conn.get()
+ pool = conn.storagePoolLookupByName(pool_name.encode("utf-8"))
+ pool.destroy()
+ with self.objstore as session:
+ session.delete('scanning', pool_name)
+ except Exception, e:
+ err = "Exception %s occured when cleaning scan result"
+ wok_log.debug(err % e.message)
+
+ def _do_deep_scan(self, params):
+ scan_params = dict(ignore_list=[])
+ scan_params['scan_path'] = params['path']
+ params['type'] = 'dir'
+
+ for pool in self.get_list():
+ try:
+ res = StoragePoolModel(conn=self.conn,
+ objstore=self.objstore).lookup(pool)
+ if res['state'] == 'active':
+ scan_params['ignore_list'].append(res['path'])
+ except Exception, e:
+ err = "Exception %s occured when get ignore path"
+ wok_log.debug(err % e.message)
+
+ params['path'] = self.scanner.scan_dir_prepare(params['name'])
+ scan_params['pool_path'] = params['path']
+ task_id = add_task('/plugins/kimchi/storagepools/%s' % ISO_POOL_NAME,
+ self.scanner.start_scan, self.objstore, scan_params)
+ # Record scanning-task/storagepool mapping for future querying
+ try:
+ with self.objstore as session:
+ session.store('scanning', params['name'], task_id)
+ return task_id
+ except Exception as e:
+ raise OperationFailed('KCHPOOL0037E', {'err': e.message})
+
+
+class StoragePoolModel(object):
+ def __init__(self, **kargs):
+ self.conn = kargs['conn']
+ self.objstore = kargs['objstore']
+
+ @staticmethod
+ def get_storagepool(name, conn):
+ conn = conn.get()
+ try:
+ return conn.storagePoolLookupByName(name.encode("utf-8"))
+ except libvirt.libvirtError as e:
+ if e.get_error_code() == libvirt.VIR_ERR_NO_STORAGE_POOL:
+ raise NotFoundError("KCHPOOL0002E", {'name': name})
+ else:
+ raise
+
+ def _get_storagepool_vols_num(self, pool):
+ try:
+ if pool.isActive():
+ pool.refresh(0)
+ return pool.numOfVolumes()
+ else:
+ return 0
+ except libvirt.libvirtError as e:
+ # If something (say a busy pool) prevents the refresh,
+ # throwing an Exception here would prevent all pools from
+ # displaying information -- so return None for busy
+ wok_log.error("ERROR: Storage Pool get vol count: %s "
+ % e.get_error_message())
+ wok_log.error("ERROR: Storage Pool get vol count error no: %s "
+ % e.get_error_code())
+ return 0
+ except Exception as e:
+ raise OperationFailed("KCHPOOL0008E",
+ {'name': pool.name(),
+ 'err': e.get_error_message()})
+
+ def _get_storage_source(self, pool_type, pool_xml):
+ source = {}
+ if pool_type not in STORAGE_SOURCES:
+ return source
+
+ for key, val in STORAGE_SOURCES[pool_type].items():
+ res = xpath_get_text(pool_xml, val)
+ if len(res) == 1:
+ source[key] = res[0]
+ elif len(res) == 0:
+ source[key] = ""
+ else:
+ source[key] = res
+ return source
+
+ def _nfs_status_online(self, pool, poolArgs=None):
+ if not poolArgs:
+ xml = pool.XMLDesc(0)
+ pool_type = xpath_get_text(xml, "/pool/@type")[0]
+ source = self._get_storage_source(pool_type, xml)
+ poolArgs = {}
+ poolArgs['name'] = pool.name()
+ poolArgs['type'] = pool_type
+ poolArgs['source'] = {'path': source['path'],
+ 'host': source['addr']}
+ conn = self.conn.get()
+ poolDef = StoragePoolDef.create(poolArgs)
+ try:
+ poolDef.prepare(conn)
+ return True
+ except Exception:
+ return False
+
+ def lookup(self, name):
+ pool = self.get_storagepool(name, self.conn)
+ info = pool.info()
+ autostart = True if pool.autostart() else False
+ persistent = True if pool.isPersistent() else False
+ xml = pool.XMLDesc(0)
+ path = xpath_get_text(xml, "/pool/target/path")[0]
+ pool_type = xpath_get_text(xml, "/pool/@type")[0]
+ source = self._get_storage_source(pool_type, xml)
+ # FIXME: nfs workaround - prevent any libvirt operation
+ # for a nfs if the corresponding NFS server is down.
+ if pool_type == 'netfs' and not self._nfs_status_online(pool):
+ wok_log.debug("NFS pool %s is offline, reason: NFS "
+ "server %s is unreachable.", name,
source['addr'])
+ # Mark state as '4' => inaccessible.
+ info[0] = 4
+ # skip calculating volumes
+ nr_volumes = 0
+ else:
+ nr_volumes = self._get_storagepool_vols_num(pool)
+
+ res = {'state': POOL_STATE_MAP[info[0]],
+ 'path': path,
+ 'source': source,
+ 'type': pool_type,
+ 'autostart': autostart,
+ 'capacity': info[1],
+ 'allocated': info[2],
+ 'available': info[3],
+ 'nr_volumes': nr_volumes,
+ 'persistent': persistent}
+
+ if not pool.isPersistent():
+ # Deal with deep scan generated pool
+ try:
+ with self.objstore as session:
+ task_id = session.get('scanning', name)
+ res['task_id'] = str(task_id)
+ res['type'] = 'kimchi-iso'
+ except NotFoundError:
+ # User created normal pool
+ pass
+ return res
+
+ def _update_lvm_disks(self, pool_name, disks):
+ # check if all the disks/partitions exists in the host
+ for disk in disks:
+ lsblk_cmd = ['lsblk', disk]
+ output, error, returncode = run_command(lsblk_cmd)
+ if returncode != 0:
+ wok_log.error('%s is not a valid disk/partition. Could not '
+ 'add it to the pool %s.', disk, pool_name)
+ raise OperationFailed('KCHPOOL0027E', {'disk': disk,
+ 'pool': pool_name})
+ # add disks to the lvm pool using vgextend + virsh refresh
+ vgextend_cmd = ["vgextend", pool_name]
+ vgextend_cmd += disks
+ output, error, returncode = run_command(vgextend_cmd)
+ if returncode != 0:
+ msg = "Could not add disks to pool %s, error: %s"
+ wok_log.error(msg, pool_name, error)
+ raise OperationFailed('KCHPOOL0028E', {'pool': pool_name,
+ 'err': error})
+ # refreshing pool state
+ pool = self.get_storagepool(pool_name, self.conn)
+ if pool.isActive():
+ pool.refresh(0)
+
+ def update(self, name, params):
+ pool = self.get_storagepool(name, self.conn)
+ if 'autostart' in params:
+ if params['autostart']:
+ pool.setAutostart(1)
+ else:
+ pool.setAutostart(0)
+
+ if 'disks' in params:
+ # check if pool is type 'logical'
+ xml = pool.XMLDesc(0)
+ pool_type = xpath_get_text(xml, "/pool/@type")[0]
+ if pool_type != 'logical':
+ raise InvalidOperation('KCHPOOL0029E')
+ self._update_lvm_disks(name, params['disks'])
+ ident = pool.name()
+ return ident.decode('utf-8')
+
+ def activate(self, name):
+ pool = self.get_storagepool(name, self.conn)
+ # FIXME: nfs workaround - do not activate a NFS pool
+ # if the NFS server is not reachable.
+ xml = pool.XMLDesc(0)
+ pool_type = xpath_get_text(xml, "/pool/@type")[0]
+ if pool_type == 'netfs' and not self._nfs_status_online(pool):
+ # block the user from activating the pool.
+ source = self._get_storage_source(pool_type, xml)
+ raise OperationFailed("KCHPOOL0032E",
+ {'name': name, 'server':
source['addr']})
+ return
+ try:
+ pool.create(0)
+ except libvirt.libvirtError as e:
+ raise OperationFailed("KCHPOOL0009E",
+ {'name': name, 'err':
e.get_error_message()})
+
+ def _pool_used_by_template(self, pool_name):
+ with self.objstore as session:
+ templates = session.get_list('template')
+ for tmpl in templates:
+ t_info = session.get('template', tmpl)
+ t_pool = pool_name_from_uri(t_info['storagepool'])
+ if t_pool == pool_name:
+ return True
+ return False
+
+ def deactivate(self, name):
+ if self._pool_used_by_template(name):
+ raise InvalidOperation('KCHPOOL0034E', {'name': name})
+
+ pool = self.get_storagepool(name, self.conn)
+ # FIXME: nfs workaround - do not try to deactivate a NFS pool
+ # if the NFS server is not reachable.
+ xml = pool.XMLDesc(0)
+ pool_type = xpath_get_text(xml, "/pool/@type")[0]
+ if pool_type == 'netfs' and not self._nfs_status_online(pool):
+ # block the user from dactivating the pool.
+ source = self._get_storage_source(pool_type, xml)
+ raise OperationFailed("KCHPOOL0033E",
+ {'name': name, 'server':
source['addr']})
+ return
+ try:
+ persistent = pool.isPersistent()
+ pool.destroy()
+ except libvirt.libvirtError as e:
+ raise OperationFailed("KCHPOOL0010E",
+ {'name': name, 'err':
e.get_error_message()})
+ # If pool was not persistent, then it was erased by destroy() and
+ # must return nothing here, to trigger _redirect() and avoid errors
+ if not persistent:
+ return ""
+
+ def delete(self, name):
+ if self._pool_used_by_template(name):
+ raise InvalidOperation('KCHPOOL0035E', {'name': name})
+
+ pool = self.get_storagepool(name, self.conn)
+ if pool.isActive():
+ raise InvalidOperation("KCHPOOL0005E", {'name': name})
+ try:
+ pool.undefine()
+ except libvirt.libvirtError as e:
+ raise OperationFailed("KCHPOOL0011E",
+ {'name': name, 'err':
e.get_error_message()})
+
+
+class IsoPoolModel(object):
+ def __init__(self, **kargs):
+ pass
+
+ def lookup(self, name):
+ return {'state': 'active',
+ 'type': 'kimchi-iso'}
diff --git a/src/wok/plugins/kimchi/model/storageservers.py
b/src/wok/plugins/kimchi/model/storageservers.py
new file mode 100644
index 0000000..accc5f5
--- /dev/null
+++ b/src/wok/plugins/kimchi/model/storageservers.py
@@ -0,0 +1,81 @@
+#
+# Project Kimchi
+#
+# Copyright IBM, Corp. 2014
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+from wok.exception import NotFoundError
+
+from storagepools import StoragePoolModel, StoragePoolsModel
+
+# Types of remote storage servers supported
+STORAGE_SERVERS = ['netfs', 'iscsi']
+
+
+class StorageServersModel(object):
+ def __init__(self, **kargs):
+ self.conn = kargs['conn']
+ self.pool = StoragePoolModel(**kargs)
+ self.pools = StoragePoolsModel(**kargs)
+
+ def get_list(self, _target_type=None):
+ if not _target_type:
+ target_type = STORAGE_SERVERS
+ else:
+ target_type = [_target_type]
+
+ pools = self.pools.get_list()
+
+ server_list = []
+ for pool in pools:
+ try:
+ pool_info = self.pool.lookup(pool)
+ if (pool_info['type'] in target_type and
+ pool_info['source']['addr'] not in server_list):
+ # Avoid to add same server for multiple times
+ # if it hosts more than one storage type
+ server_list.append(pool_info['source']['addr'])
+ except NotFoundError:
+ pass
+
+ return server_list
+
+
+class StorageServerModel(object):
+ def __init__(self, **kargs):
+ self.conn = kargs['conn']
+ self.pool = StoragePoolModel(**kargs)
+
+ def lookup(self, server):
+ conn = self.conn.get()
+ pools = conn.listStoragePools()
+ pools += conn.listDefinedStoragePools()
+ for pool in pools:
+ try:
+ pool_info = self.pool.lookup(pool)
+ if (pool_info['type'] in STORAGE_SERVERS and
+ pool_info['source']['addr'] == server):
+ info = dict(host=server)
+ if (pool_info['type'] == "iscsi" and
+ 'port' in pool_info['source']):
+ info["port"] =
pool_info['source']['port']
+ return info
+ except NotFoundError:
+ # Avoid inconsistent pool result because of lease between list
+ # lookup
+ pass
+
+ raise NotFoundError("KCHSR0001E", {'server': server})
diff --git a/src/wok/plugins/kimchi/model/storagetargets.py
b/src/wok/plugins/kimchi/model/storagetargets.py
new file mode 100644
index 0000000..4090b45
--- /dev/null
+++ b/src/wok/plugins/kimchi/model/storagetargets.py
@@ -0,0 +1,122 @@
+#
+# Project Kimchi
+#
+# Copyright IBM, Corp. 2014
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+import libvirt
+import lxml.etree as ET
+from lxml import objectify
+from lxml.builder import E
+
+from wok.utils import patch_find_nfs_target, wok_log
+
+from config import CapabilitiesModel
+from storageservers import STORAGE_SERVERS
+
+
+class StorageTargetsModel(object):
+ def __init__(self, **kargs):
+ self.conn = kargs['conn']
+ self.caps = CapabilitiesModel(**kargs)
+
+ def get_list(self, storage_server, _target_type=None, _server_port=None):
+ target_list = list()
+ if not _target_type:
+ target_types = STORAGE_SERVERS
+ else:
+ target_types = [_target_type]
+
+ for target_type in target_types:
+ if not self.caps.nfs_target_probe and target_type == 'netfs':
+ targets = patch_find_nfs_target(storage_server)
+ else:
+ xml = self._get_storage_server_spec(server=storage_server,
+ target_type=target_type,
+ server_port=_server_port)
+ conn = self.conn.get()
+ try:
+ ret = conn.findStoragePoolSources(target_type, xml, 0)
+ except libvirt.libvirtError as e:
+ err = "Query storage pool source fails because of %s"
+ wok_log.warning(err, e.get_error_message())
+ continue
+
+ targets = self._parse_target_source_result(target_type, ret)
+
+ target_list.extend(targets)
+
+ # Get all netfs and iscsi paths in use
+ used_paths = []
+ try:
+ conn = self.conn.get()
+ # Get all existing ISCSI and NFS pools
+ pools = conn.listAllStoragePools(
+ libvirt.VIR_CONNECT_LIST_STORAGE_POOLS_ISCSI |
+ libvirt.VIR_CONNECT_LIST_STORAGE_POOLS_NETFS)
+ for pool in pools:
+ pool_xml = pool.XMLDesc(0)
+ root = objectify.fromstring(pool_xml)
+ if root.get('type') == 'netfs' and \
+ root.source.dir is not None:
+ used_paths.append(root.source.dir.get('path'))
+ elif root.get('type') == 'iscsi' and \
+ root.source.device is not None:
+ used_paths.append(root.source.device.get('path'))
+
+ except libvirt.libvirtError as e:
+ err = "Query storage pool source fails because of %s"
+ wok_log.warning(err, e.get_error_message())
+
+ # Filter target_list to not not show the used paths
+ target_list = [elem for elem in target_list
+ if elem.get('target') not in used_paths]
+ return [dict(t) for t in set(tuple(t.items()) for t in target_list)]
+
+ def _get_storage_server_spec(self, **kwargs):
+ # Required parameters:
+ # server:
+ # target_type:
+ extra_args = []
+ server_type = kwargs['target_type']
+ if server_type == 'netfs':
+ extra_args.append(E.format(type='nfs'))
+ else:
+ extra_args.append(E.format(type=server_type))
+
+ host_attr = {"name": kwargs['server']}
+ server_port = kwargs.get("server_port")
+ if server_port is not None:
+ host_attr['port'] = server_port
+
+ obj = E.source(E.host(host_attr), *extra_args)
+ xml = ET.tostring(obj)
+ return xml
+
+ def _parse_target_source_result(self, target_type, xml_str):
+ root = objectify.fromstring(xml_str)
+ ret = []
+ for source in root.getchildren():
+ if target_type == 'netfs':
+ target_path = source.dir.get('path')
+ type = source.format.get('type')
+ if target_type == 'iscsi':
+ target_path = source.device.get('path')
+ type = target_type
+ host_name = source.host.get('name')
+ ret.append(dict(host=host_name, target_type=type,
+ target=target_path))
+ return ret
diff --git a/src/wok/plugins/kimchi/model/storagevolumes.py
b/src/wok/plugins/kimchi/model/storagevolumes.py
new file mode 100644
index 0000000..99b17d3
--- /dev/null
+++ b/src/wok/plugins/kimchi/model/storagevolumes.py
@@ -0,0 +1,542 @@
+#
+# Project Kimchi
+#
+# Copyright IBM, Corp. 2014-2015
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+import contextlib
+import libvirt
+import lxml.etree as ET
+import os
+import tempfile
+import threading
+import time
+import urllib2
+from lxml.builder import E
+
+from wok.exception import InvalidOperation, InvalidParameter, IsoFormatError
+from wok.exception import MissingParameter, NotFoundError, OperationFailed
+from wok.utils import add_task, get_next_clone_name, get_unique_file_name
+from wok.utils import wok_log
+from wok.xmlutils.utils import xpath_get_text
+from wok.model.tasks import TaskModel
+
+from ..config import READONLY_POOL_TYPE
+from ..isoinfo import IsoImage
+from diskutils import get_disk_used_by, set_disk_used_by
+from storagepools import StoragePoolModel
+
+
+VOLUME_TYPE_MAP = {0: 'file',
+ 1: 'block',
+ 2: 'directory',
+ 3: 'network'}
+
+READ_CHUNK_SIZE = 1048576 # 1 MiB
+REQUIRE_NAME_PARAMS = ['capacity']
+
+upload_volumes = dict()
+
+
+class StorageVolumesModel(object):
+ def __init__(self, **kargs):
+ self.conn = kargs['conn']
+ self.objstore = kargs['objstore']
+ self.task = TaskModel(**kargs)
+
+ def create(self, pool_name, params):
+ vol_source = ['url', 'capacity']
+
+ name = params.get('name')
+
+ index_list = list(i for i in range(len(vol_source))
+ if vol_source[i] in params)
+ if len(index_list) != 1:
+ raise InvalidParameter("KCHVOL0018E",
+ {'param': ",".join(vol_source)})
+
+ create_param = vol_source[index_list[0]]
+
+ # Verify if the URL is valid
+ if create_param == 'url':
+ url = params['url']
+ try:
+ urllib2.urlopen(url).close()
+ except:
+ raise InvalidParameter('KCHVOL0022E', {'url': url})
+
+ all_vol_names = self.get_list(pool_name)
+
+ if name is None:
+ # the methods listed in 'REQUIRE_NAME_PARAMS' cannot have
+ # 'name' == None
+ if create_param in REQUIRE_NAME_PARAMS:
+ raise InvalidParameter('KCHVOL0016E')
+
+ # if 'name' is omitted - except for the methods listed in
+ # 'REQUIRE_NAME_PARAMS' - the default volume name will be the
+ # file/URL basename.
+ if create_param == 'url':
+ name = os.path.basename(params['url'])
+ else:
+ name = 'upload-%s' % int(time.time())
+
+ name = get_unique_file_name(all_vol_names, name)
+ params['name'] = name
+
+ try:
+ create_func = getattr(self, '_create_volume_with_%s' %
+ create_param)
+ except AttributeError:
+ raise InvalidParameter("KCHVOL0019E", {'param':
create_param})
+
+ pool_info = StoragePoolModel(conn=self.conn,
+ objstore=self.objstore).lookup(pool_name)
+ if pool_info['type'] in READONLY_POOL_TYPE:
+ raise InvalidParameter("KCHVOL0012E", {'type':
pool_info['type']})
+ if pool_info['state'] == 'inactive':
+ raise InvalidParameter('KCHVOL0003E', {'pool': pool_name,
+ 'volume': name})
+ if name in all_vol_names:
+ raise InvalidParameter('KCHVOL0001E', {'name': name})
+
+ params['pool'] = pool_name
+ targeturi = '/plugins/kimchi/storagepools/%s/storagevolumes/%s' \
+ % (pool_name, name)
+ taskid = add_task(targeturi, create_func, self.objstore, params)
+ return self.task.lookup(taskid)
+
+ def _create_volume_with_capacity(self, cb, params):
+ pool_name = params.pop('pool')
+ vol_xml = """
+ <volume>
+ <name>%(name)s</name>
+ <allocation unit='bytes'>%(allocation)s</allocation>
+ <capacity unit='bytes'>%(capacity)s</capacity>
+ <source>
+ </source>
+ <target>
+ <format type='%(format)s'/>
+ </target>
+ </volume>
+ """
+ params.setdefault('allocation', 0)
+ params.setdefault('format', 'qcow2')
+
+ name = params['name']
+ try:
+ pool = StoragePoolModel.get_storagepool(pool_name, self.conn)
+ xml = vol_xml % params
+ except KeyError, item:
+ raise MissingParameter("KCHVOL0004E", {'item': str(item),
+ 'volume': name})
+
+ try:
+ pool.createXML(xml, 0)
+ except libvirt.libvirtError as e:
+ raise OperationFailed("KCHVOL0007E",
+ {'name': name, 'pool': pool,
+ 'err': e.get_error_message()})
+
+ vol_info = StorageVolumeModel(conn=self.conn,
+ objstore=self.objstore).lookup(pool_name,
+ name)
+
+ vol_path = vol_info['path']
+ set_disk_used_by(self.objstore, vol_info['path'], [])
+
+ if params.get('upload', False):
+ upload_volumes[vol_path] = {'lock': threading.Lock(),
+ 'offset': 0, 'cb': cb}
+ cb('ready for upload')
+ else:
+ cb('OK', True)
+
+ def _create_volume_with_url(self, cb, params):
+ pool_name = params['pool']
+ name = params['name']
+ url = params['url']
+
+ pool_model = StoragePoolModel(conn=self.conn,
+ objstore=self.objstore)
+ pool = pool_model.lookup(pool_name)
+
+ if pool['type'] in ['dir', 'netfs']:
+ file_path = os.path.join(pool['path'], name)
+ else:
+ file_path = tempfile.mkstemp(prefix=name)[1]
+
+ with contextlib.closing(urllib2.urlopen(url)) as response:
+ with open(file_path, 'w') as volume_file:
+ remote_size = response.info().getheader('Content-Length',
'-')
+ downloaded_size = 0
+
+ try:
+ while True:
+ chunk_data = response.read(READ_CHUNK_SIZE)
+ if not chunk_data:
+ break
+
+ volume_file.write(chunk_data)
+ downloaded_size += len(chunk_data)
+ cb('%s/%s' % (downloaded_size, remote_size))
+ except (IOError, libvirt.libvirtError) as e:
+ if os.path.isfile(file_path):
+ os.remove(file_path)
+
+ raise OperationFailed('KCHVOL0007E', {'name': name,
+ 'pool': pool_name,
+ 'err': e.message})
+
+ if pool['type'] in ['dir', 'netfs']:
+ virt_pool = StoragePoolModel.get_storagepool(pool_name, self.conn)
+ virt_pool.refresh(0)
+ else:
+ def _stream_handler(stream, nbytes, fd):
+ return fd.read(nbytes)
+
+ virt_stream = virt_vol = None
+
+ try:
+ task = self.create(pool_name, {'name': name,
+ 'format': 'raw',
+ 'capacity': downloaded_size,
+ 'allocation': downloaded_size})
+ self.task.wait(task['id'])
+ virt_vol = StorageVolumeModel.get_storagevolume(pool_name,
+ name,
+ self.conn)
+
+ virt_stream = self.conn.get().newStream(0)
+ virt_vol.upload(virt_stream, 0, downloaded_size, 0)
+
+ with open(file_path) as fd:
+ virt_stream.sendAll(_stream_handler, fd)
+
+ virt_stream.finish()
+ except (IOError, libvirt.libvirtError) as e:
+ try:
+ if virt_stream:
+ virt_stream.abort()
+ if virt_vol:
+ virt_vol.delete(0)
+ except libvirt.libvirtError, virt_e:
+ wok_log.error(virt_e.message)
+ finally:
+ raise OperationFailed('KCHVOL0007E', {'name': name,
+ 'pool': pool_name,
+ 'err': e.message})
+ finally:
+ os.remove(file_path)
+
+ vol_info = StorageVolumeModel(conn=self.conn,
+ objstore=self.objstore).lookup(pool_name,
+ name)
+ set_disk_used_by(self.objstore, vol_info['path'], [])
+
+ cb('OK', True)
+
+ def get_list(self, pool_name):
+ pool = StoragePoolModel.get_storagepool(pool_name, self.conn)
+ if not pool.isActive():
+ raise InvalidOperation("KCHVOL0006E", {'pool': pool_name})
+ try:
+ pool.refresh(0)
+ return sorted(map(lambda x: x.decode('utf-8'), pool.listVolumes()))
+ except libvirt.libvirtError as e:
+ raise OperationFailed("KCHVOL0008E",
+ {'pool': pool_name,
+ 'err': e.get_error_message()})
+
+
+class StorageVolumeModel(object):
+ def __init__(self, **kargs):
+ self.conn = kargs['conn']
+ self.objstore = kargs['objstore']
+ self.task = TaskModel(**kargs)
+ self.storagevolumes = StorageVolumesModel(**kargs)
+ self.storagepool = StoragePoolModel(**kargs)
+
+ @staticmethod
+ def get_storagevolume(poolname, name, conn):
+ pool = StoragePoolModel.get_storagepool(poolname, conn)
+ if not pool.isActive():
+ raise InvalidOperation("KCHVOL0006E", {'name': pool})
+ try:
+ return pool.storageVolLookupByName(name.encode("utf-8"))
+ except libvirt.libvirtError as e:
+ if e.get_error_code() == libvirt.VIR_ERR_NO_STORAGE_VOL:
+ raise NotFoundError("KCHVOL0002E", {'name': name,
+ 'pool': poolname})
+ else:
+ raise
+
+ def lookup(self, pool, name):
+ vol = StorageVolumeModel.get_storagevolume(pool, name, self.conn)
+ path = vol.path()
+ info = vol.info()
+ xml = vol.XMLDesc(0)
+ try:
+ fmt = xpath_get_text(xml, "/volume/target/format/@type")[0]
+ except IndexError:
+ # Not all types of libvirt storage can provide volume format
+ # infomation. When there is no format information, we assume
+ # it's 'raw'.
+ fmt = 'raw'
+
+ iso_img = None
+
+ # 'raw' volumes from 'logical' pools may actually be
'iso';
+ # libvirt always reports them as 'raw'
+ pool_info = self.storagepool.lookup(pool)
+ if pool_info['type'] == 'logical' and fmt == 'raw':
+ try:
+ iso_img = IsoImage(path)
+ except IsoFormatError:
+ # not 'iso' afterall
+ pass
+ else:
+ fmt = 'iso'
+
+ used_by = get_disk_used_by(self.objstore, self.conn, path)
+ res = dict(type=VOLUME_TYPE_MAP[info[0]],
+ capacity=info[1],
+ allocation=info[2],
+ path=path,
+ used_by=used_by,
+ format=fmt)
+ if fmt == 'iso':
+ if os.path.islink(path):
+ path = os.path.join(os.path.dirname(path), os.readlink(path))
+ os_distro = os_version = 'unknown'
+ try:
+ if iso_img is None:
+ iso_img = IsoImage(path)
+ os_distro, os_version = iso_img.probe()
+ bootable = True
+ except IsoFormatError:
+ bootable = False
+ res.update(
+ dict(os_distro=os_distro, os_version=os_version, path=path,
+ bootable=bootable))
+ return res
+
+ def wipe(self, pool, name):
+ volume = StorageVolumeModel.get_storagevolume(pool, name, self.conn)
+ try:
+ volume.wipePattern(libvirt.VIR_STORAGE_VOL_WIPE_ALG_ZERO, 0)
+ except libvirt.libvirtError as e:
+ raise OperationFailed("KCHVOL0009E",
+ {'name': name, 'err':
e.get_error_message()})
+
+ def delete(self, pool, name):
+ pool_info = StoragePoolModel(conn=self.conn,
+ objstore=self.objstore).lookup(pool)
+ if pool_info['type'] in READONLY_POOL_TYPE:
+ raise InvalidParameter("KCHVOL0012E", {'type':
pool_info['type']})
+
+ volume = StorageVolumeModel.get_storagevolume(pool, name, self.conn)
+ try:
+ volume.delete(0)
+ except libvirt.libvirtError as e:
+ raise OperationFailed("KCHVOL0010E",
+ {'name': name, 'err':
e.get_error_message()})
+
+ def resize(self, pool, name, size):
+ volume = StorageVolumeModel.get_storagevolume(pool, name, self.conn)
+
+ # When decreasing the storage volume capacity, the flag
+ # VIR_STORAGE_VOL_RESIZE_SHRINK must be used
+ flags = 0
+ if volume.info()[1] > size:
+ # FIXME: Even using VIR_STORAGE_VOL_RESIZE_SHRINK flag it is not
+ # possible to decrease the volume capacity due a libvirt bug
+ # For reference:
+ # -
https://bugzilla.redhat.com/show_bug.cgi?id=1021802
+ flags = libvirt.VIR_STORAGE_VOL_RESIZE_SHRINK
+
+ try:
+ volume.resize(size, flags)
+ except libvirt.libvirtError as e:
+ raise OperationFailed("KCHVOL0011E",
+ {'name': name, 'err':
e.get_error_message()})
+
+ def clone(self, pool, name, new_pool=None, new_name=None):
+ """Clone a storage volume.
+
+ Arguments:
+ pool -- The name of the original pool.
+ name -- The name of the original volume.
+ new_pool -- The name of the destination pool (optional). If omitted,
+ the new volume will be created on the same pool as the
+ original one.
+ new_name -- The name of the new volume (optional). If omitted, a new
+ value based on the original volume's name will be used.
+
+ Return:
+ A Task running the clone operation.
+ """
+ # the same pool will be used if no pool is specified
+ if new_pool is None:
+ new_pool = pool
+
+ # a default name based on the original name will be used if no name
+ # is specified
+ if new_name is None:
+ base, ext = os.path.splitext(name)
+ new_name = get_next_clone_name(self.storagevolumes.get_list(pool),
+ base, ext)
+
+ params = {'pool': pool,
+ 'name': name,
+ 'new_pool': new_pool,
+ 'new_name': new_name}
+ taskid = add_task(u'/plugins/kimchi/storagepools/%s/storagevolumes/%s'
+ % (pool, new_name), self._clone_task, self.objstore,
+ params)
+ return self.task.lookup(taskid)
+
+ def _clone_task(self, cb, params):
+ """Asynchronous function which performs the clone operation.
+
+ This function copies all the data inside the original volume into the
+ new one.
+
+ Arguments:
+ cb -- A callback function to signal the Task's progress.
+ params -- A dict with the following values:
+ "pool": The name of the original pool.
+ "name": The name of the original volume.
+ "new_pool": The name of the destination pool.
+ "new_name": The name of the new volume.
+ """
+ orig_pool_name = params['pool']
+ orig_vol_name = params['name']
+ new_pool_name = params['new_pool']
+ new_vol_name = params['new_name']
+
+ try:
+ cb('setting up volume cloning')
+ orig_vir_vol = StorageVolumeModel.get_storagevolume(orig_pool_name,
+ orig_vol_name,
+ self.conn)
+ orig_vol = self.lookup(orig_pool_name, orig_vol_name)
+ new_vir_pool = StoragePoolModel.get_storagepool(new_pool_name,
+ self.conn)
+
+ cb('building volume XML')
+ root_elem = E.volume()
+ root_elem.append(E.name(new_vol_name))
+ root_elem.append(E.capacity(unicode(orig_vol['capacity']),
+ unit='bytes'))
+ target_elem = E.target()
+ target_elem.append(E.format(type=orig_vol['format']))
+ root_elem.append(target_elem)
+ new_vol_xml = ET.tostring(root_elem, encoding='utf-8',
+ pretty_print=True)
+
+ cb('cloning volume')
+ new_vir_pool.createXMLFrom(new_vol_xml, orig_vir_vol, 0)
+ except (InvalidOperation, NotFoundError, libvirt.libvirtError), e:
+ raise OperationFailed('KCHVOL0023E',
+ {'name': orig_vol_name,
+ 'pool': orig_pool_name,
+ 'err': e.get_error_message()})
+
+ new_vol = self.lookup(new_pool_name, new_vol_name)
+ cb('adding volume to the object store')
+ set_disk_used_by(self.objstore, new_vol['path'], [])
+
+ cb('OK', True)
+
+ def doUpload(self, cb, vol, offset, data, data_size):
+ try:
+ st = self.conn.get().newStream(0)
+ vol.upload(st, offset, data_size)
+ st.send(data)
+ st.finish()
+ except Exception as e:
+ st and st.abort()
+ cb('', False)
+
+ try:
+ vol.delete(0)
+ except Exception as e:
+ pass
+
+ raise OperationFailed("KCHVOL0029E", {"err": e.message})
+
+ def update(self, pool, name, params):
+ chunk_data = params['chunk'].fullvalue()
+ chunk_size = int(params['chunk_size'])
+
+ if len(chunk_data) != chunk_size:
+ raise OperationFailed("KCHVOL0026E")
+
+ vol = StorageVolumeModel.get_storagevolume(pool, name, self.conn)
+ vol_path = vol.path()
+ vol_capacity = vol.info()[1]
+
+ vol_data = upload_volumes.get(vol_path)
+ if vol_data is None:
+ raise OperationFailed("KCHVOL0027E", {"vol": vol_path})
+
+ cb = vol_data['cb']
+ lock = vol_data['lock']
+ with lock:
+ offset = vol_data['offset']
+ if (offset + chunk_size) > vol_capacity:
+ raise OperationFailed("KCHVOL0028E")
+
+ cb('%s/%s' % (offset, vol_capacity))
+ self.doUpload(cb, vol, offset, chunk_data, chunk_size)
+ cb('%s/%s' % (offset + chunk_size, vol_capacity))
+
+ vol_data['offset'] += chunk_size
+ if vol_data['offset'] == vol_capacity:
+ del upload_volumes[vol_path]
+ cb('OK', True)
+
+
+class IsoVolumesModel(object):
+ def __init__(self, **kargs):
+ self.conn = kargs['conn']
+ self.storagevolume = StorageVolumeModel(**kargs)
+
+ def get_list(self):
+ iso_volumes = []
+ conn = self.conn.get()
+ pools = conn.listStoragePools()
+ pools += conn.listDefinedStoragePools()
+
+ for pool_name in pools:
+ try:
+ pool = StoragePoolModel.get_storagepool(pool_name, self.conn)
+ pool.refresh(0)
+ volumes = pool.listVolumes()
+ except Exception, e:
+ # Skip inactive pools
+ wok_log.debug("Shallow scan: skipping pool %s because of "
+ "error: %s", (pool_name, e.message))
+ continue
+
+ for volume in volumes:
+ res = self.storagevolume.lookup(pool_name,
+ volume.decode("utf-8"))
+ if res['format'] == 'iso' and res['bootable']:
+ res['name'] = '%s' % volume
+ iso_volumes.append(res)
+ return iso_volumes
diff --git a/src/wok/plugins/kimchi/model/templates.py
b/src/wok/plugins/kimchi/model/templates.py
new file mode 100644
index 0000000..4f0b204
--- /dev/null
+++ b/src/wok/plugins/kimchi/model/templates.py
@@ -0,0 +1,303 @@
+#
+# Project Kimchi
+#
+# Copyright IBM, Corp. 2014-2015
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+import copy
+import libvirt
+import os
+import stat
+
+from wok.exception import InvalidOperation, InvalidParameter
+from wok.exception import NotFoundError, OperationFailed
+from wok.utils import probe_file_permission_as_user, run_setfacl_set_attr
+from wok.xmlutils.utils import xpath_get_text
+
+from ..kvmusertests import UserTests
+from ..utils import pool_name_from_uri
+from ..vmtemplate import VMTemplate
+from cpuinfo import CPUInfoModel
+
+
+class TemplatesModel(object):
+ def __init__(self, **kargs):
+ self.objstore = kargs['objstore']
+ self.conn = kargs['conn']
+
+ def create(self, params):
+ name = params.get('name', '').strip()
+ iso = params.get('cdrom')
+ # check search permission
+ if iso and iso.startswith('/') and os.path.exists(iso):
+ st_mode = os.stat(iso).st_mode
+ if stat.S_ISREG(st_mode) or stat.S_ISBLK(st_mode):
+ user = UserTests().probe_user()
+ run_setfacl_set_attr(iso, user=user)
+ ret, excp = probe_file_permission_as_user(iso, user)
+ if ret is False:
+ raise InvalidParameter('KCHISO0008E',
+ {'filename': iso, 'user':
user,
+ 'err': excp})
+
+ cpu_info = params.get('cpu_info')
+ if cpu_info:
+ topology = cpu_info.get('topology')
+ # Check, even though currently only topology
+ # is supported.
+ if topology:
+ sockets = topology['sockets']
+ cores = topology['cores']
+ threads = topology['threads']
+ if params.get('cpus') is None:
+ params['cpus'] = sockets * cores * threads
+ # check_topoology will raise the appropriate
+ # exception if a topology is invalid.
+ CPUInfoModel(conn=self.conn).\
+ check_topology(params['cpus'], topology)
+
+ conn = self.conn.get()
+ pool_uri = params.get(u'storagepool', '')
+ if pool_uri:
+ try:
+ pool_name = pool_name_from_uri(pool_uri)
+ pool = conn.storagePoolLookupByName(pool_name.encode("utf-8"))
+ except Exception:
+ raise InvalidParameter("KCHTMPL0004E", {'pool':
pool_uri,
+ 'template': name})
+
+ tmp_volumes = [disk['volume'] for disk in params.get('disks',
[])
+ if 'volume' in disk]
+ self.template_volume_validate(tmp_volumes, pool)
+
+ for net_name in params.get(u'networks', []):
+ try:
+ conn.networkLookupByName(net_name.encode('utf-8'))
+ except Exception:
+ raise InvalidParameter("KCHTMPL0003E", {'network':
net_name,
+ 'template': name})
+ # Creates the template class with necessary information
+ # Checkings will be done while creating this class, so any exception
+ # will be raised here
+ t = LibvirtVMTemplate(params, scan=True, conn=self.conn)
+ name = params['name']
+ try:
+ with self.objstore as session:
+ if name in session.get_list('template'):
+ raise InvalidOperation("KCHTMPL0001E", {'name':
name})
+ session.store('template', name, t.info)
+ except InvalidOperation:
+ raise
+ except Exception, e:
+ raise OperationFailed('KCHTMPL0020E', {'err': e.message})
+
+ return name
+
+ def get_list(self):
+ with self.objstore as session:
+ return session.get_list('template')
+
+ def template_volume_validate(self, tmp_volumes, pool):
+ kwargs = {'conn': self.conn, 'objstore': self.objstore}
+ pool_type = xpath_get_text(pool.XMLDesc(0), "/pool/@type")[0]
+ pool_name = unicode(pool.name(), 'utf-8')
+
+ # as we discussion, we do not mix disks from 2 different types of
+ # storage pools, for instance: we do not create a template with 2
+ # disks, where one comes from a SCSI pool and other is a .img in
+ # a DIR pool.
+ if pool_type in ['iscsi', 'scsi']:
+ if not tmp_volumes:
+ raise InvalidParameter("KCHTMPL0018E")
+
+ storagevolumes = __import__("kimchi.model.storagevolumes",
+ fromlist=[''])
+ pool_volumes = storagevolumes.StorageVolumesModel(
+ **kwargs).get_list(pool_name)
+ vols = set(tmp_volumes) - set(pool_volumes)
+ if vols:
+ raise InvalidParameter("KCHTMPL0019E", {'pool':
pool_name,
+ 'volume': vols})
+
+
+class TemplateModel(object):
+ def __init__(self, **kargs):
+ self.objstore = kargs['objstore']
+ self.conn = kargs['conn']
+ self.templates = TemplatesModel(**kargs)
+
+ @staticmethod
+ def get_template(name, objstore, conn, overrides=None):
+ with objstore as session:
+ params = session.get('template', name)
+ if overrides:
+ params.update(overrides)
+ return LibvirtVMTemplate(params, False, conn)
+
+ def lookup(self, name):
+ t = self.get_template(name, self.objstore, self.conn)
+ return t.validate_integrity()
+
+ def clone(self, name):
+ # set default name
+ subfixs = [v[len(name):] for v in self.templates.get_list()
+ if v.startswith(name)]
+ indexs = [int(v.lstrip("-clone")) for v in subfixs
+ if v.startswith("-clone") and
+ v.lstrip("-clone").isdigit()]
+ indexs.sort()
+ index = "1" if not indexs else str(indexs[-1] + 1)
+ clone_name = name + "-clone" + index
+
+ temp = self.lookup(name)
+ temp['name'] = clone_name
+ ident = self.templates.create(temp)
+ return ident
+
+ def delete(self, name):
+ try:
+ with self.objstore as session:
+ session.delete('template', name)
+ except NotFoundError:
+ raise
+ except Exception as e:
+ raise OperationFailed('KCHTMPL0021E', {'err': e.message})
+
+ def update(self, name, params):
+ old_t = self.lookup(name)
+ new_t = copy.copy(old_t)
+ new_t.update(params)
+
+ if not self._validate_updated_cpu_params(new_t):
+ raise InvalidParameter('KCHTMPL0025E')
+
+ ident = name
+
+ conn = self.conn.get()
+ pool_uri = new_t.get(u'storagepool', '')
+
+ if pool_uri:
+ try:
+ pool_name = pool_name_from_uri(pool_uri)
+ pool = conn.storagePoolLookupByName(pool_name.encode("utf-8"))
+ except Exception:
+ raise InvalidParameter("KCHTMPL0004E", {'pool':
pool_uri,
+ 'template': name})
+ tmp_volumes = [disk['volume'] for disk in new_t.get('disks',
[])
+ if 'volume' in disk]
+ self.templates.template_volume_validate(tmp_volumes, pool)
+
+ for net_name in params.get(u'networks', []):
+ try:
+ conn.networkLookupByName(net_name.encode('utf-8'))
+ except Exception:
+ raise InvalidParameter("KCHTMPL0003E", {'network':
net_name,
+ 'template': name})
+
+ self.delete(name)
+ try:
+ ident = self.templates.create(new_t)
+ except:
+ ident = self.templates.create(old_t)
+ raise
+ return ident
+
+ def _validate_updated_cpu_params(self, info):
+ # Note: cpu_info is the parent of topology. cpus is vcpus
+ vcpus = info['cpus']
+ cpu_info = info.get('cpu_info')
+ # cpu_info will always be at least an empty dict
+ topology = cpu_info.get('topology')
+ if topology is None:
+ return True
+ return vcpus == topology['sockets'] * topology['cores'] * \
+ topology['threads']
+
+
+class LibvirtVMTemplate(VMTemplate):
+ def __init__(self, args, scan=False, conn=None):
+ self.conn = conn
+ VMTemplate.__init__(self, args, scan)
+
+ def _storage_validate(self):
+ pool_uri = self.info['storagepool']
+ pool_name = pool_name_from_uri(pool_uri)
+ try:
+ conn = self.conn.get()
+ pool = conn.storagePoolLookupByName(pool_name.encode("utf-8"))
+ except libvirt.libvirtError:
+ raise InvalidParameter("KCHTMPL0004E", {'pool': pool_uri,
+ 'template': self.name})
+
+ if not pool.isActive():
+ raise InvalidParameter("KCHTMPL0005E", {'pool': pool_name,
+ 'template': self.name})
+
+ return pool
+
+ def _get_all_networks_name(self):
+ conn = self.conn.get()
+ return sorted(conn.listNetworks() + conn.listDefinedNetworks())
+
+ def _get_all_storagepools_name(self):
+ conn = self.conn.get()
+ names = conn.listStoragePools() + conn.listDefinedStoragePools()
+ return sorted(map(lambda x: x.decode('utf-8'), names))
+
+ def _network_validate(self):
+ names = self.info['networks']
+ for name in names:
+ try:
+ conn = self.conn.get()
+ network = conn.networkLookupByName(name.encode('utf-8'))
+ except libvirt.libvirtError:
+ raise InvalidParameter("KCHTMPL0003E", {'network':
name,
+ 'template': self.name})
+
+ if not network.isActive():
+ raise InvalidParameter("KCHTMPL0007E", {'network':
name,
+ 'template': self.name})
+
+ def _get_storage_path(self):
+ pool = self._storage_validate()
+ xml = pool.XMLDesc(0)
+ return xpath_get_text(xml, "/pool/target/path")[0]
+
+ def _get_storage_type(self):
+ pool = self._storage_validate()
+ xml = pool.XMLDesc(0)
+ return xpath_get_text(xml, "/pool/@type")[0]
+
+ def _get_volume_path(self, pool, vol):
+ pool = self._storage_validate()
+ try:
+ return pool.storageVolLookupByName(vol).path()
+ except:
+ raise NotFoundError("KCHVOL0002E", {'name': vol,
+ 'pool': pool})
+
+ def fork_vm_storage(self, vm_uuid):
+ # Provision storage:
+ # TODO: Rebase on the storage API once upstream
+ pool = self._storage_validate()
+ vol_list = self.to_volume_list(vm_uuid)
+ try:
+ for v in vol_list:
+ # outgoing text to libvirt, encode('utf-8')
+ pool.createXML(v['xml'].encode('utf-8'), 0)
+ except libvirt.libvirtError as e:
+ raise OperationFailed("KCHVMSTOR0008E", {'error':
e.message})
+ return vol_list
diff --git a/src/wok/plugins/kimchi/model/users.py
b/src/wok/plugins/kimchi/model/users.py
new file mode 100644
index 0000000..2fa65dd
--- /dev/null
+++ b/src/wok/plugins/kimchi/model/users.py
@@ -0,0 +1,90 @@
+#
+# Project Kimchi
+#
+# Copyright IBM, Corp. 2014
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+import ldap
+import pwd
+
+from wok.config import config
+from wok.exception import NotFoundError
+
+
+class UsersModel(object):
+ def __init__(self, **args):
+ auth_type = config.get("authentication", "method")
+ for klass in UsersModel.__subclasses__():
+ if auth_type == klass.auth_type:
+ self.user = klass(**args)
+
+ def get_list(self, **args):
+ return self.user._get_list(**args)
+
+ def validate(self, user):
+ return self.user._validate(user)
+
+
+class PAMUsersModel(UsersModel):
+ auth_type = 'pam'
+
+ def __init__(self, **kargs):
+ pass
+
+ def _get_list(self):
+ return [user.pw_name for user in pwd.getpwall()
+ if user.pw_shell.rsplit("/")[-1] not in ["nologin",
"false"]]
+
+ def _validate(self, user):
+ try:
+ return user in self._get_list()
+ except:
+ return False
+
+
+class LDAPUsersModel(UsersModel):
+ auth_type = 'ldap'
+
+ def __init__(self, **kargs):
+ pass
+
+ def _get_list(self, _user_id=''):
+ return self._get_user(_user_id)
+
+ def _validate(self, user):
+ try:
+ self._get_user(user)
+ return True
+ except NotFoundError:
+ return False
+
+ def _get_user(self, _user_id):
+ ldap_server = config.get("authentication",
"ldap_server").strip('"')
+ ldap_search_base = config.get(
+ "authentication",
"ldap_search_base").strip('"')
+ ldap_search_filter = config.get(
+ "authentication", "ldap_search_filter",
+ vars={"username":
_user_id.encode("utf-8")}).strip('"')
+
+ connect = ldap.open(ldap_server)
+ try:
+ result = connect.search_s(
+ ldap_search_base, ldap.SCOPE_SUBTREE, ldap_search_filter)
+ if len(result) == 0:
+ raise NotFoundError("KCHAUTH0004E", {'user_id':
_user_id})
+ return result[0][1]
+ except ldap.NO_SUCH_OBJECT:
+ raise NotFoundError("KCHAUTH0004E", {'user_id': _user_id})
diff --git a/src/wok/plugins/kimchi/model/utils.py
b/src/wok/plugins/kimchi/model/utils.py
new file mode 100644
index 0000000..53d719d
--- /dev/null
+++ b/src/wok/plugins/kimchi/model/utils.py
@@ -0,0 +1,161 @@
+#
+# Project Kimchi
+#
+# Copyright IBM, Corp. 2014-2015
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+import libvirt
+from lxml import etree, objectify
+from lxml.builder import E, ElementMaker
+
+from wok.exception import OperationFailed
+
+
+KIMCHI_META_URL = "https://github.com/kimchi-project/kimchi"
+KIMCHI_NAMESPACE = "kimchi"
+
+
+def get_vm_name(vm_name, t_name, name_list):
+ if vm_name:
+ return vm_name
+ for i in xrange(1, 1000):
+ # VM will have templace name, but without slashes
+ vm_name = "%s-vm-%i" % (t_name.replace('/', '-'), i)
+ if vm_name not in name_list:
+ return vm_name
+ raise OperationFailed("KCHUTILS0003E")
+
+
+def get_vm_config_flag(dom, mode="persistent"):
+ # libvirt.VIR_DOMAIN_AFFECT_CURRENT is 0
+ # VIR_DOMAIN_AFFECT_LIVE is 1, VIR_DOMAIN_AFFECT_CONFIG is 2
+ flag = {"live": libvirt.VIR_DOMAIN_AFFECT_LIVE,
+ "persistent": libvirt.VIR_DOMAIN_AFFECT_CONFIG,
+ "current": libvirt.VIR_DOMAIN_AFFECT_CURRENT,
+ "all": libvirt.VIR_DOMAIN_AFFECT_CONFIG +
+ libvirt.VIR_DOMAIN_AFFECT_LIVE if dom.isActive() and
+ dom.isPersistent() else libvirt.VIR_DOMAIN_AFFECT_CURRENT}
+
+ return flag[mode]
+
+
+# avoid duplicate codes
+def update_node(root, node):
+ old_node = root.find(node.tag)
+ (root.replace(old_node, node) if old_node is not None
+ else root.append(node))
+ return root
+
+
+def _kimchi_set_metadata_node(dom, node):
+ # some other tools will not let libvirt create a persistent
+ # configuration, raise exception.
+ if not dom.isPersistent():
+ msg = 'The VM has not a persistent configuration'
+ raise OperationFailed("KCHVM0030E",
+ {'name': dom.name(), "err": msg})
+ xml = dom.XMLDesc(libvirt.VIR_DOMAIN_XML_INACTIVE)
+ root = etree.fromstring(xml)
+ kimchi = root.find("metadata/{%s}kimchi" % KIMCHI_META_URL)
+
+ EM = ElementMaker(namespace=KIMCHI_META_URL,
+ nsmap={KIMCHI_NAMESPACE: KIMCHI_META_URL})
+ kimchi = EM("kimchi") if kimchi is None else kimchi
+
+ update_node(kimchi, node)
+ metadata = root.find("metadata")
+ metadata = E.metadata() if metadata is None else metadata
+ update_node(metadata, kimchi)
+ update_node(root, metadata)
+ dom.connect().defineXML(etree.tostring(root))
+
+
+def libvirt_get_kimchi_metadata_node(dom, mode="current"):
+ if not metadata_exists(dom):
+ return None
+ try:
+ xml = dom.metadata(libvirt.VIR_DOMAIN_METADATA_ELEMENT,
+ KIMCHI_META_URL,
+ flags=get_vm_config_flag(dom, mode))
+ return etree.fromstring(xml)
+ except libvirt.libvirtError:
+ return None
+
+
+def set_metadata_node(dom, node, metadata_support, mode="all"):
+ if metadata_support:
+ kimchi = libvirt_get_kimchi_metadata_node(dom, mode)
+ kimchi = E.metadata(E.kimchi()) if kimchi is None else kimchi
+
+ update_node(kimchi, node)
+ kimchi_xml = etree.tostring(kimchi)
+ # From libvirt doc, Passing None for @metadata says to remove that
+ # element from the domain XML (passing the empty string leaves the
+ # element present). Do not support remove the old metadata.
+ dom.setMetadata(libvirt.VIR_DOMAIN_METADATA_ELEMENT, kimchi_xml,
+ KIMCHI_NAMESPACE, KIMCHI_META_URL,
+ flags=get_vm_config_flag(dom, mode))
+ else:
+ # FIXME remove this code when all distro libvirt supports metadata
+ # element
+ _kimchi_set_metadata_node(dom, node)
+
+
+def _kimchi_get_metadata_node(dom, tag):
+ # some other tools will not let libvirt create a persistent
+ # configuration, just return empty
+ if not dom.isPersistent():
+ return None
+ xml = dom.XMLDesc(libvirt.VIR_DOMAIN_XML_INACTIVE)
+ root = etree.fromstring(xml)
+ kimchi = root.find("metadata/{%s}kimchi" % KIMCHI_META_URL)
+ # remove the "kimchi" prefix of xml
+ if kimchi is not None:
+ for elem in kimchi.getiterator():
+ if not hasattr(elem.tag, 'find'):
+ continue
+ i = elem.tag.find('}')
+ if i >= 0:
+ elem.tag = elem.tag[i+1:]
+
+ objectify.deannotate(kimchi)
+ etree.cleanup_namespaces(kimchi)
+ return kimchi
+ return None
+
+
+def get_metadata_node(dom, tag, metadata_support, mode="current"):
+ if metadata_support:
+ kimchi = libvirt_get_kimchi_metadata_node(dom, mode)
+ else:
+ # FIXME remove this code when all distro libvirt supports metadata
+ # element
+ kimchi = _kimchi_get_metadata_node(dom, tag)
+
+ if kimchi is not None:
+ node = kimchi.find(tag)
+ if node is not None:
+ return etree.tostring(node)
+ return ""
+
+
+def metadata_exists(dom):
+ xml = dom.XMLDesc(libvirt.VIR_DOMAIN_XML_INACTIVE)
+ root = etree.fromstring(xml)
+
+ if root.find("metadata") is None:
+ return False
+ return True
diff --git a/src/wok/plugins/kimchi/model/vmhostdevs.py
b/src/wok/plugins/kimchi/model/vmhostdevs.py
new file mode 100644
index 0000000..0cc6bd3
--- /dev/null
+++ b/src/wok/plugins/kimchi/model/vmhostdevs.py
@@ -0,0 +1,336 @@
+#
+# Project Kimchi
+#
+# Copyright IBM, Corp. 2014-2015
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+import glob
+import libvirt
+import os
+import platform
+from lxml import etree, objectify
+from lxml.builder import E
+
+from wok.exception import InvalidOperation, InvalidParameter, NotFoundError
+from wok.exception import OperationFailed
+from wok.rollbackcontext import RollbackContext
+from wok.utils import run_command, wok_log
+
+from config import CapabilitiesModel
+from host import DeviceModel, DevicesModel
+from utils import get_vm_config_flag
+from vms import DOM_STATE_MAP, VMModel
+
+
+class VMHostDevsModel(object):
+ def __init__(self, **kargs):
+ self.conn = kargs['conn']
+ self.caps = CapabilitiesModel(**kargs)
+
+ def get_list(self, vmid):
+ dom = VMModel.get_vm(vmid, self.conn)
+ xmlstr = dom.XMLDesc(0)
+ root = objectify.fromstring(xmlstr)
+ try:
+ hostdev = root.devices.hostdev
+ except AttributeError:
+ return []
+
+ return [self._deduce_dev_name(e) for e in hostdev]
+
+ @staticmethod
+ def _toint(num_str):
+ if num_str.startswith('0x'):
+ return int(num_str, 16)
+ elif num_str.startswith('0'):
+ return int(num_str, 8)
+ else:
+ return int(num_str)
+
+ def _deduce_dev_name(self, e):
+ return getattr(self, '_deduce_dev_name_%s' %
e.attrib['type'])(e)
+
+ def _deduce_dev_name_pci(self, e):
+ attrib = {}
+ for field in ('domain', 'bus', 'slot',
'function'):
+ attrib[field] = self._toint(e.source.address.attrib[field])
+ return 'pci_%(domain)04x_%(bus)02x_%(slot)02x_%(function)x' % attrib
+
+ def _deduce_dev_name_scsi(self, e):
+ attrib = {}
+ for field in ('bus', 'target', 'unit'):
+ attrib[field] = self._toint(e.source.address.attrib[field])
+ attrib['host'] = self._toint(
+ e.source.adapter.attrib['name'][len('scsi_host'):])
+ return 'scsi_%(host)d_%(bus)d_%(target)d_%(unit)d' % attrib
+
+ def _deduce_dev_name_usb(self, e):
+ dev_names = DevicesModel(conn=self.conn).get_list(_cap='usb_device')
+ usb_infos = [DeviceModel(conn=self.conn).lookup(dev_name)
+ for dev_name in dev_names]
+
+ unknown_dev = None
+
+ try:
+ evendor = self._toint(e.source.vendor.attrib['id'])
+ eproduct = self._toint(e.source.product.attrib['id'])
+ except AttributeError:
+ evendor = 0
+ eproduct = 0
+ else:
+ unknown_dev = 'usb_vendor_%s_product_%s' % (evendor, eproduct)
+
+ try:
+ ebus = self._toint(e.source.address.attrib['bus'])
+ edevice = self._toint(e.source.address.attrib['device'])
+ except AttributeError:
+ ebus = -1
+ edevice = -1
+ else:
+ unknown_dev = 'usb_bus_%s_device_%s' % (ebus, edevice)
+
+ for usb_info in usb_infos:
+ ivendor = self._toint(usb_info['vendor']['id'])
+ iproduct = self._toint(usb_info['product']['id'])
+ if evendor == ivendor and eproduct == iproduct:
+ return usb_info['name']
+ ibus = usb_info['bus']
+ idevice = usb_info['device']
+ if ebus == ibus and edevice == idevice:
+ return usb_info['name']
+ return unknown_dev
+
+ def _passthrough_device_validate(self, dev_name):
+ eligible_dev_names = \
+ DevicesModel(conn=self.conn).get_list(_passthrough='true')
+ if dev_name not in eligible_dev_names:
+ raise InvalidParameter('KCHVMHDEV0002E', {'dev_name':
dev_name})
+
+ def create(self, vmid, params):
+ dev_name = params['name']
+ self._passthrough_device_validate(dev_name)
+ dev_info = DeviceModel(conn=self.conn).lookup(dev_name)
+
+ with RollbackContext() as rollback:
+ try:
+ dev = self.conn.get().nodeDeviceLookupByName(dev_name)
+ dev.dettach()
+ except Exception:
+ raise OperationFailed('KCHVMHDEV0005E', {'name':
dev_name})
+ else:
+ rollback.prependDefer(dev.reAttach)
+
+ attach_device = getattr(
+ self, '_attach_%s_device' % dev_info['device_type'])
+
+ info = attach_device(vmid, dev_info)
+ rollback.commitAll()
+
+ return info
+
+ def _get_pci_device_xml(self, dev_info):
+ if 'detach_driver' not in dev_info:
+ dev_info['detach_driver'] = 'kvm'
+
+ source = E.source(E.address(domain=str(dev_info['domain']),
+ bus=str(dev_info['bus']),
+ slot=str(dev_info['slot']),
+ function=str(dev_info['function'])))
+ driver = E.driver(name=dev_info['detach_driver'])
+ host_dev = E.hostdev(source, driver,
+ mode='subsystem', type='pci',
managed='yes')
+
+ return etree.tostring(host_dev)
+
+ @staticmethod
+ def _validate_pci_passthrough_env():
+ # Linux kernel < 3.5 doesn't provide /sys/kernel/iommu_groups
+ if os.path.isdir('/sys/kernel/iommu_groups'):
+ if not glob.glob('/sys/kernel/iommu_groups/*'):
+ raise InvalidOperation("KCHVMHDEV0003E")
+
+ # Enable virt_use_sysfs on RHEL6 and older distributions
+ # In recent Fedora, there is no virt_use_sysfs.
+ out, err, rc = run_command(['getsebool', 'virt_use_sysfs'])
+ if rc == 0 and out.rstrip('\n') != "virt_use_sysfs --> on":
+ out, err, rc = run_command(['setsebool', '-P',
+ 'virt_use_sysfs=on'])
+ if rc != 0:
+ wok_log.warning("Unable to turn on sebool virt_use_sysfs")
+
+ def _attach_pci_device(self, vmid, dev_info):
+ self._validate_pci_passthrough_env()
+
+ dom = VMModel.get_vm(vmid, self.conn)
+ # Due to libvirt limitation, we don't support live assigne device to
+ # vfio driver.
+ driver = ('vfio' if DOM_STATE_MAP[dom.info()[0]] == "shutoff"
and
+ self.caps.kernel_vfio else 'kvm')
+
+ # on powerkvm systems it must be vfio driver.
+ distro, _, _ = platform.linux_distribution()
+ if distro == 'IBM_PowerKVM':
+ driver = 'vfio'
+
+ # Attach all PCI devices in the same IOMMU group
+ dev_model = DeviceModel(conn=self.conn)
+ devs_model = DevicesModel(conn=self.conn)
+ affected_names = devs_model.get_list(
+ _passthrough_affected_by=dev_info['name'])
+ passthrough_names = devs_model.get_list(
+ _cap='pci', _passthrough='true')
+ group_names = list(set(affected_names) & set(passthrough_names))
+ pci_infos = [dev_model.lookup(dev_name) for dev_name in group_names]
+ pci_infos.append(dev_info)
+
+ device_flags = get_vm_config_flag(dom, mode='all')
+
+ with RollbackContext() as rollback:
+ for pci_info in pci_infos:
+ pci_info['detach_driver'] = driver
+ xmlstr = self._get_pci_device_xml(pci_info)
+ try:
+ dom.attachDeviceFlags(xmlstr, device_flags)
+ except libvirt.libvirtError:
+ wok_log.error(
+ 'Failed to attach host device %s to VM %s: \n%s',
+ pci_info['name'], vmid, xmlstr)
+ raise
+ rollback.prependDefer(dom.detachDeviceFlags,
+ xmlstr, device_flags)
+ rollback.commitAll()
+
+ return dev_info['name']
+
+ def _get_scsi_device_xml(self, dev_info):
+ adapter = E.adapter(name=('scsi_host%s' % dev_info['host']))
+ address = E.address(type='scsi', bus=str(dev_info['bus']),
+ target=str(dev_info['target']),
+ unit=str(dev_info['lun']))
+ host_dev = E.hostdev(E.source(adapter, address),
+ mode='subsystem', type='scsi',
sgio='unfiltered')
+ return etree.tostring(host_dev)
+
+ def _attach_scsi_device(self, vmid, dev_info):
+ xmlstr = self._get_scsi_device_xml(dev_info)
+ dom = VMModel.get_vm(vmid, self.conn)
+ dom.attachDeviceFlags(xmlstr, get_vm_config_flag(dom, mode='all'))
+ return dev_info['name']
+
+ def _get_usb_device_xml(self, dev_info):
+ source = E.source(
+ E.vendor(id=dev_info['vendor']['id']),
+ E.product(id=dev_info['product']['id']),
+ E.address(bus=str(dev_info['bus']),
+ device=str(dev_info['device'])),
+ startupPolicy='optional')
+ host_dev = E.hostdev(source, mode='subsystem',
+ ype='usb', managed='yes')
+ return etree.tostring(host_dev)
+
+ def _attach_usb_device(self, vmid, dev_info):
+ xmlstr = self._get_usb_device_xml(dev_info)
+ dom = VMModel.get_vm(vmid, self.conn)
+ dom.attachDeviceFlags(xmlstr, get_vm_config_flag(dom, mode='all'))
+ return dev_info['name']
+
+
+class VMHostDevModel(object):
+ def __init__(self, **kargs):
+ self.conn = kargs['conn']
+
+ def lookup(self, vmid, dev_name):
+ dom = VMModel.get_vm(vmid, self.conn)
+ xmlstr = dom.XMLDesc(0)
+ root = objectify.fromstring(xmlstr)
+ try:
+ hostdev = root.devices.hostdev
+ except AttributeError:
+ raise NotFoundError('KCHVMHDEV0001E',
+ {'vmid': vmid, 'dev_name': dev_name})
+
+ devsmodel = VMHostDevsModel(conn=self.conn)
+
+ for e in hostdev:
+ deduced_name = devsmodel._deduce_dev_name(e)
+ if deduced_name == dev_name:
+ return {'name': dev_name, 'type':
e.attrib['type']}
+
+ raise NotFoundError('KCHVMHDEV0001E',
+ {'vmid': vmid, 'dev_name': dev_name})
+
+ def delete(self, vmid, dev_name):
+ dom = VMModel.get_vm(vmid, self.conn)
+ xmlstr = dom.XMLDesc(0)
+ root = objectify.fromstring(xmlstr)
+
+ try:
+ hostdev = root.devices.hostdev
+ except AttributeError:
+ raise NotFoundError('KCHVMHDEV0001E',
+ {'vmid': vmid, 'dev_name': dev_name})
+
+ devsmodel = VMHostDevsModel(conn=self.conn)
+ pci_devs = [(devsmodel._deduce_dev_name(e), e) for e in hostdev
+ if e.attrib['type'] == 'pci']
+
+ for e in hostdev:
+ if devsmodel._deduce_dev_name(e) == dev_name:
+ xmlstr = etree.tostring(e)
+ dom.detachDeviceFlags(
+ xmlstr, get_vm_config_flag(dom, mode='all'))
+ if e.attrib['type'] == 'pci':
+ self._delete_affected_pci_devices(dom, dev_name, pci_devs)
+ break
+ else:
+ raise NotFoundError('KCHVMHDEV0001E',
+ {'vmid': vmid, 'dev_name': dev_name})
+
+ def _delete_affected_pci_devices(self, dom, dev_name, pci_devs):
+ dev_model = DeviceModel(conn=self.conn)
+ try:
+ dev_model.lookup(dev_name)
+ except NotFoundError:
+ return
+
+ affected_names = set(
+ DevicesModel(
+ conn=self.conn).get_list(_passthrough_affected_by=dev_name))
+
+ for pci_name, e in pci_devs:
+ if pci_name in affected_names:
+ xmlstr = etree.tostring(e)
+ dom.detachDeviceFlags(
+ xmlstr, get_vm_config_flag(dom, mode='all'))
+
+
+class VMHoldersModel(object):
+ def __init__(self, **kargs):
+ self.conn = kargs['conn']
+
+ def get_list(self, device_id):
+ devsmodel = VMHostDevsModel(conn=self.conn)
+
+ conn = self.conn.get()
+ doms = conn.listAllDomains(0)
+
+ res = []
+ for dom in doms:
+ dom_name = dom.name()
+ if device_id in devsmodel.get_list(dom_name):
+ state = DOM_STATE_MAP[dom.info()[0]]
+ res.append({"name": dom_name, "state": state})
+ return res
diff --git a/src/wok/plugins/kimchi/model/vmifaces.py
b/src/wok/plugins/kimchi/model/vmifaces.py
new file mode 100644
index 0000000..87565c8
--- /dev/null
+++ b/src/wok/plugins/kimchi/model/vmifaces.py
@@ -0,0 +1,186 @@
+#
+# Project Kimchi
+#
+# Copyright IBM, Corp. 2014-2015
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+import libvirt
+import random
+from lxml import etree, objectify
+
+from wok.exception import InvalidParameter, MissingParameter
+from wok.exception import NotFoundError, InvalidOperation
+
+from ..xmlutils.interface import get_iface_xml
+from config import CapabilitiesModel
+from vms import DOM_STATE_MAP, VMModel
+
+
+class VMIfacesModel(object):
+ def __init__(self, **kargs):
+ self.conn = kargs['conn']
+ self.caps = CapabilitiesModel(**kargs)
+
+ def get_list(self, vm):
+ macs = []
+ for iface in self.get_vmifaces(vm, self.conn):
+ macs.append(iface.mac.get('address'))
+ return macs
+
+ def create(self, vm, params):
+ conn = self.conn.get()
+ networks = conn.listNetworks() + conn.listDefinedNetworks()
+ networks = map(lambda x: x.decode('utf-8'), networks)
+
+ if params['type'] == 'network':
+ network = params.get("network")
+
+ if network is None:
+ raise MissingParameter('KCHVMIF0007E')
+
+ if network not in networks:
+ raise InvalidParameter('KCHVMIF0002E',
+ {'name': vm, 'network': network})
+
+ macs = (iface.mac.get('address')
+ for iface in self.get_vmifaces(vm, self.conn))
+
+ # user defined customized mac address
+ if 'mac' in params and params['mac']:
+ # make sure it is unique
+ if params['mac'] in macs:
+ raise InvalidParameter('KCHVMIF0009E',
+ {'name': vm, 'mac':
params['mac']})
+
+ # otherwise choose a random mac address
+ else:
+ while True:
+ params['mac'] = VMIfacesModel.random_mac()
+ if params['mac'] not in macs:
+ break
+
+ dom = VMModel.get_vm(vm, self.conn)
+
+ os_data = VMModel.vm_get_os_metadata(dom, self.caps.metadata_support)
+ os_version, os_distro = os_data
+ xml = get_iface_xml(params, conn.getInfo()[0], os_distro, os_version)
+
+ flags = 0
+ if dom.isPersistent():
+ flags |= libvirt.VIR_DOMAIN_AFFECT_CONFIG
+ if DOM_STATE_MAP[dom.info()[0]] != "shutoff":
+ flags |= libvirt.VIR_DOMAIN_AFFECT_LIVE
+
+ dom.attachDeviceFlags(xml, flags)
+
+ return params['mac']
+
+ @staticmethod
+ def get_vmifaces(vm, conn):
+ dom = VMModel.get_vm(vm, conn)
+ xml = dom.XMLDesc(0)
+ root = objectify.fromstring(xml)
+
+ return root.devices.findall("interface")
+
+ @staticmethod
+ def random_mac():
+ mac = [0x52, 0x54, 0x00,
+ random.randint(0x00, 0x7f),
+ random.randint(0x00, 0xff),
+ random.randint(0x00, 0xff)]
+ return ':'.join(map(lambda x: u'%02x' % x, mac))
+
+
+class VMIfaceModel(object):
+ def __init__(self, **kargs):
+ self.conn = kargs['conn']
+
+ def _get_vmiface(self, vm, mac):
+ ifaces = VMIfacesModel.get_vmifaces(vm, self.conn)
+
+ for iface in ifaces:
+ if iface.mac.get('address') == mac:
+ return iface
+ return None
+
+ def lookup(self, vm, mac):
+ info = {}
+
+ iface = self._get_vmiface(vm, mac)
+ if iface is None:
+ raise NotFoundError("KCHVMIF0001E", {'name': vm,
'iface': mac})
+
+ info['type'] = iface.attrib['type']
+ info['mac'] = iface.mac.get('address')
+ if iface.find("model") is not None:
+ info['model'] = iface.model.get('type')
+ if info['type'] == 'network':
+ info['network'] = iface.source.get('network')
+ if info['type'] == 'bridge':
+ info['bridge'] = iface.source.get('bridge')
+
+ return info
+
+ def delete(self, vm, mac):
+ dom = VMModel.get_vm(vm, self.conn)
+ iface = self._get_vmiface(vm, mac)
+
+ if iface is None:
+ raise NotFoundError("KCHVMIF0001E", {'name': vm,
'iface': mac})
+
+ flags = 0
+ if dom.isPersistent():
+ flags |= libvirt.VIR_DOMAIN_AFFECT_CONFIG
+ if DOM_STATE_MAP[dom.info()[0]] != "shutoff":
+ flags |= libvirt.VIR_DOMAIN_AFFECT_LIVE
+
+ dom.detachDeviceFlags(etree.tostring(iface), flags)
+
+ def update(self, vm, mac, params):
+ dom = VMModel.get_vm(vm, self.conn)
+ iface = self._get_vmiface(vm, mac)
+
+ if iface is None:
+ raise NotFoundError("KCHVMIF0001E", {'name': vm,
'iface': mac})
+
+ # cannot change mac address in a running system
+ if DOM_STATE_MAP[dom.info()[0]] != "shutoff":
+ raise InvalidOperation('KCHVMIF0011E')
+
+ # mac address is a required parameter
+ if 'mac' not in params:
+ raise MissingParameter('KCHVMIF0008E')
+
+ # new mac address must be unique
+ if self._get_vmiface(vm, params['mac']) is not None:
+ raise InvalidParameter('KCHVMIF0009E',
+ {'name': vm, 'mac':
params['mac']})
+
+ flags = 0
+ if dom.isPersistent():
+ flags |= libvirt.VIR_DOMAIN_AFFECT_CONFIG
+
+ # remove the current nic
+ xml = etree.tostring(iface)
+ dom.detachDeviceFlags(xml, flags=flags)
+
+ # add the nic with the desired mac address
+ iface.mac.attrib['address'] = params['mac']
+ xml = etree.tostring(iface)
+ dom.attachDeviceFlags(xml, flags=flags)
+
+ return [vm, params['mac']]
diff --git a/src/wok/plugins/kimchi/model/vms.py b/src/wok/plugins/kimchi/model/vms.py
new file mode 100644
index 0000000..f37b5d6
--- /dev/null
+++ b/src/wok/plugins/kimchi/model/vms.py
@@ -0,0 +1,1307 @@
+#
+# Project Kimchi
+#
+# Copyright IBM, Corp. 2014-2015
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+import libvirt
+import lxml.etree as ET
+import os
+import random
+import string
+import time
+import uuid
+from lxml import etree, objectify
+from lxml.builder import E
+from xml.etree import ElementTree
+
+from wok.config import config
+from wok.exception import InvalidOperation, InvalidParameter
+from wok.exception import NotFoundError, OperationFailed
+from wok.rollbackcontext import RollbackContext
+from wok.utils import add_task, convert_data_size, get_next_clone_name
+from wok.utils import import_class, run_setfacl_set_attr, wok_log
+from wok.xmlutils.utils import xpath_get_text, xml_item_update
+from wok.xmlutils.utils import dictize
+from wok.model.tasks import TaskModel
+
+from .. import model
+from .. import vnc
+from ..config import READONLY_POOL_TYPE
+from ..kvmusertests import UserTests
+from ..screenshot import VMScreenshot
+from ..utils import template_name_from_uri
+from ..xmlutils.cpu import get_cpu_xml, get_numa_xml
+from config import CapabilitiesModel
+from templates import TemplateModel
+from utils import get_vm_name
+from utils import get_metadata_node
+from utils import set_metadata_node
+
+
+DOM_STATE_MAP = {0: 'nostate',
+ 1: 'running',
+ 2: 'blocked',
+ 3: 'paused',
+ 4: 'shutdown',
+ 5: 'shutoff',
+ 6: 'crashed',
+ 7: 'pmsuspended'}
+
+VM_STATIC_UPDATE_PARAMS = {'name': './name',
+ 'cpus': './vcpu'}
+VM_LIVE_UPDATE_PARAMS = {}
+
+XPATH_DOMAIN_DISK =
"/domain/devices/disk[@device='disk']/source/@file"
+XPATH_DOMAIN_DISK_BY_FILE =
"./devices/disk[@device='disk']/source[@file='%s']"
+XPATH_DOMAIN_NAME = '/domain/name'
+XPATH_DOMAIN_MAC =
"/domain/devices/interface[@type='network']/mac/@address"
+XPATH_DOMAIN_MAC_BY_ADDRESS = "./devices/interface[@type='network']/"\
+ "mac[@address='%s']"
+XPATH_DOMAIN_MEMORY = '/domain/memory'
+XPATH_DOMAIN_MEMORY_UNIT = '/domain/memory/@unit'
+XPATH_DOMAIN_UUID = '/domain/uuid'
+
+XPATH_NUMA_CELL = './cpu/numa/cell'
+
+
+class VMsModel(object):
+ def __init__(self, **kargs):
+ self.conn = kargs['conn']
+ self.objstore = kargs['objstore']
+ self.caps = CapabilitiesModel(**kargs)
+ self.task = TaskModel(**kargs)
+
+ def create(self, params):
+ t_name = template_name_from_uri(params['template'])
+ vm_list = self.get_list()
+ name = get_vm_name(params.get('name'), t_name, vm_list)
+ # incoming text, from js json, is unicode, do not need decode
+ if name in vm_list:
+ raise InvalidOperation("KCHVM0001E", {'name': name})
+
+ vm_overrides = dict()
+ pool_uri = params.get('storagepool')
+ if pool_uri:
+ vm_overrides['storagepool'] = pool_uri
+ vm_overrides['fc_host_support'] = self.caps.fc_host_support
+ t = TemplateModel.get_template(t_name, self.objstore, self.conn,
+ vm_overrides)
+
+ if not self.caps.qemu_stream and t.info.get('iso_stream', False):
+ raise InvalidOperation("KCHVM0005E")
+
+ t.validate()
+ data = {'name': name, 'template': t,
+ 'graphics': params.get('graphics', {})}
+ taskid = add_task(u'/plugins/kimchi/vms/%s' % name, self._create_task,
+ self.objstore, data)
+
+ return self.task.lookup(taskid)
+
+ def _create_task(self, cb, params):
+ """
+ params: A dict with the following values:
+ - vm_uuid: The UUID of the VM being created
+ - template: The template being used to create the VM
+ - name: The name for the new VM
+ """
+ vm_uuid = str(uuid.uuid4())
+ t = params['template']
+ name = params['name']
+ conn = self.conn.get()
+
+ cb('Storing VM icon')
+ # Store the icon for displaying later
+ icon = t.info.get('icon')
+ if icon:
+ try:
+ with self.objstore as session:
+ session.store('vm', vm_uuid, {'icon': icon})
+ except Exception as e:
+ # It is possible to continue Kimchi executions without store
+ # vm icon info
+ wok_log.error('Error trying to update database with guest '
+ 'icon information due error: %s', e.message)
+
+ # If storagepool is SCSI, volumes will be LUNs and must be passed by
+ # the user from UI or manually.
+ cb('Provisioning storage for new VM')
+ vol_list = []
+ if t._get_storage_type() not in ["iscsi", "scsi"]:
+ vol_list = t.fork_vm_storage(vm_uuid)
+
+ graphics = params.get('graphics', {})
+ stream_protocols = self.caps.libvirt_stream_protocols
+ xml = t.to_vm_xml(name, vm_uuid,
+ libvirt_stream_protocols=stream_protocols,
+ graphics=graphics,
+ volumes=vol_list)
+
+ cb('Defining new VM')
+ try:
+ conn.defineXML(xml.encode('utf-8'))
+ except libvirt.libvirtError as e:
+ if t._get_storage_type() not in READONLY_POOL_TYPE:
+ for v in vol_list:
+ vol = conn.storageVolLookupByPath(v['path'])
+ vol.delete(0)
+ raise OperationFailed("KCHVM0007E", {'name': name,
+ 'err': e.get_error_message()})
+
+ cb('Updating VM metadata')
+ VMModel.vm_update_os_metadata(VMModel.get_vm(name, self.conn), t.info,
+ self.caps.metadata_support)
+ cb('OK', True)
+
+ def get_list(self):
+ return VMsModel.get_vms(self.conn)
+
+ @staticmethod
+ def get_vms(conn):
+ conn_ = conn.get()
+ names = [dom.name().decode('utf-8') for dom in conn_.listAllDomains(0)]
+ names = sorted(names, key=unicode.lower)
+ return names
+
+
+class VMModel(object):
+ def __init__(self, **kargs):
+ self.conn = kargs['conn']
+ self.objstore = kargs['objstore']
+ self.caps = CapabilitiesModel(**kargs)
+ self.vmscreenshot = VMScreenshotModel(**kargs)
+ self.users = import_class(
+ 'plugins.kimchi.model.users.UsersModel'
+ )(**kargs)
+ self.groups = import_class(
+ 'plugins.kimchi.model.groups.GroupsModel'
+ )(**kargs)
+ self.vms = VMsModel(**kargs)
+ self.task = TaskModel(**kargs)
+ self.storagepool = model.storagepools.StoragePoolModel(**kargs)
+ self.storagevolume = model.storagevolumes.StorageVolumeModel(**kargs)
+ self.storagevolumes = model.storagevolumes.StorageVolumesModel(**kargs)
+ cls = import_class('plugins.kimchi.model.vmsnapshots.VMSnapshotModel')
+ self.vmsnapshot = cls(**kargs)
+ cls = import_class('plugins.kimchi.model.vmsnapshots.VMSnapshotsModel')
+ self.vmsnapshots = cls(**kargs)
+ self.stats = {}
+
+ def update(self, name, params):
+ dom = self.get_vm(name, self.conn)
+ dom = self._static_vm_update(dom, params)
+ self._live_vm_update(dom, params)
+ return dom.name().decode('utf-8')
+
+ def clone(self, name):
+ """Clone a virtual machine based on an existing one.
+
+ The new virtual machine will have the exact same configuration as the
+ original VM, except for the name, UUID, MAC addresses and disks. The
+ name will have the form "<name>-clone-<number>", with
<number> starting
+ at 1; the UUID will be generated randomly; the MAC addresses will be
+ generated randomly with no conflicts within the original and the new
+ VM; and the disks will be new volumes [mostly] on the same storage
+ pool, with the same content as the original disks. The storage pool
+ 'default' will always be used when cloning SCSI and iSCSI disks and
+ when the original storage pool cannot hold the new volume.
+
+ An exception will be raised if the virtual machine <name> is not
+ shutoff, if there is no available space to copy a new volume to the
+ storage pool 'default' (when there was also no space to copy it to the
+ original storage pool) and if one of the virtual machine's disks belong
+ to a storage pool not supported by Kimchi.
+
+ Parameters:
+ name -- The name of the existing virtual machine to be cloned.
+
+ Return:
+ A Task running the clone operation.
+ """
+ name = name.decode('utf-8')
+
+ # VM must be shutoff in order to clone it
+ info = self.lookup(name)
+ if info['state'] != u'shutoff':
+ raise InvalidParameter('KCHVM0033E', {'name': name})
+
+ # the new VM's name will be used as the Task's 'target_uri' so it
needs
+ # to be defined now.
+
+ vms_being_created = []
+
+ # lookup names of VMs being created right now
+ with self.objstore as session:
+ task_names = session.get_list('task')
+ for tn in task_names:
+ t = session.get('task', tn)
+ if t['target_uri'].startswith('/plugins/kimchi/vms/'):
+ uri_name =
t['target_uri'].lstrip('/plugins/kimchi/vms/')
+ vms_being_created.append(uri_name)
+
+ current_vm_names = self.vms.get_list() + vms_being_created
+ new_name = get_next_clone_name(current_vm_names, name)
+
+ # create a task with the actual clone function
+ taskid = add_task(u'/plugins/kimchi/vms/%s/clone' % new_name,
+ self._clone_task, self.objstore,
+ {'name': name, 'new_name': new_name})
+
+ return self.task.lookup(taskid)
+
+ def _clone_task(self, cb, params):
+ """Asynchronous function which performs the clone operation.
+
+ Parameters:
+ cb -- A callback function to signal the Task's progress.
+ params -- A dict with the following values:
+ "name": the name of the original VM.
+ "new_name": the name of the new VM.
+ """
+ name = params['name']
+ new_name = params['new_name']
+ vir_conn = self.conn.get()
+
+ # fetch base XML
+ cb('reading source VM XML')
+ try:
+ vir_dom = vir_conn.lookupByName(name)
+ flags = libvirt.VIR_DOMAIN_XML_SECURE
+ xml = vir_dom.XMLDesc(flags).decode('utf-8')
+ except libvirt.libvirtError, e:
+ raise OperationFailed('KCHVM0035E', {'name': name,
+ 'err': e.message})
+
+ # update UUID
+ cb('updating VM UUID')
+ old_uuid = xpath_get_text(xml, XPATH_DOMAIN_UUID)[0]
+ new_uuid = unicode(uuid.uuid4())
+ xml = xml_item_update(xml, './uuid', new_uuid)
+
+ # update MAC addresses
+ cb('updating VM MAC addresses')
+ xml = self._clone_update_mac_addresses(xml)
+
+ with RollbackContext() as rollback:
+ # copy disks
+ cb('copying VM disks')
+ xml = self._clone_update_disks(xml, rollback)
+
+ # update objstore entry
+ cb('updating object store')
+ self._clone_update_objstore(old_uuid, new_uuid, rollback)
+
+ # update name
+ cb('updating VM name')
+ xml = xml_item_update(xml, './name', new_name)
+
+ # create new guest
+ cb('defining new VM')
+ try:
+ vir_conn.defineXML(xml)
+ except libvirt.libvirtError, e:
+ raise OperationFailed('KCHVM0035E', {'name': name,
+ 'err': e.message})
+
+ rollback.commitAll()
+
+ cb('OK', True)
+
+ @staticmethod
+ def _clone_update_mac_addresses(xml):
+ """Update the MAC addresses with new values in the XML descriptor
of a
+ cloning domain.
+
+ The new MAC addresses will be generated randomly, and their values are
+ guaranteed to be distinct from the ones in the original VM.
+
+ Arguments:
+ xml -- The XML descriptor of the original domain.
+
+ Return:
+ The XML descriptor <xml> with the new MAC addresses instead of the
+ old ones.
+ """
+ old_macs = xpath_get_text(xml, XPATH_DOMAIN_MAC)
+ new_macs = []
+
+ for mac in old_macs:
+ while True:
+ new_mac = model.vmifaces.VMIfacesModel.random_mac()
+ # make sure the new MAC doesn't conflict with the original VM
+ # and with the new values on the new VM.
+ if new_mac not in (old_macs + new_macs):
+ new_macs.append(new_mac)
+ break
+
+ xml = xml_item_update(xml, XPATH_DOMAIN_MAC_BY_ADDRESS % mac,
+ new_mac, 'address')
+
+ return xml
+
+ def _clone_update_disks(self, xml, rollback):
+ """Clone disks from a virtual machine. The disks are copied as
new
+ volumes and the new VM's XML is updated accordingly.
+
+ Arguments:
+ xml -- The XML descriptor of the original VM + new value for
+ "/domain/uuid".
+ rollback -- A rollback context so the new volumes can be removed if an
+ error occurs during the cloning operation.
+
+ Return:
+ The XML descriptor <xml> with the new disk paths instead of the
+ old ones.
+ """
+ # the UUID will be used to create the disk paths
+ uuid = xpath_get_text(xml, XPATH_DOMAIN_UUID)[0]
+ all_paths = xpath_get_text(xml, XPATH_DOMAIN_DISK)
+
+ vir_conn = self.conn.get()
+
+ def _delete_disk_from_objstore(path):
+ with self.objstore as session:
+ session.delete('storagevolume', path)
+
+ domain_name = xpath_get_text(xml, XPATH_DOMAIN_NAME)[0]
+
+ for i, path in enumerate(all_paths):
+ try:
+ vir_orig_vol = vir_conn.storageVolLookupByPath(path)
+ vir_pool = vir_orig_vol.storagePoolLookupByVolume()
+
+ orig_pool_name = vir_pool.name().decode('utf-8')
+ orig_vol_name = vir_orig_vol.name().decode('utf-8')
+ except libvirt.libvirtError, e:
+ raise OperationFailed('KCHVM0035E', {'name':
domain_name,
+ 'err': e.message})
+
+ orig_pool = self.storagepool.lookup(orig_pool_name)
+ orig_vol = self.storagevolume.lookup(orig_pool_name, orig_vol_name)
+
+ new_pool_name = orig_pool_name
+ new_pool = orig_pool
+
+ if orig_pool['type'] in ['dir', 'netfs',
'logical']:
+ # if a volume in a pool 'dir', 'netfs' or
'logical' cannot hold
+ # a new volume with the same size, the pool 'default' should
+ # be used
+ if orig_vol['capacity'] > orig_pool['available']:
+ wok_log.warning('storage pool \'%s\' doesn\'t have
'
+ 'enough free space to store image '
+ '\'%s\'; falling back to
\'default\'',
+ orig_pool_name, path)
+ new_pool_name = u'default'
+ new_pool = self.storagepool.lookup(u'default')
+
+ # ...and if even the pool 'default' cannot hold a new
+ # volume, raise an exception
+ if orig_vol['capacity'] > new_pool['available']:
+ domain_name = xpath_get_text(xml, XPATH_DOMAIN_NAME)[0]
+ raise InvalidOperation('KCHVM0034E',
+ {'name': domain_name})
+
+ elif orig_pool['type'] in ['scsi', 'iscsi']:
+ # SCSI and iSCSI always fall back to the storage pool 'default'
+ wok_log.warning('cannot create new volume for clone in '
+ 'storage pool \'%s\'; falling back to '
+ '\'default\'', orig_pool_name)
+ new_pool_name = u'default'
+ new_pool = self.storagepool.lookup(u'default')
+
+ # if the pool 'default' cannot hold a new volume, raise
+ # an exception
+ if orig_vol['capacity'] > new_pool['available']:
+ domain_name = xpath_get_text(xml, XPATH_DOMAIN_NAME)[0]
+ raise InvalidOperation('KCHVM0034E', {'name':
domain_name})
+
+ else:
+ # unexpected storage pool type
+ raise InvalidOperation('KCHPOOL0014E',
+ {'type': orig_pool['type']})
+
+ # new volume name: <UUID>-<loop-index>.<original
extension>
+ # e.g. 1234-5678-9012-3456-0.img
+ ext = os.path.splitext(path)[1]
+ new_vol_name = u'%s-%d%s' % (uuid, i, ext)
+ task = self.storagevolume.clone(orig_pool_name, orig_vol_name,
+ new_name=new_vol_name)
+ self.task.wait(task['id'], 3600) # 1 h
+
+ # get the new volume path and update the XML descriptor
+ new_vol = self.storagevolume.lookup(new_pool_name, new_vol_name)
+ xml = xml_item_update(xml, XPATH_DOMAIN_DISK_BY_FILE % path,
+ new_vol['path'], 'file')
+
+ # set the new disk's used_by
+ with self.objstore as session:
+ session.store('storagevolume', new_vol['path'],
+ {'used_by': [domain_name]})
+ rollback.prependDefer(_delete_disk_from_objstore, new_vol['path'])
+
+ # remove the new volume should an error occur later
+ rollback.prependDefer(self.storagevolume.delete, new_pool_name,
+ new_vol_name)
+
+ return xml
+
+ def _clone_update_objstore(self, old_uuid, new_uuid, rollback):
+ """Update Kimchi's object store with the cloning VM.
+
+ Arguments:
+ old_uuid -- The UUID of the original VM.
+ new_uuid -- The UUID of the new, clonning VM.
+ rollback -- A rollback context so the object store entry can be removed
+ if an error occurs during the cloning operation.
+ """
+ with self.objstore as session:
+ try:
+ vm = session.get('vm', old_uuid)
+ icon = vm['icon']
+ session.store('vm', new_uuid, {'icon': icon})
+ except NotFoundError:
+ # if we cannot find an object store entry for the original VM,
+ # don't store one with an empty value.
+ pass
+ else:
+ # we need to define a custom function to prepend to the
+ # rollback context because the object store session needs to be
+ # opened and closed correctly (i.e. "prependDefer" only
+ # accepts one command at a time but we need more than one to
+ # handle an object store).
+ def _rollback_objstore():
+ with self.objstore as session_rb:
+ session_rb.delete('vm', new_uuid, ignore_missing=True)
+
+ # remove the new object store entry should an error occur later
+ rollback.prependDefer(_rollback_objstore)
+
+ def _build_access_elem(self, dom, users, groups):
+ auth = config.get("authentication", "method")
+ access_xml = get_metadata_node(dom, "access",
+ self.caps.metadata_support)
+
+ auth_elem = None
+
+ if not access_xml:
+ # there is no metadata element 'access'
+ access_elem = E.access()
+ else:
+ access_elem = ET.fromstring(access_xml)
+
+ same_auth = access_elem.xpath('./auth[@type="%s"]' % auth)
+ if len(same_auth) > 0:
+ # there is already a sub-element 'auth' with the same type;
+ # update it.
+ auth_elem = same_auth[0]
+
+ if users is not None:
+ for u in auth_elem.findall('user'):
+ auth_elem.remove(u)
+
+ if groups is not None:
+ for g in auth_elem.findall('group'):
+ auth_elem.remove(g)
+
+ if auth_elem is None:
+ # there is no sub-element 'auth' with the same type
+ # (or no 'auth' at all); create it.
+ auth_elem = E.auth(type=auth)
+ access_elem.append(auth_elem)
+
+ if users is not None:
+ for u in users:
+ auth_elem.append(E.user(u))
+
+ if groups is not None:
+ for g in groups:
+ auth_elem.append(E.group(g))
+
+ return access_elem
+
+ def _vm_update_access_metadata(self, dom, params):
+ users = groups = None
+ if "users" in params:
+ users = params["users"]
+ for user in users:
+ if not self.users.validate(user):
+ raise InvalidParameter("KCHVM0027E",
+ {'users': user})
+ if "groups" in params:
+ groups = params["groups"]
+ for group in groups:
+ if not self.groups.validate(group):
+ raise InvalidParameter("KCHVM0028E",
+ {'groups': group})
+
+ if users is None and groups is None:
+ return
+
+ node = self._build_access_elem(dom, users, groups)
+ set_metadata_node(dom, node, self.caps.metadata_support)
+
+ def _get_access_info(self, dom):
+ users = groups = list()
+ access_xml = (get_metadata_node(dom, "access",
+ self.caps.metadata_support) or
+ """<access></access>""")
+ access_info = dictize(access_xml)
+ auth = config.get("authentication", "method")
+ if ('auth' in access_info['access'] and
+ ('type' in access_info['access']['auth'] or
+ len(access_info['access']['auth']) > 1)):
+ users = xpath_get_text(access_xml,
+ "/access/auth[@type='%s']/user" %
auth)
+ groups = xpath_get_text(access_xml,
+ "/access/auth[@type='%s']/group" %
auth)
+ elif auth == 'pam':
+ # Compatible to old permission tagging
+ users = xpath_get_text(access_xml, "/access/user")
+ groups = xpath_get_text(access_xml, "/access/group")
+ return users, groups
+
+ @staticmethod
+ def vm_get_os_metadata(dom, metadata_support):
+ os_xml = (get_metadata_node(dom, "os", metadata_support) or
+ """<os></os>""")
+ os_elem = ET.fromstring(os_xml)
+ return (os_elem.attrib.get("version"),
os_elem.attrib.get("distro"))
+
+ @staticmethod
+ def vm_update_os_metadata(dom, params, metadata_support):
+ distro = params.get("os_distro")
+ version = params.get("os_version")
+ if distro is None:
+ return
+ os_elem = E.os({"distro": distro, "version": version})
+ set_metadata_node(dom, os_elem, metadata_support)
+
+ def _update_graphics(self, dom, xml, params):
+ root = objectify.fromstring(xml)
+ graphics = root.devices.find("graphics")
+ if graphics is None:
+ return xml
+
+ password = params['graphics'].get("passwd")
+ if password is not None and len(password.strip()) == 0:
+ password = "".join(random.sample(string.ascii_letters +
+ string.digits, 8))
+
+ if password is not None:
+ graphics.attrib['passwd'] = password
+
+ expire = params['graphics'].get("passwdValidTo")
+ to = graphics.attrib.get('passwdValidTo')
+ if to is not None:
+ if (time.mktime(time.strptime(to, '%Y-%m-%dT%H:%M:%S')) -
+ time.time() <= 0):
+ expire = expire if expire is not None else 30
+
+ if expire is not None:
+ expire_time = time.gmtime(time.time() + float(expire))
+ valid_to = time.strftime('%Y-%m-%dT%H:%M:%S', expire_time)
+ graphics.attrib['passwdValidTo'] = valid_to
+
+ if not dom.isActive():
+ return ET.tostring(root, encoding="utf-8")
+
+ xml = dom.XMLDesc(libvirt.VIR_DOMAIN_XML_SECURE)
+ dom.updateDeviceFlags(etree.tostring(graphics),
+ libvirt.VIR_DOMAIN_AFFECT_LIVE)
+ return xml
+
+ def _backup_snapshots(self, snap, all_info):
+ """ Append "snap" and the children of "snap"
to the list "all_info".
+
+ The list *must* always contain the parent snapshots before their
+ children so the function "_redefine_snapshots" can work correctly.
+
+ Arguments:
+ snap -- a native domain snapshot.
+ all_info -- a list of dict keys:
+ "{'xml': <snap XML>, 'current': <is snap
current?>'}"
+ """
+ all_info.append({'xml': snap.getXMLDesc(0),
+ 'current': snap.isCurrent(0)})
+
+ for child in snap.listAllChildren(0):
+ self._backup_snapshots(child, all_info)
+
+ def _redefine_snapshots(self, dom, all_info):
+ """ Restore the snapshots stored in "all_info" to the
domain "dom".
+
+ Arguments:
+ dom -- the domain which will have its snapshots restored.
+ all_info -- a list of dict keys, as described in "_backup_snapshots",
+ containing the original snapshot information.
+ """
+ for info in all_info:
+ flags = libvirt.VIR_DOMAIN_SNAPSHOT_CREATE_REDEFINE
+
+ if info['current']:
+ flags |= libvirt.VIR_DOMAIN_SNAPSHOT_CREATE_CURRENT
+
+ dom.snapshotCreateXML(info['xml'], flags)
+
+ def _static_vm_update(self, dom, params):
+ old_xml = new_xml = dom.XMLDesc(0)
+
+ for key, val in params.items():
+ if key in VM_STATIC_UPDATE_PARAMS:
+ if type(val) == int:
+ val = str(val)
+ xpath = VM_STATIC_UPDATE_PARAMS[key]
+ new_xml = xml_item_update(new_xml, xpath, val)
+
+ # Updating memory and NUMA if necessary, if vm is offline
+ if not dom.isActive():
+ if 'memory' in params:
+ new_xml = self._update_memory_config(new_xml, params)
+ elif 'cpus' in params and \
+ (xpath_get_text(new_xml, XPATH_NUMA_CELL + '/@memory') != []):
+ vcpus = params['cpus']
+ new_xml = xml_item_update(
+ new_xml,
+ XPATH_NUMA_CELL,
+ value='0-' + str(vcpus - 1) if vcpus > 1 else
'0',
+ attr='cpus')
+
+ if 'graphics' in params:
+ new_xml = self._update_graphics(dom, new_xml, params)
+
+ snapshots_info = []
+ vm_name = dom.name()
+ conn = self.conn.get()
+ try:
+ if 'name' in params:
+ state = DOM_STATE_MAP[dom.info()[0]]
+ if state != 'shutoff':
+ msg_args = {'name': vm_name, 'new_name':
params['name']}
+ raise InvalidParameter("KCHVM0003E", msg_args)
+
+ lflags = libvirt.VIR_DOMAIN_SNAPSHOT_LIST_ROOTS
+ dflags = (libvirt.VIR_DOMAIN_SNAPSHOT_DELETE_CHILDREN |
+ libvirt.VIR_DOMAIN_SNAPSHOT_DELETE_METADATA_ONLY)
+
+ for virt_snap in dom.listAllSnapshots(lflags):
+ snapshots_info.append({'xml': virt_snap.getXMLDesc(0),
+ 'current': virt_snap.isCurrent(0)})
+ self._backup_snapshots(virt_snap, snapshots_info)
+
+ virt_snap.delete(dflags)
+
+ # Undefine old vm, only if name is going to change
+ dom.undefine()
+
+ dom = conn.defineXML(new_xml)
+ if 'name' in params:
+ self._redefine_snapshots(dom, snapshots_info)
+ except libvirt.libvirtError as e:
+ dom = conn.defineXML(old_xml)
+ if 'name' in params:
+ self._redefine_snapshots(dom, snapshots_info)
+
+ raise OperationFailed("KCHVM0008E", {'name': vm_name,
+ 'err': e.get_error_message()})
+ return dom
+
+ def _update_memory_config(self, xml, params):
+ # Checks if NUMA memory is already configured, if not, checks if CPU
+ # element is already configured (topology). Then add NUMA element as
+ # apropriated
+ root = ET.fromstring(xml)
+ numa_mem = xpath_get_text(xml, XPATH_NUMA_CELL + '/@memory')
+ vcpus = params.get('cpus')
+ if numa_mem == []:
+ if vcpus is None:
+ vcpus = int(xpath_get_text(xml,
+ VM_STATIC_UPDATE_PARAMS['cpus'])[0])
+ cpu = root.find('./cpu')
+ if cpu is None:
+ cpu = get_cpu_xml(vcpus, params['memory'] << 10)
+ root.insert(0, ET.fromstring(cpu))
+ else:
+ numa_element = get_numa_xml(vcpus, params['memory'] << 10)
+ cpu.insert(0, ET.fromstring(numa_element))
+ else:
+ if vcpus is not None:
+ xml = xml_item_update(
+ xml,
+ XPATH_NUMA_CELL,
+ value='0-' + str(vcpus - 1) if vcpus > 1 else
'0',
+ attr='cpus')
+ root = ET.fromstring(xml_item_update(xml, XPATH_NUMA_CELL,
+ str(params['memory'] <<
10),
+ attr='memory'))
+
+ # Remove currentMemory, automatically set later by libvirt
+ currentMem = root.find('.currentMemory')
+ if currentMem is not None:
+ root.remove(currentMem)
+
+ memory = root.find('.memory')
+ # Update/Adds maxMemory accordingly
+ if not self.caps.mem_hotplug_support:
+ if memory is not None:
+ memory.text = str(params['memory'] << 10)
+ else:
+ if memory is not None:
+ root.remove(memory)
+ maxMem = root.find('.maxMemory')
+ host_mem = self.conn.get().getInfo()[1]
+ slots = (host_mem - params['memory']) >> 10
+ # Libvirt does not accepts slots <= 1
+ if slots < 0:
+ raise OperationFailed("KCHVM0041E")
+ elif slots == 0:
+ slots = 1
+ if maxMem is None:
+ max_mem_xml = E.maxMemory(
+ str(host_mem * 1024),
+ unit='Kib',
+ slots=str(slots))
+ root.insert(0, max_mem_xml)
+ new_xml = ET.tostring(root, encoding="utf-8")
+ else:
+ # Update slots only
+ new_xml = xml_item_update(ET.tostring(root, encoding="utf-8"),
+ './maxMemory',
+ str(slots),
+ attr='slots')
+ return new_xml
+ return ET.tostring(root, encoding="utf-8")
+
+ def _live_vm_update(self, dom, params):
+ self._vm_update_access_metadata(dom, params)
+ if 'memory' in params and dom.isActive():
+ self._update_memory_live(dom, params)
+
+ def _update_memory_live(self, dom, params):
+ # Check if host supports memory device
+ if not self.caps.mem_hotplug_support:
+ raise InvalidOperation("KCHVM0046E")
+
+ # Check if the vm xml supports memory hotplug, if not, static update
+ # must be done firstly, then Kimchi is going to update the xml
+ xml = dom.XMLDesc(0)
+ numa_mem = xpath_get_text(xml, XPATH_NUMA_CELL + '/@memory')
+ max_mem = xpath_get_text(xml, './maxMemory')
+ if numa_mem == [] or max_mem == []:
+ raise OperationFailed('KCHVM0042E', {'name': dom.name()})
+
+ # Memory live update must be done in chunks of 1024 Mib or 1Gib
+ new_mem = params['memory']
+ old_mem = int(xpath_get_text(xml, XPATH_DOMAIN_MEMORY)[0]) >> 10
+ if new_mem < old_mem:
+ raise OperationFailed('KCHVM0043E')
+ if (new_mem - old_mem) % 1024 != 0:
+ raise OperationFailed('KCHVM0044E')
+
+ # Check slot spaces:
+ total_slots = int(xpath_get_text(xml, './maxMemory/@slots')[0])
+ needed_slots = (new_mem - old_mem) / 1024
+ used_slots = len(xpath_get_text(xml, './devices/memory'))
+ if needed_slots > (total_slots - used_slots):
+ raise OperationFailed('KCHVM0045E')
+ elif needed_slots == 0:
+ # New memory value is same that current memory set
+ return
+
+ # Finally, we are ok to hot add the memory devices
+ try:
+ self._hot_add_memory_devices(dom, needed_slots)
+ except Exception as e:
+ raise OperationFailed("KCHVM0047E", {'error': e.message})
+
+ def _hot_add_memory_devices(self, dom, amount):
+ # Hot add given number of memory devices in the guest
+ flags = libvirt.VIR_DOMAIN_MEM_CONFIG | libvirt.VIR_DOMAIN_MEM_LIVE
+ # Create memory device xml
+ mem_dev_xml = etree.tostring(
+ E.memory(
+ E.target(
+ E.size('1', unit='GiB'),
+ E.node('0')),
+ model='dimm'))
+ # Add chunks of 1G of memory
+ for i in range(amount):
+ dom.attachDeviceFlags(mem_dev_xml, flags)
+
+ def _has_video(self, dom):
+ dom = ElementTree.fromstring(dom.XMLDesc(0))
+ return dom.find('devices/video') is not None
+
+ def _update_guest_stats(self, name):
+ try:
+ dom = VMModel.get_vm(name, self.conn)
+
+ vm_uuid = dom.UUIDString()
+ info = dom.info()
+ state = DOM_STATE_MAP[info[0]]
+
+ if state != 'running':
+ self.stats[vm_uuid] = {}
+ return
+
+ if self.stats.get(vm_uuid, None) is None:
+ self.stats[vm_uuid] = {}
+
+ timestamp = time.time()
+ prevStats = self.stats.get(vm_uuid, {})
+ seconds = timestamp - prevStats.get('timestamp', 0)
+ self.stats[vm_uuid].update({'timestamp': timestamp})
+
+ self._get_percentage_cpu_usage(vm_uuid, info, seconds)
+ self._get_network_io_rate(vm_uuid, dom, seconds)
+ self._get_disk_io_rate(vm_uuid, dom, seconds)
+ except Exception as e:
+ # VM might be deleted just after we get the list.
+ # This is OK, just skip.
+ wok_log.debug('Error processing VM stats: %s', e.message)
+
+ def _get_percentage_cpu_usage(self, vm_uuid, info, seconds):
+ prevCpuTime = self.stats[vm_uuid].get('cputime', 0)
+
+ cpus = info[3]
+ cpuTime = info[4] - prevCpuTime
+
+ base = (((cpuTime) * 100.0) / (seconds * 1000.0 * 1000.0 * 1000.0))
+ percentage = max(0.0, min(100.0, base / cpus))
+
+ self.stats[vm_uuid].update({'cputime': info[4], 'cpu':
percentage})
+
+ def _get_network_io_rate(self, vm_uuid, dom, seconds):
+ prevNetRxKB = self.stats[vm_uuid].get('netRxKB', 0)
+ prevNetTxKB = self.stats[vm_uuid].get('netTxKB', 0)
+ currentMaxNetRate = self.stats[vm_uuid].get('max_net_io', 100)
+
+ rx_bytes = 0
+ tx_bytes = 0
+
+ tree = ElementTree.fromstring(dom.XMLDesc(0))
+ for target in tree.findall('devices/interface/target'):
+ dev = target.get('dev')
+ io = dom.interfaceStats(dev)
+ rx_bytes += io[0]
+ tx_bytes += io[4]
+
+ netRxKB = float(rx_bytes) / 1000
+ netTxKB = float(tx_bytes) / 1000
+
+ rx_stats = (netRxKB - prevNetRxKB) / seconds
+ tx_stats = (netTxKB - prevNetTxKB) / seconds
+
+ rate = rx_stats + tx_stats
+ max_net_io = round(max(currentMaxNetRate, int(rate)), 1)
+
+ self.stats[vm_uuid].update({'net_io': rate, 'max_net_io':
max_net_io,
+ 'netRxKB': netRxKB, 'netTxKB':
netTxKB})
+
+ def _get_disk_io_rate(self, vm_uuid, dom, seconds):
+ prevDiskRdKB = self.stats[vm_uuid].get('diskRdKB', 0)
+ prevDiskWrKB = self.stats[vm_uuid].get('diskWrKB', 0)
+ currentMaxDiskRate = self.stats[vm_uuid].get('max_disk_io', 100)
+
+ rd_bytes = 0
+ wr_bytes = 0
+
+ tree = ElementTree.fromstring(dom.XMLDesc(0))
+ for target in tree.findall("devices/disk/target"):
+ dev = target.get("dev")
+ io = dom.blockStats(dev)
+ rd_bytes += io[1]
+ wr_bytes += io[3]
+
+ diskRdKB = float(rd_bytes) / 1024
+ diskWrKB = float(wr_bytes) / 1024
+
+ rd_stats = (diskRdKB - prevDiskRdKB) / seconds
+ wr_stats = (diskWrKB - prevDiskWrKB) / seconds
+
+ rate = rd_stats + wr_stats
+ max_disk_io = round(max(currentMaxDiskRate, int(rate)), 1)
+
+ self.stats[vm_uuid].update({'disk_io': rate,
+ 'max_disk_io': max_disk_io,
+ 'diskRdKB': diskRdKB,
+ 'diskWrKB': diskWrKB})
+
+ def lookup(self, name):
+ dom = self.get_vm(name, self.conn)
+ info = dom.info()
+ state = DOM_STATE_MAP[info[0]]
+ screenshot = None
+ # (type, listen, port, passwd, passwdValidTo)
+ graphics = self._vm_get_graphics(name)
+ graphics_port = graphics[2]
+ graphics_port = graphics_port if state == 'running' else None
+ try:
+ if state == 'running' and self._has_video(dom):
+ screenshot = self.vmscreenshot.lookup(name)
+ elif state == 'shutoff':
+ # reset vm stats when it is powered off to avoid sending
+ # incorrect (old) data
+ self.stats[dom.UUIDString()] = {}
+ except NotFoundError:
+ pass
+
+ with self.objstore as session:
+ try:
+ extra_info = session.get('vm', dom.UUIDString())
+ except NotFoundError:
+ extra_info = {}
+ icon = extra_info.get('icon')
+
+ self._update_guest_stats(name)
+ vm_stats = self.stats.get(dom.UUIDString(), {})
+ res = {}
+ res['cpu_utilization'] = vm_stats.get('cpu', 0)
+ res['net_throughput'] = vm_stats.get('net_io', 0)
+ res['net_throughput_peak'] = vm_stats.get('max_net_io', 100)
+ res['io_throughput'] = vm_stats.get('disk_io', 0)
+ res['io_throughput_peak'] = vm_stats.get('max_disk_io', 100)
+ users, groups = self._get_access_info(dom)
+
+ if state == 'shutoff':
+ xml = dom.XMLDesc(0)
+ val = xpath_get_text(xml, XPATH_DOMAIN_MEMORY)[0]
+ unit_list = xpath_get_text(xml, XPATH_DOMAIN_MEMORY_UNIT)
+ if len(unit_list) > 0:
+ unit = unit_list[0]
+ else:
+ unit = 'KiB'
+ memory = convert_data_size(val, unit, 'MiB')
+ else:
+ memory = info[2] >> 10
+
+ return {'name': name,
+ 'state': state,
+ 'stats': res,
+ 'uuid': dom.UUIDString(),
+ 'memory': memory,
+ 'cpus': info[3],
+ 'screenshot': screenshot,
+ 'icon': icon,
+ # (type, listen, port, passwd, passwdValidTo)
+ 'graphics': {"type": graphics[0],
+ "listen": graphics[1],
+ "port": graphics_port,
+ "passwd": graphics[3],
+ "passwdValidTo": graphics[4]},
+ 'users': users,
+ 'groups': groups,
+ 'access': 'full',
+ 'persistent': True if dom.isPersistent() else False
+ }
+
+ def _vm_get_disk_paths(self, dom):
+ xml = dom.XMLDesc(0)
+ xpath = "/domain/devices/disk[@device='disk']/source/@file"
+ return xpath_get_text(xml, xpath)
+
+ @staticmethod
+ def get_vm(name, conn):
+ conn = conn.get()
+ try:
+ # outgoing text to libvirt, encode('utf-8')
+ return conn.lookupByName(name.encode("utf-8"))
+ except libvirt.libvirtError as e:
+ if e.get_error_code() == libvirt.VIR_ERR_NO_DOMAIN:
+ raise NotFoundError("KCHVM0002E", {'name': name})
+ else:
+ raise OperationFailed("KCHVM0009E", {'name': name,
+ 'err': e.message})
+
+ def delete(self, name):
+ conn = self.conn.get()
+ dom = self.get_vm(name, self.conn)
+ if not dom.isPersistent():
+ raise InvalidOperation("KCHVM0036E", {'name': name})
+
+ self._vmscreenshot_delete(dom.UUIDString())
+ paths = self._vm_get_disk_paths(dom)
+ info = self.lookup(name)
+
+ if info['state'] != 'shutoff':
+ self.poweroff(name)
+
+ # delete existing snapshots before deleting VM
+
+ # libvirt's Test driver does not support the function
+ # "virDomainListAllSnapshots", so "VMSnapshots.get_list" will
raise
+ # "OperationFailed" in that case.
+ try:
+ snapshot_names = self.vmsnapshots.get_list(name)
+ except OperationFailed, e:
+ wok_log.error('cannot list snapshots: %s; '
+ 'skipping snapshot deleting...' % e.message)
+ else:
+ for s in snapshot_names:
+ self.vmsnapshot.delete(name, s)
+
+ try:
+ dom.undefine()
+ except libvirt.libvirtError as e:
+ raise OperationFailed("KCHVM0021E",
+ {'name': name, 'err':
e.get_error_message()})
+
+ for path in paths:
+ try:
+ vol = conn.storageVolLookupByPath(path)
+ pool = vol.storagePoolLookupByVolume()
+ xml = pool.XMLDesc(0)
+ pool_type = xpath_get_text(xml, "/pool/@type")[0]
+ if pool_type not in READONLY_POOL_TYPE:
+ vol.delete(0)
+ # Update objstore to remove the volume
+ with self.objstore as session:
+ session.delete('storagevolume', path,
+ ignore_missing=True)
+ except libvirt.libvirtError as e:
+ wok_log.error('Unable to get storage volume by path: %s' %
+ e.message)
+ except Exception as e:
+ raise OperationFailed('KCHVOL0017E', {'err': e.message})
+
+ try:
+ with self.objstore as session:
+ if path in session.get_list('storagevolume'):
+ used_by = session.get('storagevolume',
path)['used_by']
+ used_by.remove(name)
+ session.store('storagevolume', path,
+ {'used_by': used_by})
+ except Exception as e:
+ raise OperationFailed('KCHVOL0017E', {'err': e.message})
+
+ try:
+ with self.objstore as session:
+ session.delete('vm', dom.UUIDString(), ignore_missing=True)
+ except Exception as e:
+ # It is possible to delete vm without delete its database info
+ wok_log.error('Error deleting vm information from database: '
+ '%s', e.message)
+
+ vnc.remove_proxy_token(name)
+
+ def start(self, name):
+ # make sure the ISO file has read permission
+ dom = self.get_vm(name, self.conn)
+ xml = dom.XMLDesc(0)
+ xpath = "/domain/devices/disk[@device='cdrom']/source/@file"
+ isofiles = xpath_get_text(xml, xpath)
+
+ user = UserTests.probe_user()
+ for iso in isofiles:
+ run_setfacl_set_attr(iso, user=user)
+
+ dom = self.get_vm(name, self.conn)
+ try:
+ dom.create()
+ except libvirt.libvirtError as e:
+ raise OperationFailed("KCHVM0019E",
+ {'name': name, 'err':
e.get_error_message()})
+
+ def poweroff(self, name):
+ dom = self.get_vm(name, self.conn)
+ try:
+ dom.destroy()
+ except libvirt.libvirtError as e:
+ raise OperationFailed("KCHVM0020E",
+ {'name': name, 'err':
e.get_error_message()})
+
+ def shutdown(self, name):
+ dom = self.get_vm(name, self.conn)
+ try:
+ dom.shutdown()
+ except libvirt.libvirtError as e:
+ raise OperationFailed("KCHVM0029E",
+ {'name': name, 'err':
e.get_error_message()})
+
+ def reset(self, name):
+ dom = self.get_vm(name, self.conn)
+ try:
+ dom.reset(flags=0)
+ except libvirt.libvirtError as e:
+ raise OperationFailed("KCHVM0022E",
+ {'name': name, 'err':
e.get_error_message()})
+
+ def _vm_get_graphics(self, name):
+ dom = self.get_vm(name, self.conn)
+ xml = dom.XMLDesc(libvirt.VIR_DOMAIN_XML_SECURE)
+
+ expr = "/domain/devices/graphics/@type"
+ res = xpath_get_text(xml, expr)
+ graphics_type = res[0] if res else None
+
+ expr = "/domain/devices/graphics/@listen"
+ res = xpath_get_text(xml, expr)
+ graphics_listen = res[0] if res else None
+
+ graphics_port = graphics_passwd = graphics_passwdValidTo = None
+ if graphics_type:
+ expr = "/domain/devices/graphics[@type='%s']/@port"
+ res = xpath_get_text(xml, expr % graphics_type)
+ graphics_port = int(res[0]) if res else None
+
+ expr = "/domain/devices/graphics[@type='%s']/@passwd"
+ res = xpath_get_text(xml, expr % graphics_type)
+ graphics_passwd = res[0] if res else None
+
+ expr =
"/domain/devices/graphics[@type='%s']/@passwdValidTo"
+ res = xpath_get_text(xml, expr % graphics_type)
+ if res:
+ to = time.mktime(time.strptime(res[0], '%Y-%m-%dT%H:%M:%S'))
+ graphics_passwdValidTo = to - time.mktime(time.gmtime())
+
+ return (graphics_type, graphics_listen, graphics_port,
+ graphics_passwd, graphics_passwdValidTo)
+
+ def connect(self, name):
+ # (type, listen, port, passwd, passwdValidTo)
+ graphics_port = self._vm_get_graphics(name)[2]
+ if graphics_port is not None:
+ vnc.add_proxy_token(name, graphics_port)
+ else:
+ raise OperationFailed("KCHVM0010E", {'name': name})
+
+ def _vmscreenshot_delete(self, vm_uuid):
+ screenshot = VMScreenshotModel.get_screenshot(vm_uuid, self.objstore,
+ self.conn)
+ screenshot.delete()
+ try:
+ with self.objstore as session:
+ session.delete('screenshot', vm_uuid)
+ except Exception as e:
+ # It is possible to continue Kimchi executions without delete
+ # screenshots
+ wok_log.error('Error trying to delete vm screenshot from '
+ 'database due error: %s', e.message)
+
+ def suspend(self, name):
+ """Suspend the virtual machine's execution and puts it in the
+ state 'paused'. Use the function "resume" to restore its
state.
+ If the VM is not running, an exception will be raised.
+
+ Parameters:
+ name -- the name of the VM to be suspended.
+ """
+ vm = self.lookup(name)
+ if vm['state'] != 'running':
+ raise InvalidOperation('KCHVM0037E', {'name': name})
+
+ vir_dom = self.get_vm(name, self.conn)
+
+ try:
+ vir_dom.suspend()
+ except libvirt.libvirtError, e:
+ raise OperationFailed('KCHVM0038E', {'name': name,
+ 'err': e.message})
+
+ def resume(self, name):
+ """Resume the virtual machine's execution and puts it in the
+ state 'running'. The VM should have been suspended previously by the
+ function "suspend" and be in the state 'paused', otherwise an
exception
+ will be raised.
+
+ Parameters:
+ name -- the name of the VM to be resumed.
+ """
+ vm = self.lookup(name)
+ if vm['state'] != 'paused':
+ raise InvalidOperation('KCHVM0039E', {'name': name})
+
+ vir_dom = self.get_vm(name, self.conn)
+
+ try:
+ vir_dom.resume()
+ except libvirt.libvirtError, e:
+ raise OperationFailed('KCHVM0040E', {'name': name,
+ 'err': e.message})
+
+
+class VMScreenshotModel(object):
+ def __init__(self, **kargs):
+ self.objstore = kargs['objstore']
+ self.conn = kargs['conn']
+
+ def lookup(self, name):
+ dom = VMModel.get_vm(name, self.conn)
+ d_info = dom.info()
+ vm_uuid = dom.UUIDString()
+ if DOM_STATE_MAP[d_info[0]] != 'running':
+ raise NotFoundError("KCHVM0004E", {'name': name})
+
+ screenshot = self.get_screenshot(vm_uuid, self.objstore, self.conn)
+ img_path = screenshot.lookup()
+ # screenshot info changed after scratch generation
+ try:
+ with self.objstore as session:
+ session.store('screenshot', vm_uuid, screenshot.info)
+ except Exception as e:
+ # It is possible to continue Kimchi executions without store
+ # screenshots
+ wok_log.error('Error trying to update database with guest '
+ 'screenshot information due error: %s', e.message)
+ return img_path
+
+ @staticmethod
+ def get_screenshot(vm_uuid, objstore, conn):
+ try:
+ with objstore as session:
+ try:
+ params = session.get('screenshot', vm_uuid)
+ except NotFoundError:
+ params = {'uuid': vm_uuid}
+ session.store('screenshot', vm_uuid, params)
+ except Exception as e:
+ # The 'except' outside of 'with' is necessary to catch
possible
+ # exception from '__exit__' when calling 'session.store'
+ # It is possible to continue Kimchi vm executions without
+ # screenshots
+ wok_log.error('Error trying to update database with guest '
+ 'screenshot information due error: %s', e.message)
+ return LibvirtVMScreenshot(params, conn)
+
+
+class LibvirtVMScreenshot(VMScreenshot):
+ def __init__(self, vm_uuid, conn):
+ VMScreenshot.__init__(self, vm_uuid)
+ self.conn = conn
+
+ def _generate_scratch(self, thumbnail):
+ def handler(stream, buf, opaque):
+ fd = opaque
+ os.write(fd, buf)
+
+ fd = os.open(thumbnail, os.O_WRONLY | os.O_TRUNC | os.O_CREAT, 0644)
+ try:
+ conn = self.conn.get()
+ dom = conn.lookupByUUIDString(self.vm_uuid)
+ vm_name = dom.name()
+ stream = conn.newStream(0)
+ dom.screenshot(stream, 0, 0)
+ stream.recvAll(handler, fd)
+ except libvirt.libvirtError:
+ try:
+ stream.abort()
+ except:
+ pass
+ raise NotFoundError("KCHVM0006E", {'name': vm_name})
+ else:
+ stream.finish()
+ finally:
+ os.close(fd)
diff --git a/src/wok/plugins/kimchi/model/vmsnapshots.py
b/src/wok/plugins/kimchi/model/vmsnapshots.py
new file mode 100644
index 0000000..fff1908
--- /dev/null
+++ b/src/wok/plugins/kimchi/model/vmsnapshots.py
@@ -0,0 +1,204 @@
+#
+# Project Kimchi
+#
+# Copyright IBM, Corp. 2014-2015
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+import libvirt
+import lxml.etree as ET
+import time
+from lxml import objectify
+from lxml.builder import E
+
+from wok.exception import InvalidOperation, NotFoundError, OperationFailed
+from wok.utils import add_task
+from wok.xmlutils.utils import xpath_get_text
+from wok.model.tasks import TaskModel
+
+from vms import DOM_STATE_MAP, VMModel
+from vmstorages import VMStorageModel, VMStoragesModel
+
+
+class VMSnapshotsModel(object):
+ def __init__(self, **kargs):
+ self.conn = kargs['conn']
+ self.objstore = kargs['objstore']
+ self.task = TaskModel(**kargs)
+ self.vmstorages = VMStoragesModel(**kargs)
+ self.vmstorage = VMStorageModel(**kargs)
+
+ def create(self, vm_name, params={}):
+ """Create a snapshot with the current domain state.
+
+ The VM must be stopped and contain only disks with format 'qcow2';
+ otherwise an exception will be raised.
+
+ Parameters:
+ vm_name -- the name of the VM where the snapshot will be created.
+ params -- a dict with the following values:
+ "name": The snapshot name (optional). If omitted, a default value
+ based on the current time will be used.
+
+ Return:
+ A Task running the operation.
+ """
+ vir_dom = VMModel.get_vm(vm_name, self.conn)
+ if DOM_STATE_MAP[vir_dom.info()[0]] != u'shutoff':
+ raise InvalidOperation('KCHSNAP0001E', {'vm': vm_name})
+
+ # if the VM has a non-CDROM disk with type 'raw', abort.
+ for storage_name in self.vmstorages.get_list(vm_name):
+ storage = self.vmstorage.lookup(vm_name, storage_name)
+ type = storage['type']
+ format = storage['format']
+
+ if type != u'cdrom' and format != u'qcow2':
+ raise InvalidOperation('KCHSNAP0010E', {'vm': vm_name,
+ 'format': format})
+
+ name = params.get('name', unicode(int(time.time())))
+
+ task_params = {'vm_name': vm_name, 'name': name}
+ taskid = add_task(u'/plugins/kimchi/vms/%s/snapshots/%s' % (vm_name,
+ name), self._create_task, self.objstore, task_params)
+ return self.task.lookup(taskid)
+
+ def _create_task(self, cb, params):
+ """Asynchronous function which actually creates the snapshot.
+
+ Parameters:
+ cb -- a callback function to signal the Task's progress.
+ params -- a dict with the following values:
+ "vm_name": the name of the VM where the snapshot will be created.
+ "name": the snapshot name.
+ """
+ vm_name = params['vm_name']
+ name = params['name']
+
+ cb('building snapshot XML')
+ root_elem = E.domainsnapshot()
+ root_elem.append(E.name(name))
+ xml = ET.tostring(root_elem, encoding='utf-8')
+
+ try:
+ cb('fetching snapshot domain')
+ vir_dom = VMModel.get_vm(vm_name, self.conn)
+ cb('creating snapshot')
+ vir_dom.snapshotCreateXML(xml, 0)
+ except (NotFoundError, OperationFailed, libvirt.libvirtError), e:
+ raise OperationFailed('KCHSNAP0002E',
+ {'name': name, 'vm': vm_name,
+ 'err': e.message})
+
+ cb('OK', True)
+
+ def get_list(self, vm_name):
+ vir_dom = VMModel.get_vm(vm_name, self.conn)
+
+ try:
+ vir_snaps = vir_dom.listAllSnapshots(0)
+ return sorted([s.getName().decode('utf-8') for s in vir_snaps],
+ key=unicode.lower)
+ except libvirt.libvirtError, e:
+ raise OperationFailed('KCHSNAP0005E',
+ {'vm': vm_name, 'err': e.message})
+
+
+class VMSnapshotModel(object):
+ def __init__(self, **kargs):
+ self.conn = kargs['conn']
+
+ def lookup(self, vm_name, name):
+ vir_snap = self.get_vmsnapshot(vm_name, name)
+
+ try:
+ snap_xml_str = vir_snap.getXMLDesc(0).decode('utf-8')
+ except libvirt.libvirtError, e:
+ raise OperationFailed('KCHSNAP0004E', {'name': name,
+ 'vm': vm_name,
+ 'err': e.message})
+
+ snap_xml = objectify.fromstring(snap_xml_str)
+
+ try:
+ parent = unicode(snap_xml.parent.name)
+ except AttributeError:
+ parent = u''
+
+ return {'created': unicode(snap_xml.creationTime),
+ 'name': unicode(snap_xml.name),
+ 'parent': parent,
+ 'state': unicode(snap_xml.state)}
+
+ def delete(self, vm_name, name):
+ try:
+ vir_snap = self.get_vmsnapshot(vm_name, name)
+ vir_snap.delete(0)
+ except libvirt.libvirtError, e:
+ raise OperationFailed('KCHSNAP0006E', {'name': name,
+ 'vm': vm_name,
+ 'err': e.message})
+
+ def revert(self, vm_name, name):
+ try:
+ vir_dom = VMModel.get_vm(vm_name, self.conn)
+ vir_snap = self.get_vmsnapshot(vm_name, name)
+ vir_dom.revertToSnapshot(vir_snap, 0)
+
+ # get vm name recorded in the snapshot and return new uri params
+ vm_new_name = xpath_get_text(vir_snap.getXMLDesc(0),
+ 'domain/name')[0]
+ return [vm_new_name, name]
+ except libvirt.libvirtError, e:
+ raise OperationFailed('KCHSNAP0009E', {'name': name,
+ 'vm': vm_name,
+ 'err': e.message})
+
+ def get_vmsnapshot(self, vm_name, name):
+ vir_dom = VMModel.get_vm(vm_name, self.conn)
+
+ try:
+ return vir_dom.snapshotLookupByName(name, 0)
+ except libvirt.libvirtError, e:
+ code = e.get_error_code()
+ if code == libvirt.VIR_ERR_NO_DOMAIN_SNAPSHOT:
+ raise NotFoundError('KCHSNAP0003E', {'name': name,
+ 'vm': vm_name})
+ else:
+ raise OperationFailed('KCHSNAP0004E', {'name': name,
+ 'vm': vm_name,
+ 'err': e.message})
+
+
+class CurrentVMSnapshotModel(object):
+ def __init__(self, **kargs):
+ self.conn = kargs['conn']
+ self.vmsnapshot = VMSnapshotModel(**kargs)
+
+ def lookup(self, vm_name):
+ vir_dom = VMModel.get_vm(vm_name, self.conn)
+
+ try:
+ vir_snap = vir_dom.snapshotCurrent(0)
+ snap_name = vir_snap.getName().decode('utf-8')
+ except libvirt.libvirtError, e:
+ if e.get_error_code() == libvirt.VIR_ERR_NO_DOMAIN_SNAPSHOT:
+ return {}
+
+ raise OperationFailed('KCHSNAP0008E',
+ {'vm': vm_name, 'err': e.message})
+
+ return self.vmsnapshot.lookup(vm_name, snap_name)
diff --git a/src/wok/plugins/kimchi/model/vmstorages.py
b/src/wok/plugins/kimchi/model/vmstorages.py
new file mode 100644
index 0000000..bec16c6
--- /dev/null
+++ b/src/wok/plugins/kimchi/model/vmstorages.py
@@ -0,0 +1,252 @@
+#
+# Project Kimchi
+#
+# Copyright IBM, Corp. 2014-2015
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+import string
+from lxml import etree
+
+from wok.exception import InvalidOperation, InvalidParameter, NotFoundError
+from wok.exception import OperationFailed
+from wok.utils import wok_log
+
+from ..osinfo import lookup
+from ..xmlutils.disk import get_device_node, get_disk_xml
+from ..xmlutils.disk import get_vm_disk_info, get_vm_disks
+from config import CapabilitiesModel
+from diskutils import get_disk_used_by, set_disk_used_by
+from storagevolumes import StorageVolumeModel
+from utils import get_vm_config_flag
+from vms import DOM_STATE_MAP, VMModel
+
+
+HOTPLUG_TYPE = ['scsi', 'virtio']
+
+
+def _get_device_bus(dev_type, dom, metadata_support):
+ try:
+ version, distro = VMModel.vm_get_os_metadata(dom, metadata_support)
+ except:
+ version, distro = ('unknown', 'unknown')
+ return lookup(distro, version)[dev_type+'_bus']
+
+
+class VMStoragesModel(object):
+ def __init__(self, **kargs):
+ self.conn = kargs['conn']
+ self.objstore = kargs['objstore']
+ self.caps = CapabilitiesModel(**kargs)
+
+ def _get_available_bus_address(self, bus_type, vm_name):
+ if bus_type not in ['ide']:
+ return dict()
+ # libvirt limitation of just 1 ide controller
+ # each controller have at most 2 buses and each bus 2 units.
+ dom = VMModel.get_vm(vm_name, self.conn)
+ disks = self.get_list(vm_name)
+ valid_id = [('0', '0'), ('0', '1'), ('1',
'0'), ('1', '1')]
+ controller_id = '0'
+ for dev_name in disks:
+ disk = get_device_node(dom, dev_name)
+ if disk.target.attrib['bus'] == 'ide':
+ controller_id = disk.address.attrib['controller']
+ bus_id = disk.address.attrib['bus']
+ unit_id = disk.address.attrib['unit']
+ if (bus_id, unit_id) in valid_id:
+ valid_id.remove((bus_id, unit_id))
+ continue
+ if not valid_id:
+ raise OperationFailed('KCHVMSTOR0014E',
+ {'type': 'ide', 'limit': 4})
+ else:
+ address = {'controller': controller_id,
+ 'bus': valid_id[0][0], 'unit': valid_id[0][1]}
+ return dict(address=address)
+
+ def create(self, vm_name, params):
+ vol_model = None
+ # Path will never be blank due to API.json verification.
+ # There is no need to cover this case here.
+ if not ('vol' in params) ^ ('path' in params):
+ raise InvalidParameter("KCHVMSTOR0017E")
+
+ dom = VMModel.get_vm(vm_name, self.conn)
+ params['bus'] = _get_device_bus(params['type'], dom,
+ self.caps.metadata_support)
+ params['format'] = 'raw'
+
+ dev_list = [dev for dev, bus in get_vm_disks(dom).iteritems()
+ if bus == params['bus']]
+ dev_list.sort()
+ if len(dev_list) == 0:
+ params['index'] = 0
+ else:
+ char = dev_list.pop()[2]
+ params['index'] = string.ascii_lowercase.index(char) + 1
+
+ if (params['bus'] not in HOTPLUG_TYPE and
+ DOM_STATE_MAP[dom.info()[0]] != 'shutoff'):
+ raise InvalidOperation('KCHVMSTOR0011E')
+
+ if params.get('vol'):
+ try:
+ pool = params['pool']
+ vol_model = StorageVolumeModel(conn=self.conn,
+ objstore=self.objstore)
+ vol_info = vol_model.lookup(pool, params['vol'])
+ except KeyError:
+ raise InvalidParameter("KCHVMSTOR0012E")
+ except Exception as e:
+ raise InvalidParameter("KCHVMSTOR0015E", {'error': e})
+ if len(vol_info['used_by']) != 0:
+ raise InvalidParameter("KCHVMSTOR0016E")
+
+ valid_format = {
+ "disk": ["raw", "bochs", "qcow",
"qcow2", "qed", "vmdk"],
+ "cdrom": "iso"}
+
+ if vol_info['type'] == 'file':
+ if (params['type'] == 'disk' and
+ vol_info['format'] in
valid_format[params['type']]):
+ params['format'] = vol_info['format']
+ else:
+ raise InvalidParameter("KCHVMSTOR0018E",
+ {"format":
vol_info['format'],
+ "type": params['type']})
+
+ params['path'] = vol_info['path']
+ params['disk'] = vol_info['type']
+
+ params.update(self._get_available_bus_address(params['bus'], vm_name))
+
+ # Add device to VM
+ dev, xml = get_disk_xml(params)
+ try:
+ conn = self.conn.get()
+ dom = conn.lookupByName(vm_name)
+ dom.attachDeviceFlags(xml, get_vm_config_flag(dom, 'all'))
+ except Exception as e:
+ raise OperationFailed("KCHVMSTOR0008E", {'error':
e.message})
+
+ # Don't put a try-block here. Let the exception be raised. If we
+ # allow disks used_by to be out of sync, data corruption could
+ # occour if a disk is added to two guests unknowingly.
+ if params.get('vol'):
+ used_by = vol_info['used_by']
+ used_by.append(vm_name)
+ set_disk_used_by(self.objstore, params['path'], used_by)
+
+ return dev
+
+ def get_list(self, vm_name):
+ dom = VMModel.get_vm(vm_name, self.conn)
+ return get_vm_disks(dom).keys()
+
+
+class VMStorageModel(object):
+ def __init__(self, **kargs):
+ self.conn = kargs['conn']
+ self.objstore = kargs['objstore']
+ self.caps = CapabilitiesModel(**kargs)
+
+ def lookup(self, vm_name, dev_name):
+ # Retrieve disk xml and format return dict
+ dom = VMModel.get_vm(vm_name, self.conn)
+ return get_vm_disk_info(dom, dev_name)
+
+ def delete(self, vm_name, dev_name):
+ conn = self.conn.get()
+
+ try:
+ bus_type = self.lookup(vm_name, dev_name)['bus']
+ dom = conn.lookupByName(vm_name)
+ except NotFoundError:
+ raise
+
+ if (bus_type not in HOTPLUG_TYPE and
+ DOM_STATE_MAP[dom.info()[0]] != 'shutoff'):
+ raise InvalidOperation('KCHVMSTOR0011E')
+
+ try:
+ disk = get_device_node(dom, dev_name)
+ path = get_vm_disk_info(dom, dev_name)['path']
+ if path is None or len(path) < 1:
+ path = self.lookup(vm_name, dev_name)['path']
+ # This has to be done before it's detached. If it wasn't
+ # in the obj store, its ref count would have been updated
+ # by get_disk_used_by()
+ if path is not None:
+ used_by = get_disk_used_by(self.objstore, self.conn, path)
+ else:
+ wok_log.error("Unable to decrement volume used_by on"
+ " delete because no path could be found.")
+ dom.detachDeviceFlags(etree.tostring(disk),
+ get_vm_config_flag(dom, 'all'))
+ except Exception as e:
+ raise OperationFailed("KCHVMSTOR0010E", {'error':
e.message})
+
+ if used_by is not None and vm_name in used_by:
+ used_by.remove(vm_name)
+ set_disk_used_by(self.objstore, path, used_by)
+ else:
+ wok_log.error("Unable to update %s:%s used_by on delete."
+ % (vm_name, dev_name))
+
+ def update(self, vm_name, dev_name, params):
+ old_disk_used_by = None
+ new_disk_used_by = None
+
+ dom = VMModel.get_vm(vm_name, self.conn)
+
+ dev_info = self.lookup(vm_name, dev_name)
+ if dev_info['type'] != 'cdrom':
+ raise InvalidOperation("KCHVMSTOR0006E")
+
+ params['path'] = params.get('path', '')
+ old_disk_path = dev_info['path']
+ new_disk_path = params['path']
+ if new_disk_path != old_disk_path:
+ # An empty path means a CD-ROM was empty or ejected:
+ if old_disk_path is not '':
+ old_disk_used_by = get_disk_used_by(
+ self.objstore, self.conn, old_disk_path)
+ if new_disk_path is not '':
+ new_disk_used_by = get_disk_used_by(
+ self.objstore, self.conn, new_disk_path)
+
+ dev_info.update(params)
+ dev, xml = get_disk_xml(dev_info)
+
+ try:
+ dom.updateDeviceFlags(xml, get_vm_config_flag(dom, 'all'))
+ except Exception as e:
+ raise OperationFailed("KCHVMSTOR0009E", {'error':
e.message})
+
+ try:
+ if old_disk_used_by is not None and \
+ vm_name in old_disk_used_by:
+ old_disk_used_by.remove(vm_name)
+ set_disk_used_by(self.objstore, old_disk_path,
+ old_disk_used_by)
+ if new_disk_used_by is not None:
+ new_disk_used_by.append(vm_name)
+ set_disk_used_by(self.objstore, new_disk_path,
+ new_disk_used_by)
+ except Exception as e:
+ wok_log.error("Unable to update dev used_by on update due to"
+ " %s:" % e.message)
+ return dev
diff --git a/src/wok/plugins/kimchi/netinfo.py b/src/wok/plugins/kimchi/netinfo.py
new file mode 100644
index 0000000..c5746d7
--- /dev/null
+++ b/src/wok/plugins/kimchi/netinfo.py
@@ -0,0 +1,216 @@
+# Project Kimchi
+#
+# Copyright IBM, Corp. 2013-2015
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+#
+
+import ethtool
+import glob
+import os
+
+
+NET_PATH = '/sys/class/net'
+NIC_PATH = '/sys/class/net/*/device'
+BRIDGE_PATH = '/sys/class/net/*/bridge'
+BONDING_PATH = '/sys/class/net/*/bonding'
+WLAN_PATH = '/sys/class/net/*/wireless'
+NET_BRPORT = '/sys/class/net/%s/brport'
+NET_MASTER = '/sys/class/net/%s/master'
+NET_STATE = '/sys/class/net/%s/carrier'
+PROC_NET_VLAN = '/proc/net/vlan/'
+BONDING_SLAVES = '/sys/class/net/%s/bonding/slaves'
+BRIDGE_PORTS = '/sys/class/net/%s/brif'
+
+
+def wlans():
+ return [b.split('/')[-2] for b in glob.glob(WLAN_PATH)]
+
+
+def is_wlan(iface):
+ return iface in wlans()
+
+
+# FIXME if we do not want to list usb nic
+def nics():
+ return list(set([b.split('/')[-2] for b in glob.glob(NIC_PATH)]) -
+ set(wlans()))
+
+
+def is_nic(iface):
+ return iface in nics()
+
+
+def bondings():
+ return [b.split('/')[-2] for b in glob.glob(BONDING_PATH)]
+
+
+def is_bonding(iface):
+ return iface in bondings()
+
+
+def vlans():
+ return list(set([b.split('/')[-1]
+ for b in glob.glob(NET_PATH + '/*')]) &
+ set([b.split('/')[-1]
+ for b in glob.glob(PROC_NET_VLAN + '*')]))
+
+
+def is_vlan(iface):
+ return iface in vlans()
+
+
+def bridges():
+ return [b.split('/')[-2] for b in glob.glob(BRIDGE_PATH)]
+
+
+def is_bridge(iface):
+ return iface in bridges()
+
+
+def all_interfaces():
+ return [d.rsplit("/", 1)[-1] for d in glob.glob(NET_PATH + '/*')]
+
+
+def slaves(bonding):
+ with open(BONDING_SLAVES % bonding) as bonding_file:
+ res = bonding_file.readline().split()
+ return res
+
+
+def ports(bridge):
+ return os.listdir(BRIDGE_PORTS % bridge)
+
+
+def is_brport(nic):
+ return os.path.exists(NET_BRPORT % nic)
+
+
+def is_bondlave(nic):
+ return os.path.exists(NET_MASTER % nic)
+
+
+def operstate(dev):
+ link_status = link_detected(dev)
+ return "down" if link_status == "n/a" else "up"
+
+
+def link_detected(dev):
+ # try to read interface carrier (link) status
+ try:
+ with open(NET_STATE % dev) as dev_file:
+ carrier = dev_file.readline().strip()
+ # when IOError is raised, interface is down
+ except IOError:
+ return "n/a"
+
+ # if value is 1, interface up with cable connected
+ # 0 corresponds to interface up with cable disconnected
+ return "yes" if carrier == '1' else "no"
+
+
+def get_vlan_device(vlan):
+ """ Return the device of the given VLAN. """
+ dev = None
+
+ if os.path.exists(PROC_NET_VLAN + vlan):
+ with open(PROC_NET_VLAN + vlan) as vlan_file:
+ for line in vlan_file:
+ if "Device:" in line:
+ dummy, dev = line.split()
+ break
+ return dev
+
+
+def get_bridge_port_device(bridge):
+ """Return the nics list that belongs to bridge."""
+ # br --- v --- bond --- nic1
+ if bridge not in bridges():
+ raise ValueError('unknown bridge %s' % bridge)
+ nics = []
+ for port in ports(bridge):
+ if port in vlans():
+ device = get_vlan_device(port)
+ if device in bondings():
+ nics.extend(slaves(device))
+ else:
+ nics.append(device)
+ if port in bondings():
+ nics.extend(slaves(port))
+ else:
+ nics.append(port)
+ return nics
+
+
+def aggregated_bridges():
+ return [bridge for bridge in bridges() if
+ (set(get_bridge_port_device(bridge)) & set(nics()))]
+
+
+def bare_nics():
+ "The nic is not a port of a bridge or a slave of bond."
+ return [nic for nic in nics() if not (is_brport(nic) or is_bondlave(nic))]
+
+
+def is_bare_nic(iface):
+ return iface in bare_nics()
+
+
+# The nic will not be exposed when it is a port of a bridge or
+# a slave of bond.
+# The bridge will not be exposed when all it's port are tap.
+def all_favored_interfaces():
+ return aggregated_bridges() + bare_nics() + bondings()
+
+
+def get_interface_type(iface):
+ # FIXME if we want to get more device type
+ # just support nic, bridge, bondings and vlan, for we just
+ # want to expose this 4 kinds of interface
+ try:
+ if is_nic(iface):
+ return "nic"
+ if is_bonding(iface):
+ return "bonding"
+ if is_bridge(iface):
+ return "bridge"
+ if is_vlan(iface):
+ return "vlan"
+ return 'unknown'
+ except IOError:
+ return 'unknown'
+
+
+def get_interface_info(iface):
+ if iface not in ethtool.get_devices():
+ raise ValueError('unknown interface: %s' % iface)
+
+ ipaddr = ''
+ netmask = ''
+ try:
+ ipaddr = ethtool.get_ipaddr(iface)
+ netmask = ethtool.get_netmask(iface)
+ except IOError:
+ pass
+
+ iface_link_detected = link_detected(iface)
+ iface_status = 'active' if iface_link_detected != "n/a" else
"inactive"
+
+ return {'name': iface,
+ 'type': get_interface_type(iface),
+ 'status': iface_status,
+ 'link_detected': iface_link_detected,
+ 'ipaddr': ipaddr,
+ 'netmask': netmask}
diff --git a/src/wok/plugins/kimchi/network.py b/src/wok/plugins/kimchi/network.py
new file mode 100644
index 0000000..1433b8a
--- /dev/null
+++ b/src/wok/plugins/kimchi/network.py
@@ -0,0 +1,62 @@
+#
+# Project Kimchi
+#
+# Copyright IBM, Corp. 2013-2014
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+#
+
+import ethtool
+import ipaddr
+
+
+APrivateNets = ipaddr.IPNetwork("10.0.0.0/8")
+BPrivateNets = ipaddr.IPNetwork("172.16.0.0/12")
+CPrivateNets = ipaddr.IPNetwork('192.168.0.0/16')
+PrivateNets = [CPrivateNets, BPrivateNets, APrivateNets]
+DefaultNetsPool = [ipaddr.IPNetwork('192.168.122.0/23'),
+ ipaddr.IPNetwork('192.168.124.0/22'),
+ ipaddr.IPNetwork('192.168.128.0/17')]
+
+
+def get_dev_netaddr(dev):
+ info = ethtool.get_interfaces_info(dev)[0]
+ return (info.ipv4_address and
+ "%s/%s" % (info.ipv4_address, info.ipv4_netmask) or '')
+
+
+def get_dev_netaddrs():
+ nets = []
+ for dev in ethtool.get_devices():
+ devnet = get_dev_netaddr(dev)
+ devnet and nets.append(ipaddr.IPNetwork(devnet))
+ return nets
+
+
+# used_nets should include all the subnet allocated in libvirt network
+# will get host network by get_dev_netaddrs
+def get_one_free_network(used_nets, nets_pool=PrivateNets):
+ def _get_free_network(nets, used_nets):
+ for net in nets.subnet(new_prefix=24):
+ if not any(net.overlaps(used) for used in used_nets):
+ return str(net)
+ return None
+
+ used_nets = used_nets + get_dev_netaddrs()
+ for nets in nets_pool:
+ net = _get_free_network(nets, used_nets)
+ if net:
+ return net
+ return None
diff --git a/src/wok/plugins/kimchi/osinfo.py b/src/wok/plugins/kimchi/osinfo.py
new file mode 100644
index 0000000..5b1277c
--- /dev/null
+++ b/src/wok/plugins/kimchi/osinfo.py
@@ -0,0 +1,213 @@
+#
+# Project Kimchi
+#
+# Copyright IBM, Corp. 2013-2015
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+import copy
+import glob
+import os
+import psutil
+from collections import defaultdict
+from configobj import ConfigObj
+from distutils.version import LooseVersion
+
+from wok.config import PluginPaths
+
+
+SUPPORTED_ARCHS = {'x86': ('i386', 'i686', 'x86_64'),
+ 'power': ('ppc', 'ppc64'),
+ 'ppc64le': ('ppc64le')}
+
+
+template_specs = {'x86': {'old': dict(disk_bus='ide',
+ nic_model='e1000',
sound_model='ich6'),
+ 'modern': dict(disk_bus='virtio',
+ nic_model='virtio',
+ sound_model='ich6')},
+ 'power': {'old': dict(disk_bus='scsi',
+ nic_model='spapr-vlan',
+ cdrom_bus='scsi',
+ kbd_type="kbd",
+ kbd_bus='usb', mouse_bus='usb',
+ tablet_bus='usb', memory=1280),
+ 'modern': dict(disk_bus='virtio',
+ nic_model='virtio',
+ cdrom_bus='scsi',
+ kbd_bus='usb',
+ kbd_type="kbd",
+ mouse_bus='usb',
tablet_bus='usb',
+ memory=1280)},
+ 'ppc64le': {'old': dict(disk_bus='virtio',
+ nic_model='virtio',
+ cdrom_bus='scsi',
+ kbd_bus='usb',
+ kbd_type="keyboard",
+ mouse_bus='usb',
tablet_bus='usb',
+ memory=1280),
+ 'modern': dict(disk_bus='virtio',
+ nic_model='virtio',
+ cdrom_bus='scsi',
+ kbd_bus='usb',
+ kbd_type="keyboard",
+ mouse_bus='usb',
tablet_bus='usb',
+ memory=1280)}}
+
+
+custom_specs = {'fedora': {'22': dict(video_model='qxl')}}
+
+
+modern_version_bases = {'x86': {'debian': '6.0',
'ubuntu': '7.10',
+ 'opensuse': '10.3', 'centos':
'5.3',
+ 'rhel': '6.0', 'fedora':
'16', 'gentoo': '0',
+ 'sles': '11', 'arch':
'0'},
+ 'power': {'rhel': '6.5',
'fedora': '19',
+ 'ubuntu': '14.04',
+ 'opensuse': '13.1',
+ 'sles': '11sp3'},
+ 'ppc64le': {'rhel': '6.5',
'fedora': '19',
+ 'ubuntu': '14.04',
+ 'opensuse': '13.1',
+ 'sles': '11sp3'}}
+
+
+icon_available_distros = [icon[5:-4] for icon in glob.glob1('%s/images/'
+ % PluginPaths('kimchi').ui_dir, 'icon-*.png')]
+
+
+def _get_tmpl_defaults():
+ """
+ ConfigObj returns a dict like below when no changes were made in the
+ template configuration file (template.conf)
+
+ {'main': {}, 'storage': {'disk.0': {}}, 'processor':
{}, 'graphics': {}}
+
+ The default values should be like below:
+
+ {'main': {'networks': ['default'], 'memory':
'1024'},
+ 'storage': {'pool': 'default',
+ 'disk.0': {'format': 'qcow2', 'size':
'10'}},
+ 'processor': {'cpus': '1'},
+ 'graphics': {'type': 'spice', 'listen':
'127.0.0.1'}}
+ """
+ # Create dict with default values
+ tmpl_defaults = defaultdict(dict)
+ tmpl_defaults['main']['networks'] = ['default']
+ tmpl_defaults['main']['memory'] = 1024
+ tmpl_defaults['storage']['pool'] = 'default'
+ tmpl_defaults['storage']['disk.0'] = {'size': 10,
'format': 'qcow2'}
+ tmpl_defaults['processor']['cpus'] = 1
+ tmpl_defaults['graphics'] = {'type': 'vnc', 'listen':
'127.0.0.1'}
+
+ default_config = ConfigObj(tmpl_defaults)
+
+ # Load template configuration file
+ config_file = os.path.join(PluginPaths('kimchi').conf_dir,
'template.conf')
+ config = ConfigObj(config_file)
+
+ # Merge default configuration with file configuration
+ default_config.merge(config)
+
+ # Create a dict with default values according to data structure
+ # expected by VMTemplate
+ defaults = {'domain': 'kvm', 'arch': os.uname()[4],
+ 'cdrom_bus': 'ide', 'cdrom_index': 2,
'mouse_bus': 'ps2'}
+
+ # Parse main section to get networks and memory values
+ main_section = default_config.pop('main')
+ defaults.update(main_section)
+
+ # Parse storage section to get storage pool and disks values
+ storage_section = default_config.pop('storage')
+ defaults['storagepool'] = '/plugins/kimchi/storagepools/' + \
+ storage_section.pop('pool')
+ defaults['disks'] = []
+ for disk in storage_section.keys():
+ data = storage_section[disk]
+ data['index'] = int(disk.split('.')[1])
+ defaults['disks'].append(data)
+
+ # Parse processor section to get cpus and cpu_topology values
+ processor_section = default_config.pop('processor')
+ defaults['cpus'] = processor_section.pop('cpus')
+ defaults['cpu_info'] = {}
+ if len(processor_section.keys()) > 0:
+ defaults['cpu_info']['topology'] = processor_section
+
+ # Update defaults values with graphics values
+ defaults['graphics'] = default_config.pop('graphics')
+
+ return defaults
+
+
+# Set defaults values according to template.conf file
+defaults = _get_tmpl_defaults()
+
+
+def _get_arch():
+ for arch, sub_archs in SUPPORTED_ARCHS.iteritems():
+ if os.uname()[4] in sub_archs:
+ return arch
+
+
+def get_template_default(template_type, field):
+ host_arch = _get_arch()
+ # Assuming 'power' = 'ppc64le' because lookup() does the same,
+ # claiming libvirt compatibility.
+ host_arch = 'power' if host_arch == 'ppc64le' else host_arch
+ tmpl_defaults = copy.deepcopy(defaults)
+ tmpl_defaults.update(template_specs[host_arch][template_type])
+ return tmpl_defaults[field]
+
+
+def lookup(distro, version):
+ """
+ Lookup all parameters needed to run a VM of a known or unknown operating
+ system type and version. The data is constructed by starting with the
+ 'defaults' and merging the parameters given for the identified OS. If
+ known, a link to a remote install CD is added.
+ """
+ params = copy.deepcopy(defaults)
+ params['os_distro'] = distro
+ params['os_version'] = version
+ arch = _get_arch()
+
+ # Setting maxMemory of the VM, which will be equal total Host memory in Kib
+ params['max_memory'] = psutil.TOTAL_PHYMEM >> 10
+
+ # set up arch to ppc64 instead of ppc64le due to libvirt compatibility
+ if params["arch"] == "ppc64le":
+ params["arch"] = "ppc64"
+
+ if distro in modern_version_bases[arch]:
+ if LooseVersion(version) >= LooseVersion(
+ modern_version_bases[arch][distro]):
+ params.update(template_specs[arch]['modern'])
+ else:
+ params.update(template_specs[arch]['old'])
+ else:
+ params['os_distro'] = params['os_version'] = "unknown"
+ params.update(template_specs[arch]['old'])
+
+ # Get custom specifications
+ params.update(custom_specs.get(distro, {}).get(version, {}))
+
+ if distro in icon_available_distros:
+ params['icon'] = 'plugins/kimchi/images/icon-%s.png' % distro
+ else:
+ params['icon'] = 'plugins/kimchi/images/icon-vm.png'
+
+ return params
diff --git a/src/wok/plugins/kimchi/po/LINGUAS b/src/wok/plugins/kimchi/po/LINGUAS
new file mode 100644
index 0000000..3fcb18f
--- /dev/null
+++ b/src/wok/plugins/kimchi/po/LINGUAS
@@ -0,0 +1,11 @@
+en_US
+pt_BR
+zh_CN
+de_DE
+es_ES
+fr_FR
+it_IT
+ja_JP
+ko_KR
+ru_RU
+zh_TW
diff --git a/src/wok/plugins/kimchi/po/Makefile.in.in
b/src/wok/plugins/kimchi/po/Makefile.in.in
new file mode 100644
index 0000000..d01fb31
--- /dev/null
+++ b/src/wok/plugins/kimchi/po/Makefile.in.in
@@ -0,0 +1,398 @@
+# Makefile for PO directory in any package using GNU gettext.
+# Copyright (C) 1995-1997, 2000-2007, 2009-2010 by Ulrich Drepper
<drepper(a)gnu.ai.mit.edu>
+#
+# This file can be copied and used freely without restrictions. It can
+# be used in projects which are not available under the GNU General Public
+# License but which still want to provide support for the GNU gettext
+# functionality.
+# Please note that the actual code of GNU gettext is covered by the GNU
+# General Public License and is *not* in the public domain.
+#
+# Origin: gettext-0.18
+GETTEXT_MACRO_VERSION = 0.18
+
+PACKAGE = @PACKAGE@
+VERSION = @VERSION@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+
+SHELL = /bin/sh
+@SET_MAKE@
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH = @srcdir@
+
+prefix = @prefix@
+exec_prefix = @exec_prefix@
+datarootdir = @datarootdir@
+datadir = @datadir@
+localedir = @prefix@/share/locale
+gettextsrcdir = $(datadir)/gettext/po
+
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+
+# We use $(MKDIR_P).
+# This macro uses the 'mkdir -p' command if possible. Otherwise, it falls back
+# on invoking install-sh with the -d option, so your package should contain
+# install-sh as described under AC_PROG_INSTALL.
+mkinstalldirs = $(SHELL) @install_sh@ -d
+install_sh = $(SHELL) @install_sh@
+MKDIR_P = @MKDIR_P@
+MKDIR_P = @MKDIR_P@
+
+GMSGFMT_ = @GMSGFMT@
+GMSGFMT_no = @GMSGFMT@
+GMSGFMT_yes = @GMSGFMT_015@
+GMSGFMT = $(GMSGFMT_$(USE_MSGCTXT))
+MSGFMT_ = @MSGFMT@
+MSGFMT_no = @MSGFMT@
+MSGFMT_yes = @MSGFMT_015@
+MSGFMT = $(MSGFMT_$(USE_MSGCTXT))
+XGETTEXT_ = @XGETTEXT@
+XGETTEXT_no = @XGETTEXT@
+XGETTEXT_yes = @XGETTEXT_015@
+XGETTEXT = $(XGETTEXT_$(USE_MSGCTXT))
+MSGMERGE = msgmerge
+MSGMERGE_UPDATE = @MSGMERGE@ --update
+MSGINIT = msginit
+MSGCONV = msgconv
+MSGFILTER = msgfilter
+
+POFILES = @POFILES@
+GMOFILES = @GMOFILES@
+UPDATEPOFILES = @UPDATEPOFILES@
+DUMMYPOFILES = @DUMMYPOFILES@
+DISTFILES.common = Makefile.in.in \
+$(DISTFILES.common.extra1) $(DISTFILES.common.extra2) $(DISTFILES.common.extra3)
+DISTFILES = $(DISTFILES.common) Makevars POTFILES.in gen-pot.in \
+$(POFILES) $(GMOFILES) \
+$(DISTFILES.extra1) $(DISTFILES.extra2) $(DISTFILES.extra3)
+
+POTFILES = \
+
+CATALOGS = @CATALOGS@
+
+# Makevars gets inserted here. (Don't remove this line!)
+
+.SUFFIXES:
+.SUFFIXES: .po .gmo .mo .sed .sin .nop .po-create .po-update
+
+.po.mo:
+ @echo "$(MSGFMT) -c -o $@ $<"; \
+ $(MSGFMT) -c -o t-$@ $< && mv t-$@ $@
+
+.po.gmo:
+ @lang=`echo $* | sed -e 's,.*/,,'`; \
+ test "$(srcdir)" = . && cdcmd="" || cdcmd="cd $(srcdir)
&& "; \
+ echo "$${cdcmd}rm -f $${lang}.gmo && $(GMSGFMT) -c --statistics --verbose
-o $${lang}.gmo $${lang}.po"; \
+ cd $(srcdir) && rm -f $${lang}.gmo && $(GMSGFMT) -c --statistics
--verbose -o t-$${lang}.gmo $${lang}.po && mv t-$${lang}.gmo $${lang}.gmo
+
+.sin.sed:
+ sed -e '/^#/d' $< > t-$@
+ mv t-$@ $@
+
+
+all: check-macro-version update-gmo all-@USE_NLS@
+
+all-yes: stamp-po
+all-no:
+
+# Ensure that the gettext macros and this Makefile.in.in are in sync.
+check-macro-version:
+ @test "$(GETTEXT_MACRO_VERSION)" = "@GETTEXT_MACRO_VERSION@" \
+ || { echo "*** error: gettext infrastructure mismatch: using a Makefile.in.in
from gettext version $(GETTEXT_MACRO_VERSION) but the autoconf macros are from gettext
version @GETTEXT_MACRO_VERSION@" 1>&2; \
+ exit 1; \
+ }
+
+# $(srcdir)/$(DOMAIN).pot is only created when needed. When xgettext finds no
+# internationalized messages, no $(srcdir)/$(DOMAIN).pot is created (because
+# we don't want to bother translators with empty POT files). We assume that
+# LINGUAS is empty in this case, i.e. $(POFILES) and $(GMOFILES) are empty.
+# In this case, stamp-po is a nop (i.e. a phony target).
+
+# stamp-po is a timestamp denoting the last time at which the CATALOGS have
+# been loosely updated. Its purpose is that when a developer or translator
+# checks out the package via CVS, and the $(DOMAIN).pot file is not in CVS,
+# "make" will update the $(DOMAIN).pot and the $(CATALOGS), but subsequent
+# invocations of "make" will do nothing. This timestamp would not be necessary
+# if updating the $(CATALOGS) would always touch them; however, the rule for
+# $(POFILES) has been designed to not touch files that don't need to be
+# changed.
+stamp-po: $(srcdir)/$(DOMAIN).pot
+ test ! -f $(srcdir)/$(DOMAIN).pot || \
+ test -z "$(GMOFILES)" || $(MAKE) $(GMOFILES)
+ @test ! -f $(srcdir)/$(DOMAIN).pot || { \
+ echo "touch stamp-po" && \
+ echo timestamp > stamp-poT && \
+ mv stamp-poT stamp-po; \
+ }
+
+# Note: Target 'all' must not depend on target '$(DOMAIN).pot-update',
+# otherwise packages like GCC can not be built if only parts of the source
+# have been downloaded.
+
+$(DOMAIN).pot-update: $(POTFILES) $(srcdir)/POTFILES.in
+ $(srcdir)/gen-pot $(POTFILES)
+
+# This rule has no dependencies: we don't need to update $(DOMAIN).pot at
+# every "make" invocation, only create it when it is missing.
+# Only "make $(DOMAIN).pot-update" or "make dist" will force an
update.
+$(srcdir)/$(DOMAIN).pot:
+ $(MAKE) $(DOMAIN).pot-update
+
+# This target rebuilds a PO file if $(DOMAIN).pot has changed.
+# Note that a PO file is not touched if it doesn't need to be changed.
+$(POFILES): $(srcdir)/$(DOMAIN).pot
+ @lang=`echo $@ | sed -e 's,.*/,,' -e 's/\.po$$//'`; \
+ if test -f "$(srcdir)/$${lang}.po"; then \
+ test "$(srcdir)" = . && cdcmd="" || cdcmd="cd
$(srcdir) && "; \
+ echo "$${cdcmd}$(MSGMERGE_UPDATE) $(MSGMERGE_OPTIONS) --lang=$${lang} $${lang}.po
$(DOMAIN).pot"; \
+ cd $(srcdir) \
+ && { case `$(MSGMERGE_UPDATE) --version | sed 1q | sed -e
's,^[^0-9]*,,'` in \
+ '' | 0.[0-9] | 0.[0-9].* | 0.1[0-7] | 0.1[0-7].*) \
+ $(MSGMERGE_UPDATE) $(MSGMERGE_OPTIONS) $${lang}.po $(DOMAIN).pot;; \
+ *) \
+ $(MSGMERGE_UPDATE) $(MSGMERGE_OPTIONS) --lang=$${lang} $${lang}.po
$(DOMAIN).pot;; \
+ esac; \
+ }; \
+ else \
+ $(MAKE) $${lang}.po-create; \
+ fi
+
+
+install: install-exec install-data
+install-exec:
+install-data: install-data-@USE_NLS@
+ if test "$(PACKAGE)" = "gettext-tools"; then \
+ $(MKDIR_P) $(DESTDIR)$(gettextsrcdir); \
+ for file in $(DISTFILES.common) Makevars.template; do \
+ $(INSTALL_DATA) $(srcdir)/$$file \
+ $(DESTDIR)$(gettextsrcdir)/$$file; \
+ done; \
+ for file in Makevars; do \
+ rm -f $(DESTDIR)$(gettextsrcdir)/$$file; \
+ done; \
+ else \
+ : ; \
+ fi
+install-data-no: all
+install-data-yes: all
+ @catalogs='$(CATALOGS)'; \
+ for cat in $$catalogs; do \
+ cat=`basename $$cat`; \
+ lang=`echo $$cat | sed -e 's/\.gmo$$//'`; \
+ dir=$(localedir)/$$lang/LC_MESSAGES; \
+ $(MKDIR_P) $(DESTDIR)$$dir; \
+ if test -r $$cat; then realcat=$$cat; else realcat=$(srcdir)/$$cat; fi; \
+ $(INSTALL_DATA) $$realcat $(DESTDIR)$$dir/$(DOMAIN).mo; \
+ echo "installing $$realcat as $(DESTDIR)$$dir/$(DOMAIN).mo"; \
+ for lc in '' $(EXTRA_LOCALE_CATEGORIES); do \
+ if test -n "$$lc"; then \
+ if (cd $(DESTDIR)$(localedir)/$$lang && LC_ALL=C ls -l -d $$lc
2>/dev/null) | grep ' -> ' >/dev/null; then \
+ link=`cd $(DESTDIR)$(localedir)/$$lang && LC_ALL=C ls -l -d $$lc | sed
-e 's/^.* -> //'`; \
+ mv $(DESTDIR)$(localedir)/$$lang/$$lc $(DESTDIR)$(localedir)/$$lang/$$lc.old; \
+ mkdir $(DESTDIR)$(localedir)/$$lang/$$lc; \
+ (cd $(DESTDIR)$(localedir)/$$lang/$$lc.old && \
+ for file in *; do \
+ if test -f $$file; then \
+ ln -s ../$$link/$$file $(DESTDIR)$(localedir)/$$lang/$$lc/$$file; \
+ fi; \
+ done); \
+ rm -f $(DESTDIR)$(localedir)/$$lang/$$lc.old; \
+ else \
+ if test -d $(DESTDIR)$(localedir)/$$lang/$$lc; then \
+ :; \
+ else \
+ rm -f $(DESTDIR)$(localedir)/$$lang/$$lc; \
+ mkdir $(DESTDIR)$(localedir)/$$lang/$$lc; \
+ fi; \
+ fi; \
+ rm -f $(DESTDIR)$(localedir)/$$lang/$$lc/$(DOMAIN).mo; \
+ ln -s ../LC_MESSAGES/$(DOMAIN).mo $(DESTDIR)$(localedir)/$$lang/$$lc/$(DOMAIN).mo
2>/dev/null || \
+ ln $(DESTDIR)$(localedir)/$$lang/LC_MESSAGES/$(DOMAIN).mo
$(DESTDIR)$(localedir)/$$lang/$$lc/$(DOMAIN).mo 2>/dev/null || \
+ cp -p $(DESTDIR)$(localedir)/$$lang/LC_MESSAGES/$(DOMAIN).mo
$(DESTDIR)$(localedir)/$$lang/$$lc/$(DOMAIN).mo; \
+ echo "installing $$realcat link as
$(DESTDIR)$(localedir)/$$lang/$$lc/$(DOMAIN).mo"; \
+ fi; \
+ done; \
+ done
+
+install-strip: install
+
+installdirs: installdirs-exec installdirs-data
+installdirs-exec:
+installdirs-data: installdirs-data-@USE_NLS@
+ if test "$(PACKAGE)" = "gettext-tools"; then \
+ $(MKDIR_P) $(DESTDIR)$(gettextsrcdir); \
+ else \
+ : ; \
+ fi
+installdirs-data-no:
+installdirs-data-yes:
+ @catalogs='$(CATALOGS)'; \
+ for cat in $$catalogs; do \
+ cat=`basename $$cat`; \
+ lang=`echo $$cat | sed -e 's/\.gmo$$//'`; \
+ dir=$(localedir)/$$lang/LC_MESSAGES; \
+ $(MKDIR_P) $(DESTDIR)$$dir; \
+ for lc in '' $(EXTRA_LOCALE_CATEGORIES); do \
+ if test -n "$$lc"; then \
+ if (cd $(DESTDIR)$(localedir)/$$lang && LC_ALL=C ls -l -d $$lc
2>/dev/null) | grep ' -> ' >/dev/null; then \
+ link=`cd $(DESTDIR)$(localedir)/$$lang && LC_ALL=C ls -l -d $$lc | sed
-e 's/^.* -> //'`; \
+ mv $(DESTDIR)$(localedir)/$$lang/$$lc $(DESTDIR)$(localedir)/$$lang/$$lc.old; \
+ mkdir $(DESTDIR)$(localedir)/$$lang/$$lc; \
+ (cd $(DESTDIR)$(localedir)/$$lang/$$lc.old && \
+ for file in *; do \
+ if test -f $$file; then \
+ ln -s ../$$link/$$file $(DESTDIR)$(localedir)/$$lang/$$lc/$$file; \
+ fi; \
+ done); \
+ rm -f $(DESTDIR)$(localedir)/$$lang/$$lc.old; \
+ else \
+ if test -d $(DESTDIR)$(localedir)/$$lang/$$lc; then \
+ :; \
+ else \
+ rm -f $(DESTDIR)$(localedir)/$$lang/$$lc; \
+ mkdir $(DESTDIR)$(localedir)/$$lang/$$lc; \
+ fi; \
+ fi; \
+ fi; \
+ done; \
+ done
+
+# Define this as empty until I found a useful application.
+installcheck:
+
+uninstall: uninstall-exec uninstall-data
+uninstall-exec:
+uninstall-data: uninstall-data-@USE_NLS@
+ if test "$(PACKAGE)" = "gettext-tools"; then \
+ for file in $(DISTFILES.common) Makevars.template; do \
+ rm -f $(DESTDIR)$(gettextsrcdir)/$$file; \
+ done; \
+ else \
+ : ; \
+ fi
+uninstall-data-no:
+uninstall-data-yes:
+ catalogs='$(CATALOGS)'; \
+ for cat in $$catalogs; do \
+ cat=`basename $$cat`; \
+ lang=`echo $$cat | sed -e 's/\.gmo$$//'`; \
+ for lc in LC_MESSAGES $(EXTRA_LOCALE_CATEGORIES); do \
+ rm -f $(DESTDIR)$(localedir)/$$lang/$$lc/$(DOMAIN).mo; \
+ done; \
+ done
+
+check: all
+
+info dvi ps pdf html tags TAGS ctags CTAGS ID:
+
+mostlyclean:
+ rm -f remove-potcdate.sed
+ rm -f stamp-poT
+ rm -f core core.* $(DOMAIN).po $(DOMAIN).1po $(DOMAIN).2po *.new.po
+ rm -fr *.o
+
+clean: mostlyclean
+
+distclean: clean
+ rm -f Makefile Makefile.in POTFILES *.mo
+
+maintainer-clean: distclean
+ @echo "This command is intended for maintainers to use;"
+ @echo "it deletes files that may require special tools to rebuild."
+ rm -f stamp-po $(GMOFILES)
+
+distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir)
+dist distdir:
+ $(MAKE) update-po
+ @$(MAKE) dist2
+# This is a separate target because 'update-po' must be executed before.
+dist2: stamp-po $(DISTFILES)
+ dists="$(DISTFILES)"; \
+ if test "$(PACKAGE)" = "gettext-tools"; then \
+ dists="$$dists Makevars.template"; \
+ fi; \
+ if test -f $(srcdir)/$(DOMAIN).pot; then \
+ dists="$$dists $(DOMAIN).pot stamp-po"; \
+ fi; \
+ if test -f $(srcdir)/ChangeLog; then \
+ dists="$$dists ChangeLog"; \
+ fi; \
+ for i in 0 1 2 3 4 5 6 7 8 9; do \
+ if test -f $(srcdir)/ChangeLog.$$i; then \
+ dists="$$dists ChangeLog.$$i"; \
+ fi; \
+ done; \
+ if test -f $(srcdir)/LINGUAS; then dists="$$dists LINGUAS"; fi; \
+ for file in $$dists; do \
+ if test -f $$file; then \
+ cp -p $$file $(distdir) || exit 1; \
+ else \
+ cp -p $(srcdir)/$$file $(distdir) || exit 1; \
+ fi; \
+ done
+
+update-po: Makefile
+ $(MAKE) $(DOMAIN).pot-update
+ test -z "$(UPDATEPOFILES)" || $(MAKE) $(UPDATEPOFILES)
+ $(MAKE) update-gmo
+
+# General rule for creating PO files.
+
+.nop.po-create:
+ @lang=`echo $@ | sed -e 's/\.po-create$$//'`; \
+ echo "File $$lang.po does not exist. If you are a translator, you can create it
through 'msginit'." 1>&2; \
+ exit 1
+
+# General rule for updating PO files.
+
+.nop.po-update:
+ @lang=`echo $@ | sed -e 's/\.po-update$$//'`; \
+ if test "$(PACKAGE)" = "gettext-tools"; then
PATH=`pwd`/../src:$$PATH; fi; \
+ tmpdir=`pwd`; \
+ echo "$$lang:"; \
+ test "$(srcdir)" = . && cdcmd="" || cdcmd="cd $(srcdir)
&& "; \
+ echo "$${cdcmd}$(MSGMERGE) $(MSGMERGE_OPTIONS) --lang=$$lang $$lang.po
$(DOMAIN).pot -o $$lang.new.po"; \
+ cd $(srcdir); \
+ if { case `$(MSGMERGE) --version | sed 1q | sed -e 's,^[^0-9]*,,'` in \
+ '' | 0.[0-9] | 0.[0-9].* | 0.1[0-7] | 0.1[0-7].*) \
+ $(MSGMERGE) $(MSGMERGE_OPTIONS) -o $$tmpdir/$$lang.new.po $$lang.po
$(DOMAIN).pot;; \
+ *) \
+ $(MSGMERGE) $(MSGMERGE_OPTIONS) --lang=$$lang -o $$tmpdir/$$lang.new.po
$$lang.po $(DOMAIN).pot;; \
+ esac; \
+ }; then \
+ if cmp $$lang.po $$tmpdir/$$lang.new.po >/dev/null 2>&1; then \
+ rm -f $$tmpdir/$$lang.new.po; \
+ else \
+ if mv -f $$tmpdir/$$lang.new.po $$lang.po; then \
+ :; \
+ else \
+ echo "msgmerge for $$lang.po failed: cannot move $$tmpdir/$$lang.new.po to
$$lang.po" 1>&2; \
+ exit 1; \
+ fi; \
+ fi; \
+ else \
+ echo "msgmerge for $$lang.po failed!" 1>&2; \
+ rm -f $$tmpdir/$$lang.new.po; \
+ fi
+
+$(DUMMYPOFILES):
+
+update-gmo: Makefile $(GMOFILES)
+ @:
+
+# Recreate Makefile by invoking config.status. Explicitly invoke the shell,
+# because execution permission bits may not work on the current file system.
+# Use @SHELL@, which is the shell determined by autoconf for the use by its
+# scripts, not $(SHELL) which is hardwired to /bin/sh and may be deficient.
+Makefile: Makefile.in.in Makevars $(top_builddir)/config.status @POMAKEFILEDEPS@
+ cd $(top_builddir) \
+ && @SHELL@ ./config.status $(subdir)/$@.in po-directories
+
+force:
+
+# Tell versions [3.59,3.63) of GNU make not to export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/src/wok/plugins/kimchi/po/Makevars b/src/wok/plugins/kimchi/po/Makevars
new file mode 100644
index 0000000..c29a807
--- /dev/null
+++ b/src/wok/plugins/kimchi/po/Makevars
@@ -0,0 +1,41 @@
+# Makefile variables for PO directory in any package using GNU gettext.
+
+# Usually the message domain is the same as the package name.
+DOMAIN = kimchi
+
+# These two variables depend on the location of this directory.
+subdir = po
+top_builddir = ..
+
+# These options get passed to xgettext.
+XGETTEXT_OPTIONS = --keyword=_ --keyword=N_
+
+# This is the copyright holder that gets inserted into the header of the
+# $(DOMAIN).pot file. Set this to the copyright holder of the surrounding
+# package. (Note that the msgstr strings, extracted from the package's
+# sources, belong to the copyright holder of the package.) Translators are
+# expected to transfer the copyright for their translations to this person
+# or entity, or to disclaim their copyright. The empty string stands for
+# the public domain; in this case the translators are expected to disclaim
+# their copyright.
+COPYRIGHT_HOLDER =
+
+# This is the email address or URL to which the translators shall report
+# bugs in the untranslated strings:
+# - Strings which are not entire sentences, see the maintainer guidelines
+# in the GNU gettext documentation, section 'Preparing Strings'.
+# - Strings which use unclear terms or require additional context to be
+# understood.
+# - Strings which make invalid assumptions about notation of date, time or
+# money.
+# - Pluralisation problems.
+# - Incorrect English spelling.
+# - Incorrect formatting.
+# It can be your email address, or a mailing list address where translators
+# can write to without being subscribed, or the URL of a web page through
+# which the translators can contact you.
+MSGID_BUGS_ADDRESS = project-kimchi(a)googlegroups.com
+
+# This is the list of locale categories, beyond LC_MESSAGES, for which the
+# message catalogs shall be used. It is usually empty.
+EXTRA_LOCALE_CATEGORIES =
diff --git a/src/wok/plugins/kimchi/po/POTFILES.in
b/src/wok/plugins/kimchi/po/POTFILES.in
new file mode 100644
index 0000000..92eef1e
--- /dev/null
+++ b/src/wok/plugins/kimchi/po/POTFILES.in
@@ -0,0 +1,3 @@
+# List of source files which contain translatable strings.
+i18n.py
+ui/pages/*.tmpl
diff --git a/src/wok/plugins/kimchi/po/de_DE.po b/src/wok/plugins/kimchi/po/de_DE.po
new file mode 100644
index 0000000..d3f3cc3
--- /dev/null
+++ b/src/wok/plugins/kimchi/po/de_DE.po
@@ -0,0 +1,2288 @@
+# English translations for kimchi package.
+# Copyright (C) 2013 ORGANIZATION
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: kimchi 0.1\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2015-07-01 16:11-0300\n"
+"PO-Revision-Date: 2013-07-11 17:32-0400\n"
+"Last-Translator: Cr��stian Viana <vianac(a)linux.vnet.ibm.com>\n"
+"Language-Team: English\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Language: de_DE\n"
+"Generated-By: pygettext.py 1.5\n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+
+#, python-format
+msgid "Unknown parameter %(value)s"
+msgstr ""
+
+#, python-format
+msgid "Timeout of %(seconds)s seconds expired while running task
'%(task)s."
+msgstr ""
+
+#, python-format
+msgid "User %(user_id)s not found with given LDAP settings."
+msgstr ""
+
+msgid "Unknown \"_cap\" specified"
+msgstr ""
+
+msgid "\"_passthrough\" should be \"true\" or
\"false\""
+msgstr ""
+
+msgid "\"_passthrough_affected_by\" should be a device name string"
+msgstr ""
+
+#, python-format
+msgid "Error while getting block devices. Details: %(err)s"
+msgstr "Fehler beim Abrufen von Blockeinheiten. Details: %(err)s"
+
+#, python-format
+msgid "Error while getting block device information for %(device)s."
+msgstr "Fehler beim Abrufen von Blockeinheitinformationen f��r %(device)s."
+
+#, python-format
+msgid "Unable to find distro file: %(filename)s"
+msgstr "Distro-Datei konnte nicht gefunden werden: %(filename)s"
+
+#, python-format
+msgid ""
+"Unable to parse distro file: %(filename)s. Make sure, it is a JSON file."
+msgstr ""
+"Distro-Datei konnte nicht analysiert werden: %(filename)s. Stellen Sie "
+"sicher, dass es sich um eine JSON-Datei handelt."
+
+#, python-format
+msgid "Unable to login to iSCSI host target %(portal)s. Details: %(err)s"
+msgstr "Fehler beim Anmelden bei iSCSI-Hostziel %(portal)s. Details: %(err)s"
+
+#, python-format
+msgid "Unable to login to iSCSI host %(host)s target %(target)s"
+msgstr "Anmeldung bei iSCSI-Host %(host)s Ziel %(target)s nicht m��glich"
+
+#, python-format
+msgid "Unable to find ISO file %(filename)s"
+msgstr ""
+
+#, python-format
+msgid "The ISO file %(filename)s is not bootable"
+msgstr "Die ISO-Datei %(filename)s ist nicht bootf��hig"
+
+#, python-format
+msgid "The ISO file %(filename)s does not have a valid El Torito boot record"
+msgstr "Die ISO-Datei %(filename)s hat keinen g��ltigen El Torito-Bootsatz"
+
+#, python-format
+msgid "Invalid El Torito validation entry in ISO %(filename)s"
+msgstr "Ung��ltiger El Torito-Pr��feintrag in ISO-Datei %(filename)s"
+
+#, python-format
+msgid "Invalid El Torito boot indicator in ISO %(filename)s"
+msgstr "Ung��ltiger El Torito-Boot-Indikator in ISO-Datei %(filename)s"
+
+#, python-format
+msgid "Unexpected volume type for primary volume in ISO %(filename)s"
+msgstr ""
+"Unerwarteter Datentr��gertyp f��r Prim��rdatentr��ger in ISO-Datei
%(filename)s"
+
+#, python-format
+msgid "Bad format while reading volume descriptor in ISO %(filename)s"
+msgstr ""
+"Ung��ltiges Format beim Lesen des Datentr��gerdeskriptors in ISO-Datei %"
+"(filename)s"
+
+#, python-format
+msgid ""
+"The hypervisor doesn't have permission to use this ISO %(filename)s. "
+"Consider moving it under /var/lib/libvirt, or set the search permission to "
+"file access control lists for '%(user)s' user if possible, or add the
'%"
+"(user)s' to the ISO path group, or (not recommended) 'chmod -R o+x "
+"'path_to_iso'.Details: %(err)s"
+msgstr ""
+"Der Hypervisor hat nicht die Berechtigung, die ISO-Datei %(filename)s zu "
+"verwenden. Verschieben Sie sie entweder nach /var/lib/libvirt oder setzen "
+"Sie, sofern m��glich, die Suchberechtigung auf Dateizugriffssteuerungslisten
"
+"f��r den Benutzer '%(user)s' oder f��gen Sie '%(user)s' der
ISO-Pfadgruppe "
+"hinzu oder (nicht empfohlen) 'chmod -R o+x 'path_to_iso'. Details:
%(err)s"
+
+msgid "An error occurred when probing image OS information."
+msgstr ""
+
+msgid "No OS information found in given image."
+msgstr ""
+
+#, python-format
+msgid "Unable to read image file %(filename)s"
+msgstr ""
+
+#, python-format
+msgid ""
+"Image file must be an existing file on system. %(filename)s is not a valid "
+"input."
+msgstr ""
+
+#, python-format
+msgid "Virtual machine %(name)s already exists"
+msgstr "Virtuelle Maschine %(name)s ist bereits vorhanden"
+
+#, python-format
+msgid "Virtual machine %(name)s does not exist"
+msgstr "Virtuelle Maschine %(name)s ist nicht vorhanden"
+
+#, python-format
+msgid ""
+"Unable to rename virtual machine %(name)s. The name %(new_name)s is already "
+"in use or the virtual machine is not powered off."
+msgstr ""
+
+#, python-format
+msgid "Unable to retrieve screenshot for stopped virtual machine %(name)s"
+msgstr ""
+"Screenshot f��r gestoppte virtuelle Maschine %(name)s konnte nicht abgerufen
"
+"werden"
+
+msgid "Remote ISO image is not supported by this server."
+msgstr "Fernes ISO-Image wird von diesem Server nicht unterst��tzt."
+
+#, python-format
+msgid "Screenshot is not supported on virtual machine %(name)s"
+msgstr ""
+
+#, python-format
+msgid "Unable to create virtual machine %(name)s. Details: %(err)s"
+msgstr ""
+"Virtuelle Maschine %(name)s konnte nicht erstellt werden. Details: %(err)s"
+
+#, python-format
+msgid "Unable to update virtual machine %(name)s. Details: %(err)s"
+msgstr ""
+"Virtuelle Maschine %(name)s konnte nicht erstellt werden. Details: %(err)s"
+
+#, python-format
+msgid "Unable to retrieve virtual machine %(name)s. Details: %(err)s"
+msgstr ""
+"Virtuelle Maschine %(name)s konnte nicht abgerufen werden. Details: %(err)s"
+
+#, python-format
+msgid "Unable to connect to powered off virtual machine %(name)s."
+msgstr ""
+"Verbindung zur abgeschalteten Maschine %(name)s konnte nicht hergestellt "
+"werden."
+
+msgid "Virtual machine name must be a string without slashes (/)"
+msgstr ""
+
+#, python-format
+msgid "Invalid template URI %(value)s specified for virtual machine"
+msgstr ""
+
+#, python-format
+msgid "Invalid storage pool URI %(value)s specified for virtual machine"
+msgstr ""
+
+msgid "Supported virtual machine graphics are Spice or VNC"
+msgstr ""
+
+msgid "Graphics address to listen on must be IPv4 or IPv6"
+msgstr "Zu ��berwachende Grafikadresse muss IPv4 oder IPv6 sein"
+
+msgid "Specify a template to create a virtual machine from"
+msgstr "Vorlage angeben, aus der eine virtuelle Maschine erstellt werden soll"
+
+#, python-format
+msgid "Unable to start virtual machine %(name)s. Details: %(err)s"
+msgstr ""
+"Virtuelle Maschine %(name)s konnte nicht gestartet werden. Details: %(err)s"
+
+#, python-format
+msgid "Unable to power off virtual machine %(name)s. Details: %(err)s"
+msgstr ""
+"Virtuelle Maschine %(name)s konnte nicht gestoppt werden. Details: %(err)s"
+
+#, python-format
+msgid "Unable to delete virtual machine %(name)s. Details: %(err)s"
+msgstr ""
+"Virtuelle Maschine %(name)s konnte nicht gel��scht werden. Details: %(err)s"
+
+#, python-format
+msgid "Unable to reset virtual machine %(name)s. Details: %(err)s"
+msgstr ""
+"Virtuelle Maschine %(name)s konnte nicht umbenannt werden. Details: %(err)s"
+
+msgid "User name list must be an array"
+msgstr ""
+
+msgid "User name must be a string"
+msgstr "Netzname muss eine Zeichenfolge sein"
+
+msgid "Group name list must be an array"
+msgstr ""
+
+msgid "Group name must be a string"
+msgstr "Netzname muss eine Zeichenfolge sein"
+
+#, python-format
+msgid "User(s) '%(users)s' do not exist"
+msgstr "Benutzer '%(users)s' ist nicht vorhanden."
+
+#, python-format
+msgid "Group(s) '%(groups)s' do not exist"
+msgstr "Benutzer '%(groups)s' ist nicht vorhanden."
+
+#, python-format
+msgid "Unable to shutdown virtual machine %(name)s. Details: %(err)s"
+msgstr ""
+"Virtuelle Maschine %(name)s konnte nicht gestoppt werden. Details: %(err)s"
+
+#, python-format
+msgid ""
+"Unable to get access metadata of virtual machine %(name)s. Details: %(err)s"
+msgstr ""
+"Virtuelle Maschine %(name)s konnte nicht gestartet werden. Details: %(err)s"
+
+msgid "The guest console password must be a string."
+msgstr ""
+
+msgid "The life time for the guest console password must be a number."
+msgstr ""
+
+#, python-format
+msgid "Virtual machine '%(name)s' must be stopped before cloning it."
+msgstr ""
+
+#, python-format
+msgid "Insufficient disk space to clone virtual machine '%(name)s'"
+msgstr ""
+
+#, python-format
+msgid "Unable to clone VM '%(name)s'. Details: %(err)s"
+msgstr ""
+
+#, python-format
+msgid "Invalid operation for non-persistent virtual machine %(name)s"
+msgstr ""
+
+#, python-format
+msgid "Cannot suspend VM '%(name)s' because it is not running."
+msgstr ""
+
+#, python-format
+msgid "Unable to suspend VM '%(name)s'. Details: %(err)s"
+msgstr ""
+
+#, python-format
+msgid "Cannot resume VM '%(name)s' because it is not paused."
+msgstr ""
+
+#, python-format
+msgid "Unable to resume VM '%(name)s'. Details: %(err)s"
+msgstr ""
+
+msgid "Memory assigned is higher then the maximum allowed in the host."
+msgstr ""
+
+#, python-format
+msgid ""
+"VM '%(name)s' does not support live memory update. Update the memory with
"
+"the machine offline to enable this feature."
+msgstr ""
+
+msgid "Only increase memory is allowed in active VMs"
+msgstr ""
+
+msgid ""
+"For live memory update, new memory value must be equal old memory value plus
"
+"multiples of 1024 Mib"
+msgstr ""
+
+msgid "There are not enough free slots of 1024 Mib in the guest."
+msgstr ""
+
+msgid ""
+"Host's libvirt version does not support memory devices. Libvirt must be >=
"
+"1.2.14"
+msgstr ""
+
+#, python-format
+msgid "Error attaching memory device. Details: %(error)s"
+msgstr ""
+
+#, python-format
+msgid ""
+"VM %(vmid)s does not contain directly assigned host device %(dev_name)s."
+msgstr ""
+
+#, python-format
+msgid "The host device %(dev_name)s is not allowed to directly assign to VM."
+msgstr ""
+
+msgid ""
+"No IOMMU groups found. Host PCI pass through needs IOMMU group to function "
+"correctly. Please enable Intel VT-d or AMD IOMMU in your BIOS, then verify "
+"the Kernel is compiled with IOMMU support. For Intel CPU, add intel_iommu=on
"
+"to your Kernel parameter in /boot/grub2/grub.conf. For AMD CPU, add iommu=pt
"
+"iommu=1."
+msgstr ""
+
+msgid "\"name\" should be a device name string"
+msgstr ""
+
+#, python-format
+msgid ""
+"The device %(name)s is probably in use by the host. Unable to attach it to "
+"the guest."
+msgstr ""
+
+#, python-format
+msgid "Interface %(iface)s does not exist in virtual machine %(name)s"
+msgstr ""
+"Schnittstelle %(iface)s ist in virtueller Maschine %(name)s nicht vorhanden"
+
+#, python-format
+msgid ""
+"Network %(network)s specified for virtual machine %(name)s does not exist"
+msgstr ""
+"Das f��r die virtuelle Maschine %(name)s angegebene Netz %(network)s ist "
+"nicht vorhanden"
+
+msgid "Supported virtual machine interfaces type is only network"
+msgstr "Unterst��tzter Schnittstellentyp einer virtuellen Maschine ist nur
Netz"
+
+msgid "Network name for virtual machine interface must be a string"
+msgstr ""
+"Netzname f��r Schnittstelle einer virtuellen Maschine muss eine Zeichenfolge
"
+"sein"
+
+msgid "Invalid network model card specified for virtual machine interface"
+msgstr ""
+"Ung��ltige Netzmodellkarte f��r Schnittstelle einer virtuellen Maschine "
+"angegeben"
+
+msgid "Specify type and network to add a new virtual machine interface"
+msgstr ""
+"Geben Sie Typ und Netz an, um eine neue Schnittstelle f��r eine virtuelle "
+"Maschine hinzuzuf��gen"
+
+msgid "MAC Address must respect this format FF:FF:FF:FF:FF:FF"
+msgstr ""
+
+#, python-format
+msgid "MAC Address %(mac)s already exists in virtual machine %(name)s"
+msgstr ""
+
+msgid "Invalid MAC Address"
+msgstr ""
+
+msgid "Cannot change MAC address of a running virtual machine"
+msgstr ""
+
+#, python-format
+msgid "Template %(name)s already exists"
+msgstr "Vorlage %(name)s ist bereits vorhanden"
+
+#, python-format
+msgid ""
+"Network '%(network)s' specified for template %(template)s does not
exist"
+msgstr ""
+"Das f��r Vorlage %(template)s angegebene Netz '%(network)s' ist nicht
"
+"vorhanden"
+
+#, python-format
+msgid ""
+"Storage pool %(pool)s specified for template %(template)s does not exist"
+msgstr ""
+"Der f��r Vorlage %(template)s angegebene Speicherpool '%(pool)s' ist nicht
"
+"vorhanden"
+
+#, python-format
+msgid "Storage pool %(pool)s specified for template %(template)s is not
active"
+msgstr ""
+"Der f��r Vorlage %(template)s angegebene Speicherpool '%(pool)s' ist nicht
"
+"aktiv"
+
+#, python-format
+msgid "Invalid parameter '%(param)s' specified for CDROM."
+msgstr "Ung��ltiger Parameter '%(param)s' f��r CD-ROM angegeben."
+
+#, python-format
+msgid "Network %(network)s specified for template %(template)s is not active"
+msgstr ""
+"Das f��r Vorlage %(template)s angegebene Netz %(network)s ist nicht aktiv"
+
+msgid "Template name must be a string"
+msgstr "Vorlagenname muss eine Zeichenfolge sein"
+
+msgid "Template icon must be a path to the image"
+msgstr "Vorlagensymbol muss ein Pfad zum Image sein"
+
+msgid "Template distribution must be a string"
+msgstr "Vorlagenverteilung muss eine Zeichenfolge sein"
+
+msgid "Template distribution version must be a string"
+msgstr "Vorlagenverteilungsversion muss eine Zeichenfolge sein"
+
+msgid "The number of CPUs must be an integer greater than 0"
+msgstr "Die Anzahl der CPUs muss eine Ganzzahl sein"
+
+msgid "Amount of memory (MB) must be an integer greater than 512"
+msgstr "Speicherkapazit��t (MB) muss eine Ganzzahl gr����er als 512 sein"
+
+msgid "Template CDROM must be a local or remote ISO file"
+msgstr "Vorlagen-CD-ROM muss eine lokale oder ferne ISO-Datei sein"
+
+#, python-format
+msgid "Invalid storage pool URI %(value)s specified for template"
+msgstr "Ung��ltiger Speicherpool-URI %(value)s f��r Vorlage angegeben"
+
+msgid "Specify an ISO image as CDROM or a base image to create a template"
+msgstr "Geben Sie ein ISO-Image als CD-ROM an, um eine Vorlage zu erstellen"
+
+msgid "All networks for the template must be specified in a list."
+msgstr "Alle Netze f��r die Vorlage m��ssen in einer Liste angegeben werden."
+
+msgid "Specify a volume to a template when storage pool is iSCSI or SCSI"
+msgstr ""
+
+#, python-format
+msgid "The volume %(volume)s is not in storage pool %(pool)s"
+msgstr ""
+
+#, python-format
+msgid "Unable to create template due error: %(err)s"
+msgstr ""
+"Vorlage kann aufgrund des folgenden Fehlers nicht erstellt werden: %(err)s"
+
+#, python-format
+msgid "Unable to delete template due error: %(err)s"
+msgstr ""
+"Vorlage kann aufgrund des folgenden Fehlers nicht gel��scht werden: %(err)s"
+
+msgid "Disk size must be an integer greater than 1GB."
+msgstr ""
+
+msgid "Template base image must be a valid local image file"
+msgstr "Vorlagen-CD-ROM muss eine lokale oder ferne ISO-Datei sein"
+
+#, python-format
+msgid "Cannot identify base image %(path)s format"
+msgstr ""
+
+msgid ""
+"When specifying CPU topology, VCPUs must be a product of sockets, cores, and
"
+"threads."
+msgstr ""
+
+msgid ""
+"When specifying CPU topology, each element must be an integer greater than "
+"zero."
+msgstr ""
+
+msgid ""
+"Invalid disk image format. Valid formats: bochs, cloop, cow, dmg, qcow, "
+"qcow2, qed, raw, vmdk, vpc."
+msgstr ""
+
+#, python-format
+msgid "Storage pool %(name)s already exists"
+msgstr "Speicherpool %(name)s ist bereits vorhanden"
+
+#, python-format
+msgid "Storage pool %(name)s does not exist"
+msgstr "Speicherpool %(name)s ist nicht vorhanden"
+
+#, python-format
+msgid "Specify %(item)s in order to create the storage pool %(name)s"
+msgstr "Geben Sie %(item)s an, um den Speicherpool %(name)s zu erstellen"
+
+#, python-format
+msgid "Unable to delete active storage pool %(name)s"
+msgstr "Aktiver Speicherpool %(name)s konnte nicht gel��scht werden"
+
+#, python-format
+msgid "Unable to list storage pools. Details: %(err)s"
+msgstr "Speicherpools konnten nicht aufgelistet werden. Details: %(err)s"
+
+#, python-format
+msgid "Unable to create storage pool %(name)s. Details: %(err)s"
+msgstr "Speicherpool %(name)s konnte nicht erstellt werden. Details: %(err)s"
+
+#, python-format
+msgid ""
+"Unable to get number of storage volumes in storage pool %(name)s. Details: %"
+"(err)s"
+msgstr ""
+"Anzahl der Speicherdatentr��ger im Speicherpool %(name)s konnte nicht "
+"abgerufen werden. Details: %(err)s"
+
+#, python-format
+msgid "Unable to activate storage pool %(name)s. Details: %(err)s"
+msgstr "Speicherpool %(name)s konnte nicht aktiviert werden. Details: %(err)s"
+
+#, python-format
+msgid "Unable to deactivate storage pool %(name)s. Details: %(err)s"
+msgstr ""
+"Speicherpool %(name)s konnte nicht inaktiviert werden. Details: %(err)s"
+
+#, python-format
+msgid "Unable to delete storage pool %(name)s. Details: %(err)s"
+msgstr "Speicherpool %(name)s konnte nicht gel��scht werden. Details: %(err)s"
+
+#, python-format
+msgid ""
+"Unable to create NFS Pool as export path %(path)s may block during mount"
+msgstr ""
+"NFS-Pool konnte nicht erstellt werden, weil Exportpfad %(path)s beim Mounten
"
+"blockieren kann"
+
+#, python-format
+msgid "Unable to create NFS Pool as export path %(path)s mount failed"
+msgstr ""
+"NFS-Pool konnte nicht erstellt werden, weil das Mounten des Exportpfads%"
+"(path)s fehlgeschlagen ist"
+
+#, python-format
+msgid "Unsupported storage pool type: %(type)s"
+msgstr "Nicht unterst��tzter Speicherpooltyp: %(type)s"
+
+#, python-format
+msgid "Error while retrieving storage pool XML to %(pool)s"
+msgstr ""
+
+msgid "Storage pool name must be a string without slashes (/)"
+msgstr ""
+
+msgid ""
+"Supported storage pool types are dir, netfs, logical, iscsi, isci and
kimchi-"
+"iso"
+msgstr ""
+
+msgid "Storage pool path must be a string"
+msgstr "Speicherpoolpfad muss eine Zeichenfolge sein"
+
+msgid "Storage pool host must be a IP or hostname"
+msgstr "Speicherpoolhost muss eine IP oder ein Hostname sein"
+
+msgid "Storage pool device must be the absolute path to the block device"
+msgstr ""
+
+msgid "Storage pool devices parameter must be a list"
+msgstr "Einheitenparameter des Speicherpools muss eine Liste sein"
+
+msgid "Target IQN of an iSCSI pool must be a string"
+msgstr "Ziel-IQN eines iSCSI-Pools muss eine Zeichenfolge sein"
+
+msgid "Port of a remote storage server must be an integer between 1 and 65535"
+msgstr ""
+"Port eines fernen Speicherservers muss eine Ganzzahl zwischen 1 und 65535 "
+"sein"
+
+msgid "iSCSI target username must be a string"
+msgstr ""
+
+msgid "iSCSI target password must be a string"
+msgstr ""
+
+msgid "Specify name and type to create a storage pool"
+msgstr "Geben Sie Name und Typ an, um einen Speicherpool zu erstellen"
+
+#, python-format
+msgid ""
+"%(disk)s is not a valid disk/partition. Could not add it to the pool %(pool)"
+"s."
+msgstr ""
+"%(disk)s ist keine g��ltige Platte/Partition. Sie konnte nicht hinzugef��gt "
+"werden zum Pool %(pool)s."
+
+#, python-format
+msgid "Unable to extend logical pool %(pool)s. Details: %(err)s"
+msgstr ""
+
+msgid "The parameter disks only can be updated for logical storage pool."
+msgstr ""
+"Die Parameterplatten k��nnen nur f��r den logischen Speicherpool aktualisiert
"
+"werden."
+
+msgid "The SCSI host adapter name must be a string."
+msgstr "Der Name des SCSI-Hostadapters muss eine Zeichenfolge sein."
+
+msgid "The storage pool kimchi_isos is reserved for internal use"
+msgstr "Der Speicherpool kimchi_isos ist f��r die interne Verwendung
reserviert"
+
+#, python-format
+msgid ""
+"Unable to activate NFS storage pool %(name)s. NFS server %(server)s is "
+"unreachable."
+msgstr ""
+"Der NFS-Speicherpool %(name)s konnte nicht aktiviert werden. NFS-Server %"
+"(server)s ist nicht erreichbar."
+
+#, python-format
+msgid ""
+"Unable to deactivate NFS storage pool %(name)s. NFS server %(server)s is "
+"unreachable."
+msgstr ""
+"Der NFS-Speicherpool %(name)s konnte nicht inaktiviert werden. NFS-Server %"
+"(server)s ist nicht erreichbar."
+
+#, python-format
+msgid ""
+"Unable to deactivate pool %(name)s as it is associated with some templates"
+msgstr ""
+"Pool %(name)s konnte nicht inaktiviert werden, weil er einigen Vorlagen "
+"zugeordnet ist"
+
+#, python-format
+msgid "Unable to delete pool %(name)s as it is associated with some templates"
+msgstr ""
+"Pool %(name)s konnte nicht gel��scht werden, weil er einigen Vorlagen "
+"zugeordnet ist"
+
+#, python-format
+msgid ""
+"A volume group named '%(name)s' already exists. Please, choose another name
"
+"to create the logical pool."
+msgstr ""
+"Eine Datentr��gergruppe mit dem Namen '%(name)s' ist bereits vorhanden.
"
+"W��hlen Sie einen anderen Namen aus, um den logischen Pool zu erstellen."
+
+#, python-format
+msgid "Unable to update database with deep scan information due error:
%(err)s"
+msgstr ""
+"Datenbank mit Tiefenscaninformationen kann aufgrund des folgenden Fehlers "
+"nicht aktualisiert werden: %(err)s"
+
+#, python-format
+msgid "Storage volume %(name)s already exists"
+msgstr "Speicherdatentr��ger %(name)s ist bereits vorhanden"
+
+#, python-format
+msgid "Storage volume %(name)s does not exist in storage pool %(pool)s"
+msgstr ""
+"Speicherdatentr��ger %(name)s ist nicht im Speicherpool %(pool)s vorhanden"
+
+#, python-format
+msgid ""
+"Unable to create storage volume %(volume)s because storage pool %(pool)s is "
+"not active"
+msgstr ""
+
+#, python-format
+msgid "Specify %(item)s in order to create storage volume %(volume)s"
+msgstr "Geben Sie %(item)s an, um Speicherdatentr��ger %(volume)s zu
erstellen"
+
+#, python-format
+msgid ""
+"Unable to list storage volumes because storage pool %(pool)s is not active"
+msgstr ""
+"Speicherdatentr��ger konnten nicht aufgelistet werden, weil Speicherpool %"
+"(pool)s nicht aktiv ist"
+
+#, python-format
+msgid ""
+"Unable to create storage volume %(name)s in storage pool %(pool)s. Details:
%"
+"(err)s"
+msgstr ""
+"Speicherdatentr��ger %(name)s konnte nicht in Speicherpool %(pool)s erstellt
"
+"werden. Details: %(err)s"
+
+#, python-format
+msgid ""
+"Unable to list storage volumes in storage pool %(pool)s. Details: %(err)s"
+msgstr ""
+"Speicherdatentr��ger konnten nicht in Speicherpool %(pool)s aufgelistet "
+"werden. Details: %(err)s"
+
+#, python-format
+msgid "Unable to wipe storage volumes %(name)s. Details: %(err)s"
+msgstr ""
+"Speicherdatentr��ger %(name)s konnten nicht bereinigt werden. Details:
%(err)s"
+
+#, python-format
+msgid "Unable to delete storage volume %(name)s. Details: %(err)s"
+msgstr ""
+"Speicherdatentr��ger %(name)s konnte nicht gel��scht werden. Details:
%(err)s"
+
+#, python-format
+msgid "Unable to resize storage volume %(name)s. Details: %(err)s"
+msgstr ""
+"Gr����e des Speicherdatentr��gers %(name)s konnte nicht ge��ndert werden. "
+"Details: %(err)s"
+
+#, python-format
+msgid "Storage type %(type)s does not support volume create and delete"
+msgstr ""
+"Speichertyp %(type)s unterst��tzt nicht das Erstellen und L��schen von "
+"Datentr��gern"
+
+msgid "Storage volume name must be a string"
+msgstr "Name des Speicherdatentr��gers muss eine Zeichenfolge sein"
+
+msgid "Storage volume allocation must be an integer number"
+msgstr "Zuordnung des Speicherdatentr��gers muss eine Ganzzahl sein"
+
+msgid ""
+"Storage volume format not supported. Valid formats: bochs, cloop, cow, dmg, "
+"qcow, qcow2, qed, raw, vmdk, vpc."
+msgstr ""
+
+msgid "Storage volume requires a volume name"
+msgstr "Speicherdatentr��ger erfordert einen Datentr��gernamen"
+
+#, python-format
+msgid ""
+"Unable to update database with storage volume information due error: %(err)s"
+msgstr ""
+"Datenbank mit Datentr��gerinformationen kann aufgrund des folgenden Fehlers "
+"nicht aktualisiert werden: %(err)s"
+
+#, python-format
+msgid "Only one of parameter %(param)s can be specified"
+msgstr ""
+
+#, python-format
+msgid "Create volume from %(param)s is not supported"
+msgstr ""
+
+msgid "Storage volume capacity must be an integer number."
+msgstr ""
+
+msgid "Storage volume URL must be http://, https://, ftp:// or ftps://."
+msgstr ""
+
+#, python-format
+msgid "Unable to access file %(url)s. Please, check it."
+msgstr ""
+
+#, python-format
+msgid ""
+"Unable to clone storage volume '%(name)s' in pool '%(pool)s'.
Details: %(err)"
+"s"
+msgstr ""
+
+msgid "Specify chunk data and its size to upload a file."
+msgstr ""
+
+msgid "In order to upload a storage volume, specify the 'upload'
parameter."
+msgstr ""
+
+msgid ""
+"Unable to upload chunk data as it does not match with requested chunk size."
+msgstr ""
+
+#, python-format
+msgid "The storage volume %(vol)s is not under an upload process."
+msgstr ""
+
+msgid "The upload chunk data will exceed the storage volume size."
+msgstr ""
+
+#, python-format
+msgid "Unable to upload chunk data to storage volume. Details: %(err)s."
+msgstr ""
+
+#, python-format
+msgid "Interface %(name)s does not exist"
+msgstr "Schnittstelle %(name)s ist nicht vorhanden"
+
+#, python-format
+msgid "Network %(name)s already exists"
+msgstr "Netz %(name)s ist bereits vorhanden"
+
+#, python-format
+msgid "Network %(name)s does not exist"
+msgstr "Netz %(name)s ist nicht vorhanden"
+
+#, python-format
+msgid "Subnet %(subnet)s specified for network %(network)s is not valid."
+msgstr ""
+"Das f��r das Netz %(network)s angegebene Teilnetz %(subnet)s ist nicht
g��ltig."
+
+#, python-format
+msgid "Specify a network interface to create bridged network %(name)s"
+msgstr ""
+"Geben Sie eine Netzschnittstelle an, um ��berbr��cktes Netz %(name)s zu "
+"erstellen"
+
+#, python-format
+msgid "Unable to delete active network %(name)s"
+msgstr "Aktives Netz %(name)s konnte nicht gel��scht werden"
+
+#, python-format
+msgid "Interface %(iface)s specified for network %(network)s is already in
use"
+msgstr ""
+"Die f��r das Netz %(network)s angegebene Schnittstelle %(iface)s wird bereits
"
+"verwendet"
+
+msgid "Interface should be bare NIC, bonding or bridge device."
+msgstr "Schnittstelle sollte blo��es NIC, Bonding oder Br��ckeneinheit sein."
+
+#, python-format
+msgid "Unable to create network %(name)s. Details: %(err)s"
+msgstr "Netz %(name)s konnte nicht erstellt werden. Details: %(err)s"
+
+#, python-format
+msgid "Unable to find a free IP address for network '%(name)s'"
+msgstr "Es konnte keine freie IP-Adresse f��r Netz '%(name)s' gefunden
werden"
+
+#, python-format
+msgid "The interface %(iface)s already exists."
+msgstr ""
+
+msgid "Network name must be a string without slashes (/) or quotes (\")"
+msgstr ""
+
+msgid "Supported network types are isolated, NAT and bridge"
+msgstr "Unterst��tzte Netztypen sind Isoliert, NAT und Br��cke"
+
+msgid "Network subnet must be a string with IP address and prefix or netmask"
+msgstr ""
+"Teilnetz des Netzes muss eine Zeichenfolge mit IP-Adresse und Pr��fix oder "
+"Netzmaske sein"
+
+msgid "Network interface must be a string"
+msgstr "Netzschnittstelle muss eine Zeichenfolge sein"
+
+msgid "Network VLAN ID must be an integer between 1 and 4094"
+msgstr "Netz-VLAN-ID muss eine Ganzzahl zwischen 1 und 4094 sein"
+
+msgid "Specify name and type to create a Network"
+msgstr "Geben Sie Name und Typ an, um ein Netz zu erstellen"
+
+#, python-format
+msgid ""
+"Unable to delete network %(name)s. There are some virtual machines %(vms)s "
+"and/or templates linked to this network."
+msgstr ""
+"Netz %(name)s konnte nicht inaktiviert werden. Es sind einige virtuellen "
+"Maschinen %(vms)s und/oder Vorlagen mit diesem Netz verkn��pft."
+
+#, python-format
+msgid ""
+"Unable to deactivate network %(name)s. There are some virtual machines
%(vms)"
+"s and/or templates linked to this network."
+msgstr ""
+"Netz %(name)s konnte nicht inaktiviert werden. Es sind einige virtuellen "
+"Maschinen %(vms)s und/oder Vorlagen mit diesem Netz verkn��pft."
+
+#, python-format
+msgid "Bridge device %(name)s can not be the trunk device of a VLAN."
+msgstr "Br��ckeneinheit %(name)s kann nicht die Trunkeinheit eines VLAN sein."
+
+#, python-format
+msgid "Failed to activate interface %(iface)s: %(err)s."
+msgstr "Schnittstelle %(iface)s konnte nicht aktiviert werden: %(err)s."
+
+#, python-format
+msgid ""
+"Failed to activate interface %(iface)s. Please check the physical link "
+"status."
+msgstr ""
+"Schnittstelle %(iface)s konnte nicht aktiviert werden. Bitte ��berpr��fen Sie
"
+"den Status der physischen Verbindung."
+
+#, python-format
+msgid "Failed to start network %(name)s. Details: %(err)s"
+msgstr ""
+
+#, python-format
+msgid "Debug report %(name)s does not exist"
+msgstr "Debugbericht %(name)s ist nicht vorhanden"
+
+msgid "Debug report tool not found in system"
+msgstr "Debugberichtstool nicht im System gefunden"
+
+#, python-format
+msgid "Unable to create debug report %(name)s. Details: %(err)s."
+msgstr "Debugbericht %(name)s konnte nicht erstellt werden. Details: %(err)s."
+
+#, python-format
+msgid "Can not find any debug report with the given name %(name)s"
+msgstr ""
+
+#, python-format
+msgid "Unable to generate debug report %(name)s. Details: %(err)s"
+msgstr "Debugbericht %(name)s konnte nicht generiert werden. Details: %(err)s"
+
+msgid "You should give a name for the debug report file."
+msgstr ""
+
+msgid ""
+"Debug report name must be a string. Only letters, digits, underscore ('_')
"
+"and hyphen ('-') are allowed."
+msgstr ""
+
+#, python-format
+msgid ""
+"The debug report with specified name \"%(name)s\" already exists. Please
use "
+"another one."
+msgstr ""
+"Eine Datentr��gergruppe mit dem Namen '%(name)s' ist bereits vorhanden.
"
+"W��hlen Sie einen anderen Namen aus, um den logischen Pool zu erstellen."
+
+#, python-format
+msgid "Storage server %(server)s was not used by Kimchi"
+msgstr "Speicherserver %(server)s wurde nicht von Kimchi verwendet"
+
+#, python-format
+msgid "Distro '%(name)s' does not exist"
+msgstr "Distro '%(name)s' ist nicht vorhanden"
+
+#, python-format
+msgid "Partition %(name)s does not exist in the host"
+msgstr "Partition %(name)s ist nicht im Host vorhanden"
+
+msgid "Unable to shutdown host machine as there are running virtual machines"
+msgstr ""
+"Hostmaschine konnte nicht heruntergefahren werden, weil virtuelle Maschinen "
+"ausgef��hrt werden"
+
+msgid "Unable to reboot host machine as there are running virtual machines"
+msgstr ""
+"Hostmaschine konnte nicht neu gestartet werden, weil virtuelle Maschinen "
+"ausgef��hrt werden"
+
+#, python-format
+msgid "Node device '%(name)s' not found"
+msgstr "Knoteneinheit '%(name)s' nicht gefunden"
+
+msgid "Conflicting flag filters specified."
+msgstr ""
+
+msgid "No packages marked for update"
+msgstr "Keine Pakete f��r Aktualisierung markiert"
+
+#, python-format
+msgid "Package %(name)s is not marked to be updated."
+msgstr "Paket %(name)s ist nicht f��r Aktualisierung markiert."
+
+#, python-format
+msgid "Error while getting packages marked to be updated. Details: %(err)s"
+msgstr ""
+"Fehler beim Abrufen von Paketen, die f��r die Aktualsierung markiert sind. "
+"Details: %(err)s"
+
+msgid "There is no compatible package manager for this system."
+msgstr "Es gibt keinen kompatiblen Paketmanager f��r dieses System."
+
+#, python-format
+msgid "Invalid URI %(uri)s"
+msgstr "Ung��ltiger URI %(uri)s"
+
+msgid "Unable to choose a virtual machine name"
+msgstr ""
+
+msgid "Invalid storage type. Types supported: 'cdrom', 'disk'"
+msgstr "Ung��ltiger Speichertyp. Unterst��tzte Typen: 'cdrom'"
+
+#, python-format
+msgid "The path '%(value)s' is not a valid local/remote path for the
device"
+msgstr ""
+
+msgid "Only CDROM path can be update."
+msgstr ""
+
+#, python-format
+msgid ""
+"The storage device %(dev_name)s does not exist in the virtual machine %"
+"(vm_name)s"
+msgstr ""
+
+#, python-format
+msgid "Error while creating new storage device: %(error)s"
+msgstr "Fehler beim Erstellen einer neuen Speichereinheit: %(error)s"
+
+#, python-format
+msgid "Error while updating storage device: %(error)s"
+msgstr "Fehler beim Aktualisieren einer Speichereinheit: %(error)s"
+
+#, python-format
+msgid "Error while removing storage device: %(error)s"
+msgstr "Fehler beim Entfernen einer Speichereinheit: %(error)s"
+
+msgid "Do not support IDE device hot plug"
+msgstr ""
+
+msgid ""
+"Specify type and path or type and pool/volume to add a new virtual machine "
+"disk"
+msgstr ""
+"Geben Sie Typ und Pfad an, um einen neuen Datentr��ger f��r eine virtuelle "
+"Maschine hinzuzf��gen"
+
+msgid "Specify path to update virtual machine disk"
+msgstr ""
+"Geben Sie einen Pfad an, um die Platte der virtuellen Maschine zu "
+"aktualisieren"
+
+#, python-format
+msgid "Controller type %(type)s limitation of %(limit)s devices reached"
+msgstr ""
+
+#, python-format
+msgid "Cannot retrieve disk path information for given pool/volume: %(error)s"
+msgstr ""
+
+msgid "Volume already in use by other virtual machine."
+msgstr ""
+
+msgid ""
+"Only one of path or pool/volume can be specified to add a new virtual "
+"machine disk"
+msgstr ""
+"Geben Sie Typ und Pfad an, um einen neuen Datentr��ger f��r eine virtuelle "
+"Maschine hinzuzf��gen"
+
+#, python-format
+msgid ""
+"Volume chosen with format %(format)s does not fit in the storage type
%(type)"
+"s"
+msgstr ""
+
+msgid "YUM Repository ID must be one word only string."
+msgstr ""
+"YUM-Repository-ID darf nur ein aus einer Zeichenfolge bestehendes Wort sein."
+
+msgid "Repository URL must be an http://, ftp:// or file:// URL."
+msgstr "Repository-URL muss ein http://-, ftp://- oder file://-URL sein."
+
+msgid ""
+"Repository configuration is a dictionary with specific values according to "
+"repository type."
+msgstr ""
+"Repository-Konfiguration ist ein W��rterbuch mit bestimmten Werten "
+"hinsichtlich Repository-Typ."
+
+msgid "Distribution to DEB repository must be a string"
+msgstr "Verteilung an DEB-Repository muss eine Zeichenfolge sein"
+
+msgid "Components to DEB repository must be listed in a array"
+msgstr "Komponenten f��r DEB-Repository m��ssen in einem Array aufgelistet
sein"
+
+msgid "Components to DEB repository must be a string"
+msgstr "Komponenten f��r DEB-Repository m��ssen eine Zeichenfolge sein"
+
+msgid "Mirror list to repository must be a string"
+msgstr ""
+
+msgid "YUM Repository name must be string."
+msgstr "Name des YUM-Repositorys muss eine Zeichenfolge sein."
+
+msgid "GPG check must be a boolean value."
+msgstr "GPG-Pr��fung muss ein boolescher Wert sein."
+
+msgid "GPG key must be a URL pointing to the ASCII-armored file."
+msgstr "GPG-Schl��ssel muss ein URL sein, der auf die ASCII-Armor-Datei
zeigt."
+
+#, python-format
+msgid "Could not update repository %(repo_id)s."
+msgstr "Repository %(repo_id)s konnte nicht aktualisiert werden."
+
+#, python-format
+msgid "Repository %(repo_id)s does not exist."
+msgstr "Repository %(repo_id)s ist nicht vorhanden."
+
+msgid ""
+"Specify repository base URL, mirror list or metalink in order to create or "
+"update a YUM repository."
+msgstr ""
+
+msgid "Repository management tool was not recognized for your system."
+msgstr "Repository-Verwaltungstool wurde f��r Ihr System nicht erkannt."
+
+#, python-format
+msgid "Repository %(repo_id)s is already enabled."
+msgstr "Repository %(repo_id)s ist bereits aktiviert."
+
+#, python-format
+msgid "Repository %(repo_id)s is already disabled."
+msgstr "Repository %(repo_id)s ist bereits inaktiviert."
+
+#, python-format
+msgid "Could not remove repository %(repo_id)s."
+msgstr "Repository %(repo_id)s konnte nicht entfernt werden."
+
+#, python-format
+msgid "Could not write repository configuration file %(repo_file)s"
+msgstr ""
+"Repository-Konfigurationsdatei %(repo_file)s konnte nicht geschrieben werden"
+
+msgid "Specify repository distribution in order to create a DEB repository."
+msgstr ""
+"Geben Sie die Repository-Verteilung an, um ein DEB-Repository zu erstellen."
+
+#, python-format
+msgid "Could not enable repository %(repo_id)s."
+msgstr "Repository %(repo_id)s konnte nicht aktiviert werden."
+
+#, python-format
+msgid "Could not disable repository %(repo_id)s."
+msgstr "Repository %(repo_id)s konnte nicht inaktiviert werden."
+
+msgid "YUM Repository ID already exists"
+msgstr "YUM-Repository-ID ist bereits vorhanden"
+
+msgid "YUM Repository name must be a string"
+msgstr "YUM-Repository-Name muss eine Zeichenfolge sein"
+
+#, python-format
+msgid "Unable to list repositories. Details: '%(err)s'"
+msgstr "Repositorys konnten nicht aufgelistet werden. Details:
'%(err)s'"
+
+#, python-format
+msgid "Unable to retrieve repository information. Details: '%(err)s'"
+msgstr ""
+"Repository-Informationen konnten nicht abgerufen werden. Details:
'%(err)s'"
+
+#, python-format
+msgid "Unable to add repository. Details: '%(err)s'"
+msgstr "Repository konnte nicht hinzugef��gt werden. Details:
'%(err)s'"
+
+#, python-format
+msgid "Unable to remove repository. Details: '%(err)s'"
+msgstr "Repository konnte nicht entfernt werden. Details: '%(err)s'"
+
+#, python-format
+msgid ""
+"Configuration items: '%(items)s' are not supported by repository
manager"
+msgstr ""
+
+msgid "Repository metalink must be an http://, ftp:// or file:// URL."
+msgstr ""
+
+msgid "Cannot specify mirrorlist and metalink at the same time."
+msgstr ""
+
+#, python-format
+msgid ""
+"Virtual machine '%(vm)s' must be stopped before creating a snapshot of
it."
+msgstr ""
+
+#, python-format
+msgid ""
+"Unable to create snapshot '%(name)s' on virtual machine '%(vm)s'.
Details: %"
+"(err)s"
+msgstr ""
+
+#, python-format
+msgid "Snapshot '%(name)s' does not exist on virtual machine
'%(vm)s'."
+msgstr ""
+
+#, python-format
+msgid ""
+"Unable to retrieve snapshot '%(name)s' on virtual machine '%(vm)s'.
Details: "
+"%(err)s"
+msgstr ""
+
+#, python-format
+msgid "Unable to list snapshots on virtual machine '%(vm)s'. Details:
%(err)s"
+msgstr ""
+
+#, python-format
+msgid ""
+"Unable to delete snapshot '%(name)s' on virtual machine '%(vm)s'.
Details: %"
+"(err)s"
+msgstr ""
+
+#, python-format
+msgid ""
+"Unable to retrieve current snapshot of virtual machine '%(vm)s'. Details:
%"
+"(err)s"
+msgstr ""
+
+#, python-format
+msgid ""
+"Unable to revert virtual machine '%(vm)s' to snapshot '%(name)s'.
Details: %"
+"(err)s"
+msgstr ""
+
+#, python-format
+msgid ""
+"Unable to create snapshot of virtual machine '%(vm)s' because it contains a
"
+"disk with format '%(format)s'; only 'qcow2' is supported."
+msgstr ""
+
+msgid "The number of vCPUs is too large for this system."
+msgstr ""
+
+msgid "Invalid vCPU/topology combination."
+msgstr ""
+
+msgid "This host (or current configuration) does not allow CPU topology."
+msgstr ""
+
+msgid "ERROR CODE"
+msgstr "FEHLERCODE"
+
+msgid "REASON"
+msgstr "GRUND"
+
+msgid "STACK"
+msgstr "STACK"
+
+msgid "Go to Homepage"
+msgstr "Gehe zu Homepage"
+
+msgid "Create a New Virtual Machine"
+msgstr "Neue virtuelle Maschine erstellen"
+
+msgid "Virtual Machine Name"
+msgstr "Name der virtuellen Maschine"
+
+msgid ""
+"The name used to identify the virtual machine. If omitted, a name will be "
+"chosen based on the template used."
+msgstr ""
+"Der f��r die Kennzeichnung der virtuellen Maschine verwendete Name. Falls er
"
+"ausgelassen wird, wird ein Name anhand der verwendeten Vorlage ausgew��hlt."
+
+msgid "Template"
+msgstr "Vorlage"
+
+msgid "Please create a template first."
+msgstr "Erstellen Sie zun��chst eine Vorlage."
+
+msgid "Create a Template"
+msgstr "Vorlage erstellen"
+
+msgid "Please choose a template."
+msgstr "W��hlen Sie eine Vorlage aus."
+
+msgid "OS"
+msgstr "BS"
+
+msgid "OS Version"
+msgstr "BS-Version"
+
+msgid "CPUS"
+msgstr "CPUS"
+
+msgid "Memory"
+msgstr "Speicher"
+
+msgid "Create"
+msgstr "Erstellen"
+
+msgid "Creating..."
+msgstr ""
+
+msgid "Cancel"
+msgstr "Abbrechen"
+
+msgid "Edit Guest"
+msgstr "Gast bearbeiten"
+
+msgid "General"
+msgstr "Allgemein"
+
+msgid "Storage"
+msgstr "Speicher"
+
+msgid "Interface"
+msgstr "Schnittstelle"
+
+msgid "Permission"
+msgstr "Version"
+
+msgid "Host PCI Device"
+msgstr ""
+
+msgid "Snapshot"
+msgstr ""
+
+msgid "Name"
+msgstr "Name"
+
+msgid "CPUs"
+msgstr "CPUs"
+
+msgid "Memory (MB)"
+msgstr "Speicher"
+
+msgid "Icon"
+msgstr "Symbol"
+
+msgid "Device"
+msgstr "Einheitenname"
+
+msgid "Path"
+msgstr "NFS-Pfad"
+
+msgid "Network"
+msgstr "Netz"
+
+msgid "Type"
+msgstr "Typ"
+
+msgid "MAC Address"
+msgstr ""
+
+msgid "Available system users and groups"
+msgstr ""
+
+msgid "Selected system users and groups"
+msgstr ""
+
+msgid "User"
+msgstr ""
+
+msgid "All"
+msgstr "Alle"
+
+msgid "To Add"
+msgstr ""
+
+msgid "Added"
+msgstr ""
+
+msgid "filter"
+msgstr ""
+
+msgid "Product"
+msgstr ""
+
+msgid "Vendor"
+msgstr "Anbieter"
+
+msgid "Created"
+msgstr ""
+
+msgid "Save"
+msgstr "Speichern"
+
+msgid "Replace"
+msgstr "Ersetzen"
+
+msgid "Detach"
+msgstr "Abh��ngen"
+
+msgid "revert"
+msgstr ""
+
+msgid "Start"
+msgstr "Starten"
+
+msgid "Reset"
+msgstr "Zur��cksetzen"
+
+msgid "Pause"
+msgstr ""
+
+msgid "Resume"
+msgstr ""
+
+msgid "Power Off"
+msgstr ""
+
+msgid "Actions"
+msgstr "Aktionen"
+
+msgid "Connect"
+msgstr "Verbinden"
+
+msgid "Clone"
+msgstr ""
+
+msgid "Edit"
+msgstr "Bearbeiten"
+
+msgid "Shut Down"
+msgstr "Herunterfahren"
+
+msgid "Delete"
+msgstr "L��schen"
+
+msgid "CPU"
+msgstr "CPU"
+
+msgid "Disk I/O"
+msgstr "Platten-E/A"
+
+msgid "Network I/O"
+msgstr "Netz-E/A"
+
+msgid "Livetile"
+msgstr "Live Tile"
+
+msgid "No guests found."
+msgstr "Keine G��ste gefunden."
+
+msgid "Add a Storage Device to VM"
+msgstr "Speichereinheit zur virtuellen Maschine hinzuf��gen"
+
+msgid "Device Type"
+msgstr "Einheitentyp"
+
+msgid "The device type. Currently, \"cdrom\" and \"disk\" are
supported."
+msgstr "Der Einheitentyp. Derzeit wird nur \"cdrom\" unterst��tzt."
+
+msgid "Storage Pool"
+msgstr "Speicherpool"
+
+msgid "Storage pool which volume located in"
+msgstr "Speicherpoolpfad muss eine Zeichenfolge sein"
+
+msgid "Storage Volume"
+msgstr "Speicherpoolname"
+
+msgid "Storage volume to be attached"
+msgstr "Name des Speicherdatentr��gers muss eine Zeichenfolge sein"
+
+msgid "File Path"
+msgstr "Dateipfad"
+
+msgid "The ISO file path in the server for CDROM."
+msgstr "Der ISO-Dateipfad auf dem Server f��r die CD-ROM."
+
+msgid "Attach"
+msgstr "Anh��ngen"
+
+msgid "Shut down"
+msgstr "Herunterfahren"
+
+msgid "Restart"
+msgstr "Erneut starten"
+
+msgid "Basic Information"
+msgstr "Basisinformationen"
+
+msgid "OS Distro"
+msgstr "BS-Distro"
+
+msgid "OS Code Name"
+msgstr "BS-Codename"
+
+msgid "Processor"
+msgstr "Prozessor"
+
+msgid "CPU(s)"
+msgstr ""
+
+msgid "System Statistics"
+msgstr "Systemstatistik"
+
+msgid "Software Updates"
+msgstr "Software-Updates"
+
+msgid "Update Progress"
+msgstr "Aktualisierungsfortschritt"
+
+msgid "Repositories"
+msgstr "Repositorys"
+
+msgid "Debug Reports"
+msgstr "Debugberichte"
+
+msgid "The username or password you entered is incorrect. Please try again."
+msgstr ""
+"Der Benutzername oder das Kennwort, den bzw. das Sie eingegeben haben, ist "
+"falsch. Versuchen Sie es bitte erneut."
+
+msgid "This field is required."
+msgstr "Dieses Feld ist erforderlich."
+
+msgid "Log in"
+msgstr "Anmelden"
+
+msgid "Logging in..."
+msgstr "Wird angemeldet..."
+
+msgid "Host"
+msgstr "Host"
+
+msgid "Guests"
+msgstr "G��ste"
+
+msgid "Templates"
+msgstr "Vorlagen"
+
+msgid "Failed to get application configuration"
+msgstr "Anwendungskonfiguration konnte nicht abgerufen werden"
+
+msgid "This is not a valid Linux path"
+msgstr "Dies ist kein g��ltiger Linux-Pfad"
+
+msgid "This is not a valid URL."
+msgstr "Dies ist kein g��ltiger URL."
+
+msgid "No such data available."
+msgstr "Keine solchen Daten verf��gbar."
+
+msgid ""
+"Can not contact the host system. Verify the host system is up and that you "
+"have network connectivity to it. HTTP request response %1. "
+msgstr ""
+"Hostsystem kann nicht kontaktiert werden. Pr��fen Sie, ob das Hostsystem "
+"aktiv ist und obNetzkonnektivit��t besteht. HTTP-Anforderungsantwort %1. "
+
+msgid "Unable to read file."
+msgstr ""
+
+msgid "Error while uploading file."
+msgstr ""
+
+msgid "Delete Confirmation"
+msgstr "L��schbest��tigung"
+
+msgid "OK"
+msgstr "OK"
+
+msgid "Confirm"
+msgstr "Best��tigen"
+
+msgid "Warning"
+msgstr "Warnung"
+
+msgid "Cloning..."
+msgstr ""
+
+msgid "Loading..."
+msgstr "Wird geladen..."
+
+msgid "An error occurred while retrieving system information."
+msgstr ""
+
+msgid "Retry"
+msgstr "Wiederholen"
+
+msgid "Detailed message:"
+msgstr "Detaillierte Meldung:"
+
+msgid "No ISO found"
+msgstr ""
+
+msgid "This is not a valid ISO file."
+msgstr "Dies ist keine g��ltige ISO-Datei."
+
+msgid "This may take a long time. Do you want to continue?"
+msgstr "Dies wird einige Zeit dauern. M��chten Sie fortfahren?"
+
+msgid "This will permanently delete the template. Would you like to continue?"
+msgstr "Hiermit wird die Vorlage dauerhaft gel��scht. M��chten Sie
fortfahren?"
+
+msgid "Unable to shut down system as there are some virtual machines running!"
+msgstr ""
+"System konnte nicht heruntergefahren werden, weil einige virtuellen "
+"Maschinen ausgef��hrt werden!"
+
+msgid "Max:"
+msgstr "Max:"
+
+msgid "Utilization"
+msgstr "Auslastung"
+
+msgid "Available"
+msgstr "Verf��gbar"
+
+msgid "Read Rate"
+msgstr "Leserate"
+
+msgid "Write Rate"
+msgstr "Schreibrate"
+
+msgid "Received"
+msgstr "Empfangen"
+
+msgid "Sent"
+msgstr "Gesendet"
+
+msgid ""
+"Shutting down or restarting host will cause unsaved work lost. Continue to "
+"shut down/restarting?"
+msgstr ""
+"Durch das Herunterfahren oder Neustarten des Hosts k��nnen ungesicherte "
+"Arbeiten verloren gehen. M��chten Sie mit dem Herunterfahren/Neustarten "
+"fortfahren?"
+
+msgid ""
+"Repository will be removed permanently and can't be recovered. Do you want
"
+"to continue?"
+msgstr ""
+"Repository wird dauerhaft entfernt und kann nicht wiederhergestellt werden. "
+"M��chten Sie fortfahren?"
+
+msgid "ID"
+msgstr "ID"
+
+msgid "Base URL"
+msgstr "Basis-URL"
+
+msgid "Is Mirror"
+msgstr "Ist Spiegel"
+
+msgid "URL Args"
+msgstr "URL-Args"
+
+msgid "Enabled"
+msgstr "Aktiviert"
+
+msgid "GPG Check"
+msgstr "GPG-Pr��fung"
+
+msgid "GPG Key"
+msgstr "GPG-Schl��ssel"
+
+msgid "Add"
+msgstr "Hinzuf��gen"
+
+msgid "Remove"
+msgstr "Entfernen"
+
+msgid "Enable"
+msgstr "Aktivieren"
+
+msgid "Disable"
+msgstr "Inaktivieren"
+
+msgid "Package Name"
+msgstr "Paketname"
+
+msgid "Version"
+msgstr "Version"
+
+msgid "Architecture"
+msgstr "Architektur"
+
+msgid "Repository"
+msgstr "Repository"
+
+msgid "Update All"
+msgstr "Alle aktualisieren"
+
+msgid "Updating..."
+msgstr "Wird aktualisiert..."
+
+msgid "Failed to retrieve packages update information."
+msgstr ""
+
+msgid "Failed to update package(s)."
+msgstr "Pakete konnten nicht aktualisiert werden."
+
+msgid ""
+"Debug report will be removed permanently and can't be recovered. Do you want
"
+"to continue?"
+msgstr ""
+"Debugbericht wird dauerhaft entfernt und kann nicht wiederhergestellt "
+"werden. M��chten Sie fortfahren?"
+
+msgid "Generated Time"
+msgstr "Generierte Zeit"
+
+msgid "Generate"
+msgstr "Generieren"
+
+msgid "Generating..."
+msgstr "Wird generiert..."
+
+msgid "Rename"
+msgstr "Umbenennen"
+
+msgid "Download"
+msgstr "Herunterladen"
+
+msgid ""
+"Report name should contain only letters, digits, underscore ('_') and/or
"
+"hyphen ('-')."
+msgstr ""
+"Berichtsname darf nur Buchstaben, Zahlen und/oder Bindestriche ('-')
"
+"enthalten."
+
+msgid "Pending..."
+msgstr "Wird geladen..."
+
+msgid "Report name is the same as the original one."
+msgstr ""
+
+msgid ""
+"This will delete the virtual machine and its virtual disks. This operation "
+"cannot be undone. Would you like to continue?"
+msgstr ""
+"Hiermit werden die virtuelle Maschine und deren virtuellen Platten gel��scht.
"
+"Diese Operation kann nicht r��ckg��ngig gemacht werden. M��chten Sie
fortfahren?"
+
+msgid "Power off Confirmation"
+msgstr "L��schbest��tigung"
+
+msgid ""
+"This action may produce undesirable results, for example unflushed disk "
+"cache in the guest. Would you like to continue?"
+msgstr ""
+
+msgid "Reset Confirmation"
+msgstr "L��schbest��tigung"
+
+msgid ""
+"There is a risk of data loss caused by reset without the guest OS shutdown. "
+"Would you like to continue?"
+msgstr ""
+
+msgid "Shut Down Confirmation"
+msgstr "L��schbest��tigung"
+
+msgid "Note the guest OS may ignore this request. Would you like to continue?"
+msgstr "Hiermit wird die Vorlage dauerhaft gel��scht. M��chten Sie
fortfahren?"
+
+msgid "Virtual Machine delete Confirmation"
+msgstr ""
+
+msgid ""
+"This virtual machine is not persistent. Power Off will delete it. Continue?"
+msgstr ""
+
+msgid ""
+"When the target guest has SCSI or iSCSI volumes, they will be cloned on "
+"default storage pool. The same will happen when the target pool does not "
+"have enough space to clone the volumes. Do you want to continue?"
+msgstr ""
+
+msgid ""
+"This CDROM will be detached permanently and you can re-attach it. Continue "
+"to detach it?"
+msgstr ""
+"Diese CD-ROM wird dauerhaft abgeh��ngt und Sie k��nnen sie neu anh��ngen. "
+"M��chten Sie mit dem Abh��ngen fortfahren?"
+
+msgid "Attaching..."
+msgstr "Wird angeh��ngt..."
+
+msgid "Replacing..."
+msgstr "Wird ersetzt..."
+
+msgid "Successfully attached!"
+msgstr "Erfolgreich angeh��ngt!"
+
+msgid "Successfully replaced!"
+msgstr "Erfolgreich ersetzt!"
+
+msgid "Successfully detached!"
+msgstr "Erfolgreich abgeh��ngt!"
+
+msgid ""
+"This disk will be detached permanently and you can re-attach it. Continue to
"
+"detach it?"
+msgstr ""
+
+msgid "interface:"
+msgstr ""
+
+msgid "address:"
+msgstr ""
+
+msgid "link_type:"
+msgstr ""
+
+msgid "block:"
+msgstr ""
+
+msgid "drive_type:"
+msgstr ""
+
+msgid "model:"
+msgstr ""
+
+msgid "Affected devices:"
+msgstr ""
+
+msgid "The VLAN id must be between 1 and 4094."
+msgstr "Die VLAN-ID muss zwischen 1 und 4094 liegen."
+
+msgid "unavailable"
+msgstr "nicht verf��gbar"
+
+msgid ""
+"This action will interrupt network connectivity for any virtual machine that
"
+"depend on this network."
+msgstr ""
+"Diese Aktion unterbricht die Netzkonnektivit��t f��r jede virtuelle Maschine,
"
+"die von diesem Netz abh��ngt."
+
+msgid "Create a network"
+msgstr "Netz erstellen"
+
+msgid ""
+"This network is not persistent. Instead of stop, this action will "
+"permanently delete it. Would you like to continue?"
+msgstr ""
+"Dieser Speicherpool ist nicht permanent. Durch diese Aktion wird er nicht "
+"inaktiviert, sondern permanent gel��scht. M��chten Sie fortfahren?"
+
+msgid ""
+"The bridged VLAN tag may not work well with NetworkManager enabled. You "
+"should consider disabling it."
+msgstr ""
+
+msgid ""
+"This will permanently delete the storage pool. Would you like to continue?"
+msgstr ""
+"Hiermit wird der Speicherpool dauerhaft gel��scht. M��chten Sie fortfahren?"
+
+msgid "This storage pool is empty."
+msgstr "Dieser Speicherpool ist leer."
+
+msgid ""
+"It will format your disk and you will loose any data in there, are you sure "
+"to continue? "
+msgstr ""
+"Hiermit wird Ihre Platte formatiert und Sie verlieren s��mtliche Daten "
+"darauf. Sind Sie sicher, dass Sie fortfahren m��chten? "
+
+msgid "SCSI Fibre Channel"
+msgstr "SCSI-Fibre Channel"
+
+msgid "No SCSI adapters found."
+msgstr "Keine SCSI-Adapter gefunden."
+
+msgid "Loading iSCSI targets..."
+msgstr ""
+
+msgid "No iSCSI found. Please input one."
+msgstr ""
+
+msgid "Failed to load iSCSI targets."
+msgstr ""
+
+msgid "The storage pool name can not be blank."
+msgstr "Der Speicherpoolname darf nicht leer sein."
+
+msgid "The storage pool path can not be blank."
+msgstr "Der Speicherpoolpfad darf nicht leer sein."
+
+msgid "NFS server mount path can not be blank."
+msgstr "Der Mountpfad des NFS-Servers darf nicht leer sein."
+
+msgid "Invalid NFS mount path."
+msgstr "Ung��ltiger NFS-Mountpfad."
+
+msgid "No logical device selected."
+msgstr "Keine logische Einheit ausgew��hlt."
+
+msgid "The iSCSI target can not be blank."
+msgstr "Das iSCSI-Ziel darf nicht leer sein."
+
+msgid "Server name can not be blank."
+msgstr "Servername darf nicht leer sein."
+
+msgid "This is not a valid Server Name or IP. Please, modify it."
+msgstr ""
+
+msgid "Looking for available partitions ..."
+msgstr "Es wird nach verf��gbaren Partitionen gesucht..."
+
+msgid "No available partitions found."
+msgstr "Keine g��ltigen Partitionen gefunden."
+
+msgid ""
+"This storage pool is not persistent. Instead of deactivate, this action will
"
+"permanently delete it. Would you like to continue?"
+msgstr ""
+"Dieser Speicherpool ist nicht permanent. Durch diese Aktion wird er nicht "
+"inaktiviert, sondern permanent gel��scht. M��chten Sie fortfahren?"
+
+msgid "Unable to retrieve partitions information."
+msgstr ""
+"Repository-Informationen konnten nicht abgerufen werden. Details:
'%(err)s'"
+
+msgid "In progress..."
+msgstr ""
+
+msgid "Failed!"
+msgstr ""
+
+msgid "CDROM path needs to be a valid local/remote path and cannot be blank."
+msgstr ""
+
+msgid "Disk pool or volume cannot be blank."
+msgstr "Der Speicherpoolname darf nicht leer sein."
+
+msgid "Filter"
+msgstr ""
+
+msgid "Network Name"
+msgstr "Netzname"
+
+msgid "State"
+msgstr "Status"
+
+msgid "Network Type"
+msgstr "Netztyp"
+
+msgid "Address Space"
+msgstr "Adressraum"
+
+msgid "Name should not contain '/' and '\"'."
+msgstr "Ung��ltiger Speicherpoolname. Er darf nicht '/' enthalten."
+
+msgid "Isolated: no external network connection"
+msgstr "Isolatiert: keine physisische Netzverbindung"
+
+msgid "NAT: outbound physical network connection only"
+msgstr "NAT: nur ausgehende physische Netzverbindung"
+
+msgid "Bridged: Virtual machines are connected to physical network directly"
+msgstr ""
+"��berbr��ckt: Virtuelle Maschinen sind direkt mit physischem Netz verbunden"
+
+msgid "(No interfaces found)"
+msgstr ""
+
+msgid "Destination"
+msgstr "Ziel:"
+
+msgid "Enable VLAN"
+msgstr "Virtuelles LAN (VLAN) aktivieren:"
+
+msgid "VLAN ID"
+msgstr "VLAN-ID:"
+
+msgid "Stop"
+msgstr "Stoppen"
+
+msgid "Generate a New Debug Report"
+msgstr "Neuen Debugbericht erstellen"
+
+msgid "Report Name"
+msgstr "Berichtsname"
+
+msgid ""
+"The name used to identify the report. If omitted, a name will be chosen "
+"based on current time. Name can contain: letters, digits, underscore
(\"_\") "
+"and hyphen (\"-\")."
+msgstr ""
+"Der Name, mit dem der Bericht gekennzeichnet wird. Falls er ausgelassen "
+"wird, wird ein Name basierend auf der aktuellen Zeit ausgew��hlt. Der Name "
+"darf Buchstaben, Zahlen und Bindestriche (\"-\") enthalten."
+
+msgid "Rename a Debug Report"
+msgstr "Neuen Debugbericht erstellen"
+
+msgid ""
+"The name used to identify the report. Name can contain: letters, digits and "
+"hyphen (\"-\")."
+msgstr ""
+"Der Name, mit dem der Bericht gekennzeichnet wird. Falls er ausgelassen "
+"wird, wird ein Name basierend auf der aktuellen Zeit ausgew��hlt. Der Name "
+"darf Buchstaben, Zahlen und Bindestriche (\"-\") enthalten."
+
+msgid "Submit"
+msgstr ""
+
+msgid "Add a Repository"
+msgstr "Repository hinzuf��gen"
+
+msgid "Identifier"
+msgstr "Kennung"
+
+msgid "Single word, unique identifier for the repository."
+msgstr "Einzelnes Wort, eindeutige Kennung f��r das Repository."
+
+msgid "Textual name for the repository."
+msgstr "Textname f��r das Repository."
+
+msgid "URL"
+msgstr "URL"
+
+msgid "Required Field"
+msgstr "Erforderliches Feld"
+
+msgid "URL to the repository. Supported protocols are http, ftp, and file."
+msgstr "URL zum Repository. Unterst��tzte Protokolle sind http, ftp und file."
+
+msgid "Repository is a mirror"
+msgstr "Repository ist ein Spiegel."
+
+msgid "Distribution"
+msgstr "Verteilung"
+
+msgid "Distribution of the DEB repository."
+msgstr "Verteilung des DEB-Repositorys."
+
+msgid "Components"
+msgstr "Komponenten"
+
+msgid "List of components in DEB repository."
+msgstr "Liste der Komponenten im DEB-Repository."
+
+msgid "Edit Repository"
+msgstr "Repository bearbeiten"
+
+msgid "Mirror List URL"
+msgstr "Spiegellisten-URL"
+
+msgid "Yes"
+msgstr "Ja"
+
+msgid "No"
+msgstr "Nein"
+
+msgid "Capacity"
+msgstr "Kapazit��t"
+
+msgid "Allocated"
+msgstr "Zugeordnet"
+
+msgid "Location"
+msgstr "Position"
+
+msgid "Device path"
+msgstr "Einheitenpfad"
+
+msgid "active"
+msgstr "aktiv"
+
+msgid "inactive"
+msgstr "inaktiv"
+
+msgid "Deactivate"
+msgstr "Inaktivieren"
+
+msgid "Activate"
+msgstr "Aktivieren"
+
+msgid "Add Volume"
+msgstr ""
+
+msgid "Extend"
+msgstr ""
+
+msgid "Undefine"
+msgstr "Definition aufheben"
+
+msgid "Format"
+msgstr "Format:"
+
+msgid "Allocation"
+msgstr "Zuordnung:"
+
+msgid "Define a New Storage Pool"
+msgstr "Neuen Speicherpool definieren"
+
+msgid "Storage Pool Name"
+msgstr "Speicherpoolname"
+
+msgid ""
+"The name used to identify the storage pools, and it should not be empty."
+msgstr ""
+"Der Name, mit dem die Speicherpools gekennzeichnet werden. Er darf nicht "
+"leer sein."
+
+msgid "Storage Pool Type"
+msgstr "Speicherpooltyp"
+
+msgid "Storage Path"
+msgstr "Speicherpfad"
+
+msgid ""
+"The path of the Storage Pool. Each Storage Pool must have a unique path."
+msgstr ""
+"Der Pfad des Speicherpools. Jeder Speicherpool muss einen eindeutigen Pfad "
+"haben."
+
+msgid ""
+"Kimchi will try to create the directory when it does not already exist in "
+"your system."
+msgstr ""
+"Kimchi versucht, das Verzeichnis zu erstellen, wenn es noch nicht in Ihrem "
+"System vorhanden ist."
+
+msgid "NFS Server IP"
+msgstr "NFS-Server-IP"
+
+msgid "NFS server IP or hostname. It can be input or chosen from history."
+msgstr ""
+"IP oder Hostname des NFS-Servers. Diese(r) kann eingegeben oder aus dem "
+"Verlauf ausgew��hlt werden."
+
+msgid "NFS Path"
+msgstr "NFS-Pfad"
+
+msgid "The NFS exported path on NFS server."
+msgstr "Der NFS-Exportpfad auf dem NFS-Server."
+
+msgid "iSCSI Server"
+msgstr "iSCSI-Server"
+
+msgid "Server"
+msgstr "Server"
+
+msgid "Port"
+msgstr "Port"
+
+msgid "iSCSI server IP or hostname. It should not be empty."
+msgstr "IP oder Hostname des iSCSI-Servers. Diese(r) darf nicht leer sein."
+
+msgid "Target"
+msgstr "Ziel"
+
+msgid "The iSCSI target on iSCSI server"
+msgstr "Das iSCSI-Ziel auf dem iSCSI-Server"
+
+msgid "Add iSCSI Authentication"
+msgstr "iSCSI-Authentifizierung hinzuf��gen"
+
+msgid "iSCSI Authentication"
+msgstr "iSCSI-Authentifizierung"
+
+msgid "User Name"
+msgstr "Benutzername"
+
+msgid "Password"
+msgstr "Kennwort"
+
+msgid "SCSI Adapter"
+msgstr "SCSI-Adapter"
+
+msgid "Please, wait..."
+msgstr "Bitte warten..."
+
+msgid "Add a Volume to Storage Pool"
+msgstr ""
+
+msgid "Fetch from remote URL"
+msgstr ""
+
+msgid "Enter the remote URL here."
+msgstr ""
+
+msgid "Upload a file"
+msgstr ""
+
+msgid "Choose the file you want to upload."
+msgstr ""
+
+msgid "Add Template"
+msgstr "Vorlage hinzuf��gen"
+
+msgid "Where is the source media for this template? "
+msgstr "Wo ist der Quellendatentr��ger f��r diese Vorlage?"
+
+msgid "Local ISO Image"
+msgstr "Lokales ISO-Image"
+
+msgid "Local Image File"
+msgstr ""
+
+msgid "Remote ISO Image"
+msgstr "Fernes ISO-Image"
+
+msgid "Search ISOs"
+msgstr "ISOs suchen"
+
+msgid "The following ISOs are available:"
+msgstr "Die folgenden ISOs sind verf��gbar:"
+
+msgid "OS: "
+msgstr "BS: "
+
+msgid "Version: "
+msgstr "Version: "
+
+msgid "Size: "
+msgstr "Gr����e: "
+
+msgid "Search more ISOs"
+msgstr "Weitere ISOs suchen"
+
+msgid "Create Templates from Selected ISO"
+msgstr "Vorlagen aus ausgew��hltem ISO erstellen"
+
+msgid "I want to use a specific ISO file"
+msgstr "Ich m��chte eine bestimmte ISO-Datei verwenden"
+
+msgid "Loading default remote ISOs ..."
+msgstr "Standardm����ige ferne ISOs werden geladen ..."
+
+msgid "Arch: "
+msgstr "Arch: "
+
+msgid "I want to use a custom URL"
+msgstr "Ich m��chte einen benutzerdefinierten URL verwenden"
+
+msgid "Edit Template"
+msgstr "Vorlage bearbeiten"
+
+msgid "CDROM"
+msgstr "CD-ROM"
+
+msgid "Image File"
+msgstr ""
+
+msgid "Graphics"
+msgstr "Grafik"
+
+msgid "Disk(GB)"
+msgstr ""
+
+msgid "Disk Format"
+msgstr ""
+
+msgid "CPU Number"
+msgstr "CPU-Anzahl"
+
+msgid "Manually set CPU topology"
+msgstr ""
+
+msgid "Cores"
+msgstr ""
+
+msgid "Threads"
+msgstr ""
+
+msgid "No templates found."
+msgstr "Keine Vorlagen gefunden."
+
+#~ msgid "Delete is not allowed for %(resource)s"
+#~ msgstr "L��schen ist nicht zul��ssig f��r %(resource)s"
+
+#~ msgid "%(resource)s does not implement update method"
+#~ msgstr "%(resource)s implementiert keine Aktualisierungsmethode"
+
+#~ msgid "Create is not allowed for %(resource)s"
+#~ msgstr "Erstellen ist nicht zul��ssig f��r %(resource)s"
+
+#~ msgid "Unable to parse JSON request"
+#~ msgstr "JSON-Anfrage konnte nicht analysiert werden"
+
+#~ msgid "This API only supports JSON"
+#~ msgstr "Diese API unterst��tzt nur JSON"
+
+#~ msgid "Datastore is not initiated in the model object."
+#~ msgstr "Datenspeicher wird nicht im Modellobjekt initialisiert."
+
+#~ msgid "Unable to start task due error: %(err)s"
+#~ msgstr ""
+#~ "Task kann aufgrund des folgenden Fehlers nicht gestartet werden: %(err)s"
+
+#~ msgid ""
+#~ "Authentication failed for user '%(username)s'. [Error code:
%(code)s]"
+#~ msgstr ""
+#~ "Authentifizierung f��r Benutzer '%(username)s' fehlgeschlagen. "
+#~ "[Fehlercode: %(code)s]"
+
+#~ msgid "You are not authorized to access Kimchi"
+#~ msgstr "Sie sind nicht berechtigt, auf Kimchi zuzugreifen"
+
+#~ msgid "Specify %(item)s to login into Kimchi"
+#~ msgstr "Geben Sie %(item)s an, um sich bei Kimchi anzumelden"
+
+#~ msgid "Unable to find %(item)s in datastore"
+#~ msgstr "%(item)s konnten nicht im Datenspeicher gefunden werden"
+
+#~ msgid "Timeout while running command '%(cmd)s' after %(seconds)s
seconds"
+#~ msgstr ""
+#~ "Zeitlimit��berschreitung beim Ausf��hren des Befehls '%(cmd)s' nach
%"
+#~ "(seconds)s Sekunden"
+
+#~ msgid "Help"
+#~ msgstr "Hilfe"
+
+#~ msgid "About"
+#~ msgstr "Informationen"
+
+#~ msgid "Log out"
+#~ msgstr "Abmelden"
+
+#~ msgid "Version:"
+#~ msgstr "Version:"
diff --git a/src/wok/plugins/kimchi/po/en_US.po b/src/wok/plugins/kimchi/po/en_US.po
new file mode 100644
index 0000000..a5d0d44
--- /dev/null
+++ b/src/wok/plugins/kimchi/po/en_US.po
@@ -0,0 +1,2075 @@
+# English translations for kimchi package.
+# Copyright (C) 2013 ORGANIZATION
+# Adam Litke <agl(a)us.ibm.com>, 2013.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: kimchi 0.1\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2015-07-01 16:11-0300\n"
+"PO-Revision-Date: 2013-07-11 17:32-0400\n"
+"Last-Translator: Cr��stian Viana <vianac(a)linux.vnet.ibm.com>\n"
+"Language-Team: English\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Language: en_US\n"
+"Generated-By: pygettext.py 1.5\n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+
+#, python-format
+msgid "Unknown parameter %(value)s"
+msgstr ""
+
+#, python-format
+msgid "Timeout of %(seconds)s seconds expired while running task
'%(task)s."
+msgstr ""
+
+#, python-format
+msgid "User %(user_id)s not found with given LDAP settings."
+msgstr ""
+
+msgid "Unknown \"_cap\" specified"
+msgstr ""
+
+msgid "\"_passthrough\" should be \"true\" or
\"false\""
+msgstr ""
+
+msgid "\"_passthrough_affected_by\" should be a device name string"
+msgstr ""
+
+#, python-format
+msgid "Error while getting block devices. Details: %(err)s"
+msgstr ""
+
+#, python-format
+msgid "Error while getting block device information for %(device)s."
+msgstr ""
+
+#, python-format
+msgid "Unable to find distro file: %(filename)s"
+msgstr ""
+
+#, python-format
+msgid ""
+"Unable to parse distro file: %(filename)s. Make sure, it is a JSON file."
+msgstr ""
+
+#, python-format
+msgid "Unable to login to iSCSI host target %(portal)s. Details: %(err)s"
+msgstr ""
+
+#, python-format
+msgid "Unable to login to iSCSI host %(host)s target %(target)s"
+msgstr ""
+
+#, python-format
+msgid "Unable to find ISO file %(filename)s"
+msgstr ""
+
+#, python-format
+msgid "The ISO file %(filename)s is not bootable"
+msgstr ""
+
+#, python-format
+msgid "The ISO file %(filename)s does not have a valid El Torito boot record"
+msgstr ""
+
+#, python-format
+msgid "Invalid El Torito validation entry in ISO %(filename)s"
+msgstr ""
+
+#, python-format
+msgid "Invalid El Torito boot indicator in ISO %(filename)s"
+msgstr ""
+
+#, python-format
+msgid "Unexpected volume type for primary volume in ISO %(filename)s"
+msgstr ""
+
+#, python-format
+msgid "Bad format while reading volume descriptor in ISO %(filename)s"
+msgstr ""
+
+#, python-format
+msgid ""
+"The hypervisor doesn't have permission to use this ISO %(filename)s. "
+"Consider moving it under /var/lib/libvirt, or set the search permission to "
+"file access control lists for '%(user)s' user if possible, or add the
'%"
+"(user)s' to the ISO path group, or (not recommended) 'chmod -R o+x "
+"'path_to_iso'.Details: %(err)s"
+msgstr ""
+
+msgid "An error occurred when probing image OS information."
+msgstr ""
+
+msgid "No OS information found in given image."
+msgstr ""
+
+#, python-format
+msgid "Unable to read image file %(filename)s"
+msgstr ""
+
+#, python-format
+msgid ""
+"Image file must be an existing file on system. %(filename)s is not a valid "
+"input."
+msgstr ""
+
+#, python-format
+msgid "Virtual machine %(name)s already exists"
+msgstr ""
+
+#, python-format
+msgid "Virtual machine %(name)s does not exist"
+msgstr ""
+
+#, python-format
+msgid ""
+"Unable to rename virtual machine %(name)s. The name %(new_name)s is already "
+"in use or the virtual machine is not powered off."
+msgstr ""
+
+#, python-format
+msgid "Unable to retrieve screenshot for stopped virtual machine %(name)s"
+msgstr ""
+
+msgid "Remote ISO image is not supported by this server."
+msgstr ""
+
+#, python-format
+msgid "Screenshot is not supported on virtual machine %(name)s"
+msgstr ""
+
+#, python-format
+msgid "Unable to create virtual machine %(name)s. Details: %(err)s"
+msgstr ""
+
+#, python-format
+msgid "Unable to update virtual machine %(name)s. Details: %(err)s"
+msgstr ""
+
+#, python-format
+msgid "Unable to retrieve virtual machine %(name)s. Details: %(err)s"
+msgstr ""
+
+#, python-format
+msgid "Unable to connect to powered off virtual machine %(name)s."
+msgstr ""
+
+msgid "Virtual machine name must be a string without slashes (/)"
+msgstr ""
+
+#, python-format
+msgid "Invalid template URI %(value)s specified for virtual machine"
+msgstr ""
+
+#, python-format
+msgid "Invalid storage pool URI %(value)s specified for virtual machine"
+msgstr ""
+
+msgid "Supported virtual machine graphics are Spice or VNC"
+msgstr ""
+
+msgid "Graphics address to listen on must be IPv4 or IPv6"
+msgstr ""
+
+msgid "Specify a template to create a virtual machine from"
+msgstr ""
+
+#, python-format
+msgid "Unable to start virtual machine %(name)s. Details: %(err)s"
+msgstr ""
+
+#, python-format
+msgid "Unable to power off virtual machine %(name)s. Details: %(err)s"
+msgstr ""
+
+#, python-format
+msgid "Unable to delete virtual machine %(name)s. Details: %(err)s"
+msgstr ""
+
+#, python-format
+msgid "Unable to reset virtual machine %(name)s. Details: %(err)s"
+msgstr ""
+
+msgid "User name list must be an array"
+msgstr ""
+
+msgid "User name must be a string"
+msgstr ""
+
+msgid "Group name list must be an array"
+msgstr ""
+
+msgid "Group name must be a string"
+msgstr ""
+
+#, python-format
+msgid "User(s) '%(users)s' do not exist"
+msgstr ""
+
+#, python-format
+msgid "Group(s) '%(groups)s' do not exist"
+msgstr ""
+
+#, python-format
+msgid "Unable to shutdown virtual machine %(name)s. Details: %(err)s"
+msgstr ""
+
+#, python-format
+msgid ""
+"Unable to get access metadata of virtual machine %(name)s. Details: %(err)s"
+msgstr ""
+
+msgid "The guest console password must be a string."
+msgstr ""
+
+msgid "The life time for the guest console password must be a number."
+msgstr ""
+
+#, python-format
+msgid "Virtual machine '%(name)s' must be stopped before cloning it."
+msgstr ""
+
+#, python-format
+msgid "Insufficient disk space to clone virtual machine '%(name)s'"
+msgstr ""
+
+#, python-format
+msgid "Unable to clone VM '%(name)s'. Details: %(err)s"
+msgstr ""
+
+#, python-format
+msgid "Invalid operation for non-persistent virtual machine %(name)s"
+msgstr ""
+
+#, python-format
+msgid "Cannot suspend VM '%(name)s' because it is not running."
+msgstr ""
+
+#, python-format
+msgid "Unable to suspend VM '%(name)s'. Details: %(err)s"
+msgstr ""
+
+#, python-format
+msgid "Cannot resume VM '%(name)s' because it is not paused."
+msgstr ""
+
+#, python-format
+msgid "Unable to resume VM '%(name)s'. Details: %(err)s"
+msgstr ""
+
+msgid "Memory assigned is higher then the maximum allowed in the host."
+msgstr ""
+
+#, python-format
+msgid ""
+"VM '%(name)s' does not support live memory update. Update the memory with
"
+"the machine offline to enable this feature."
+msgstr ""
+
+msgid "Only increase memory is allowed in active VMs"
+msgstr ""
+
+msgid ""
+"For live memory update, new memory value must be equal old memory value plus
"
+"multiples of 1024 Mib"
+msgstr ""
+
+msgid "There are not enough free slots of 1024 Mib in the guest."
+msgstr ""
+
+msgid ""
+"Host's libvirt version does not support memory devices. Libvirt must be >=
"
+"1.2.14"
+msgstr ""
+
+#, python-format
+msgid "Error attaching memory device. Details: %(error)s"
+msgstr ""
+
+#, python-format
+msgid ""
+"VM %(vmid)s does not contain directly assigned host device %(dev_name)s."
+msgstr ""
+
+#, python-format
+msgid "The host device %(dev_name)s is not allowed to directly assign to VM."
+msgstr ""
+
+msgid ""
+"No IOMMU groups found. Host PCI pass through needs IOMMU group to function "
+"correctly. Please enable Intel VT-d or AMD IOMMU in your BIOS, then verify "
+"the Kernel is compiled with IOMMU support. For Intel CPU, add intel_iommu=on
"
+"to your Kernel parameter in /boot/grub2/grub.conf. For AMD CPU, add iommu=pt
"
+"iommu=1."
+msgstr ""
+
+msgid "\"name\" should be a device name string"
+msgstr ""
+
+#, python-format
+msgid ""
+"The device %(name)s is probably in use by the host. Unable to attach it to "
+"the guest."
+msgstr ""
+
+#, python-format
+msgid "Interface %(iface)s does not exist in virtual machine %(name)s"
+msgstr ""
+
+#, python-format
+msgid ""
+"Network %(network)s specified for virtual machine %(name)s does not exist"
+msgstr ""
+
+msgid "Supported virtual machine interfaces type is only network"
+msgstr ""
+
+msgid "Network name for virtual machine interface must be a string"
+msgstr ""
+
+msgid "Invalid network model card specified for virtual machine interface"
+msgstr ""
+
+msgid "Specify type and network to add a new virtual machine interface"
+msgstr ""
+
+msgid "MAC Address must respect this format FF:FF:FF:FF:FF:FF"
+msgstr ""
+
+#, python-format
+msgid "MAC Address %(mac)s already exists in virtual machine %(name)s"
+msgstr ""
+
+msgid "Invalid MAC Address"
+msgstr ""
+
+msgid "Cannot change MAC address of a running virtual machine"
+msgstr ""
+
+#, python-format
+msgid "Template %(name)s already exists"
+msgstr ""
+
+#, python-format
+msgid ""
+"Network '%(network)s' specified for template %(template)s does not
exist"
+msgstr ""
+
+#, python-format
+msgid ""
+"Storage pool %(pool)s specified for template %(template)s does not exist"
+msgstr ""
+
+#, python-format
+msgid "Storage pool %(pool)s specified for template %(template)s is not
active"
+msgstr ""
+
+#, python-format
+msgid "Invalid parameter '%(param)s' specified for CDROM."
+msgstr ""
+
+#, python-format
+msgid "Network %(network)s specified for template %(template)s is not active"
+msgstr ""
+
+msgid "Template name must be a string"
+msgstr ""
+
+msgid "Template icon must be a path to the image"
+msgstr ""
+
+msgid "Template distribution must be a string"
+msgstr ""
+
+msgid "Template distribution version must be a string"
+msgstr ""
+
+msgid "The number of CPUs must be an integer greater than 0"
+msgstr ""
+
+msgid "Amount of memory (MB) must be an integer greater than 512"
+msgstr ""
+
+msgid "Template CDROM must be a local or remote ISO file"
+msgstr ""
+
+#, python-format
+msgid "Invalid storage pool URI %(value)s specified for template"
+msgstr ""
+
+msgid "Specify an ISO image as CDROM or a base image to create a template"
+msgstr ""
+
+msgid "All networks for the template must be specified in a list."
+msgstr ""
+
+msgid "Specify a volume to a template when storage pool is iSCSI or SCSI"
+msgstr ""
+
+#, python-format
+msgid "The volume %(volume)s is not in storage pool %(pool)s"
+msgstr ""
+
+#, python-format
+msgid "Unable to create template due error: %(err)s"
+msgstr ""
+
+#, python-format
+msgid "Unable to delete template due error: %(err)s"
+msgstr ""
+
+msgid "Disk size must be an integer greater than 1GB."
+msgstr ""
+
+msgid "Template base image must be a valid local image file"
+msgstr ""
+
+#, python-format
+msgid "Cannot identify base image %(path)s format"
+msgstr ""
+
+msgid ""
+"When specifying CPU topology, VCPUs must be a product of sockets, cores, and
"
+"threads."
+msgstr ""
+
+msgid ""
+"When specifying CPU topology, each element must be an integer greater than "
+"zero."
+msgstr ""
+
+msgid ""
+"Invalid disk image format. Valid formats: bochs, cloop, cow, dmg, qcow, "
+"qcow2, qed, raw, vmdk, vpc."
+msgstr ""
+
+#, python-format
+msgid "Storage pool %(name)s already exists"
+msgstr ""
+
+#, python-format
+msgid "Storage pool %(name)s does not exist"
+msgstr ""
+
+#, python-format
+msgid "Specify %(item)s in order to create the storage pool %(name)s"
+msgstr ""
+
+#, python-format
+msgid "Unable to delete active storage pool %(name)s"
+msgstr ""
+
+#, python-format
+msgid "Unable to list storage pools. Details: %(err)s"
+msgstr ""
+
+#, python-format
+msgid "Unable to create storage pool %(name)s. Details: %(err)s"
+msgstr ""
+
+#, python-format
+msgid ""
+"Unable to get number of storage volumes in storage pool %(name)s. Details: %"
+"(err)s"
+msgstr ""
+
+#, python-format
+msgid "Unable to activate storage pool %(name)s. Details: %(err)s"
+msgstr ""
+
+#, python-format
+msgid "Unable to deactivate storage pool %(name)s. Details: %(err)s"
+msgstr ""
+
+#, python-format
+msgid "Unable to delete storage pool %(name)s. Details: %(err)s"
+msgstr ""
+
+#, python-format
+msgid ""
+"Unable to create NFS Pool as export path %(path)s may block during mount"
+msgstr ""
+
+#, python-format
+msgid "Unable to create NFS Pool as export path %(path)s mount failed"
+msgstr ""
+
+#, python-format
+msgid "Unsupported storage pool type: %(type)s"
+msgstr ""
+
+#, python-format
+msgid "Error while retrieving storage pool XML to %(pool)s"
+msgstr ""
+
+msgid "Storage pool name must be a string without slashes (/)"
+msgstr ""
+
+msgid ""
+"Supported storage pool types are dir, netfs, logical, iscsi, isci and
kimchi-"
+"iso"
+msgstr ""
+
+msgid "Storage pool path must be a string"
+msgstr ""
+
+msgid "Storage pool host must be a IP or hostname"
+msgstr ""
+
+msgid "Storage pool device must be the absolute path to the block device"
+msgstr ""
+
+msgid "Storage pool devices parameter must be a list"
+msgstr ""
+
+msgid "Target IQN of an iSCSI pool must be a string"
+msgstr ""
+
+msgid "Port of a remote storage server must be an integer between 1 and 65535"
+msgstr ""
+
+msgid "iSCSI target username must be a string"
+msgstr ""
+
+msgid "iSCSI target password must be a string"
+msgstr ""
+
+msgid "Specify name and type to create a storage pool"
+msgstr ""
+
+#, python-format
+msgid ""
+"%(disk)s is not a valid disk/partition. Could not add it to the pool %(pool)"
+"s."
+msgstr ""
+
+#, python-format
+msgid "Unable to extend logical pool %(pool)s. Details: %(err)s"
+msgstr ""
+
+msgid "The parameter disks only can be updated for logical storage pool."
+msgstr ""
+
+msgid "The SCSI host adapter name must be a string."
+msgstr ""
+
+msgid "The storage pool kimchi_isos is reserved for internal use"
+msgstr ""
+
+#, python-format
+msgid ""
+"Unable to activate NFS storage pool %(name)s. NFS server %(server)s is "
+"unreachable."
+msgstr ""
+
+#, python-format
+msgid ""
+"Unable to deactivate NFS storage pool %(name)s. NFS server %(server)s is "
+"unreachable."
+msgstr ""
+
+#, python-format
+msgid ""
+"Unable to deactivate pool %(name)s as it is associated with some templates"
+msgstr ""
+
+#, python-format
+msgid "Unable to delete pool %(name)s as it is associated with some templates"
+msgstr ""
+
+#, python-format
+msgid ""
+"A volume group named '%(name)s' already exists. Please, choose another name
"
+"to create the logical pool."
+msgstr ""
+
+#, python-format
+msgid "Unable to update database with deep scan information due error:
%(err)s"
+msgstr ""
+
+#, python-format
+msgid "Storage volume %(name)s already exists"
+msgstr ""
+
+#, python-format
+msgid "Storage volume %(name)s does not exist in storage pool %(pool)s"
+msgstr ""
+
+#, python-format
+msgid ""
+"Unable to create storage volume %(volume)s because storage pool %(pool)s is "
+"not active"
+msgstr ""
+
+#, python-format
+msgid "Specify %(item)s in order to create storage volume %(volume)s"
+msgstr ""
+
+#, python-format
+msgid ""
+"Unable to list storage volumes because storage pool %(pool)s is not active"
+msgstr ""
+
+#, python-format
+msgid ""
+"Unable to create storage volume %(name)s in storage pool %(pool)s. Details:
%"
+"(err)s"
+msgstr ""
+
+#, python-format
+msgid ""
+"Unable to list storage volumes in storage pool %(pool)s. Details: %(err)s"
+msgstr ""
+
+#, python-format
+msgid "Unable to wipe storage volumes %(name)s. Details: %(err)s"
+msgstr ""
+
+#, python-format
+msgid "Unable to delete storage volume %(name)s. Details: %(err)s"
+msgstr ""
+
+#, python-format
+msgid "Unable to resize storage volume %(name)s. Details: %(err)s"
+msgstr ""
+
+#, python-format
+msgid "Storage type %(type)s does not support volume create and delete"
+msgstr ""
+
+msgid "Storage volume name must be a string"
+msgstr ""
+
+msgid "Storage volume allocation must be an integer number"
+msgstr ""
+
+msgid ""
+"Storage volume format not supported. Valid formats: bochs, cloop, cow, dmg, "
+"qcow, qcow2, qed, raw, vmdk, vpc."
+msgstr ""
+
+msgid "Storage volume requires a volume name"
+msgstr ""
+
+#, python-format
+msgid ""
+"Unable to update database with storage volume information due error: %(err)s"
+msgstr ""
+
+#, python-format
+msgid "Only one of parameter %(param)s can be specified"
+msgstr ""
+
+#, python-format
+msgid "Create volume from %(param)s is not supported"
+msgstr ""
+
+msgid "Storage volume capacity must be an integer number."
+msgstr ""
+
+msgid "Storage volume URL must be http://, https://, ftp:// or ftps://."
+msgstr ""
+
+#, python-format
+msgid "Unable to access file %(url)s. Please, check it."
+msgstr ""
+
+#, python-format
+msgid ""
+"Unable to clone storage volume '%(name)s' in pool '%(pool)s'.
Details: %(err)"
+"s"
+msgstr ""
+
+msgid "Specify chunk data and its size to upload a file."
+msgstr ""
+
+msgid "In order to upload a storage volume, specify the 'upload'
parameter."
+msgstr ""
+
+msgid ""
+"Unable to upload chunk data as it does not match with requested chunk size."
+msgstr ""
+
+#, python-format
+msgid "The storage volume %(vol)s is not under an upload process."
+msgstr ""
+
+msgid "The upload chunk data will exceed the storage volume size."
+msgstr ""
+
+#, python-format
+msgid "Unable to upload chunk data to storage volume. Details: %(err)s."
+msgstr ""
+
+#, python-format
+msgid "Interface %(name)s does not exist"
+msgstr ""
+
+#, python-format
+msgid "Network %(name)s already exists"
+msgstr ""
+
+#, python-format
+msgid "Network %(name)s does not exist"
+msgstr ""
+
+#, python-format
+msgid "Subnet %(subnet)s specified for network %(network)s is not valid."
+msgstr ""
+
+#, python-format
+msgid "Specify a network interface to create bridged network %(name)s"
+msgstr ""
+
+#, python-format
+msgid "Unable to delete active network %(name)s"
+msgstr ""
+
+#, python-format
+msgid "Interface %(iface)s specified for network %(network)s is already in
use"
+msgstr ""
+
+msgid "Interface should be bare NIC, bonding or bridge device."
+msgstr ""
+
+#, python-format
+msgid "Unable to create network %(name)s. Details: %(err)s"
+msgstr ""
+
+#, python-format
+msgid "Unable to find a free IP address for network '%(name)s'"
+msgstr ""
+
+#, python-format
+msgid "The interface %(iface)s already exists."
+msgstr ""
+
+msgid "Network name must be a string without slashes (/) or quotes (\")"
+msgstr ""
+
+msgid "Supported network types are isolated, NAT and bridge"
+msgstr ""
+
+msgid "Network subnet must be a string with IP address and prefix or netmask"
+msgstr ""
+
+msgid "Network interface must be a string"
+msgstr ""
+
+msgid "Network VLAN ID must be an integer between 1 and 4094"
+msgstr ""
+
+msgid "Specify name and type to create a Network"
+msgstr ""
+
+#, python-format
+msgid ""
+"Unable to delete network %(name)s. There are some virtual machines %(vms)s "
+"and/or templates linked to this network."
+msgstr ""
+
+#, python-format
+msgid ""
+"Unable to deactivate network %(name)s. There are some virtual machines
%(vms)"
+"s and/or templates linked to this network."
+msgstr ""
+
+#, python-format
+msgid "Bridge device %(name)s can not be the trunk device of a VLAN."
+msgstr ""
+
+#, python-format
+msgid "Failed to activate interface %(iface)s: %(err)s."
+msgstr ""
+
+#, python-format
+msgid ""
+"Failed to activate interface %(iface)s. Please check the physical link "
+"status."
+msgstr ""
+
+#, python-format
+msgid "Failed to start network %(name)s. Details: %(err)s"
+msgstr ""
+
+#, python-format
+msgid "Debug report %(name)s does not exist"
+msgstr ""
+
+msgid "Debug report tool not found in system"
+msgstr ""
+
+#, python-format
+msgid "Unable to create debug report %(name)s. Details: %(err)s."
+msgstr ""
+
+#, python-format
+msgid "Can not find any debug report with the given name %(name)s"
+msgstr ""
+
+#, python-format
+msgid "Unable to generate debug report %(name)s. Details: %(err)s"
+msgstr ""
+
+msgid "You should give a name for the debug report file."
+msgstr ""
+
+msgid ""
+"Debug report name must be a string. Only letters, digits, underscore ('_')
"
+"and hyphen ('-') are allowed."
+msgstr ""
+
+#, python-format
+msgid ""
+"The debug report with specified name \"%(name)s\" already exists. Please
use "
+"another one."
+msgstr ""
+
+#, python-format
+msgid "Storage server %(server)s was not used by Kimchi"
+msgstr ""
+
+#, python-format
+msgid "Distro '%(name)s' does not exist"
+msgstr ""
+
+#, python-format
+msgid "Partition %(name)s does not exist in the host"
+msgstr ""
+
+msgid "Unable to shutdown host machine as there are running virtual machines"
+msgstr ""
+
+msgid "Unable to reboot host machine as there are running virtual machines"
+msgstr ""
+
+#, python-format
+msgid "Node device '%(name)s' not found"
+msgstr ""
+
+msgid "Conflicting flag filters specified."
+msgstr ""
+
+msgid "No packages marked for update"
+msgstr ""
+
+#, python-format
+msgid "Package %(name)s is not marked to be updated."
+msgstr ""
+
+#, python-format
+msgid "Error while getting packages marked to be updated. Details: %(err)s"
+msgstr ""
+
+msgid "There is no compatible package manager for this system."
+msgstr ""
+
+#, python-format
+msgid "Invalid URI %(uri)s"
+msgstr ""
+
+msgid "Unable to choose a virtual machine name"
+msgstr ""
+
+msgid "Invalid storage type. Types supported: 'cdrom', 'disk'"
+msgstr ""
+
+#, python-format
+msgid "The path '%(value)s' is not a valid local/remote path for the
device"
+msgstr ""
+
+msgid "Only CDROM path can be update."
+msgstr ""
+
+#, python-format
+msgid ""
+"The storage device %(dev_name)s does not exist in the virtual machine %"
+"(vm_name)s"
+msgstr ""
+
+#, python-format
+msgid "Error while creating new storage device: %(error)s"
+msgstr ""
+
+#, python-format
+msgid "Error while updating storage device: %(error)s"
+msgstr ""
+
+#, python-format
+msgid "Error while removing storage device: %(error)s"
+msgstr ""
+
+msgid "Do not support IDE device hot plug"
+msgstr ""
+
+msgid ""
+"Specify type and path or type and pool/volume to add a new virtual machine "
+"disk"
+msgstr ""
+
+msgid "Specify path to update virtual machine disk"
+msgstr ""
+
+#, python-format
+msgid "Controller type %(type)s limitation of %(limit)s devices reached"
+msgstr ""
+
+#, python-format
+msgid "Cannot retrieve disk path information for given pool/volume: %(error)s"
+msgstr ""
+
+msgid "Volume already in use by other virtual machine."
+msgstr ""
+
+msgid ""
+"Only one of path or pool/volume can be specified to add a new virtual "
+"machine disk"
+msgstr ""
+
+#, python-format
+msgid ""
+"Volume chosen with format %(format)s does not fit in the storage type
%(type)"
+"s"
+msgstr ""
+
+msgid "YUM Repository ID must be one word only string."
+msgstr ""
+
+msgid "Repository URL must be an http://, ftp:// or file:// URL."
+msgstr ""
+
+msgid ""
+"Repository configuration is a dictionary with specific values according to "
+"repository type."
+msgstr ""
+
+msgid "Distribution to DEB repository must be a string"
+msgstr ""
+
+msgid "Components to DEB repository must be listed in a array"
+msgstr ""
+
+msgid "Components to DEB repository must be a string"
+msgstr ""
+
+msgid "Mirror list to repository must be a string"
+msgstr ""
+
+msgid "YUM Repository name must be string."
+msgstr ""
+
+msgid "GPG check must be a boolean value."
+msgstr ""
+
+msgid "GPG key must be a URL pointing to the ASCII-armored file."
+msgstr ""
+
+#, python-format
+msgid "Could not update repository %(repo_id)s."
+msgstr ""
+
+#, python-format
+msgid "Repository %(repo_id)s does not exist."
+msgstr ""
+
+msgid ""
+"Specify repository base URL, mirror list or metalink in order to create or "
+"update a YUM repository."
+msgstr ""
+
+msgid "Repository management tool was not recognized for your system."
+msgstr ""
+
+#, python-format
+msgid "Repository %(repo_id)s is already enabled."
+msgstr ""
+
+#, python-format
+msgid "Repository %(repo_id)s is already disabled."
+msgstr ""
+
+#, python-format
+msgid "Could not remove repository %(repo_id)s."
+msgstr ""
+
+#, python-format
+msgid "Could not write repository configuration file %(repo_file)s"
+msgstr ""
+
+msgid "Specify repository distribution in order to create a DEB repository."
+msgstr ""
+
+#, python-format
+msgid "Could not enable repository %(repo_id)s."
+msgstr ""
+
+#, python-format
+msgid "Could not disable repository %(repo_id)s."
+msgstr ""
+
+msgid "YUM Repository ID already exists"
+msgstr ""
+
+msgid "YUM Repository name must be a string"
+msgstr ""
+
+#, python-format
+msgid "Unable to list repositories. Details: '%(err)s'"
+msgstr ""
+
+#, python-format
+msgid "Unable to retrieve repository information. Details: '%(err)s'"
+msgstr ""
+
+#, python-format
+msgid "Unable to add repository. Details: '%(err)s'"
+msgstr ""
+
+#, python-format
+msgid "Unable to remove repository. Details: '%(err)s'"
+msgstr ""
+
+#, python-format
+msgid ""
+"Configuration items: '%(items)s' are not supported by repository
manager"
+msgstr ""
+
+msgid "Repository metalink must be an http://, ftp:// or file:// URL."
+msgstr ""
+
+msgid "Cannot specify mirrorlist and metalink at the same time."
+msgstr ""
+
+#, python-format
+msgid ""
+"Virtual machine '%(vm)s' must be stopped before creating a snapshot of
it."
+msgstr ""
+
+#, python-format
+msgid ""
+"Unable to create snapshot '%(name)s' on virtual machine '%(vm)s'.
Details: %"
+"(err)s"
+msgstr ""
+
+#, python-format
+msgid "Snapshot '%(name)s' does not exist on virtual machine
'%(vm)s'."
+msgstr ""
+
+#, python-format
+msgid ""
+"Unable to retrieve snapshot '%(name)s' on virtual machine '%(vm)s'.
Details: "
+"%(err)s"
+msgstr ""
+
+#, python-format
+msgid "Unable to list snapshots on virtual machine '%(vm)s'. Details:
%(err)s"
+msgstr ""
+
+#, python-format
+msgid ""
+"Unable to delete snapshot '%(name)s' on virtual machine '%(vm)s'.
Details: %"
+"(err)s"
+msgstr ""
+
+#, python-format
+msgid ""
+"Unable to retrieve current snapshot of virtual machine '%(vm)s'. Details:
%"
+"(err)s"
+msgstr ""
+
+#, python-format
+msgid ""
+"Unable to revert virtual machine '%(vm)s' to snapshot '%(name)s'.
Details: %"
+"(err)s"
+msgstr ""
+
+#, python-format
+msgid ""
+"Unable to create snapshot of virtual machine '%(vm)s' because it contains a
"
+"disk with format '%(format)s'; only 'qcow2' is supported."
+msgstr ""
+
+msgid "The number of vCPUs is too large for this system."
+msgstr ""
+
+msgid "Invalid vCPU/topology combination."
+msgstr ""
+
+msgid "This host (or current configuration) does not allow CPU topology."
+msgstr ""
+
+msgid "ERROR CODE"
+msgstr ""
+
+msgid "REASON"
+msgstr ""
+
+msgid "STACK"
+msgstr ""
+
+msgid "Go to Homepage"
+msgstr ""
+
+msgid "Create a New Virtual Machine"
+msgstr ""
+
+msgid "Virtual Machine Name"
+msgstr ""
+
+msgid ""
+"The name used to identify the virtual machine. If omitted, a name will be "
+"chosen based on the template used."
+msgstr ""
+
+msgid "Template"
+msgstr ""
+
+msgid "Please create a template first."
+msgstr ""
+
+msgid "Create a Template"
+msgstr ""
+
+msgid "Please choose a template."
+msgstr ""
+
+msgid "OS"
+msgstr ""
+
+msgid "OS Version"
+msgstr ""
+
+msgid "CPUS"
+msgstr ""
+
+msgid "Memory"
+msgstr ""
+
+msgid "Create"
+msgstr ""
+
+msgid "Creating..."
+msgstr ""
+
+msgid "Cancel"
+msgstr ""
+
+msgid "Edit Guest"
+msgstr ""
+
+msgid "General"
+msgstr ""
+
+msgid "Storage"
+msgstr ""
+
+msgid "Interface"
+msgstr ""
+
+msgid "Permission"
+msgstr ""
+
+msgid "Host PCI Device"
+msgstr ""
+
+msgid "Snapshot"
+msgstr ""
+
+msgid "Name"
+msgstr ""
+
+msgid "CPUs"
+msgstr ""
+
+msgid "Memory (MB)"
+msgstr ""
+
+msgid "Icon"
+msgstr ""
+
+msgid "Device"
+msgstr ""
+
+msgid "Path"
+msgstr ""
+
+msgid "Network"
+msgstr ""
+
+msgid "Type"
+msgstr ""
+
+msgid "MAC Address"
+msgstr ""
+
+msgid "Available system users and groups"
+msgstr ""
+
+msgid "Selected system users and groups"
+msgstr ""
+
+msgid "User"
+msgstr ""
+
+msgid "All"
+msgstr ""
+
+msgid "To Add"
+msgstr ""
+
+msgid "Added"
+msgstr ""
+
+msgid "filter"
+msgstr ""
+
+msgid "Product"
+msgstr ""
+
+msgid "Vendor"
+msgstr ""
+
+msgid "Created"
+msgstr ""
+
+msgid "Save"
+msgstr ""
+
+msgid "Replace"
+msgstr ""
+
+msgid "Detach"
+msgstr ""
+
+msgid "revert"
+msgstr ""
+
+msgid "Start"
+msgstr ""
+
+msgid "Reset"
+msgstr ""
+
+msgid "Pause"
+msgstr ""
+
+msgid "Resume"
+msgstr ""
+
+msgid "Power Off"
+msgstr ""
+
+msgid "Actions"
+msgstr ""
+
+msgid "Connect"
+msgstr ""
+
+msgid "Clone"
+msgstr ""
+
+msgid "Edit"
+msgstr ""
+
+msgid "Shut Down"
+msgstr ""
+
+msgid "Delete"
+msgstr ""
+
+msgid "CPU"
+msgstr ""
+
+msgid "Disk I/O"
+msgstr ""
+
+msgid "Network I/O"
+msgstr ""
+
+msgid "Livetile"
+msgstr ""
+
+msgid "No guests found."
+msgstr ""
+
+msgid "Add a Storage Device to VM"
+msgstr ""
+
+msgid "Device Type"
+msgstr ""
+
+msgid "The device type. Currently, \"cdrom\" and \"disk\" are
supported."
+msgstr ""
+
+msgid "Storage Pool"
+msgstr ""
+
+msgid "Storage pool which volume located in"
+msgstr ""
+
+msgid "Storage Volume"
+msgstr ""
+
+msgid "Storage volume to be attached"
+msgstr ""
+
+msgid "File Path"
+msgstr ""
+
+msgid "The ISO file path in the server for CDROM."
+msgstr ""
+
+msgid "Attach"
+msgstr ""
+
+msgid "Shut down"
+msgstr ""
+
+msgid "Restart"
+msgstr ""
+
+msgid "Basic Information"
+msgstr ""
+
+msgid "OS Distro"
+msgstr ""
+
+msgid "OS Code Name"
+msgstr ""
+
+msgid "Processor"
+msgstr ""
+
+msgid "CPU(s)"
+msgstr ""
+
+msgid "System Statistics"
+msgstr ""
+
+msgid "Software Updates"
+msgstr ""
+
+msgid "Update Progress"
+msgstr ""
+
+msgid "Repositories"
+msgstr ""
+
+msgid "Debug Reports"
+msgstr ""
+
+msgid "The username or password you entered is incorrect. Please try again."
+msgstr ""
+
+msgid "This field is required."
+msgstr ""
+
+msgid "Log in"
+msgstr ""
+
+msgid "Logging in..."
+msgstr ""
+
+msgid "Host"
+msgstr ""
+
+msgid "Guests"
+msgstr ""
+
+msgid "Templates"
+msgstr ""
+
+msgid "Failed to get application configuration"
+msgstr ""
+
+msgid "This is not a valid Linux path"
+msgstr ""
+
+msgid "This is not a valid URL."
+msgstr ""
+
+msgid "No such data available."
+msgstr ""
+
+msgid ""
+"Can not contact the host system. Verify the host system is up and that you "
+"have network connectivity to it. HTTP request response %1. "
+msgstr ""
+
+msgid "Unable to read file."
+msgstr ""
+
+msgid "Error while uploading file."
+msgstr ""
+
+msgid "Delete Confirmation"
+msgstr ""
+
+msgid "OK"
+msgstr ""
+
+msgid "Confirm"
+msgstr ""
+
+msgid "Warning"
+msgstr ""
+
+msgid "Cloning..."
+msgstr ""
+
+msgid "Loading..."
+msgstr ""
+
+msgid "An error occurred while retrieving system information."
+msgstr ""
+
+msgid "Retry"
+msgstr ""
+
+msgid "Detailed message:"
+msgstr ""
+
+msgid "No ISO found"
+msgstr ""
+
+msgid "This is not a valid ISO file."
+msgstr ""
+
+msgid "This may take a long time. Do you want to continue?"
+msgstr ""
+
+msgid "This will permanently delete the template. Would you like to continue?"
+msgstr ""
+
+msgid "Unable to shut down system as there are some virtual machines running!"
+msgstr ""
+
+msgid "Max:"
+msgstr ""
+
+msgid "Utilization"
+msgstr ""
+
+msgid "Available"
+msgstr ""
+
+msgid "Read Rate"
+msgstr ""
+
+msgid "Write Rate"
+msgstr ""
+
+msgid "Received"
+msgstr ""
+
+msgid "Sent"
+msgstr ""
+
+msgid ""
+"Shutting down or restarting host will cause unsaved work lost. Continue to "
+"shut down/restarting?"
+msgstr ""
+
+msgid ""
+"Repository will be removed permanently and can't be recovered. Do you want
"
+"to continue?"
+msgstr ""
+
+msgid "ID"
+msgstr ""
+
+msgid "Base URL"
+msgstr ""
+
+msgid "Is Mirror"
+msgstr ""
+
+msgid "URL Args"
+msgstr ""
+
+msgid "Enabled"
+msgstr ""
+
+msgid "GPG Check"
+msgstr ""
+
+msgid "GPG Key"
+msgstr ""
+
+msgid "Add"
+msgstr ""
+
+msgid "Remove"
+msgstr ""
+
+msgid "Enable"
+msgstr ""
+
+msgid "Disable"
+msgstr ""
+
+msgid "Package Name"
+msgstr ""
+
+msgid "Version"
+msgstr ""
+
+msgid "Architecture"
+msgstr ""
+
+msgid "Repository"
+msgstr ""
+
+msgid "Update All"
+msgstr ""
+
+msgid "Updating..."
+msgstr ""
+
+msgid "Failed to retrieve packages update information."
+msgstr ""
+
+msgid "Failed to update package(s)."
+msgstr ""
+
+msgid ""
+"Debug report will be removed permanently and can't be recovered. Do you want
"
+"to continue?"
+msgstr ""
+
+msgid "Generated Time"
+msgstr ""
+
+msgid "Generate"
+msgstr ""
+
+msgid "Generating..."
+msgstr ""
+
+msgid "Rename"
+msgstr ""
+
+msgid "Download"
+msgstr ""
+
+msgid ""
+"Report name should contain only letters, digits, underscore ('_') and/or
"
+"hyphen ('-')."
+msgstr ""
+
+msgid "Pending..."
+msgstr ""
+
+msgid "Report name is the same as the original one."
+msgstr ""
+
+msgid ""
+"This will delete the virtual machine and its virtual disks. This operation "
+"cannot be undone. Would you like to continue?"
+msgstr ""
+
+msgid "Power off Confirmation"
+msgstr ""
+
+msgid ""
+"This action may produce undesirable results, for example unflushed disk "
+"cache in the guest. Would you like to continue?"
+msgstr ""
+
+msgid "Reset Confirmation"
+msgstr ""
+
+msgid ""
+"There is a risk of data loss caused by reset without the guest OS shutdown. "
+"Would you like to continue?"
+msgstr ""
+
+msgid "Shut Down Confirmation"
+msgstr ""
+
+msgid "Note the guest OS may ignore this request. Would you like to continue?"
+msgstr ""
+
+msgid "Virtual Machine delete Confirmation"
+msgstr ""
+
+msgid ""
+"This virtual machine is not persistent. Power Off will delete it. Continue?"
+msgstr ""
+
+msgid ""
+"When the target guest has SCSI or iSCSI volumes, they will be cloned on "
+"default storage pool. The same will happen when the target pool does not "
+"have enough space to clone the volumes. Do you want to continue?"
+msgstr ""
+
+msgid ""
+"This CDROM will be detached permanently and you can re-attach it. Continue "
+"to detach it?"
+msgstr ""
+
+msgid "Attaching..."
+msgstr ""
+
+msgid "Replacing..."
+msgstr ""
+
+msgid "Successfully attached!"
+msgstr ""
+
+msgid "Successfully replaced!"
+msgstr ""
+
+msgid "Successfully detached!"
+msgstr ""
+
+msgid ""
+"This disk will be detached permanently and you can re-attach it. Continue to
"
+"detach it?"
+msgstr ""
+
+msgid "interface:"
+msgstr ""
+
+msgid "address:"
+msgstr ""
+
+msgid "link_type:"
+msgstr ""
+
+msgid "block:"
+msgstr ""
+
+msgid "drive_type:"
+msgstr ""
+
+msgid "model:"
+msgstr ""
+
+msgid "Affected devices:"
+msgstr ""
+
+msgid "The VLAN id must be between 1 and 4094."
+msgstr ""
+
+msgid "unavailable"
+msgstr ""
+
+msgid ""
+"This action will interrupt network connectivity for any virtual machine that
"
+"depend on this network."
+msgstr ""
+
+msgid "Create a network"
+msgstr ""
+
+msgid ""
+"This network is not persistent. Instead of stop, this action will "
+"permanently delete it. Would you like to continue?"
+msgstr ""
+
+msgid ""
+"The bridged VLAN tag may not work well with NetworkManager enabled. You "
+"should consider disabling it."
+msgstr ""
+
+msgid ""
+"This will permanently delete the storage pool. Would you like to continue?"
+msgstr ""
+
+msgid "This storage pool is empty."
+msgstr ""
+
+msgid ""
+"It will format your disk and you will loose any data in there, are you sure "
+"to continue? "
+msgstr ""
+
+msgid "SCSI Fibre Channel"
+msgstr ""
+
+msgid "No SCSI adapters found."
+msgstr ""
+
+msgid "Loading iSCSI targets..."
+msgstr ""
+
+msgid "No iSCSI found. Please input one."
+msgstr ""
+
+msgid "Failed to load iSCSI targets."
+msgstr ""
+
+msgid "The storage pool name can not be blank."
+msgstr ""
+
+msgid "The storage pool path can not be blank."
+msgstr ""
+
+msgid "NFS server mount path can not be blank."
+msgstr ""
+
+msgid "Invalid NFS mount path."
+msgstr ""
+
+msgid "No logical device selected."
+msgstr ""
+
+msgid "The iSCSI target can not be blank."
+msgstr ""
+
+msgid "Server name can not be blank."
+msgstr ""
+
+msgid "This is not a valid Server Name or IP. Please, modify it."
+msgstr ""
+
+msgid "Looking for available partitions ..."
+msgstr ""
+
+msgid "No available partitions found."
+msgstr ""
+
+msgid ""
+"This storage pool is not persistent. Instead of deactivate, this action will
"
+"permanently delete it. Would you like to continue?"
+msgstr ""
+
+msgid "Unable to retrieve partitions information."
+msgstr ""
+
+msgid "In progress..."
+msgstr ""
+
+msgid "Failed!"
+msgstr ""
+
+msgid "CDROM path needs to be a valid local/remote path and cannot be blank."
+msgstr ""
+
+msgid "Disk pool or volume cannot be blank."
+msgstr ""
+
+msgid "Filter"
+msgstr ""
+
+msgid "Network Name"
+msgstr ""
+
+msgid "State"
+msgstr ""
+
+msgid "Network Type"
+msgstr ""
+
+msgid "Address Space"
+msgstr ""
+
+msgid "Name should not contain '/' and '\"'."
+msgstr ""
+
+msgid "Isolated: no external network connection"
+msgstr ""
+
+msgid "NAT: outbound physical network connection only"
+msgstr ""
+
+msgid "Bridged: Virtual machines are connected to physical network directly"
+msgstr ""
+
+msgid "(No interfaces found)"
+msgstr ""
+
+msgid "Destination"
+msgstr ""
+
+msgid "Enable VLAN"
+msgstr ""
+
+msgid "VLAN ID"
+msgstr ""
+
+msgid "Stop"
+msgstr ""
+
+msgid "Generate a New Debug Report"
+msgstr ""
+
+msgid "Report Name"
+msgstr ""
+
+msgid ""
+"The name used to identify the report. If omitted, a name will be chosen "
+"based on current time. Name can contain: letters, digits, underscore
(\"_\") "
+"and hyphen (\"-\")."
+msgstr ""
+
+msgid "Rename a Debug Report"
+msgstr ""
+
+msgid ""
+"The name used to identify the report. Name can contain: letters, digits and "
+"hyphen (\"-\")."
+msgstr ""
+
+msgid "Submit"
+msgstr ""
+
+msgid "Add a Repository"
+msgstr ""
+
+msgid "Identifier"
+msgstr ""
+
+msgid "Single word, unique identifier for the repository."
+msgstr ""
+
+msgid "Textual name for the repository."
+msgstr ""
+
+msgid "URL"
+msgstr ""
+
+msgid "Required Field"
+msgstr ""
+
+msgid "URL to the repository. Supported protocols are http, ftp, and file."
+msgstr ""
+
+msgid "Repository is a mirror"
+msgstr ""
+
+msgid "Distribution"
+msgstr ""
+
+msgid "Distribution of the DEB repository."
+msgstr ""
+
+msgid "Components"
+msgstr ""
+
+msgid "List of components in DEB repository."
+msgstr ""
+
+msgid "Edit Repository"
+msgstr ""
+
+msgid "Mirror List URL"
+msgstr ""
+
+msgid "Yes"
+msgstr ""
+
+msgid "No"
+msgstr ""
+
+msgid "Capacity"
+msgstr ""
+
+msgid "Allocated"
+msgstr ""
+
+msgid "Location"
+msgstr ""
+
+msgid "Device path"
+msgstr ""
+
+msgid "active"
+msgstr ""
+
+msgid "inactive"
+msgstr ""
+
+msgid "Deactivate"
+msgstr ""
+
+msgid "Activate"
+msgstr ""
+
+msgid "Add Volume"
+msgstr ""
+
+msgid "Extend"
+msgstr ""
+
+msgid "Undefine"
+msgstr ""
+
+msgid "Format"
+msgstr ""
+
+msgid "Allocation"
+msgstr ""
+
+msgid "Define a New Storage Pool"
+msgstr ""
+
+msgid "Storage Pool Name"
+msgstr ""
+
+msgid ""
+"The name used to identify the storage pools, and it should not be empty."
+msgstr ""
+
+msgid "Storage Pool Type"
+msgstr ""
+
+msgid "Storage Path"
+msgstr ""
+
+msgid ""
+"The path of the Storage Pool. Each Storage Pool must have a unique path."
+msgstr ""
+
+msgid ""
+"Kimchi will try to create the directory when it does not already exist in "
+"your system."
+msgstr ""
+
+msgid "NFS Server IP"
+msgstr ""
+
+msgid "NFS server IP or hostname. It can be input or chosen from history."
+msgstr ""
+
+msgid "NFS Path"
+msgstr ""
+
+msgid "The NFS exported path on NFS server."
+msgstr ""
+
+msgid "iSCSI Server"
+msgstr ""
+
+msgid "Server"
+msgstr ""
+
+msgid "Port"
+msgstr ""
+
+msgid "iSCSI server IP or hostname. It should not be empty."
+msgstr ""
+
+msgid "Target"
+msgstr ""
+
+msgid "The iSCSI target on iSCSI server"
+msgstr ""
+
+msgid "Add iSCSI Authentication"
+msgstr ""
+
+msgid "iSCSI Authentication"
+msgstr ""
+
+msgid "User Name"
+msgstr ""
+
+msgid "Password"
+msgstr ""
+
+msgid "SCSI Adapter"
+msgstr ""
+
+msgid "Please, wait..."
+msgstr ""
+
+msgid "Add a Volume to Storage Pool"
+msgstr ""
+
+msgid "Fetch from remote URL"
+msgstr ""
+
+msgid "Enter the remote URL here."
+msgstr ""
+
+msgid "Upload a file"
+msgstr ""
+
+msgid "Choose the file you want to upload."
+msgstr ""
+
+msgid "Add Template"
+msgstr ""
+
+msgid "Where is the source media for this template? "
+msgstr ""
+
+msgid "Local ISO Image"
+msgstr ""
+
+msgid "Local Image File"
+msgstr ""
+
+msgid "Remote ISO Image"
+msgstr ""
+
+msgid "Search ISOs"
+msgstr ""
+
+msgid "The following ISOs are available:"
+msgstr ""
+
+msgid "OS: "
+msgstr ""
+
+msgid "Version: "
+msgstr ""
+
+msgid "Size: "
+msgstr ""
+
+msgid "Search more ISOs"
+msgstr ""
+
+msgid "Create Templates from Selected ISO"
+msgstr ""
+
+msgid "I want to use a specific ISO file"
+msgstr ""
+
+msgid "Loading default remote ISOs ..."
+msgstr ""
+
+msgid "Arch: "
+msgstr ""
+
+msgid "I want to use a custom URL"
+msgstr ""
+
+msgid "Edit Template"
+msgstr ""
+
+msgid "CDROM"
+msgstr ""
+
+msgid "Image File"
+msgstr ""
+
+msgid "Graphics"
+msgstr ""
+
+msgid "Disk(GB)"
+msgstr ""
+
+msgid "Disk Format"
+msgstr ""
+
+msgid "CPU Number"
+msgstr ""
+
+msgid "Manually set CPU topology"
+msgstr ""
+
+msgid "Cores"
+msgstr ""
+
+msgid "Threads"
+msgstr ""
+
+msgid "No templates found."
+msgstr ""
diff --git a/src/wok/plugins/kimchi/po/es_ES.po b/src/wok/plugins/kimchi/po/es_ES.po
new file mode 100644
index 0000000..d71e621
--- /dev/null
+++ b/src/wok/plugins/kimchi/po/es_ES.po
@@ -0,0 +1,2305 @@
+# English translations for kimchi package.
+# Copyright (C) 2013 ORGANIZATION
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: kimchi 0.1\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2015-07-01 16:11-0300\n"
+"PO-Revision-Date: 2013-07-11 17:32-0400\n"
+"Last-Translator: Cr��stian Viana <vianac(a)linux.vnet.ibm.com>\n"
+"Language-Team: English\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Language: es_ES\n"
+"Generated-By: pygettext.py 1.5\n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+
+#, python-format
+msgid "Unknown parameter %(value)s"
+msgstr ""
+
+#, python-format
+msgid "Timeout of %(seconds)s seconds expired while running task
'%(task)s."
+msgstr ""
+
+#, python-format
+msgid "User %(user_id)s not found with given LDAP settings."
+msgstr ""
+
+msgid "Unknown \"_cap\" specified"
+msgstr ""
+
+msgid "\"_passthrough\" should be \"true\" or
\"false\""
+msgstr ""
+
+msgid "\"_passthrough_affected_by\" should be a device name string"
+msgstr ""
+
+#, python-format
+msgid "Error while getting block devices. Details: %(err)s"
+msgstr ""
+"Se ha producido un error al obtener dispositivos de bloque. Detalles:
%(err)s"
+
+#, python-format
+msgid "Error while getting block device information for %(device)s."
+msgstr ""
+"Se ha producido un error al obtener informaci��n de dispositivo de bloque "
+"para %(device)s."
+
+#, python-format
+msgid "Unable to find distro file: %(filename)s"
+msgstr "No se puede encontrar el archivo distro: %(filename)s"
+
+#, python-format
+msgid ""
+"Unable to parse distro file: %(filename)s. Make sure, it is a JSON file."
+msgstr ""
+"No se puede analizar el archivo distro: %(filename)s. Aseg��rese de que es un
"
+"archivo JSON."
+
+#, python-format
+msgid "Unable to login to iSCSI host target %(portal)s. Details: %(err)s"
+msgstr ""
+"No se puede iniciar la sesi��n en %(portal)s del destino de host iSCSI. "
+"Detalles: %(err)s"
+
+#, python-format
+msgid "Unable to login to iSCSI host %(host)s target %(target)s"
+msgstr ""
+"No se puede iniciar la sesi��n en el destino %(target)s del %(host)s host de
"
+"iSCSI"
+
+#, python-format
+msgid "Unable to find ISO file %(filename)s"
+msgstr ""
+
+#, python-format
+msgid "The ISO file %(filename)s is not bootable"
+msgstr "El archivo ISO %(filename)s no es arrancable"
+
+#, python-format
+msgid "The ISO file %(filename)s does not have a valid El Torito boot record"
+msgstr ""
+"El archivo ISO %(filename)s no tiene un registro de arranque de El Torito "
+"v��lido"
+
+#, python-format
+msgid "Invalid El Torito validation entry in ISO %(filename)s"
+msgstr "Entrada de validaci��n de El Torito no v��lida en ISO %(filename)s"
+
+#, python-format
+msgid "Invalid El Torito boot indicator in ISO %(filename)s"
+msgstr "Indicador de arranque de El Torito no v��lido en ISO %(filename)s"
+
+#, python-format
+msgid "Unexpected volume type for primary volume in ISO %(filename)s"
+msgstr ""
+"Tipo de volumen inesperado para el volumen primario en ISO %(filename)s"
+
+#, python-format
+msgid "Bad format while reading volume descriptor in ISO %(filename)s"
+msgstr ""
+"Formato incorrecto mientras se le��a el descriptor de volumen en ISO %"
+"(filename)s"
+
+#, python-format
+msgid ""
+"The hypervisor doesn't have permission to use this ISO %(filename)s. "
+"Consider moving it under /var/lib/libvirt, or set the search permission to "
+"file access control lists for '%(user)s' user if possible, or add the
'%"
+"(user)s' to the ISO path group, or (not recommended) 'chmod -R o+x "
+"'path_to_iso'.Details: %(err)s"
+msgstr ""
+"El hipervisor no tiene permiso para utilizar este ISO %(filename)s. "
+"Considere moverlo a /var/lib/libvirt, o establezca el permiso de b��squeda en
"
+"listas de control de accesos de archivo para el usuario '%(user)s' si es
"
+"posible, o a��ada el '%(user)s' al grupo de v��as de acceso ISO, o (no
"
+"recomendado) 'chmod -R o+x 'path_to_iso'.Detalles: %(err)s"
+
+msgid "An error occurred when probing image OS information."
+msgstr ""
+
+msgid "No OS information found in given image."
+msgstr ""
+
+#, python-format
+msgid "Unable to read image file %(filename)s"
+msgstr ""
+
+#, python-format
+msgid ""
+"Image file must be an existing file on system. %(filename)s is not a valid "
+"input."
+msgstr ""
+
+#, python-format
+msgid "Virtual machine %(name)s already exists"
+msgstr "La m��quina virtual %(name)s ya existe"
+
+#, python-format
+msgid "Virtual machine %(name)s does not exist"
+msgstr "La m��quina virtual %(name)s no existe"
+
+#, python-format
+msgid ""
+"Unable to rename virtual machine %(name)s. The name %(new_name)s is already "
+"in use or the virtual machine is not powered off."
+msgstr ""
+
+#, python-format
+msgid "Unable to retrieve screenshot for stopped virtual machine %(name)s"
+msgstr ""
+"No se puede recuperar la captura de pantalla para la m��quina virtual "
+"detenida %(name)s"
+
+msgid "Remote ISO image is not supported by this server."
+msgstr "La imagen ISO remota no est�� soportada por este servidor."
+
+#, python-format
+msgid "Screenshot is not supported on virtual machine %(name)s"
+msgstr ""
+
+#, python-format
+msgid "Unable to create virtual machine %(name)s. Details: %(err)s"
+msgstr "No se puede crear la m��quina virtual %(name)s. Detalles: %(err)s"
+
+#, python-format
+msgid "Unable to update virtual machine %(name)s. Details: %(err)s"
+msgstr "No se puede crear la m��quina virtual %(name)s. Detalles: %(err)s"
+
+#, python-format
+msgid "Unable to retrieve virtual machine %(name)s. Details: %(err)s"
+msgstr "No se puede recuperar la m��quina virtual %(name)s. Detalles: %(err)s"
+
+#, python-format
+msgid "Unable to connect to powered off virtual machine %(name)s."
+msgstr ""
+
+msgid "Virtual machine name must be a string without slashes (/)"
+msgstr ""
+
+#, python-format
+msgid "Invalid template URI %(value)s specified for virtual machine"
+msgstr ""
+
+#, python-format
+msgid "Invalid storage pool URI %(value)s specified for virtual machine"
+msgstr ""
+
+msgid "Supported virtual machine graphics are Spice or VNC"
+msgstr ""
+
+msgid "Graphics address to listen on must be IPv4 or IPv6"
+msgstr ""
+"La direcci��n de gr��ficos en que hay que estar a la escucha debe ser IPv4 o
"
+"IPv6"
+
+msgid "Specify a template to create a virtual machine from"
+msgstr ""
+"Especifique una plantilla a partir de la que se crear�� una m��quina virtual"
+
+#, python-format
+msgid "Unable to start virtual machine %(name)s. Details: %(err)s"
+msgstr "No se puede iniciar la m��quina virtual %(name)s. Detalles: %(err)s"
+
+#, python-format
+msgid "Unable to power off virtual machine %(name)s. Details: %(err)s"
+msgstr "No se puede detener la m��quina virtual %(name)s. Detalles: %(err)s"
+
+#, python-format
+msgid "Unable to delete virtual machine %(name)s. Details: %(err)s"
+msgstr "No se puede suprimir la m��quina virtual %(name)s. Detalles: %(err)s"
+
+#, python-format
+msgid "Unable to reset virtual machine %(name)s. Details: %(err)s"
+msgstr "No se puede redenominar la m��quina virtual %(name)s. Detalles:
%(err)s"
+
+msgid "User name list must be an array"
+msgstr ""
+
+msgid "User name must be a string"
+msgstr "El nombre de red debe ser una serie"
+
+msgid "Group name list must be an array"
+msgstr ""
+
+msgid "Group name must be a string"
+msgstr "El nombre de red debe ser una serie"
+
+#, python-format
+msgid "User(s) '%(users)s' do not exist"
+msgstr "El usuario '%(users)s' no existe."
+
+#, python-format
+msgid "Group(s) '%(groups)s' do not exist"
+msgstr "El usuario '%(groups)s' no existe."
+
+#, python-format
+msgid "Unable to shutdown virtual machine %(name)s. Details: %(err)s"
+msgstr "No se puede detener la m��quina virtual %(name)s. Detalles: %(err)s"
+
+#, python-format
+msgid ""
+"Unable to get access metadata of virtual machine %(name)s. Details: %(err)s"
+msgstr "No se puede iniciar la m��quina virtual %(name)s. Detalles: %(err)s"
+
+msgid "The guest console password must be a string."
+msgstr ""
+
+msgid "The life time for the guest console password must be a number."
+msgstr ""
+
+#, python-format
+msgid "Virtual machine '%(name)s' must be stopped before cloning it."
+msgstr ""
+
+#, python-format
+msgid "Insufficient disk space to clone virtual machine '%(name)s'"
+msgstr ""
+
+#, python-format
+msgid "Unable to clone VM '%(name)s'. Details: %(err)s"
+msgstr ""
+
+#, python-format
+msgid "Invalid operation for non-persistent virtual machine %(name)s"
+msgstr ""
+
+#, python-format
+msgid "Cannot suspend VM '%(name)s' because it is not running."
+msgstr ""
+
+#, python-format
+msgid "Unable to suspend VM '%(name)s'. Details: %(err)s"
+msgstr ""
+
+#, python-format
+msgid "Cannot resume VM '%(name)s' because it is not paused."
+msgstr ""
+
+#, python-format
+msgid "Unable to resume VM '%(name)s'. Details: %(err)s"
+msgstr ""
+
+msgid "Memory assigned is higher then the maximum allowed in the host."
+msgstr ""
+
+#, python-format
+msgid ""
+"VM '%(name)s' does not support live memory update. Update the memory with
"
+"the machine offline to enable this feature."
+msgstr ""
+
+msgid "Only increase memory is allowed in active VMs"
+msgstr ""
+
+msgid ""
+"For live memory update, new memory value must be equal old memory value plus
"
+"multiples of 1024 Mib"
+msgstr ""
+
+msgid "There are not enough free slots of 1024 Mib in the guest."
+msgstr ""
+
+msgid ""
+"Host's libvirt version does not support memory devices. Libvirt must be >=
"
+"1.2.14"
+msgstr ""
+
+#, python-format
+msgid "Error attaching memory device. Details: %(error)s"
+msgstr ""
+
+#, python-format
+msgid ""
+"VM %(vmid)s does not contain directly assigned host device %(dev_name)s."
+msgstr ""
+
+#, python-format
+msgid "The host device %(dev_name)s is not allowed to directly assign to VM."
+msgstr ""
+
+msgid ""
+"No IOMMU groups found. Host PCI pass through needs IOMMU group to function "
+"correctly. Please enable Intel VT-d or AMD IOMMU in your BIOS, then verify "
+"the Kernel is compiled with IOMMU support. For Intel CPU, add intel_iommu=on
"
+"to your Kernel parameter in /boot/grub2/grub.conf. For AMD CPU, add iommu=pt
"
+"iommu=1."
+msgstr ""
+
+msgid "\"name\" should be a device name string"
+msgstr ""
+
+#, python-format
+msgid ""
+"The device %(name)s is probably in use by the host. Unable to attach it to "
+"the guest."
+msgstr ""
+
+#, python-format
+msgid "Interface %(iface)s does not exist in virtual machine %(name)s"
+msgstr "La interfaz %(iface)s no existe en la m��quina virtual %(name)s"
+
+#, python-format
+msgid ""
+"Network %(network)s specified for virtual machine %(name)s does not exist"
+msgstr ""
+"La red %(network)s especificada para la m��quina virtual %(name)s no existe"
+
+msgid "Supported virtual machine interfaces type is only network"
+msgstr "El tipo de interfaces de m��quina virtual soportado es de red
solamente"
+
+msgid "Network name for virtual machine interface must be a string"
+msgstr ""
+"El nombre de red para la interfaz de m��quina virtual debe ser una serie"
+
+msgid "Invalid network model card specified for virtual machine interface"
+msgstr ""
+"Especificada tarjeta de modelo de red no v��lida para la interfaz de m��quina
"
+"virtual"
+
+msgid "Specify type and network to add a new virtual machine interface"
+msgstr ""
+"Especifique el tipo y la red para a��adir una interfaz de m��quina virtual "
+"nueva"
+
+msgid "MAC Address must respect this format FF:FF:FF:FF:FF:FF"
+msgstr ""
+
+#, python-format
+msgid "MAC Address %(mac)s already exists in virtual machine %(name)s"
+msgstr ""
+
+msgid "Invalid MAC Address"
+msgstr ""
+
+msgid "Cannot change MAC address of a running virtual machine"
+msgstr ""
+
+#, python-format
+msgid "Template %(name)s already exists"
+msgstr "La plantilla %(name)s ya existe"
+
+#, python-format
+msgid ""
+"Network '%(network)s' specified for template %(template)s does not
exist"
+msgstr ""
+"La red '%(network)s' especificada para la plantilla %(template)s no
existe"
+
+#, python-format
+msgid ""
+"Storage pool %(pool)s specified for template %(template)s does not exist"
+msgstr ""
+"La agrupaci��n de almacenamiento %(pool)s especificada para la plantilla %"
+"(template)s no existe"
+
+#, python-format
+msgid "Storage pool %(pool)s specified for template %(template)s is not
active"
+msgstr ""
+"La agrupaci��n de almacenamiento %(pool)s especificada para la plantilla %"
+"(template)s no est�� activa"
+
+#, python-format
+msgid "Invalid parameter '%(param)s' specified for CDROM."
+msgstr "Par��metro no v��lido '%(param)s' especificado para CDROM."
+
+#, python-format
+msgid "Network %(network)s specified for template %(template)s is not active"
+msgstr ""
+"La red %(network)s especificada para la plantilla %(template)s no est��
activa"
+
+msgid "Template name must be a string"
+msgstr "El nombre de plantilla debe ser una serie"
+
+msgid "Template icon must be a path to the image"
+msgstr "El icono de plantilla debe ser una v��a de acceso a la imagen"
+
+msgid "Template distribution must be a string"
+msgstr "La distribuci��n de plantilla debe ser una serie"
+
+msgid "Template distribution version must be a string"
+msgstr "La versi��n de distribuci��n de plantilla debe ser una serie"
+
+msgid "The number of CPUs must be an integer greater than 0"
+msgstr "El n��mero de CPUs debe ser un entero"
+
+msgid "Amount of memory (MB) must be an integer greater than 512"
+msgstr "La cantidad de memoria (MB) debe ser un entero mayor que 512"
+
+msgid "Template CDROM must be a local or remote ISO file"
+msgstr "El CDROM de plantilla debe ser un archivo ISO local o remoto"
+
+#, python-format
+msgid "Invalid storage pool URI %(value)s specified for template"
+msgstr ""
+"URI de agrupaci��n de almacenamiento no v��lido %(value)s especificado para la
"
+"plantilla"
+
+msgid "Specify an ISO image as CDROM or a base image to create a template"
+msgstr "Especifique una imagen de ISO como CDROM para crear una plantilla"
+
+msgid "All networks for the template must be specified in a list."
+msgstr "Todas las redes para la plantilla deben especificarse en una lista."
+
+msgid "Specify a volume to a template when storage pool is iSCSI or SCSI"
+msgstr ""
+
+#, python-format
+msgid "The volume %(volume)s is not in storage pool %(pool)s"
+msgstr ""
+
+#, python-format
+msgid "Unable to create template due error: %(err)s"
+msgstr "No se puede crear la plantilla debido a un error: %(err)s"
+
+#, python-format
+msgid "Unable to delete template due error: %(err)s"
+msgstr "No se puede suprimir la plantilla debido a un error: %(err)s"
+
+msgid "Disk size must be an integer greater than 1GB."
+msgstr ""
+
+msgid "Template base image must be a valid local image file"
+msgstr "El CDROM de plantilla debe ser un archivo ISO local o remoto"
+
+#, python-format
+msgid "Cannot identify base image %(path)s format"
+msgstr ""
+
+msgid ""
+"When specifying CPU topology, VCPUs must be a product of sockets, cores, and
"
+"threads."
+msgstr ""
+
+msgid ""
+"When specifying CPU topology, each element must be an integer greater than "
+"zero."
+msgstr ""
+
+msgid ""
+"Invalid disk image format. Valid formats: bochs, cloop, cow, dmg, qcow, "
+"qcow2, qed, raw, vmdk, vpc."
+msgstr ""
+
+#, python-format
+msgid "Storage pool %(name)s already exists"
+msgstr "La agrupaci��n de almacenamiento %(name)s ya existe"
+
+#, python-format
+msgid "Storage pool %(name)s does not exist"
+msgstr "La agrupaci��n de almacenamiento %(name)s no existe"
+
+#, python-format
+msgid "Specify %(item)s in order to create the storage pool %(name)s"
+msgstr ""
+"Especifique %(item)s para poder crear la agrupaci��n de almacenamiento
%(name)"
+"s"
+
+#, python-format
+msgid "Unable to delete active storage pool %(name)s"
+msgstr "No se puede suprimir la agrupaci��n de almacenamiento activa %(name)s"
+
+#, python-format
+msgid "Unable to list storage pools. Details: %(err)s"
+msgstr "No se pueden listar agrupaciones de almacenamiento. Detalles: %(err)s"
+
+#, python-format
+msgid "Unable to create storage pool %(name)s. Details: %(err)s"
+msgstr ""
+"No se puede crear la agrupaci��n de almacenamiento %(name)s. Detalles:
%(err)s"
+
+#, python-format
+msgid ""
+"Unable to get number of storage volumes in storage pool %(name)s. Details: %"
+"(err)s"
+msgstr ""
+"No se puede obtener el n��mero de vol��menes de almacenamiento en la "
+"agrupaci��n de almacenamiento %(name)s. Detalles: %(err)s"
+
+#, python-format
+msgid "Unable to activate storage pool %(name)s. Details: %(err)s"
+msgstr ""
+"No se puede activar la agrupaci��n de almacenamiento %(name)s. Detalles: %"
+"(err)s"
+
+#, python-format
+msgid "Unable to deactivate storage pool %(name)s. Details: %(err)s"
+msgstr ""
+"No se puede desactivar la agrupaci��n de almacenamiento %(name)s. Detalles:
%"
+"(err)s"
+
+#, python-format
+msgid "Unable to delete storage pool %(name)s. Details: %(err)s"
+msgstr ""
+"No se puede suprimir la agrupaci��n de almacenamiento %(name)s. Detalles: %"
+"(err)s"
+
+#, python-format
+msgid ""
+"Unable to create NFS Pool as export path %(path)s may block during mount"
+msgstr ""
+"No se puede crear la agrupaci��n de NFS ya que la v��a de acceso de "
+"exportaci��n %(path)s podr��a bloquearse durante el montaje"
+
+#, python-format
+msgid "Unable to create NFS Pool as export path %(path)s mount failed"
+msgstr ""
+"No se puede crear la agrupaci��n de NFS ya que el montaje de la v��a de acceso
"
+"de exportaci��n %(path)s ha fallado"
+
+#, python-format
+msgid "Unsupported storage pool type: %(type)s"
+msgstr "Tipo de agrupaci��n de almacenamiento no soportado: %(type)s"
+
+#, python-format
+msgid "Error while retrieving storage pool XML to %(pool)s"
+msgstr ""
+
+msgid "Storage pool name must be a string without slashes (/)"
+msgstr ""
+
+msgid ""
+"Supported storage pool types are dir, netfs, logical, iscsi, isci and
kimchi-"
+"iso"
+msgstr ""
+
+msgid "Storage pool path must be a string"
+msgstr "La v��a de acceso de la agrupaci��n de almacenamiento debe ser una
serie"
+
+msgid "Storage pool host must be a IP or hostname"
+msgstr ""
+"El host de la agrupaci��n de almacenamiento debe ser un IP o nombre de host"
+
+msgid "Storage pool device must be the absolute path to the block device"
+msgstr ""
+
+msgid "Storage pool devices parameter must be a list"
+msgstr ""
+"El par��metro de los dispositivos de agrupaci��n de almacenamiento debe ser "
+"una lista"
+
+msgid "Target IQN of an iSCSI pool must be a string"
+msgstr "El IQN destino de una agrupaci��n de iSCSI debe ser una serie"
+
+msgid "Port of a remote storage server must be an integer between 1 and 65535"
+msgstr ""
+"El puerto de un servidor de almacenamiento remoto debe ser un entero entre 1
"
+"y 65535"
+
+msgid "iSCSI target username must be a string"
+msgstr ""
+
+msgid "iSCSI target password must be a string"
+msgstr ""
+
+msgid "Specify name and type to create a storage pool"
+msgstr ""
+"Especifique el nombre y el tipo para crear una agrupaci��n de almacenamiento"
+
+#, python-format
+msgid ""
+"%(disk)s is not a valid disk/partition. Could not add it to the pool %(pool)"
+"s."
+msgstr ""
+"%(disk)s no es un disco/partici��n. No se ha podido a��adir a la agrupaci��n
%"
+"(pool)s."
+
+#, python-format
+msgid "Unable to extend logical pool %(pool)s. Details: %(err)s"
+msgstr ""
+
+msgid "The parameter disks only can be updated for logical storage pool."
+msgstr ""
+"Los discos de par��metro s��lo pueden actualizarse para la agrupaci��n de "
+"almacenamiento l��gico."
+
+msgid "The SCSI host adapter name must be a string."
+msgstr "El nombre del adaptador de host SCSI debe ser una serie."
+
+msgid "The storage pool kimchi_isos is reserved for internal use"
+msgstr ""
+"La agrupaci��n de almacenamiento kimchi_isos est�� reservada para uso
interno"
+
+#, python-format
+msgid ""
+"Unable to activate NFS storage pool %(name)s. NFS server %(server)s is "
+"unreachable."
+msgstr ""
+"No se puede activar la agrupaci��n de almacenamiento NFS %(name)s. El "
+"servidor NFS %(server)s est�� fuera de alcance."
+
+#, python-format
+msgid ""
+"Unable to deactivate NFS storage pool %(name)s. NFS server %(server)s is "
+"unreachable."
+msgstr ""
+"No se puede desactivar la agrupaci��n de almacenamiento NFS %(name)s. El "
+"servidor NFS %(server)s est�� fuera de alcance."
+
+#, python-format
+msgid ""
+"Unable to deactivate pool %(name)s as it is associated with some templates"
+msgstr ""
+"No se puede desactivar la agrupaci��n %(name)s ya que est�� asociada con "
+"algunas plantillas"
+
+#, python-format
+msgid "Unable to delete pool %(name)s as it is associated with some templates"
+msgstr ""
+"No se puede suprimir la agrupaci��n %(name)s ya que est�� asociada con algunas
"
+"plantillas"
+
+#, python-format
+msgid ""
+"A volume group named '%(name)s' already exists. Please, choose another name
"
+"to create the logical pool."
+msgstr ""
+"Un grupo de vol��menes denominado '%(name)s' ya existe. Elija otro nombre
"
+"para crear la agrupaci��n l��gica."
+
+#, python-format
+msgid "Unable to update database with deep scan information due error:
%(err)s"
+msgstr ""
+"No se puede actualizar la base de datos con la informaci��n de exploraci��n "
+"profunda debido a un error: %(err)s"
+
+#, python-format
+msgid "Storage volume %(name)s already exists"
+msgstr "El volumen de almacenamiento %(name)s ya existe"
+
+#, python-format
+msgid "Storage volume %(name)s does not exist in storage pool %(pool)s"
+msgstr ""
+"El volumen de almacenamiento %(name)s no existe en la agrupaci��n de "
+"almacenamiento %(pool)s"
+
+#, python-format
+msgid ""
+"Unable to create storage volume %(volume)s because storage pool %(pool)s is "
+"not active"
+msgstr ""
+
+#, python-format
+msgid "Specify %(item)s in order to create storage volume %(volume)s"
+msgstr ""
+"Especifique %(item)s para poder crear el volumen de almacenamiento
%(volume)s"
+
+#, python-format
+msgid ""
+"Unable to list storage volumes because storage pool %(pool)s is not active"
+msgstr ""
+"No se pueden listar los vol��menes de almacenamiento porque la agrupaci��n de
"
+"almacenamiento %(pool)s no est�� activa"
+
+#, python-format
+msgid ""
+"Unable to create storage volume %(name)s in storage pool %(pool)s. Details:
%"
+"(err)s"
+msgstr ""
+"No se puede crear el volumen de almacenamiento %(name)s en la agrupaci��n de
"
+"almacenamiento %(pool)s. Detalles: %(err)s"
+
+#, python-format
+msgid ""
+"Unable to list storage volumes in storage pool %(pool)s. Details: %(err)s"
+msgstr ""
+"No se pueden listar vol��menes de almacenamiento en la agrupaci��n de "
+"almacenamiento %(pool)s. Detalles: %(err)s"
+
+#, python-format
+msgid "Unable to wipe storage volumes %(name)s. Details: %(err)s"
+msgstr ""
+"No se pueden borrar los vol��menes de almacenamiento %(name)s. Detalles: %"
+"(err)s"
+
+#, python-format
+msgid "Unable to delete storage volume %(name)s. Details: %(err)s"
+msgstr ""
+"No se puede suprimir el volumen de almacenamiento %(name)s. Detalles:
%(err)s"
+
+#, python-format
+msgid "Unable to resize storage volume %(name)s. Details: %(err)s"
+msgstr ""
+"No se puede redimensionar el volumen de almacenamiento %(name)s. Detalles: %"
+"(err)s"
+
+#, python-format
+msgid "Storage type %(type)s does not support volume create and delete"
+msgstr ""
+"El tipo de almacenamiento %(type)s no da soporte a crear y suprimir
vol��menes"
+
+msgid "Storage volume name must be a string"
+msgstr "El nombre de volumen de almacenamiento debe ser una serie"
+
+msgid "Storage volume allocation must be an integer number"
+msgstr "La asignaci��n de volumen de almacenamiento debe ser un n��mero
entero"
+
+msgid ""
+"Storage volume format not supported. Valid formats: bochs, cloop, cow, dmg, "
+"qcow, qcow2, qed, raw, vmdk, vpc."
+msgstr ""
+
+msgid "Storage volume requires a volume name"
+msgstr "El volumen de almacenamiento requiere un nombre de volumen"
+
+#, python-format
+msgid ""
+"Unable to update database with storage volume information due error: %(err)s"
+msgstr ""
+"No se puede actualizar la base de datos con la informaci��n de volumen de "
+"almacenamiento debido a un error: %(err)s"
+
+#, python-format
+msgid "Only one of parameter %(param)s can be specified"
+msgstr ""
+
+#, python-format
+msgid "Create volume from %(param)s is not supported"
+msgstr ""
+
+msgid "Storage volume capacity must be an integer number."
+msgstr ""
+
+msgid "Storage volume URL must be http://, https://, ftp:// or ftps://."
+msgstr ""
+
+#, python-format
+msgid "Unable to access file %(url)s. Please, check it."
+msgstr ""
+
+#, python-format
+msgid ""
+"Unable to clone storage volume '%(name)s' in pool '%(pool)s'.
Details: %(err)"
+"s"
+msgstr ""
+
+msgid "Specify chunk data and its size to upload a file."
+msgstr ""
+
+msgid "In order to upload a storage volume, specify the 'upload'
parameter."
+msgstr ""
+
+msgid ""
+"Unable to upload chunk data as it does not match with requested chunk size."
+msgstr ""
+
+#, python-format
+msgid "The storage volume %(vol)s is not under an upload process."
+msgstr ""
+
+msgid "The upload chunk data will exceed the storage volume size."
+msgstr ""
+
+#, python-format
+msgid "Unable to upload chunk data to storage volume. Details: %(err)s."
+msgstr ""
+
+#, python-format
+msgid "Interface %(name)s does not exist"
+msgstr "La interfaz %(name)s no existe"
+
+#, python-format
+msgid "Network %(name)s already exists"
+msgstr "La red %(name)s ya existe"
+
+#, python-format
+msgid "Network %(name)s does not exist"
+msgstr "La red %(name)s no existe"
+
+#, python-format
+msgid "Subnet %(subnet)s specified for network %(network)s is not valid."
+msgstr ""
+"La subred %(subnet)s especificada para la red %(network)s no es v��lida."
+
+#, python-format
+msgid "Specify a network interface to create bridged network %(name)s"
+msgstr "Especifique una interfaz de red para crear una red puenteada %(name)s"
+
+#, python-format
+msgid "Unable to delete active network %(name)s"
+msgstr "No se puede suprimir la red activa %(name)s"
+
+#, python-format
+msgid "Interface %(iface)s specified for network %(network)s is already in
use"
+msgstr ""
+"La interfaz %(iface)s especificada para la red %(network)s ya est�� en uso"
+
+msgid "Interface should be bare NIC, bonding or bridge device."
+msgstr "La interfaz debe ser dispositivo de puente, enlazado o NIC simple."
+
+#, python-format
+msgid "Unable to create network %(name)s. Details: %(err)s"
+msgstr "No se puede crear la red %(name)s. Detalles: %(err)s"
+
+#, python-format
+msgid "Unable to find a free IP address for network '%(name)s'"
+msgstr "No se puede encontrar una direcci��n IP libre para la red
'%(name)s'"
+
+#, python-format
+msgid "The interface %(iface)s already exists."
+msgstr "La interfaz %(iface)s ya existe"
+
+msgid "Network name must be a string without slashes (/) or quotes (\")"
+msgstr ""
+
+msgid "Supported network types are isolated, NAT and bridge"
+msgstr "Los tipos de red soportados son aislada, NAT y puente"
+
+msgid "Network subnet must be a string with IP address and prefix or netmask"
+msgstr ""
+"La subred de red debe ser una serie con direcci��n IP y prefijo o m��scara de
"
+"red"
+
+msgid "Network interface must be a string"
+msgstr "La interfaz de red debe ser una serie"
+
+msgid "Network VLAN ID must be an integer between 1 and 4094"
+msgstr "El ID de VLAN de red debe ser un entero entre 1 y 4094"
+
+msgid "Specify name and type to create a Network"
+msgstr "Especifique el nombre y el tipo para crear una red"
+
+#, python-format
+msgid ""
+"Unable to delete network %(name)s. There are some virtual machines %(vms)s "
+"and/or templates linked to this network."
+msgstr ""
+"No se puede suprimir la red %(name)s. Hay algunas m��quinas virtuales %(vms)s
"
+"y/o plantillas enlazadas a esta red."
+
+#, python-format
+msgid ""
+"Unable to deactivate network %(name)s. There are some virtual machines
%(vms)"
+"s and/or templates linked to this network."
+msgstr ""
+"No se puede desactivar la red %(name)s. Hay algunas m��quinas virtuales
%(vms)"
+"s y/o plantillas enlazadas a esta red."
+
+#, python-format
+msgid "Bridge device %(name)s can not be the trunk device of a VLAN."
+msgstr ""
+"El dispositivo de puente %(name)s no puede ser el dispositivo de conexi��n "
+"troncal de una VLAN."
+
+#, python-format
+msgid "Failed to activate interface %(iface)s: %(err)s."
+msgstr "No se puede activar la interfaz %(iface)s: %(err)s."
+
+#, python-format
+msgid ""
+"Failed to activate interface %(iface)s. Please check the physical link "
+"status."
+msgstr ""
+"No se puede activar la interfaz %(iface)s. Compruebe el estado del enlace "
+"f��sico."
+
+#, python-format
+msgid "Failed to start network %(name)s. Details: %(err)s"
+msgstr ""
+
+#, python-format
+msgid "Debug report %(name)s does not exist"
+msgstr "El informe de depuraci��n %(name)s no existe"
+
+msgid "Debug report tool not found in system"
+msgstr "Herramienta de informes de depuraci��n no encontrada en el sistema"
+
+#, python-format
+msgid "Unable to create debug report %(name)s. Details: %(err)s."
+msgstr ""
+"No se puede crear el informe de depuraci��n %(name)s. Detalles: %(err)s."
+
+#, python-format
+msgid "Can not find any debug report with the given name %(name)s"
+msgstr ""
+
+#, python-format
+msgid "Unable to generate debug report %(name)s. Details: %(err)s"
+msgstr ""
+"No se puede generar el informe de depuraci��n %(name)s. Detalles: %(err)s"
+
+msgid "You should give a name for the debug report file."
+msgstr ""
+
+msgid ""
+"Debug report name must be a string. Only letters, digits, underscore ('_')
"
+"and hyphen ('-') are allowed."
+msgstr ""
+
+#, python-format
+msgid ""
+"The debug report with specified name \"%(name)s\" already exists. Please
use "
+"another one."
+msgstr ""
+"Un grupo de vol��menes denominado '%(name)s' ya existe. Elija otro nombre
"
+"para crear la agrupaci��n l��gica."
+
+#, python-format
+msgid "Storage server %(server)s was not used by Kimchi"
+msgstr "Kimchi no utilizaba el servidor de almacenamiento %(server)s"
+
+#, python-format
+msgid "Distro '%(name)s' does not exist"
+msgstr "Distro '%(name)s' no existe"
+
+#, python-format
+msgid "Partition %(name)s does not exist in the host"
+msgstr "La partici��n %(name)s no existe en el host"
+
+msgid "Unable to shutdown host machine as there are running virtual machines"
+msgstr ""
+"No se puede concluir la m��quina host ya que hay m��quinas virtuales en "
+"ejecuci��n"
+
+msgid "Unable to reboot host machine as there are running virtual machines"
+msgstr ""
+"No se puede rearrancar la m��quina host ya que hay m��quinas virtuales en "
+"ejecuci��n"
+
+#, python-format
+msgid "Node device '%(name)s' not found"
+msgstr "No se ha encontrado el dispositivo de nodo '%(name)s'"
+
+msgid "Conflicting flag filters specified."
+msgstr ""
+
+msgid "No packages marked for update"
+msgstr "No hay paquetes marcados para su actualizaci��n"
+
+#, python-format
+msgid "Package %(name)s is not marked to be updated."
+msgstr "El paquete %(name)s no est�� marcado para su actualizaci��n."
+
+#, python-format
+msgid "Error while getting packages marked to be updated. Details: %(err)s"
+msgstr ""
+"Se ha producido un error al obtener paquetes marcados para su actualizaci��n.
"
+"Detalles: %(err)s"
+
+msgid "There is no compatible package manager for this system."
+msgstr "No hay ning��n gestor de paquetes compatible para este sistema."
+
+#, python-format
+msgid "Invalid URI %(uri)s"
+msgstr "URI %(uri)s no v��lido"
+
+msgid "Unable to choose a virtual machine name"
+msgstr ""
+
+msgid "Invalid storage type. Types supported: 'cdrom', 'disk'"
+msgstr "Tipo de almacenamiento no v��lido. Tipos soportados: 'cdrom'"
+
+#, python-format
+msgid "The path '%(value)s' is not a valid local/remote path for the
device"
+msgstr ""
+
+msgid "Only CDROM path can be update."
+msgstr ""
+
+#, python-format
+msgid ""
+"The storage device %(dev_name)s does not exist in the virtual machine %"
+"(vm_name)s"
+msgstr ""
+
+#, python-format
+msgid "Error while creating new storage device: %(error)s"
+msgstr ""
+"Se ha producido un error al crear el nuevo dispositivo de almacenamiento: %"
+"(error)s"
+
+#, python-format
+msgid "Error while updating storage device: %(error)s"
+msgstr ""
+"Se ha producido un error al actualizar el dispositivo de almacenamiento: %"
+"(error)s"
+
+#, python-format
+msgid "Error while removing storage device: %(error)s"
+msgstr ""
+"Se ha producido un error al eliminar el dispositivo de almacenamiento: %"
+"(error)s"
+
+msgid "Do not support IDE device hot plug"
+msgstr ""
+
+msgid ""
+"Specify type and path or type and pool/volume to add a new virtual machine "
+"disk"
+msgstr ""
+"Especifique el tipo y la v��a de acceso para a��adir un disco de m��quina "
+"virtual nuevo"
+
+msgid "Specify path to update virtual machine disk"
+msgstr ""
+"Especifique la v��a de acceso para actualizar el disco de m��quina virtual"
+
+#, python-format
+msgid "Controller type %(type)s limitation of %(limit)s devices reached"
+msgstr ""
+
+#, python-format
+msgid "Cannot retrieve disk path information for given pool/volume: %(error)s"
+msgstr ""
+
+msgid "Volume already in use by other virtual machine."
+msgstr ""
+
+msgid ""
+"Only one of path or pool/volume can be specified to add a new virtual "
+"machine disk"
+msgstr ""
+"Especifique el tipo y la v��a de acceso para a��adir un disco de m��quina "
+"virtual nuevo"
+
+#, python-format
+msgid ""
+"Volume chosen with format %(format)s does not fit in the storage type
%(type)"
+"s"
+msgstr ""
+
+msgid "YUM Repository ID must be one word only string."
+msgstr "El ID de repositorio YUM debe ser una serie de una sola palabra."
+
+msgid "Repository URL must be an http://, ftp:// or file:// URL."
+msgstr "El URL de repositorio debe ser http://, ftp:// o archivo:// URL."
+
+msgid ""
+"Repository configuration is a dictionary with specific values according to "
+"repository type."
+msgstr ""
+"La configuraci��n de repositorio es un diccionario con valores espec��ficos "
+"seg��n el tipo de repositorio."
+
+msgid "Distribution to DEB repository must be a string"
+msgstr "El repositorio de Distribuci��n a DEB debe ser una serie"
+
+msgid "Components to DEB repository must be listed in a array"
+msgstr "El repositorio de Componentes a DEB debe estar listado en una matriz"
+
+msgid "Components to DEB repository must be a string"
+msgstr "El repositorio de Componentes a DEB debe ser una serie"
+
+msgid "Mirror list to repository must be a string"
+msgstr ""
+
+msgid "YUM Repository name must be string."
+msgstr "El nombre del repositorio YUM debe ser una serie."
+
+msgid "GPG check must be a boolean value."
+msgstr "La comprobaci��n de GPG debe ser un valor booleano."
+
+msgid "GPG key must be a URL pointing to the ASCII-armored file."
+msgstr "La clave GPG debe ser un URL que apunta al archivo blindado por
ASCII."
+
+#, python-format
+msgid "Could not update repository %(repo_id)s."
+msgstr "No se ha podido actualizar el repositorio %(repo_id)s."
+
+#, python-format
+msgid "Repository %(repo_id)s does not exist."
+msgstr "El repositorio %(repo_id)s no existe."
+
+msgid ""
+"Specify repository base URL, mirror list or metalink in order to create or "
+"update a YUM repository."
+msgstr ""
+
+msgid "Repository management tool was not recognized for your system."
+msgstr ""
+"La herramienta de gesti��n de repositorio no se ha reconocido para su
sistema."
+
+#, python-format
+msgid "Repository %(repo_id)s is already enabled."
+msgstr "El repositorio %(repo_id)s ya est�� habilitado."
+
+#, python-format
+msgid "Repository %(repo_id)s is already disabled."
+msgstr "El repositorio %(repo_id)s ya est�� inhabilitado."
+
+#, python-format
+msgid "Could not remove repository %(repo_id)s."
+msgstr "No se ha podido eliminar el repositorio %(repo_id)s."
+
+#, python-format
+msgid "Could not write repository configuration file %(repo_file)s"
+msgstr ""
+"No se ha podido grabar el archivo de configuraci��n del repositorio %"
+"(repo_file)s"
+
+msgid "Specify repository distribution in order to create a DEB repository."
+msgstr ""
+"Especifique la distribuci��n del repositorio para crear un repositorio de
DEB."
+
+#, python-format
+msgid "Could not enable repository %(repo_id)s."
+msgstr "No se ha podido habilitar el repositorio %(repo_id)s."
+
+#, python-format
+msgid "Could not disable repository %(repo_id)s."
+msgstr "No se ha podido inhabilitar el repositorio %(repo_id)s."
+
+msgid "YUM Repository ID already exists"
+msgstr "El ID de repositorio de YUM ya existe"
+
+msgid "YUM Repository name must be a string"
+msgstr "El nombre del repositorio de YUM debe ser una serie"
+
+#, python-format
+msgid "Unable to list repositories. Details: '%(err)s'"
+msgstr "No se pueden listar repositorios. Detalles: '%(err)s'"
+
+#, python-format
+msgid "Unable to retrieve repository information. Details: '%(err)s'"
+msgstr "No se puede recuperar informaci��n del repositorio. Detalles:
'%(err)s'"
+
+#, python-format
+msgid "Unable to add repository. Details: '%(err)s'"
+msgstr "No se puede a��adir el repositorio. Detalles: '%(err)s'"
+
+#, python-format
+msgid "Unable to remove repository. Details: '%(err)s'"
+msgstr "No se puede eliminar el repositorio. Detalles: '%(err)s'"
+
+#, python-format
+msgid ""
+"Configuration items: '%(items)s' are not supported by repository
manager"
+msgstr ""
+
+msgid "Repository metalink must be an http://, ftp:// or file:// URL."
+msgstr ""
+
+msgid "Cannot specify mirrorlist and metalink at the same time."
+msgstr ""
+
+#, python-format
+msgid ""
+"Virtual machine '%(vm)s' must be stopped before creating a snapshot of
it."
+msgstr ""
+
+#, python-format
+msgid ""
+"Unable to create snapshot '%(name)s' on virtual machine '%(vm)s'.
Details: %"
+"(err)s"
+msgstr ""
+
+#, python-format
+msgid "Snapshot '%(name)s' does not exist on virtual machine
'%(vm)s'."
+msgstr ""
+
+#, python-format
+msgid ""
+"Unable to retrieve snapshot '%(name)s' on virtual machine '%(vm)s'.
Details: "
+"%(err)s"
+msgstr ""
+
+#, python-format
+msgid "Unable to list snapshots on virtual machine '%(vm)s'. Details:
%(err)s"
+msgstr ""
+
+#, python-format
+msgid ""
+"Unable to delete snapshot '%(name)s' on virtual machine '%(vm)s'.
Details: %"
+"(err)s"
+msgstr ""
+
+#, python-format
+msgid ""
+"Unable to retrieve current snapshot of virtual machine '%(vm)s'. Details:
%"
+"(err)s"
+msgstr ""
+
+#, python-format
+msgid ""
+"Unable to revert virtual machine '%(vm)s' to snapshot '%(name)s'.
Details: %"
+"(err)s"
+msgstr ""
+
+#, python-format
+msgid ""
+"Unable to create snapshot of virtual machine '%(vm)s' because it contains a
"
+"disk with format '%(format)s'; only 'qcow2' is supported."
+msgstr ""
+
+msgid "The number of vCPUs is too large for this system."
+msgstr ""
+
+msgid "Invalid vCPU/topology combination."
+msgstr ""
+
+msgid "This host (or current configuration) does not allow CPU topology."
+msgstr ""
+
+msgid "ERROR CODE"
+msgstr "C��DIGO DE ERROR"
+
+msgid "REASON"
+msgstr "RAZ��N"
+
+msgid "STACK"
+msgstr "PILA"
+
+msgid "Go to Homepage"
+msgstr "Ir a la p��gina inicial"
+
+msgid "Create a New Virtual Machine"
+msgstr "Crear una nueva m��quina virtual"
+
+msgid "Virtual Machine Name"
+msgstr "Nombre de m��quina virtual"
+
+msgid ""
+"The name used to identify the virtual machine. If omitted, a name will be "
+"chosen based on the template used."
+msgstr ""
+"El nombre que se utiliza para identificar la m��quina virtual. Si se omite, "
+"se elegir�� un nombre bas��ndose en la plantilla utilizada."
+
+msgid "Template"
+msgstr "Plantilla"
+
+msgid "Please create a template first."
+msgstr "Cree una plantilla primero."
+
+msgid "Create a Template"
+msgstr "Crear una plantilla"
+
+msgid "Please choose a template."
+msgstr "Elija una plantilla."
+
+msgid "OS"
+msgstr "SO"
+
+msgid "OS Version"
+msgstr "Versi��n del SO"
+
+msgid "CPUS"
+msgstr "CPUS"
+
+msgid "Memory"
+msgstr "Memoria"
+
+msgid "Create"
+msgstr "Crear"
+
+msgid "Creating..."
+msgstr ""
+
+msgid "Cancel"
+msgstr "Cancelar"
+
+msgid "Edit Guest"
+msgstr "Editar invitado"
+
+msgid "General"
+msgstr "General"
+
+msgid "Storage"
+msgstr "Almacenamiento"
+
+msgid "Interface"
+msgstr "Interfaz"
+
+msgid "Permission"
+msgstr "Versi��n"
+
+msgid "Host PCI Device"
+msgstr ""
+
+msgid "Snapshot"
+msgstr ""
+
+msgid "Name"
+msgstr "Nombre"
+
+msgid "CPUs"
+msgstr "CPUs"
+
+msgid "Memory (MB)"
+msgstr "Memoria"
+
+msgid "Icon"
+msgstr "Icono"
+
+msgid "Device"
+msgstr "Nombre de dispositivo"
+
+msgid "Path"
+msgstr "V��a de acceso NFS"
+
+msgid "Network"
+msgstr "Red"
+
+msgid "Type"
+msgstr "Tipo"
+
+msgid "MAC Address"
+msgstr ""
+
+msgid "Available system users and groups"
+msgstr ""
+
+msgid "Selected system users and groups"
+msgstr ""
+
+msgid "User"
+msgstr ""
+
+msgid "All"
+msgstr "Todo"
+
+msgid "To Add"
+msgstr ""
+
+msgid "Added"
+msgstr ""
+
+msgid "filter"
+msgstr ""
+
+msgid "Product"
+msgstr ""
+
+msgid "Vendor"
+msgstr "Proveedor"
+
+msgid "Created"
+msgstr ""
+
+msgid "Save"
+msgstr "Guardar"
+
+msgid "Replace"
+msgstr "Sustituir"
+
+msgid "Detach"
+msgstr "Desconectar"
+
+msgid "revert"
+msgstr ""
+
+msgid "Start"
+msgstr "Iniciar"
+
+msgid "Reset"
+msgstr "Restablecer"
+
+msgid "Pause"
+msgstr ""
+
+msgid "Resume"
+msgstr ""
+
+msgid "Power Off"
+msgstr ""
+
+msgid "Actions"
+msgstr "Acciones"
+
+msgid "Connect"
+msgstr "Conectar"
+
+msgid "Clone"
+msgstr ""
+
+msgid "Edit"
+msgstr "Editar"
+
+msgid "Shut Down"
+msgstr "Concluir"
+
+msgid "Delete"
+msgstr "Suprimir"
+
+msgid "CPU"
+msgstr "CPU"
+
+msgid "Disk I/O"
+msgstr "E/S de disco"
+
+msgid "Network I/O"
+msgstr "E/S de red"
+
+msgid "Livetile"
+msgstr "Livetile"
+
+msgid "No guests found."
+msgstr "No se ha encontrado invitados."
+
+msgid "Add a Storage Device to VM"
+msgstr "A��adir un dispositivo de almacenamiento a VM"
+
+msgid "Device Type"
+msgstr "Tipo de dispositivo"
+
+msgid "The device type. Currently, \"cdrom\" and \"disk\" are
supported."
+msgstr "El tipo de dispositivo. Actualmente s��lo est�� soportado
\"cdrom\"."
+
+msgid "Storage Pool"
+msgstr "Agrupaci��n de almacenamiento"
+
+msgid "Storage pool which volume located in"
+msgstr "La v��a de acceso de la agrupaci��n de almacenamiento debe ser una
serie"
+
+msgid "Storage Volume"
+msgstr "Nombre de agrupaci��n de almacenamiento"
+
+msgid "Storage volume to be attached"
+msgstr "El nombre de volumen de almacenamiento debe ser una serie"
+
+msgid "File Path"
+msgstr "V��a de acceso de archivo"
+
+msgid "The ISO file path in the server for CDROM."
+msgstr "La v��a de acceso del archivo ISO en el servidor para el CDROM."
+
+msgid "Attach"
+msgstr "Conectar"
+
+msgid "Shut down"
+msgstr "Concluir"
+
+msgid "Restart"
+msgstr "Reiniciar"
+
+msgid "Basic Information"
+msgstr "Informaci��n b��sica"
+
+msgid "OS Distro"
+msgstr "Distro de SO"
+
+msgid "OS Code Name"
+msgstr "Nombre de c��digo de SO"
+
+msgid "Processor"
+msgstr "Procesador"
+
+msgid "CPU(s)"
+msgstr ""
+
+msgid "System Statistics"
+msgstr "Estad��sticas del sistema"
+
+msgid "Software Updates"
+msgstr "Actualizaciones de software"
+
+msgid "Update Progress"
+msgstr "Actualizar progreso"
+
+msgid "Repositories"
+msgstr "Repositorios"
+
+msgid "Debug Reports"
+msgstr "Informes de depuraci��n"
+
+msgid "The username or password you entered is incorrect. Please try again."
+msgstr ""
+"El nombre de usuario o contrase��a que ha especificado es incorrecto. Por "
+"favor, vuelva a intentarlo."
+
+msgid "This field is required."
+msgstr "Este campo es obligatorio."
+
+msgid "Log in"
+msgstr "Iniciar sesi��n"
+
+msgid "Logging in..."
+msgstr "Iniciando sesi��n..."
+
+msgid "Host"
+msgstr "Host"
+
+msgid "Guests"
+msgstr "Invitados"
+
+msgid "Templates"
+msgstr "Plantillas"
+
+msgid "Failed to get application configuration"
+msgstr "No se ha podido obtener la configuraci��n de la aplicaci��n"
+
+msgid "This is not a valid Linux path"
+msgstr "No es una v��a de acceso de Linux v��lida"
+
+msgid "This is not a valid URL."
+msgstr "No es un URL v��lido."
+
+msgid "No such data available."
+msgstr "No hay datos de ese tipo disponibles."
+
+msgid ""
+"Can not contact the host system. Verify the host system is up and that you "
+"have network connectivity to it. HTTP request response %1. "
+msgstr ""
+"No se puede contactar con el sistema host, Verifique que el sistema host "
+"est�� activo y que tiene conectividad de red con ��l. Respuesta de solicitud
"
+"HTTP %1. "
+
+msgid "Unable to read file."
+msgstr ""
+
+msgid "Error while uploading file."
+msgstr ""
+
+msgid "Delete Confirmation"
+msgstr "Confirmaci��n de supresi��n"
+
+msgid "OK"
+msgstr "Aceptar"
+
+msgid "Confirm"
+msgstr "Confirmar"
+
+msgid "Warning"
+msgstr "Aviso"
+
+msgid "Cloning..."
+msgstr ""
+
+msgid "Loading..."
+msgstr "Cargando..."
+
+msgid "An error occurred while retrieving system information."
+msgstr ""
+
+msgid "Retry"
+msgstr "Reintentar"
+
+msgid "Detailed message:"
+msgstr "Mensaje detallado:"
+
+msgid "No ISO found"
+msgstr ""
+
+msgid "This is not a valid ISO file."
+msgstr "No es un archivo ISO v��lido."
+
+msgid "This may take a long time. Do you want to continue?"
+msgstr "Tardar�� mucho tiempo. ��Desea continuar?"
+
+msgid "This will permanently delete the template. Would you like to continue?"
+msgstr "Esto suprimir�� permanentemente la plantilla. ��Desea continuar?"
+
+msgid "Unable to shut down system as there are some virtual machines running!"
+msgstr ""
+"No se puede concluir el sistema ya que hay algunas m��quinas virtuales en "
+"ejecuci��n."
+
+msgid "Max:"
+msgstr "M��x.:"
+
+msgid "Utilization"
+msgstr "Utilizaci��n"
+
+msgid "Available"
+msgstr "Disponible"
+
+msgid "Read Rate"
+msgstr "Velocidad de lectura"
+
+msgid "Write Rate"
+msgstr "Velocidad de escritura"
+
+msgid "Received"
+msgstr "Recibido"
+
+msgid "Sent"
+msgstr "Enviado"
+
+msgid ""
+"Shutting down or restarting host will cause unsaved work lost. Continue to "
+"shut down/restarting?"
+msgstr ""
+"Concluir o reiniciar el host har�� que se pierda el trabajo no guardado. "
+"��Desea continuar para concluir/reiniciar?"
+
+msgid ""
+"Repository will be removed permanently and can't be recovered. Do you want
"
+"to continue?"
+msgstr ""
+"El repositorio se eliminar�� de forma permanente y no se puede recuperar. "
+"��Desea continuar?"
+
+msgid "ID"
+msgstr "ID"
+
+msgid "Base URL"
+msgstr "URL base"
+
+msgid "Is Mirror"
+msgstr "Es duplicado"
+
+msgid "URL Args"
+msgstr "Args de URL"
+
+msgid "Enabled"
+msgstr "Habilitado"
+
+msgid "GPG Check"
+msgstr "Comprobaci��n GPG"
+
+msgid "GPG Key"
+msgstr "Clave GPG"
+
+msgid "Add"
+msgstr "A��adir"
+
+msgid "Remove"
+msgstr "Eliminar"
+
+msgid "Enable"
+msgstr "Habilitar"
+
+msgid "Disable"
+msgstr "Inhabilitar"
+
+msgid "Package Name"
+msgstr "Nombre de paquete"
+
+msgid "Version"
+msgstr "Versi��n"
+
+msgid "Architecture"
+msgstr "Arquitectura"
+
+msgid "Repository"
+msgstr "Repositorio"
+
+msgid "Update All"
+msgstr "Actualizar todo"
+
+msgid "Updating..."
+msgstr "Actualizando..."
+
+msgid "Failed to retrieve packages update information."
+msgstr ""
+
+msgid "Failed to update package(s)."
+msgstr "No se han podido actualizar paquetes."
+
+msgid ""
+"Debug report will be removed permanently and can't be recovered. Do you want
"
+"to continue?"
+msgstr ""
+"El informe de depuraci��n se eliminar�� permanentemente y no se puede "
+"recuperar. ��Desea continuar?"
+
+msgid "Generated Time"
+msgstr "Tiempo generado"
+
+msgid "Generate"
+msgstr "Generar"
+
+msgid "Generating..."
+msgstr "Generando..."
+
+msgid "Rename"
+msgstr "Redenominar"
+
+msgid "Download"
+msgstr "Descargar"
+
+msgid ""
+"Report name should contain only letters, digits, underscore ('_') and/or
"
+"hyphen ('-')."
+msgstr ""
+"El nombre de informe debe contener s��lo letras, d��gitos y/o gui��n
('-')."
+
+msgid "Pending..."
+msgstr "Cargando..."
+
+msgid "Report name is the same as the original one."
+msgstr ""
+
+msgid ""
+"This will delete the virtual machine and its virtual disks. This operation "
+"cannot be undone. Would you like to continue?"
+msgstr ""
+"Esto suprimir�� la m��quina virtual y sus discos virtuales. Esta operaci��n no
"
+"puede deshacerse. ��Desea continuar?"
+
+msgid "Power off Confirmation"
+msgstr "Confirmaci��n de supresi��n"
+
+msgid ""
+"This action may produce undesirable results, for example unflushed disk "
+"cache in the guest. Would you like to continue?"
+msgstr ""
+
+msgid "Reset Confirmation"
+msgstr "Confirmaci��n de supresi��n"
+
+msgid ""
+"There is a risk of data loss caused by reset without the guest OS shutdown. "
+"Would you like to continue?"
+msgstr ""
+
+msgid "Shut Down Confirmation"
+msgstr "Confirmaci��n de supresi��n"
+
+msgid "Note the guest OS may ignore this request. Would you like to continue?"
+msgstr "Esto suprimir�� permanentemente la plantilla. ��Desea continuar?"
+
+msgid "Virtual Machine delete Confirmation"
+msgstr ""
+
+msgid ""
+"This virtual machine is not persistent. Power Off will delete it. Continue?"
+msgstr ""
+
+msgid ""
+"When the target guest has SCSI or iSCSI volumes, they will be cloned on "
+"default storage pool. The same will happen when the target pool does not "
+"have enough space to clone the volumes. Do you want to continue?"
+msgstr ""
+
+msgid ""
+"This CDROM will be detached permanently and you can re-attach it. Continue "
+"to detach it?"
+msgstr ""
+"Este CDROM se desconectar�� de forma permanente pero puede volver a "
+"conectarlo. ��Desea continuar para desconectarlo?"
+
+msgid "Attaching..."
+msgstr "Conectando..."
+
+msgid "Replacing..."
+msgstr "Sustituyendo..."
+
+msgid "Successfully attached!"
+msgstr "��Conectado correctamente!"
+
+msgid "Successfully replaced!"
+msgstr "��Sustituido correctamente!"
+
+msgid "Successfully detached!"
+msgstr "��Desconectado correctamente!"
+
+msgid ""
+"This disk will be detached permanently and you can re-attach it. Continue to
"
+"detach it?"
+msgstr ""
+
+msgid "interface:"
+msgstr ""
+
+msgid "address:"
+msgstr ""
+
+msgid "link_type:"
+msgstr ""
+
+msgid "block:"
+msgstr ""
+
+msgid "drive_type:"
+msgstr ""
+
+msgid "model:"
+msgstr ""
+
+msgid "Affected devices:"
+msgstr ""
+
+msgid "The VLAN id must be between 1 and 4094."
+msgstr "El ID de VLAN debe estar entre 1 y 4094."
+
+msgid "unavailable"
+msgstr "no disponible"
+
+msgid ""
+"This action will interrupt network connectivity for any virtual machine that
"
+"depend on this network."
+msgstr ""
+"Esta acci��n interrumpir�� la conectividad de red para cualquier m��quina "
+"virtual que dependa de esta red."
+
+msgid "Create a network"
+msgstr "Crear una red"
+
+msgid ""
+"This network is not persistent. Instead of stop, this action will "
+"permanently delete it. Would you like to continue?"
+msgstr ""
+"Esta agrupaci��n de almacenamiento no es persistente. En lugar de desactivar,
"
+"esta acci��n la suprimir�� permanentemente. ��Desea continuar?"
+
+msgid ""
+"The bridged VLAN tag may not work well with NetworkManager enabled. You "
+"should consider disabling it."
+msgstr ""
+
+msgid ""
+"This will permanently delete the storage pool. Would you like to continue?"
+msgstr ""
+"Esto suprimir�� permanentemente la agrupaci��n de almacenamiento. ��Desea "
+"continuar?"
+
+msgid "This storage pool is empty."
+msgstr "Esta agrupaci��n de almacenamiento est�� vac��a."
+
+msgid ""
+"It will format your disk and you will loose any data in there, are you sure "
+"to continue? "
+msgstr ""
+"Dar�� formato al disco y se perder��n los datos que tenga en ��l. ��Est�� seguro
"
+"de que desea continuar? "
+
+msgid "SCSI Fibre Channel"
+msgstr "Canal de fibra de SCSI"
+
+msgid "No SCSI adapters found."
+msgstr "No se han encontrado adaptadores SCSI."
+
+msgid "Loading iSCSI targets..."
+msgstr ""
+
+msgid "No iSCSI found. Please input one."
+msgstr ""
+
+msgid "Failed to load iSCSI targets."
+msgstr ""
+
+msgid "The storage pool name can not be blank."
+msgstr "El nombre de la agrupaci��n de almacenamiento no puede estar en
blanco."
+
+msgid "The storage pool path can not be blank."
+msgstr ""
+"La v��a de acceso de la agrupaci��n de almacenamiento no puede estar en
blanco."
+
+msgid "NFS server mount path can not be blank."
+msgstr "La v��a de acceso de montaje del servidor NFS no puede estar en
blanco."
+
+msgid "Invalid NFS mount path."
+msgstr "V��a de acceso de montaje de NFS no v��lida."
+
+msgid "No logical device selected."
+msgstr "No se ha seleccionado ning��n dispositivo l��gico."
+
+msgid "The iSCSI target can not be blank."
+msgstr "El destino iSCSI no puede estar en blanco."
+
+msgid "Server name can not be blank."
+msgstr "El nombre de servidor no puede estar en blanco."
+
+msgid "This is not a valid Server Name or IP. Please, modify it."
+msgstr ""
+
+msgid "Looking for available partitions ..."
+msgstr "Buscando particiones disponibles..."
+
+msgid "No available partitions found."
+msgstr "No se han encontrado particiones disponibles."
+
+msgid ""
+"This storage pool is not persistent. Instead of deactivate, this action will
"
+"permanently delete it. Would you like to continue?"
+msgstr ""
+"Esta agrupaci��n de almacenamiento no es persistente. En lugar de desactivar,
"
+"esta acci��n la suprimir�� permanentemente. ��Desea continuar?"
+
+msgid "Unable to retrieve partitions information."
+msgstr "No se puede recuperar informaci��n del repositorio. Detalles:
'%(err)s'"
+
+msgid "In progress..."
+msgstr ""
+
+msgid "Failed!"
+msgstr ""
+
+msgid "CDROM path needs to be a valid local/remote path and cannot be blank."
+msgstr ""
+
+msgid "Disk pool or volume cannot be blank."
+msgstr "El nombre de la agrupaci��n de almacenamiento no puede estar en
blanco."
+
+msgid "Filter"
+msgstr ""
+
+msgid "Network Name"
+msgstr "Nombre de red"
+
+msgid "State"
+msgstr "Estado"
+
+msgid "Network Type"
+msgstr "Tipo de red"
+
+msgid "Address Space"
+msgstr "Espacio de direcciones"
+
+msgid "Name should not contain '/' and '\"'."
+msgstr ""
+"Nombre de agrupaci��n de almacenamiento no v��lido. No debe contener
'/'."
+
+msgid "Isolated: no external network connection"
+msgstr "Aislado: no hay conexi��n de red f��sica"
+
+msgid "NAT: outbound physical network connection only"
+msgstr "NAT: conexi��n de red f��sica saliente solamente"
+
+msgid "Bridged: Virtual machines are connected to physical network directly"
+msgstr ""
+"Puenteado: Las m��quinas virtuales est��n conectadas a la red f��sica "
+"directamente"
+
+msgid "(No interfaces found)"
+msgstr ""
+
+msgid "Destination"
+msgstr "Destino:"
+
+msgid "Enable VLAN"
+msgstr "Habilitar VLAN:"
+
+msgid "VLAN ID"
+msgstr "ID de VLAN:"
+
+msgid "Stop"
+msgstr "Detener"
+
+msgid "Generate a New Debug Report"
+msgstr "Generar un Informe de depuraci��n nuevo"
+
+msgid "Report Name"
+msgstr "Nombre de informe"
+
+msgid ""
+"The name used to identify the report. If omitted, a name will be chosen "
+"based on current time. Name can contain: letters, digits, underscore
(\"_\") "
+"and hyphen (\"-\")."
+msgstr ""
+"El nombre que se utiliza para identificar el informe. Si se omite, se "
+"elegir�� un nombre bas��ndose en la hora actual. El nombre puede contener: "
+"letras, d��gitos y gui��n (\"-\")."
+
+msgid "Rename a Debug Report"
+msgstr "Generar un Informe de depuraci��n nuevo"
+
+msgid ""
+"The name used to identify the report. Name can contain: letters, digits and "
+"hyphen (\"-\")."
+msgstr ""
+"El nombre que se utiliza para identificar el informe. Si se omite, se "
+"elegir�� un nombre bas��ndose en la hora actual. El nombre puede contener: "
+"letras, d��gitos y gui��n (\"-\")."
+
+msgid "Submit"
+msgstr ""
+
+msgid "Add a Repository"
+msgstr "A��adir un repositorio"
+
+msgid "Identifier"
+msgstr "Identificador"
+
+msgid "Single word, unique identifier for the repository."
+msgstr "Identificador exclusivo de una sola palabra para el repositorio."
+
+msgid "Textual name for the repository."
+msgstr "Nombre textual para el repositorio."
+
+msgid "URL"
+msgstr "URL"
+
+msgid "Required Field"
+msgstr "Campo obligatorio"
+
+msgid "URL to the repository. Supported protocols are http, ftp, and file."
+msgstr "URL al repositorio. Los protocolos soportados son http, ftp y
archivo."
+
+msgid "Repository is a mirror"
+msgstr "El repositorio es un duplicado."
+
+msgid "Distribution"
+msgstr "Distribuci��n"
+
+msgid "Distribution of the DEB repository."
+msgstr "Distribuci��n del repositorio DEB."
+
+msgid "Components"
+msgstr "Componentes"
+
+msgid "List of components in DEB repository."
+msgstr "Lista de componentes en el repositorio DEB."
+
+msgid "Edit Repository"
+msgstr "Editar repositorio"
+
+msgid "Mirror List URL"
+msgstr "URL de lista duplicada"
+
+msgid "Yes"
+msgstr "S��"
+
+msgid "No"
+msgstr "No"
+
+msgid "Capacity"
+msgstr "Capacidad"
+
+msgid "Allocated"
+msgstr "Asignado"
+
+msgid "Location"
+msgstr "Ubicaci��n"
+
+msgid "Device path"
+msgstr "V��a de acceso del dispositivo"
+
+msgid "active"
+msgstr "activo"
+
+msgid "inactive"
+msgstr "inactivo"
+
+msgid "Deactivate"
+msgstr "Desactivar"
+
+msgid "Activate"
+msgstr "Activar"
+
+msgid "Add Volume"
+msgstr ""
+
+msgid "Extend"
+msgstr ""
+
+msgid "Undefine"
+msgstr "No definir"
+
+msgid "Format"
+msgstr "Formato:"
+
+msgid "Allocation"
+msgstr "Asignado:"
+
+msgid "Define a New Storage Pool"
+msgstr "Definir una agrupaci��n de almacenamiento nueva"
+
+msgid "Storage Pool Name"
+msgstr "Nombre de agrupaci��n de almacenamiento"
+
+msgid ""
+"The name used to identify the storage pools, and it should not be empty."
+msgstr ""
+"El nombre que se utiliza para identificar las agrupaciones de almacenamiento
"
+"y no debe estar vac��o."
+
+msgid "Storage Pool Type"
+msgstr "Tipo de agrupaci��n de almacenamiento"
+
+msgid "Storage Path"
+msgstr "V��a de acceso de almacenamiento"
+
+msgid ""
+"The path of the Storage Pool. Each Storage Pool must have a unique path."
+msgstr ""
+"La v��a de acceso de la agrupaci��n de almacenamiento. Cada agrupaci��n de "
+"almacenamiento debe tener una v��a de acceso exclusiva."
+
+msgid ""
+"Kimchi will try to create the directory when it does not already exist in "
+"your system."
+msgstr "Kimchi intentar�� crear el directorio cuando no existe en el sistema."
+
+msgid "NFS Server IP"
+msgstr "IP de Servidor NFS"
+
+msgid "NFS server IP or hostname. It can be input or chosen from history."
+msgstr ""
+"IP o nombre de host de servidor NFS. Puede especificarse o elegirse del "
+"historial."
+
+msgid "NFS Path"
+msgstr "V��a de acceso NFS"
+
+msgid "The NFS exported path on NFS server."
+msgstr "La v��a de acceso exportada de NFS en el servidor NFS."
+
+msgid "iSCSI Server"
+msgstr "Servidor iSCSI"
+
+msgid "Server"
+msgstr "Servidor"
+
+msgid "Port"
+msgstr "Puerto"
+
+msgid "iSCSI server IP or hostname. It should not be empty."
+msgstr "IP o nombre de host de servidor iSCSI. No debe estar vac��o."
+
+msgid "Target"
+msgstr "Destino"
+
+msgid "The iSCSI target on iSCSI server"
+msgstr "El destino iSCSI en el servidor iSCSI"
+
+msgid "Add iSCSI Authentication"
+msgstr "A��adir Autenticaci��n iSCSI"
+
+msgid "iSCSI Authentication"
+msgstr "Autenticaci��n iSCSI"
+
+msgid "User Name"
+msgstr "Nombre de usuario"
+
+msgid "Password"
+msgstr "Contrase��a"
+
+msgid "SCSI Adapter"
+msgstr "Adaptador SCSI"
+
+msgid "Please, wait..."
+msgstr "Por favor, espere..."
+
+msgid "Add a Volume to Storage Pool"
+msgstr ""
+
+msgid "Fetch from remote URL"
+msgstr ""
+
+msgid "Enter the remote URL here."
+msgstr ""
+
+msgid "Upload a file"
+msgstr ""
+
+msgid "Choose the file you want to upload."
+msgstr ""
+
+msgid "Add Template"
+msgstr "A��adir plantilla"
+
+msgid "Where is the source media for this template? "
+msgstr "��D��nde est�� el soporte de origen para esta plantilla?"
+
+msgid "Local ISO Image"
+msgstr "Imagen ISO local"
+
+msgid "Local Image File"
+msgstr ""
+
+msgid "Remote ISO Image"
+msgstr "Imagen ISO remota"
+
+msgid "Search ISOs"
+msgstr "Buscar ISOs"
+
+msgid "The following ISOs are available:"
+msgstr "Las siguientes ISO est��n disponibles:"
+
+msgid "OS: "
+msgstr "SO: "
+
+msgid "Version: "
+msgstr "Versi��n: "
+
+msgid "Size: "
+msgstr "Tama��o: "
+
+msgid "Search more ISOs"
+msgstr "Buscar m��s ISO"
+
+msgid "Create Templates from Selected ISO"
+msgstr "Crear plantillas a partir de ISO seleccionadas"
+
+msgid "I want to use a specific ISO file"
+msgstr "Deseo utilizar un archivo ISO espec��fico"
+
+msgid "Loading default remote ISOs ..."
+msgstr "Cargando ISO remotas predeterminadas ..."
+
+msgid "Arch: "
+msgstr "Arch: "
+
+msgid "I want to use a custom URL"
+msgstr "Deseo utilizar un URL personalizado"
+
+msgid "Edit Template"
+msgstr "Editar plantilla"
+
+msgid "CDROM"
+msgstr "CDROM"
+
+msgid "Image File"
+msgstr ""
+
+msgid "Graphics"
+msgstr "Gr��ficos"
+
+msgid "Disk(GB)"
+msgstr ""
+
+msgid "Disk Format"
+msgstr ""
+
+msgid "CPU Number"
+msgstr "N��mero de CPU"
+
+msgid "Manually set CPU topology"
+msgstr ""
+
+msgid "Cores"
+msgstr ""
+
+msgid "Threads"
+msgstr ""
+
+msgid "No templates found."
+msgstr "No se han encontrado plantillas."
+
+#~ msgid "Delete is not allowed for %(resource)s"
+#~ msgstr "Suprimir no est�� permitido para %(resource)s"
+
+#~ msgid "%(resource)s does not implement update method"
+#~ msgstr "%(resource)s no implementa m��todo de actualizaci��n"
+
+#~ msgid "Create is not allowed for %(resource)s"
+#~ msgstr "Crear no est�� permitido para %(resource)s"
+
+#~ msgid "Unable to parse JSON request"
+#~ msgstr "No se puede analizar la solicitud JSON"
+
+#~ msgid "This API only supports JSON"
+#~ msgstr "Esta API s��lo da soporte a JSON"
+
+#~ msgid "Datastore is not initiated in the model object."
+#~ msgstr "El almac��n de datos no se ha iniciado en el objeto de modelo."
+
+#~ msgid "Unable to start task due error: %(err)s"
+#~ msgstr "No se puede iniciar la tarea debido a un error: %(err)s"
+
+#~ msgid ""
+#~ "Authentication failed for user '%(username)s'. [Error code:
%(code)s]"
+#~ msgstr ""
+#~ "La autenticaci��n ha fallado para el usuario '%(username)s'. [C��digo de
"
+#~ "error: %(code)s]"
+
+#~ msgid "You are not authorized to access Kimchi"
+#~ msgstr "No tiene autorizaci��n para acceder a Kimchi"
+
+#~ msgid "Specify %(item)s to login into Kimchi"
+#~ msgstr "Especifique %(item)s para iniciar la sesi��n en Kimchi"
+
+#~ msgid "Unable to find %(item)s in datastore"
+#~ msgstr "No se puede encontrar %(item)s en el almac��n de datos"
+
+#~ msgid "Timeout while running command '%(cmd)s' after %(seconds)s
seconds"
+#~ msgstr ""
+#~ "Tiempo de espera excedido al ejecutar el mandato '%(cmd)s' despu��s de
%"
+#~ "(seconds)s segundos"
+
+#~ msgid "Help"
+#~ msgstr "Ayuda"
+
+#~ msgid "About"
+#~ msgstr "Acerca de"
+
+#~ msgid "Log out"
+#~ msgstr "Finalizar sesi��n"
+
+#~ msgid "Version:"
+#~ msgstr "Versi��n:"
diff --git a/src/wok/plugins/kimchi/po/fr_FR.po b/src/wok/plugins/kimchi/po/fr_FR.po
new file mode 100644
index 0000000..b996e8a
--- /dev/null
+++ b/src/wok/plugins/kimchi/po/fr_FR.po
@@ -0,0 +1,2338 @@
+# English translations for kimchi package.
+# Copyright (C) 2013 ORGANIZATION
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: kimchi 0.1\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2015-07-01 16:11-0300\n"
+"PO-Revision-Date: 2014-08-27 21:30+0000\n"
+"Last-Translator: BobSynfig\n"
+"Language-Team: French (
http://www.transifex.com/projects/p/kimchi/language/"
+"fr/)\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Language: fr_FR\n"
+"Generated-By: pygettext.py 1.5\n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+
+#, python-format
+msgid "Unknown parameter %(value)s"
+msgstr "Param��tre inconnu %(value)s"
+
+#, python-format
+msgid "Timeout of %(seconds)s seconds expired while running task
'%(task)s."
+msgstr ""
+
+#, python-format
+msgid "User %(user_id)s not found with given LDAP settings."
+msgstr ""
+
+msgid "Unknown \"_cap\" specified"
+msgstr "\"_cap\" sp��cifi��e inconnue"
+
+msgid "\"_passthrough\" should be \"true\" or
\"false\""
+msgstr "\"_passthrough\" doit ��tre \"true\" ou
\"false\""
+
+msgid "\"_passthrough_affected_by\" should be a device name string"
+msgstr "\"_passthrough_affected_by\" doit ��tre un nom de
p��riph��rique"
+
+#, python-format
+msgid "Error while getting block devices. Details: %(err)s"
+msgstr "Erreur durant l'acc��s aux p��riph��riques de bloc. D��tails:
%(err)s"
+
+#, python-format
+msgid "Error while getting block device information for %(device)s."
+msgstr ""
+"Erreur durant l'obtention de l'information sur le p��riph��rique de bloc
%"
+"(device)s."
+
+#, python-format
+msgid "Unable to find distro file: %(filename)s"
+msgstr "Impossible de trouver le fichier de distro: %(filename)s"
+
+#, python-format
+msgid ""
+"Unable to parse distro file: %(filename)s. Make sure, it is a JSON file."
+msgstr ""
+"Impossible de parser le fichier de distro: %(filename)s. Veuillez vous "
+"assurer qu'il s'agit d'un fichier JSON."
+
+#, python-format
+msgid "Unable to login to iSCSI host target %(portal)s. Details: %(err)s"
+msgstr ""
+"Impossible de se connecter �� l'h��te cible iSCSI %(portal)s. D��tails: %(err)s
"
+
+#, python-format
+msgid "Unable to login to iSCSI host %(host)s target %(target)s"
+msgstr "Impossible de se connecter �� l'h��te iSCSI %(host)s cible
%(target)s"
+
+#, python-format
+msgid "Unable to find ISO file %(filename)s"
+msgstr "Impossible de trouver le fichier ISO %(filename)s"
+
+#, python-format
+msgid "The ISO file %(filename)s is not bootable"
+msgstr "Le fichier ISO %(filename)s n'est pas bootable"
+
+#, python-format
+msgid "The ISO file %(filename)s does not have a valid El Torito boot record"
+msgstr ""
+"Le fichier ISO %(filename)s n'a pas d'enregistrement de boot El Torito
valide"
+
+#, python-format
+msgid "Invalid El Torito validation entry in ISO %(filename)s"
+msgstr "Entr��e de validation El Torito invalide dans l'ISO %(filename)s"
+
+#, python-format
+msgid "Invalid El Torito boot indicator in ISO %(filename)s"
+msgstr "Indicateur de boot El Torito invalide dans l'ISO %(filename)s"
+
+#, python-format
+msgid "Unexpected volume type for primary volume in ISO %(filename)s"
+msgstr ""
+"Type de volume inattendu pour le volume primaire dans l'ISO %(filename)s"
+
+#, python-format
+msgid "Bad format while reading volume descriptor in ISO %(filename)s"
+msgstr ""
+"Mauvais format durant la lecture du descripteur de volume dans l'ISO %"
+"(filename)s"
+
+#, python-format
+msgid ""
+"The hypervisor doesn't have permission to use this ISO %(filename)s. "
+"Consider moving it under /var/lib/libvirt, or set the search permission to "
+"file access control lists for '%(user)s' user if possible, or add the
'%"
+"(user)s' to the ISO path group, or (not recommended) 'chmod -R o+x "
+"'path_to_iso'.Details: %(err)s"
+msgstr ""
+"L'hyperviseur n'a pas la permission d'utiliser cet ISO %(filename)s.
"
+"Veuillez consid��rer de le d��placer sous /var/lib/libvirt,, ou de d��finir la
"
+"permission de recherche sur les listes de contrpole d'acc��s fichier pour
"
+"l'utilisateur '%(user)s' si possible, ou ajouter le '%(user)s'
au groupe de "
+"chemins d'ISO, ou (non recommand��) 'chmod -R o+x
'chemin_vers_iso'.D��tails: "
+"%(err)s"
+
+msgid "An error occurred when probing image OS information."
+msgstr ""
+"Une erreur est survenue lors de la d��tection de l'information d'OS de
"
+"l'image."
+
+msgid "No OS information found in given image."
+msgstr "Aucune information d'OS trouv��e sur l'image donn��e."
+
+#, python-format
+msgid "Unable to read image file %(filename)s"
+msgstr "Impossible de lire le fichier image %(filename)s"
+
+#, python-format
+msgid ""
+"Image file must be an existing file on system. %(filename)s is not a valid "
+"input."
+msgstr ""
+"Le fichier image doit ��tre un fichier existant sur le syst��me. %(filename)s
"
+"n'est pas une donn��e valide."
+
+#, python-format
+msgid "Virtual machine %(name)s already exists"
+msgstr "La machine virtuelle %(name)s existe d��j��"
+
+#, python-format
+msgid "Virtual machine %(name)s does not exist"
+msgstr "La machine virtuelle %(name)s n'existe pas"
+
+#, python-format
+msgid ""
+"Unable to rename virtual machine %(name)s. The name %(new_name)s is already "
+"in use or the virtual machine is not powered off."
+msgstr ""
+"Impossible de renommer la machine virtuelle %(name)s. Le nom %(new_name)s "
+"est d��ja utilis�� ou la machine virtuelle n'est pas ��teinte."
+
+#, python-format
+msgid "Unable to retrieve screenshot for stopped virtual machine %(name)s"
+msgstr ""
+"Impossible de r��cup��rer une capture d'��cran pour la machine virtuelle
"
+"stopp��e %(name)s"
+
+msgid "Remote ISO image is not supported by this server."
+msgstr "L'image ISO distante n'est pas support��e par le serveur."
+
+#, python-format
+msgid "Screenshot is not supported on virtual machine %(name)s"
+msgstr "Copie d'��cran non support��e par la machine virtuelle %(name)s"
+
+#, python-format
+msgid "Unable to create virtual machine %(name)s. Details: %(err)s"
+msgstr "Impossible de cr��er la machine virtuelle %(name)s. D��tails: %(err)s"
+
+#, python-format
+msgid "Unable to update virtual machine %(name)s. Details: %(err)s"
+msgstr ""
+"Impossible de mettre �� jour la machine virtuelle %(name)s. D��tails:
%(err)s"
+
+#, python-format
+msgid "Unable to retrieve virtual machine %(name)s. Details: %(err)s"
+msgstr ""
+"Impossible de r��cup��rer la machine virtuelle %(name)s. D��tails: %(err)s"
+
+#, python-format
+msgid "Unable to connect to powered off virtual machine %(name)s."
+msgstr "Impossible de se connecter �� la machine virtuelle ��teinte %(name)s."
+
+msgid "Virtual machine name must be a string without slashes (/)"
+msgstr ""
+
+#, python-format
+msgid "Invalid template URI %(value)s specified for virtual machine"
+msgstr ""
+
+#, python-format
+msgid "Invalid storage pool URI %(value)s specified for virtual machine"
+msgstr ""
+
+msgid "Supported virtual machine graphics are Spice or VNC"
+msgstr ""
+
+msgid "Graphics address to listen on must be IPv4 or IPv6"
+msgstr "L'adresse d'��coute du graphics doit ��tre IPv4 ou IPv6"
+
+msgid "Specify a template to create a virtual machine from"
+msgstr "Sp��cifier un mod��le �� partir duquel cr��er une machine virtuelle"
+
+#, python-format
+msgid "Unable to start virtual machine %(name)s. Details: %(err)s"
+msgstr "Impossible de d��marrer la machine virtuelle %(name)s. D��tails:
%(err)s"
+
+#, python-format
+msgid "Unable to power off virtual machine %(name)s. Details: %(err)s"
+msgstr ""
+"Impossible de mettre hors tension la machine virtuelle %(name)s. D��tails: %"
+"(err)s"
+
+#, python-format
+msgid "Unable to delete virtual machine %(name)s. Details: %(err)s"
+msgstr ""
+"Impossible de supprimer la machine virtuelle %(name)s. D��tails: %(err)s"
+
+#, python-format
+msgid "Unable to reset virtual machine %(name)s. Details: %(err)s"
+msgstr ""
+"Impossible de r��initrialiser la machine virtuelle %(name)s. D��tails:
%(err)s"
+
+msgid "User name list must be an array"
+msgstr ""
+
+msgid "User name must be a string"
+msgstr "Le nom d'utilisateur doit ��tre une cha��ne de caract��res"
+
+msgid "Group name list must be an array"
+msgstr ""
+
+msgid "Group name must be a string"
+msgstr "Le nom de groupe doit ��tre une cha��ne de caract��res"
+
+#, python-format
+msgid "User(s) '%(users)s' do not exist"
+msgstr "Le(s) utilisateur(s) '%(users)s' n'existe(nt) pas"
+
+#, python-format
+msgid "Group(s) '%(groups)s' do not exist"
+msgstr "Le(s) groupe(s) '%(groups)s' n'existe(nt) pas"
+
+#, python-format
+msgid "Unable to shutdown virtual machine %(name)s. Details: %(err)s"
+msgstr "Impossible d'��teindre la machine virtuelle %(name)s. D��tails:
%(err)s"
+
+#, python-format
+msgid ""
+"Unable to get access metadata of virtual machine %(name)s. Details: %(err)s"
+msgstr ""
+"Impossible d'acc��der aux metadata de la machine virtuelle %(name)s. D��tails:
"
+"%(err)s"
+
+msgid "The guest console password must be a string."
+msgstr "Le mot de passe de console invit��e doit ��tre une cha��ne de
caract��res."
+
+msgid "The life time for the guest console password must be a number."
+msgstr "La dur��e de vie du mot de passe de console invit��e doit ��tre un
nombre"
+
+#, python-format
+msgid "Virtual machine '%(name)s' must be stopped before cloning it."
+msgstr ""
+
+#, python-format
+msgid "Insufficient disk space to clone virtual machine '%(name)s'"
+msgstr ""
+
+#, python-format
+msgid "Unable to clone VM '%(name)s'. Details: %(err)s"
+msgstr ""
+
+#, python-format
+msgid "Invalid operation for non-persistent virtual machine %(name)s"
+msgstr ""
+
+#, python-format
+msgid "Cannot suspend VM '%(name)s' because it is not running."
+msgstr ""
+
+#, python-format
+msgid "Unable to suspend VM '%(name)s'. Details: %(err)s"
+msgstr ""
+
+#, python-format
+msgid "Cannot resume VM '%(name)s' because it is not paused."
+msgstr ""
+
+#, python-format
+msgid "Unable to resume VM '%(name)s'. Details: %(err)s"
+msgstr ""
+
+msgid "Memory assigned is higher then the maximum allowed in the host."
+msgstr ""
+
+#, python-format
+msgid ""
+"VM '%(name)s' does not support live memory update. Update the memory with
"
+"the machine offline to enable this feature."
+msgstr ""
+
+msgid "Only increase memory is allowed in active VMs"
+msgstr ""
+
+msgid ""
+"For live memory update, new memory value must be equal old memory value plus
"
+"multiples of 1024 Mib"
+msgstr ""
+
+msgid "There are not enough free slots of 1024 Mib in the guest."
+msgstr ""
+
+msgid ""
+"Host's libvirt version does not support memory devices. Libvirt must be >=
"
+"1.2.14"
+msgstr ""
+
+#, python-format
+msgid "Error attaching memory device. Details: %(error)s"
+msgstr ""
+
+#, python-format
+msgid ""
+"VM %(vmid)s does not contain directly assigned host device %(dev_name)s."
+msgstr ""
+"La machine virtuelle %(vmid)s ne peut pas contenir le p��riph��rique h��te "
+"directement assign�� %(dev_name)s."
+
+#, python-format
+msgid "The host device %(dev_name)s is not allowed to directly assign to VM."
+msgstr ""
+"The p��riph��rique h��te %(dev_name)s ne peut ��tre directement assign�� �� la
"
+"machine virtuelle"
+
+msgid ""
+"No IOMMU groups found. Host PCI pass through needs IOMMU group to function "
+"correctly. Please enable Intel VT-d or AMD IOMMU in your BIOS, then verify "
+"the Kernel is compiled with IOMMU support. For Intel CPU, add intel_iommu=on
"
+"to your Kernel parameter in /boot/grub2/grub.conf. For AMD CPU, add iommu=pt
"
+"iommu=1."
+msgstr ""
+
+msgid "\"name\" should be a device name string"
+msgstr "\"name\" doit ��tre un nom de p��riph��rique"
+
+#, python-format
+msgid ""
+"The device %(name)s is probably in use by the host. Unable to attach it to "
+"the guest."
+msgstr ""
+
+#, python-format
+msgid "Interface %(iface)s does not exist in virtual machine %(name)s"
+msgstr "L'interface %(iface)s n'existe pas dans la machine virtuelle
%(name)s"
+
+#, python-format
+msgid ""
+"Network %(network)s specified for virtual machine %(name)s does not exist"
+msgstr ""
+"Le r��seau %(network)s sp��cifi�� pour la machine virtuelle %(name)s n'existe
"
+"pas"
+
+msgid "Supported virtual machine interfaces type is only network"
+msgstr ""
+"Le type d'interface de machine virtuelle support�� est r��seau
uniquement"
+
+msgid "Network name for virtual machine interface must be a string"
+msgstr ""
+"Le nom de r��seau pour l'interface de la machine virtuelle doit ��tre une
"
+"cha��ne de caract��res"
+
+msgid "Invalid network model card specified for virtual machine interface"
+msgstr ""
+"Mod��le de carte r��seau sp��cifi�� invalide pour l'interface de machine
"
+"virtuelle"
+
+msgid "Specify type and network to add a new virtual machine interface"
+msgstr ""
+"Sp��cifier le type et le r��seau �� ajouter �� la nouvelle interface de la "
+"machine virtuelle"
+
+msgid "MAC Address must respect this format FF:FF:FF:FF:FF:FF"
+msgstr ""
+
+#, python-format
+msgid "MAC Address %(mac)s already exists in virtual machine %(name)s"
+msgstr ""
+
+msgid "Invalid MAC Address"
+msgstr ""
+
+msgid "Cannot change MAC address of a running virtual machine"
+msgstr ""
+
+#, python-format
+msgid "Template %(name)s already exists"
+msgstr "Le mod��le %(name)s existe d��j��"
+
+#, python-format
+msgid ""
+"Network '%(network)s' specified for template %(template)s does not
exist"
+msgstr ""
+"Le r��seau '%(network)s' sp��cifi�� pour le mod��le %(template)s
n'existe pas"
+
+#, python-format
+msgid ""
+"Storage pool %(pool)s specified for template %(template)s does not exist"
+msgstr ""
+"Le pool de stockage sp��cifi�� %(pool)s pour le mod��le %(template)s n'existe
"
+"pas"
+
+#, python-format
+msgid "Storage pool %(pool)s specified for template %(template)s is not
active"
+msgstr ""
+"Le pool de stockage sp��cifi�� %(pool)s pour le mod��le %(template)s n'est pas
"
+"actif"
+
+#, python-format
+msgid "Invalid parameter '%(param)s' specified for CDROM."
+msgstr "Param��tres '%(param)s' sp��cifi�� invalide pour le CDROM"
+
+#, python-format
+msgid "Network %(network)s specified for template %(template)s is not active"
+msgstr ""
+"Le r��seau %(network)s sp��cifi�� pour le mod��le %(template)s n'est pas
actif"
+
+msgid "Template name must be a string"
+msgstr "Le mod��le de nom doit ��tre une cha��ne de caract��res"
+
+msgid "Template icon must be a path to the image"
+msgstr "Le mod��le d'icone doit ��tre un chemin vers l'image"
+
+msgid "Template distribution must be a string"
+msgstr "Le mod��le de distribution doit ��tre une cha��ne de caract��res"
+
+msgid "Template distribution version must be a string"
+msgstr ""
+"Le mod��le de version de distribution doit ��tre une cha��ne de caract��res"
+
+msgid "The number of CPUs must be an integer greater than 0"
+msgstr "Le nombre de CPU doit ��tre un nombre entier sup��rieur �� 0"
+
+msgid "Amount of memory (MB) must be an integer greater than 512"
+msgstr "La quantit�� de m��moire (Mo) doit ��tre un nombre entier sup��rieur ��
512"
+
+msgid "Template CDROM must be a local or remote ISO file"
+msgstr "Le CDROM mod��le doit ��tre un fichier ISO local ou distant"
+
+#, python-format
+msgid "Invalid storage pool URI %(value)s specified for template"
+msgstr "URI %(value)s du pool de stockage sp��cifi��e invalide pour le
mod��le"
+
+msgid "Specify an ISO image as CDROM or a base image to create a template"
+msgstr ""
+"Sp��cifiez une image ISO comme CDROM ou une image de base pour cr��er un
mod��le"
+
+msgid "All networks for the template must be specified in a list."
+msgstr "Tous les r��seaux pour le mod��le doivent ��tre sp��cifi��s dans une
liste"
+
+msgid "Specify a volume to a template when storage pool is iSCSI or SCSI"
+msgstr ""
+
+#, python-format
+msgid "The volume %(volume)s is not in storage pool %(pool)s"
+msgstr "Le volume %(volume)s n'est pas dans le pool de stockage %(pool)s"
+
+#, python-format
+msgid "Unable to create template due error: %(err)s"
+msgstr "Impossible de cr��er le mod��le �� cause de l'erreur: %(err)s"
+
+#, python-format
+msgid "Unable to delete template due error: %(err)s"
+msgstr "Impossilbe de supprimer le mod��le �� cause de l'erreur: %(err)s"
+
+msgid "Disk size must be an integer greater than 1GB."
+msgstr "La taille de disque doit ��tre un entier sup��rieur �� 1Go."
+
+msgid "Template base image must be a valid local image file"
+msgstr "L'image de base de mod��le doit petre un fichier image local
valide"
+
+#, python-format
+msgid "Cannot identify base image %(path)s format"
+msgstr "Ne peut identifier le format de l'image de base %(path)s"
+
+msgid ""
+"When specifying CPU topology, VCPUs must be a product of sockets, cores, and
"
+"threads."
+msgstr ""
+
+msgid ""
+"When specifying CPU topology, each element must be an integer greater than "
+"zero."
+msgstr ""
+"Dans la topologie de CPU, chaque ��l��ment doit ��tre un entier strictement "
+"positif."
+
+msgid ""
+"Invalid disk image format. Valid formats: bochs, cloop, cow, dmg, qcow, "
+"qcow2, qed, raw, vmdk, vpc."
+msgstr ""
+
+#, python-format
+msgid "Storage pool %(name)s already exists"
+msgstr "Le pool de stockage %(name)s existe d��j��"
+
+#, python-format
+msgid "Storage pool %(name)s does not exist"
+msgstr "Le pool de stockage %(name)s n'existe pas"
+
+#, python-format
+msgid "Specify %(item)s in order to create the storage pool %(name)s"
+msgstr "Sp��cifier %(item)s afin de cr��er le pool de stockage %(name)s"
+
+#, python-format
+msgid "Unable to delete active storage pool %(name)s"
+msgstr "Impossible de supprimer le pool de stockage actif %(name)s"
+
+#, python-format
+msgid "Unable to list storage pools. Details: %(err)s"
+msgstr "Impossible de lister les pools de stockage. D��tails: %(err)s"
+
+#, python-format
+msgid "Unable to create storage pool %(name)s. Details: %(err)s"
+msgstr "Impossilble de cr��er le pool de stockage %(name)s. D��tails: %(err)s"
+
+#, python-format
+msgid ""
+"Unable to get number of storage volumes in storage pool %(name)s. Details: %"
+"(err)s"
+msgstr ""
+"Impossible d'obtenir le nombre de volumes de stockage dans le pool de "
+"stockage%(name)s. D��tails: %(err)s"
+
+#, python-format
+msgid "Unable to activate storage pool %(name)s. Details: %(err)s"
+msgstr "Impossible d'activer le pool de stockage %(name)s. D��tails:
%(err)s"
+
+#, python-format
+msgid "Unable to deactivate storage pool %(name)s. Details: %(err)s"
+msgstr ""
+"Impossible de d��sactiver le pool de stockage %(name)s. D��tails: %(err)s"
+
+#, python-format
+msgid "Unable to delete storage pool %(name)s. Details: %(err)s"
+msgstr ""
+"Impossible de supprimer le pool de stockage %(name)s. D��tails: %(err)s "
+
+#, python-format
+msgid ""
+"Unable to create NFS Pool as export path %(path)s may block during mount"
+msgstr ""
+"Impossible de cr��er le Pool NFS du fait que le chemin d'export %(path)s
"
+"pourrait se bloquer durant le montage"
+
+#, python-format
+msgid "Unable to create NFS Pool as export path %(path)s mount failed"
+msgstr ""
+"Impossible de cr��er le pool NFS du fait que le montage du chemin d'export
%"
+"(path)s a ��chou��"
+
+#, python-format
+msgid "Unsupported storage pool type: %(type)s"
+msgstr "Type de pool de stockage non support��: %(type)s"
+
+#, python-format
+msgid "Error while retrieving storage pool XML to %(pool)s"
+msgstr ""
+
+msgid "Storage pool name must be a string without slashes (/)"
+msgstr ""
+
+msgid ""
+"Supported storage pool types are dir, netfs, logical, iscsi, isci and
kimchi-"
+"iso"
+msgstr ""
+"Les types de pool de stockage support��s sont: dir, netfs, logical, iscsi, "
+"isci et kimchi-iso"
+
+msgid "Storage pool path must be a string"
+msgstr "Le chemin du pool de stockage doit ��tre une cha��ne de caract��res"
+
+msgid "Storage pool host must be a IP or hostname"
+msgstr "L'h��te du pool de stockage doit ��tre une IP ou un nom
d'h��te"
+
+msgid "Storage pool device must be the absolute path to the block device"
+msgstr ""
+
+msgid "Storage pool devices parameter must be a list"
+msgstr "Le param��tre de p��riph��rique de pool de stockage doit ��tre une
list"
+
+msgid "Target IQN of an iSCSI pool must be a string"
+msgstr "La cible IQN d'un pool iSCSI doit ��tre une cha��ne de
caract��res"
+
+msgid "Port of a remote storage server must be an integer between 1 and 65535"
+msgstr ""
+"Le port d'un serveur de stockage distant doit ��tre un nombre entier entre 1
"
+"et 65535"
+
+msgid "iSCSI target username must be a string"
+msgstr ""
+"Le nom d'utilisateur de la cible iSCSI doit ��tre une cha��ne de
caract��res"
+
+msgid "iSCSI target password must be a string"
+msgstr "Le mot de passe de la cible iSCSI doit ��tre une cha��ne de
caract��res"
+
+msgid "Specify name and type to create a storage pool"
+msgstr "Sp��cifier un nom et un type pour cr��er un pool de stockage"
+
+#, python-format
+msgid ""
+"%(disk)s is not a valid disk/partition. Could not add it to the pool %(pool)"
+"s."
+msgstr ""
+"%(disk)s n'est pas un(e) disque/partition valide. N'a pu l'ajouter au
pool %"
+"(pool)s."
+
+#, python-format
+msgid "Unable to extend logical pool %(pool)s. Details: %(err)s"
+msgstr "Impossible d'agrandir le pool logique %(pool)s. D��tails: %(err)s"
+
+msgid "The parameter disks only can be updated for logical storage pool."
+msgstr ""
+"Les disques en param��tre peuvent seulement ��tre mis �� jour pour un pool de
"
+"stockage logique."
+
+msgid "The SCSI host adapter name must be a string."
+msgstr "Le nom d'adaptateur de l'h��te SCSI doit ��tre une chapine de
caract��res"
+
+msgid "The storage pool kimchi_isos is reserved for internal use"
+msgstr "Le pool de stockage kimchi_isos est r��serv�� �� un usage interne"
+
+#, python-format
+msgid ""
+"Unable to activate NFS storage pool %(name)s. NFS server %(server)s is "
+"unreachable."
+msgstr ""
+"Impossible d'activer le pool de stockage NFS%(name)s. Le serveur NFS %"
+"(server)s n'est pas joignable."
+
+#, python-format
+msgid ""
+"Unable to deactivate NFS storage pool %(name)s. NFS server %(server)s is "
+"unreachable."
+msgstr ""
+"Impossible de d��sactiver le pool de stockage NFS%(name)s. Le serveur NFS %"
+"(server)s n'est pas joignable."
+
+#, python-format
+msgid ""
+"Unable to deactivate pool %(name)s as it is associated with some templates"
+msgstr ""
+"Impossible de d��sactiver le pool %(name)s du fait qu'il est associ�� �� des
"
+"mod��les"
+
+#, python-format
+msgid "Unable to delete pool %(name)s as it is associated with some templates"
+msgstr ""
+"Impossible de supprimer le pool %(name)s du fait qu'il est associ�� �� des
"
+"mod��les"
+
+#, python-format
+msgid ""
+"A volume group named '%(name)s' already exists. Please, choose another name
"
+"to create the logical pool."
+msgstr ""
+"Un groupe de volume appel�� '%(name)s' existe d��j��. Veuillez choisir un
autre "
+"nom pour cr��er le pool logique."
+
+#, python-format
+msgid "Unable to update database with deep scan information due error:
%(err)s"
+msgstr ""
+"Impossible de mettre �� jour la base de donn��es avec les informations de scan
"
+"profond �� cause de l'erreur: %(err)s"
+
+#, python-format
+msgid "Storage volume %(name)s already exists"
+msgstr "Le volume de stockage %(name)s existe d��j��"
+
+#, python-format
+msgid "Storage volume %(name)s does not exist in storage pool %(pool)s"
+msgstr ""
+"Le volume de stockage %(name)s n'existe pas dans le pool de stockage
%(pool)s"
+
+#, python-format
+msgid ""
+"Unable to create storage volume %(volume)s because storage pool %(pool)s is "
+"not active"
+msgstr ""
+"Impossible de cr��er le volume de stockage %(volume)s car le pool de stockage
"
+"%(pool)s n'est pas actif"
+
+#, python-format
+msgid "Specify %(item)s in order to create storage volume %(volume)s"
+msgstr "Sp��cifier %(item)s afin de cr��er le volume de stockage %(volume)s"
+
+#, python-format
+msgid ""
+"Unable to list storage volumes because storage pool %(pool)s is not active"
+msgstr ""
+"Impossible de lister les volumes de stockage car le pool de stockage %(pool)"
+"s n'est pas actif"
+
+#, python-format
+msgid ""
+"Unable to create storage volume %(name)s in storage pool %(pool)s. Details:
%"
+"(err)s"
+msgstr ""
+"Impossible de cr��er le volume de stockage %(name)s dans le pool de stockage
%"
+"(pool)s. D��tails: %(err)s"
+
+#, python-format
+msgid ""
+"Unable to list storage volumes in storage pool %(pool)s. Details: %(err)s"
+msgstr ""
+"Impossible de lister les volumes de stockage dans le pool de stockage
%(pool)"
+"s. D��tails: %(err)s"
+
+#, python-format
+msgid "Unable to wipe storage volumes %(name)s. Details: %(err)s"
+msgstr "Impossible de wiper les volumes de stockage %(name)s. D��tails:
%(err)s"
+
+#, python-format
+msgid "Unable to delete storage volume %(name)s. Details: %(err)s"
+msgstr ""
+"Impossible de supprimer le volume de stockage %(name)s. D��tails: %(err)s "
+
+#, python-format
+msgid "Unable to resize storage volume %(name)s. Details: %(err)s"
+msgstr ""
+"Impossible de redimensionner le volume de stockage %(name)s. D��tails:
%(err)s"
+
+#, python-format
+msgid "Storage type %(type)s does not support volume create and delete"
+msgstr ""
+"Le type de stockage %(type)s ne supporte pas ni la cr��ation ni la "
+"suppression de volume"
+
+msgid "Storage volume name must be a string"
+msgstr "Le nom de volume de stockage doit ��tre une cha��ne de caract��res"
+
+msgid "Storage volume allocation must be an integer number"
+msgstr "L'allocation de volume de stockage doit ��tre une nombre entier"
+
+msgid ""
+"Storage volume format not supported. Valid formats: bochs, cloop, cow, dmg, "
+"qcow, qcow2, qed, raw, vmdk, vpc."
+msgstr ""
+
+msgid "Storage volume requires a volume name"
+msgstr "Le volume de stockage requiert un nom de volume"
+
+#, python-format
+msgid ""
+"Unable to update database with storage volume information due error: %(err)s"
+msgstr ""
+"Impossible de mettre �� jour la base de donn��es avec les informations du "
+"volume de stockage �� cause de l'erreur: %(err)s"
+
+#, python-format
+msgid "Only one of parameter %(param)s can be specified"
+msgstr "Seulement un seul des param��tre %(param)s peut ��tre sp��cifi��"
+
+#, python-format
+msgid "Create volume from %(param)s is not supported"
+msgstr "La cr��ation de volume avec %(param)s n'est pas support��e"
+
+msgid "Storage volume capacity must be an integer number."
+msgstr "La capacit�� du volume de stockage doit ��tre un nombre entier."
+
+msgid "Storage volume URL must be http://, https://, ftp:// or ftps://."
+msgstr ""
+"L'URL du volume de stockage doit ��tre http://, https://, ftp:// ou
ftps://."
+
+#, python-format
+msgid "Unable to access file %(url)s. Please, check it."
+msgstr "Impossible d'acc��der au fichier %(url)s. Veuillez le v��rifier."
+
+#, python-format
+msgid ""
+"Unable to clone storage volume '%(name)s' in pool '%(pool)s'.
Details: %(err)"
+"s"
+msgstr ""
+
+msgid "Specify chunk data and its size to upload a file."
+msgstr ""
+
+msgid "In order to upload a storage volume, specify the 'upload'
parameter."
+msgstr ""
+
+msgid ""
+"Unable to upload chunk data as it does not match with requested chunk size."
+msgstr ""
+
+#, python-format
+msgid "The storage volume %(vol)s is not under an upload process."
+msgstr ""
+
+msgid "The upload chunk data will exceed the storage volume size."
+msgstr ""
+
+#, python-format
+msgid "Unable to upload chunk data to storage volume. Details: %(err)s."
+msgstr ""
+
+#, python-format
+msgid "Interface %(name)s does not exist"
+msgstr "L'interface %(name)s n'existe pas"
+
+#, python-format
+msgid "Network %(name)s already exists"
+msgstr "Le r��seau %(name)s existe d��j��"
+
+#, python-format
+msgid "Network %(name)s does not exist"
+msgstr "Le r��seau %(name)s n'existe pas"
+
+#, python-format
+msgid "Subnet %(subnet)s specified for network %(network)s is not valid."
+msgstr ""
+"Le sous-r��seau %(subnet)s sp��cifi�� pour le r��seau %(network)s n'est pas
"
+"valide"
+
+#, python-format
+msgid "Specify a network interface to create bridged network %(name)s"
+msgstr "Sp��cifier une interface r��seau pour cr��er le r��seau bridge
%(name)s"
+
+#, python-format
+msgid "Unable to delete active network %(name)s"
+msgstr "Impossible de supprimer le r��seau actif %(name)s"
+
+#, python-format
+msgid "Interface %(iface)s specified for network %(network)s is already in
use"
+msgstr ""
+"L'interface %(iface)s sp��cifi��e pour le r��seau %(network)s est d��j��
utilis��e"
+
+msgid "Interface should be bare NIC, bonding or bridge device."
+msgstr "L'interface doit ��tre un p��riph��rique NIC vide, bonding ou
bridg��."
+
+#, python-format
+msgid "Unable to create network %(name)s. Details: %(err)s"
+msgstr "Impossible de cr��er le r��seau %(name)s. D��tails: %(err)s"
+
+#, python-format
+msgid "Unable to find a free IP address for network '%(name)s'"
+msgstr "Impossible de trouver une adresse IP libre pour le r��seau
'%(name)s'"
+
+#, python-format
+msgid "The interface %(iface)s already exists."
+msgstr "L'interface %(iface)s existe d��j��"
+
+msgid "Network name must be a string without slashes (/) or quotes (\")"
+msgstr ""
+
+msgid "Supported network types are isolated, NAT and bridge"
+msgstr "Les types de r��seaux support��s sont isolated, NAT et bridge"
+
+msgid "Network subnet must be a string with IP address and prefix or netmask"
+msgstr ""
+"Le sous-r��seau doit ��tre une chaine de caract��res avec une adresse IP et un
"
+"pr��fixe ou un masque de r��seau"
+
+msgid "Network interface must be a string"
+msgstr "L'interface de r��seau doit ��tre une cha��ne de caract��res"
+
+msgid "Network VLAN ID must be an integer between 1 and 4094"
+msgstr "L'ID de VLAN du r��seau doit ��tre un nombre entier entre 1 et
4094"
+
+msgid "Specify name and type to create a Network"
+msgstr "Sp��cifiez un nom et un type pour cr��er un r��seau"
+
+#, python-format
+msgid ""
+"Unable to delete network %(name)s. There are some virtual machines %(vms)s "
+"and/or templates linked to this network."
+msgstr ""
+"Impossible de supprimer le r��seau %(name)s. Il y a des machines virtuelles
%"
+"(vms)s et/ou des mod��les li��s �� ce r��seau. "
+
+#, python-format
+msgid ""
+"Unable to deactivate network %(name)s. There are some virtual machines
%(vms)"
+"s and/or templates linked to this network."
+msgstr ""
+"Impossible de d��sactiver r��seau %(name)s. Il y a des machines virtuelles%"
+"(vms)s et/ou des mod��les li��s �� ce r��seau. "
+
+#, python-format
+msgid "Bridge device %(name)s can not be the trunk device of a VLAN."
+msgstr ""
+"Le p��riph��rique bridge %(name)s ne peut ��tre le p��riph��rique tronc d'un
VLAN."
+
+#, python-format
+msgid "Failed to activate interface %(iface)s: %(err)s."
+msgstr "��chec durant l'activation de l'interface %(iface)s: %(err)s."
+
+#, python-format
+msgid ""
+"Failed to activate interface %(iface)s. Please check the physical link "
+"status."
+msgstr ""
+"��chec durant l'activation de l'interface %(iface)s. Veuillez v��rifier le
"
+"statut du lien physique."
+
+#, python-format
+msgid "Failed to start network %(name)s. Details: %(err)s"
+msgstr ""
+
+#, python-format
+msgid "Debug report %(name)s does not exist"
+msgstr "Le rapport de d��boggage %(name)s n'existe pas"
+
+msgid "Debug report tool not found in system"
+msgstr "L'outil de rapport de d��boggage n'a pas ��t�� trouv�� dans le
syst��me"
+
+#, python-format
+msgid "Unable to create debug report %(name)s. Details: %(err)s."
+msgstr ""
+"Impossible de cr��er le rapport de d��boggage %(name)s. D��tails: %(err)s."
+
+#, python-format
+msgid "Can not find any debug report with the given name %(name)s"
+msgstr ""
+"Impossible de trouver un rapport de d��boggage avec le nom fourni %(name)s"
+
+#, python-format
+msgid "Unable to generate debug report %(name)s. Details: %(err)s"
+msgstr ""
+"Impossible de g��n��rer le rapport de d��boggage %(name)s. D��tails: %(err)s"
+
+msgid "You should give a name for the debug report file."
+msgstr "Vous devriez donner un nom au fichier de rapport de d��boggage."
+
+msgid ""
+"Debug report name must be a string. Only letters, digits, underscore ('_')
"
+"and hyphen ('-') are allowed."
+msgstr ""
+"Le nom du rapport de d��boggage doit ��tre une cha��ne de caract��res. Seulement
"
+"les lettres, chiffres, blanc soulign�� ('_') et tirets ('-') sont
accept��s."
+
+#, python-format
+msgid ""
+"The debug report with specified name \"%(name)s\" already exists. Please
use "
+"another one."
+msgstr ""
+"Le rapport de d��boggage avec le nom sp��cifi�� \"%(name)s\" existe
d��j��. "
+"Veuillez en utiliser un autre."
+
+#, python-format
+msgid "Storage server %(server)s was not used by Kimchi"
+msgstr "Le server de stockage %(server)s n'��tait pas utilis�� par Kimchi"
+
+#, python-format
+msgid "Distro '%(name)s' does not exist"
+msgstr "La distro '%(name)s' n'existe pas"
+
+#, python-format
+msgid "Partition %(name)s does not exist in the host"
+msgstr "La partition %(name)s n'existe pas sur cet h��te"
+
+msgid "Unable to shutdown host machine as there are running virtual machines"
+msgstr ""
+"Impossible d'��teindre la machine h��te car des machines virtuelles en sont
"
+"cours d'ex��cution"
+
+msgid "Unable to reboot host machine as there are running virtual machines"
+msgstr ""
+"Impossible de red��marrer la machine h��te car des machines virtuelles en sont
"
+"cours d'ex��cution"
+
+#, python-format
+msgid "Node device '%(name)s' not found"
+msgstr "P��riph��rique de noeud '%(name)s' non trouv��"
+
+msgid "Conflicting flag filters specified."
+msgstr "Filtres incompatibles sp��cifi��s."
+
+msgid "No packages marked for update"
+msgstr "Aucun paquet marqu�� pour mise �� jour"
+
+#, python-format
+msgid "Package %(name)s is not marked to be updated."
+msgstr "Le paquet %(name)s n'est pas marqu�� pour mise �� jour"
+
+#, python-format
+msgid "Error while getting packages marked to be updated. Details: %(err)s"
+msgstr ""
+"Erreur durant la r��cup��ration des paquets marqu��s pour la mise�� jour. "
+"D��tails: %(err)s"
+
+msgid "There is no compatible package manager for this system."
+msgstr "Il n'y a pas de gestionnaire de paquets compatible avec ce
syst��me."
+
+#, python-format
+msgid "Invalid URI %(uri)s"
+msgstr "URI %(uri)s invalide"
+
+msgid "Unable to choose a virtual machine name"
+msgstr "Impossible de s��lectionner un nom de machine virtuelle"
+
+msgid "Invalid storage type. Types supported: 'cdrom', 'disk'"
+msgstr "Type de stockage invalide. Les Types support��s sont: 'cdrom',
'disk'"
+
+#, python-format
+msgid "The path '%(value)s' is not a valid local/remote path for the
device"
+msgstr ""
+
+msgid "Only CDROM path can be update."
+msgstr "Seulement le chemin d'un CDROM peut ��tre modifi��."
+
+#, python-format
+msgid ""
+"The storage device %(dev_name)s does not exist in the virtual machine %"
+"(vm_name)s"
+msgstr ""
+"Le p��riph��rique de stockage %(dev_name)s n'existe pas dans la machine "
+"virtuelle %(vm_name)s"
+
+#, python-format
+msgid "Error while creating new storage device: %(error)s"
+msgstr ""
+"Erreur durant la cr��ation du nouveau p��riph��rique de stockage: %(error)s"
+
+#, python-format
+msgid "Error while updating storage device: %(error)s"
+msgstr "Erreur durant la mise �� jour du p��riph��rique de stockage:
%(error)s"
+
+#, python-format
+msgid "Error while removing storage device: %(error)s"
+msgstr "Erreur durant le retrait du p��riph��rique de stockage: %(error)s"
+
+msgid "Do not support IDE device hot plug"
+msgstr "Ne pas supporter le branchement �� chaud de p��riph��rique IDE"
+
+msgid ""
+"Specify type and path or type and pool/volume to add a new virtual machine "
+"disk"
+msgstr ""
+"Sp��cifier le type et le chemin ou le type et le pool/volume pour ajouter un
"
+"nouveau disque de machine virtuelle."
+
+msgid "Specify path to update virtual machine disk"
+msgstr "Sp��cifier un chemin pour mettre �� jour le disque de machine
virtuelle"
+
+#, python-format
+msgid "Controller type %(type)s limitation of %(limit)s devices reached"
+msgstr ""
+"La limitation de %(limit)s p��riph��riques a ��t�� atteinte pour le contr��leur
"
+"de type %(type)s "
+
+#, python-format
+msgid "Cannot retrieve disk path information for given pool/volume: %(error)s"
+msgstr ""
+
+msgid "Volume already in use by other virtual machine."
+msgstr ""
+
+msgid ""
+"Only one of path or pool/volume can be specified to add a new virtual "
+"machine disk"
+msgstr ""
+"Seul un chemin ou pool/volume peut ��tre sp��cifi�� pour ajouter un nouveau "
+"disque de machine virtuelle"
+
+#, python-format
+msgid ""
+"Volume chosen with format %(format)s does not fit in the storage type
%(type)"
+"s"
+msgstr ""
+"Le volume de format %(format)s s��lectionn�� ne correspond pas au type de "
+"stockage %(type)s"
+
+msgid "YUM Repository ID must be one word only string."
+msgstr ""
+"L'ID du d��p��t YUM doit ��tre une cha��ne de caract��res ne comportant
qu'un "
+"seul mot"
+
+msgid "Repository URL must be an http://, ftp:// or file:// URL."
+msgstr "L'URL du d��p��t doit ��tre une URL en http://, ftp:// ou
file://."
+
+msgid ""
+"Repository configuration is a dictionary with specific values according to "
+"repository type."
+msgstr ""
+"La configuration du d��p��t est un dictionaire avec des valeurs sp��cifiques en
"
+"accord avec le type de d��p��t."
+
+msgid "Distribution to DEB repository must be a string"
+msgstr ""
+"La distribution dans le nom de d��p��t DEB doit ��tre une cha��ne de
caract��res"
+
+msgid "Components to DEB repository must be listed in a array"
+msgstr "Les composants dans le d��p��t DEB doivent ��tre list��s dans un
tableau"
+
+msgid "Components to DEB repository must be a string"
+msgstr "Les composants dans le d��p��t DEB doivent ��tre une cha��ne de
caract��res"
+
+msgid "Mirror list to repository must be a string"
+msgstr ""
+
+msgid "YUM Repository name must be string."
+msgstr "Le nom du d��p��t YUM doit ��tre une cha��ne de caract��res"
+
+msgid "GPG check must be a boolean value."
+msgstr "La v��rification GPG doit ��tre une valeur bool��enne."
+
+msgid "GPG key must be a URL pointing to the ASCII-armored file."
+msgstr "La cl�� GPG doit ��tre une URL pointant vers un fichier ASCII non
arm��."
+
+#, python-format
+msgid "Could not update repository %(repo_id)s."
+msgstr "Ne peut mettre �� jour le d��p��t %(repo_id)s."
+
+#, python-format
+msgid "Repository %(repo_id)s does not exist."
+msgstr "Le d��p��t %(repo_id)s n'existe pas."
+
+msgid ""
+"Specify repository base URL, mirror list or metalink in order to create or "
+"update a YUM repository."
+msgstr ""
+
+msgid "Repository management tool was not recognized for your system."
+msgstr "L'outil de gestion de d��p��t n'a pas ��t�� reconnu pour votre
syst��me."
+
+#, python-format
+msgid "Repository %(repo_id)s is already enabled."
+msgstr "Le d��p��t %(repo_id)s est d��j�� activ��."
+
+#, python-format
+msgid "Repository %(repo_id)s is already disabled."
+msgstr "Le d��p��t %(repo_id)s est d��j�� d��sactiv��."
+
+#, python-format
+msgid "Could not remove repository %(repo_id)s."
+msgstr "Ne peut supprimer le d��p��t %(repo_id)s. "
+
+#, python-format
+msgid "Could not write repository configuration file %(repo_file)s"
+msgstr "Ne peut ��crire le fichier de configuration du d��p��t %(repo_file)s"
+
+msgid "Specify repository distribution in order to create a DEB repository."
+msgstr "Sp��cifier la distribution du d��p��t afin de cr��er un d��p��t DEB."
+
+#, python-format
+msgid "Could not enable repository %(repo_id)s."
+msgstr "Ne peut activer le d��p��t %(repo_id)s."
+
+#, python-format
+msgid "Could not disable repository %(repo_id)s."
+msgstr "Ne peut d��sactiver le d��p��t %(repo_id)s."
+
+msgid "YUM Repository ID already exists"
+msgstr "L'ID du d��p��t YUM existe d��j��"
+
+msgid "YUM Repository name must be a string"
+msgstr "Le nom du d��p��t YUM doit ��tre une cha��ne de caract��res"
+
+#, python-format
+msgid "Unable to list repositories. Details: '%(err)s'"
+msgstr "Impossible de lister les d��p��ts. D��tails: '%(err)s'"
+
+#, python-format
+msgid "Unable to retrieve repository information. Details: '%(err)s'"
+msgstr "Impossible de r��cup��rer les informations du d��p��t. D��tails:
'%(err)s'"
+
+#, python-format
+msgid "Unable to add repository. Details: '%(err)s'"
+msgstr "Impossible d'ajouter un d��p��t. D��tails: '%(err)s'"
+
+#, python-format
+msgid "Unable to remove repository. Details: '%(err)s'"
+msgstr "Impossible de supprimer un d��p��t. D��tails: '%(err)s'"
+
+#, python-format
+msgid ""
+"Configuration items: '%(items)s' are not supported by repository
manager"
+msgstr ""
+"��l��ments de configurations: %(items)s ne sont pas support��s par le "
+"gestionnaire de d��p��t"
+
+msgid "Repository metalink must be an http://, ftp:// or file:// URL."
+msgstr ""
+
+msgid "Cannot specify mirrorlist and metalink at the same time."
+msgstr ""
+
+#, python-format
+msgid ""
+"Virtual machine '%(vm)s' must be stopped before creating a snapshot of
it."
+msgstr ""
+
+#, python-format
+msgid ""
+"Unable to create snapshot '%(name)s' on virtual machine '%(vm)s'.
Details: %"
+"(err)s"
+msgstr ""
+
+#, python-format
+msgid "Snapshot '%(name)s' does not exist on virtual machine
'%(vm)s'."
+msgstr ""
+
+#, python-format
+msgid ""
+"Unable to retrieve snapshot '%(name)s' on virtual machine '%(vm)s'.
Details: "
+"%(err)s"
+msgstr ""
+
+#, python-format
+msgid "Unable to list snapshots on virtual machine '%(vm)s'. Details:
%(err)s"
+msgstr ""
+
+#, python-format
+msgid ""
+"Unable to delete snapshot '%(name)s' on virtual machine '%(vm)s'.
Details: %"
+"(err)s"
+msgstr ""
+
+#, python-format
+msgid ""
+"Unable to retrieve current snapshot of virtual machine '%(vm)s'. Details:
%"
+"(err)s"
+msgstr ""
+
+#, python-format
+msgid ""
+"Unable to revert virtual machine '%(vm)s' to snapshot '%(name)s'.
Details: %"
+"(err)s"
+msgstr ""
+
+#, python-format
+msgid ""
+"Unable to create snapshot of virtual machine '%(vm)s' because it contains a
"
+"disk with format '%(format)s'; only 'qcow2' is supported."
+msgstr ""
+
+msgid "The number of vCPUs is too large for this system."
+msgstr ""
+
+msgid "Invalid vCPU/topology combination."
+msgstr ""
+
+msgid "This host (or current configuration) does not allow CPU topology."
+msgstr ""
+
+msgid "ERROR CODE"
+msgstr "ERROR CODE"
+
+msgid "REASON"
+msgstr "REASON"
+
+msgid "STACK"
+msgstr "STACK"
+
+msgid "Go to Homepage"
+msgstr "Aller �� la page d'accueil"
+
+msgid "Create a New Virtual Machine"
+msgstr "Cr��er une nouvelle Machine Virtuelle"
+
+msgid "Virtual Machine Name"
+msgstr "Nom de Machine Virtuelle"
+
+msgid ""
+"The name used to identify the virtual machine. If omitted, a name will be "
+"chosen based on the template used."
+msgstr ""
+"Le nm est utilis�� pour identifier une machine virtuelle. Si omis, un nom "
+"sera choisi en se basant sur le mod��le utilis��."
+
+msgid "Template"
+msgstr "Mod��le"
+
+msgid "Please create a template first."
+msgstr "Veuillez d'abord cr��er un mod��le."
+
+msgid "Create a Template"
+msgstr "Cr��er un mod��le"
+
+msgid "Please choose a template."
+msgstr "Veuillez choisir un mod��le"
+
+msgid "OS"
+msgstr "OS"
+
+msgid "OS Version"
+msgstr "Version de l'OS"
+
+msgid "CPUS"
+msgstr "CPUS"
+
+msgid "Memory"
+msgstr "M��moire"
+
+msgid "Create"
+msgstr "Cr��er"
+
+msgid "Creating..."
+msgstr "Cr��ation en cours..."
+
+msgid "Cancel"
+msgstr "Annuler"
+
+msgid "Edit Guest"
+msgstr "��diter l'Invit��"
+
+msgid "General"
+msgstr "G��n��ral"
+
+msgid "Storage"
+msgstr "Stockage"
+
+msgid "Interface"
+msgstr "Interface"
+
+msgid "Permission"
+msgstr "Permission"
+
+msgid "Host PCI Device"
+msgstr "P��riph��rique PCI H��te"
+
+msgid "Snapshot"
+msgstr ""
+
+msgid "Name"
+msgstr "Nom"
+
+msgid "CPUs"
+msgstr "CPUs"
+
+msgid "Memory (MB)"
+msgstr "M��moire (Mo)"
+
+msgid "Icon"
+msgstr "Icone"
+
+msgid "Device"
+msgstr "P��riph��rique"
+
+msgid "Path"
+msgstr "Chemin"
+
+msgid "Network"
+msgstr "R��seau"
+
+msgid "Type"
+msgstr "Type"
+
+msgid "MAC Address"
+msgstr ""
+
+msgid "Available system users and groups"
+msgstr "Utilisateurs et groupes syst��mes disponibles"
+
+msgid "Selected system users and groups"
+msgstr "Utilisateurs et groupes syst��mes s��lectionn��s"
+
+msgid "User"
+msgstr ""
+
+msgid "All"
+msgstr "Tous"
+
+msgid "To Add"
+msgstr "�� Ajouter"
+
+msgid "Added"
+msgstr "Ajouter"
+
+msgid "filter"
+msgstr "Filtre"
+
+msgid "Product"
+msgstr "Produit"
+
+msgid "Vendor"
+msgstr "Vendeur"
+
+msgid "Created"
+msgstr ""
+
+msgid "Save"
+msgstr "Enregistrer"
+
+msgid "Replace"
+msgstr "Remplacer"
+
+msgid "Detach"
+msgstr "D��tacher"
+
+msgid "revert"
+msgstr ""
+
+msgid "Start"
+msgstr "D��marrer"
+
+msgid "Reset"
+msgstr "R��initialiser"
+
+msgid "Pause"
+msgstr ""
+
+msgid "Resume"
+msgstr ""
+
+msgid "Power Off"
+msgstr "Mettre hors tension"
+
+msgid "Actions"
+msgstr "Actions"
+
+msgid "Connect"
+msgstr "Connecter"
+
+msgid "Clone"
+msgstr "Cloner"
+
+msgid "Edit"
+msgstr "��diter"
+
+msgid "Shut Down"
+msgstr "��teindre"
+
+msgid "Delete"
+msgstr "Supprimer"
+
+msgid "CPU"
+msgstr "CPU"
+
+msgid "Disk I/O"
+msgstr "E/S Disque"
+
+msgid "Network I/O"
+msgstr "E/S R��seau"
+
+msgid "Livetile"
+msgstr "Livetile"
+
+msgid "No guests found."
+msgstr "Aucun invit�� trouv��."
+
+msgid "Add a Storage Device to VM"
+msgstr "Ajouter un P��riph��rique de Stockage �� la VM"
+
+msgid "Device Type"
+msgstr "Type de P��riph��rique"
+
+msgid "The device type. Currently, \"cdrom\" and \"disk\" are
supported."
+msgstr ""
+"Le type de p��riph��rique. Actuellement, \"cdrom\" et \"disk\"
sont support��s."
+
+msgid "Storage Pool"
+msgstr "Pool de Stockage"
+
+msgid "Storage pool which volume located in"
+msgstr "Pool de Stockage dans lequel le volume est situ��"
+
+msgid "Storage Volume"
+msgstr "Volume de Stockage"
+
+msgid "Storage volume to be attached"
+msgstr "Le volume de stockage �� attacher"
+
+msgid "File Path"
+msgstr "Chemin de Fichier"
+
+msgid "The ISO file path in the server for CDROM."
+msgstr "Le chemin de fichier ISO sur le serveur comme CDROM."
+
+msgid "Attach"
+msgstr "Attacher"
+
+msgid "Shut down"
+msgstr "��teindre"
+
+msgid "Restart"
+msgstr "Red��marrer"
+
+msgid "Basic Information"
+msgstr "Informations de Base"
+
+msgid "OS Distro"
+msgstr "Distro de l'OS"
+
+msgid "OS Code Name"
+msgstr "Nom de code de l'OS"
+
+msgid "Processor"
+msgstr "Processeur"
+
+msgid "CPU(s)"
+msgstr ""
+
+msgid "System Statistics"
+msgstr "Statistiques Syst��me"
+
+msgid "Software Updates"
+msgstr "Mises �� jour Logiciel"
+
+msgid "Update Progress"
+msgstr "Progr��s de la Mise �� Jour"
+
+msgid "Repositories"
+msgstr "D��p��ts"
+
+msgid "Debug Reports"
+msgstr "Rapports de D��boggage"
+
+msgid "The username or password you entered is incorrect. Please try again."
+msgstr ""
+"Le nom d'utilisateur ou le mot de passe que vous avez entr�� est incorrect.
"
+"Veuillez essayer �� nouveau."
+
+msgid "This field is required."
+msgstr "Ce champ est requis."
+
+msgid "Log in"
+msgstr "Se connecter"
+
+msgid "Logging in..."
+msgstr "En cours de connexion..."
+
+msgid "Host"
+msgstr "H��te"
+
+msgid "Guests"
+msgstr "Invit��s"
+
+msgid "Templates"
+msgstr "Mod��les"
+
+msgid "Failed to get application configuration"
+msgstr "��chec lors de l'obtention de la configuration de
l'application"
+
+msgid "This is not a valid Linux path"
+msgstr "Ce n'est pas un chemin Linux valide"
+
+msgid "This is not a valid URL."
+msgstr "Ce n'est pas une URL valide."
+
+msgid "No such data available."
+msgstr "De telles donn��es ne sont pas disponibles."
+
+msgid ""
+"Can not contact the host system. Verify the host system is up and that you "
+"have network connectivity to it. HTTP request response %1. "
+msgstr ""
+"Ne peut contacter le syst��me h��te. V��rifiez que le syst��me h��te est allum��
"
+"et que vous avez une connectivit�� r��seau avec lui. R��ponse de requ��te HTTP
%"
+"1."
+
+msgid "Unable to read file."
+msgstr ""
+
+msgid "Error while uploading file."
+msgstr ""
+
+msgid "Delete Confirmation"
+msgstr "Confirmation de Suppression"
+
+msgid "OK"
+msgstr "OK"
+
+msgid "Confirm"
+msgstr "Confirmer"
+
+msgid "Warning"
+msgstr "Avertissement"
+
+msgid "Cloning..."
+msgstr ""
+
+msgid "Loading..."
+msgstr "Chargement en cours..."
+
+msgid "An error occurred while retrieving system information."
+msgstr ""
+
+msgid "Retry"
+msgstr "Essayer �� nouveau"
+
+msgid "Detailed message:"
+msgstr "Message d��taill��:"
+
+msgid "No ISO found"
+msgstr "Aucune ISO d��tect��e"
+
+msgid "This is not a valid ISO file."
+msgstr "Ce n'est pas un fichier ISO valide."
+
+msgid "This may take a long time. Do you want to continue?"
+msgstr "Cela va prendre un long moment. Voulez-vous continuer ?"
+
+msgid "This will permanently delete the template. Would you like to continue?"
+msgstr ""
+"Cela va supprimer de mani��re permanent le mod��le. Souhaites-vous continuer
?"
+
+msgid "Unable to shut down system as there are some virtual machines running!"
+msgstr ""
+"Impossible d'��teindre le syst��me du fait que certaines machines virtuelles
"
+"sont lanc��es !"
+
+msgid "Max:"
+msgstr "Max:"
+
+msgid "Utilization"
+msgstr "Utilisation"
+
+msgid "Available"
+msgstr "Disponible"
+
+msgid "Read Rate"
+msgstr "Taux en Lecture"
+
+msgid "Write Rate"
+msgstr "Taux en ��criture"
+
+msgid "Received"
+msgstr "Re��u"
+
+msgid "Sent"
+msgstr "Envoy��"
+
+msgid ""
+"Shutting down or restarting host will cause unsaved work lost. Continue to "
+"shut down/restarting?"
+msgstr ""
+"��teindre ou red��marrer l'h��te causera la perte de tout travail non "
+"enregistr��. Continuer �� ��teindre/red��marrer ?"
+
+msgid ""
+"Repository will be removed permanently and can't be recovered. Do you want
"
+"to continue?"
+msgstr ""
+"Le d��p��t sera retir�� de fa��on permanente et ne pourra ��tre r��tabli.
Voulez-"
+"vous continuer ?"
+
+msgid "ID"
+msgstr "ID"
+
+msgid "Base URL"
+msgstr "URL de base"
+
+msgid "Is Mirror"
+msgstr "Est un miroir"
+
+msgid "URL Args"
+msgstr "Arguments d'URL"
+
+msgid "Enabled"
+msgstr "Activ��"
+
+msgid "GPG Check"
+msgstr "V��rification GPG"
+
+msgid "GPG Key"
+msgstr "Cl�� GPG"
+
+msgid "Add"
+msgstr "Ajouter"
+
+msgid "Remove"
+msgstr "Retirer"
+
+msgid "Enable"
+msgstr "Activer"
+
+msgid "Disable"
+msgstr "D��sactiver"
+
+msgid "Package Name"
+msgstr "Nom de paquet"
+
+msgid "Version"
+msgstr "Version"
+
+msgid "Architecture"
+msgstr "Architecture"
+
+msgid "Repository"
+msgstr "D��p��t"
+
+msgid "Update All"
+msgstr "Tout mettre �� jour"
+
+msgid "Updating..."
+msgstr "En cours de mise �� jour..."
+
+msgid "Failed to retrieve packages update information."
+msgstr "��chec de r��cup��ration des informations de mise-��-jour des
paquets."
+
+msgid "Failed to update package(s)."
+msgstr "��chec durant la mise �� jour du/des paquet(s)"
+
+msgid ""
+"Debug report will be removed permanently and can't be recovered. Do you want
"
+"to continue?"
+msgstr ""
+"Le rapport de d��boggage sera enlev�� de fa��on permanente et ne pourra ��tre
"
+"r��tabli. Voulez-vous continuer ?"
+
+msgid "Generated Time"
+msgstr "Horodatage de g��n��ration"
+
+msgid "Generate"
+msgstr "G��n��rer"
+
+msgid "Generating..."
+msgstr "En cours de g��n��ration..."
+
+msgid "Rename"
+msgstr "Renommer"
+
+msgid "Download"
+msgstr "T��l��charger"
+
+msgid ""
+"Report name should contain only letters, digits, underscore ('_') and/or
"
+"hyphen ('-')."
+msgstr ""
+"Le nom de rapport devrait contenir uniquement des lettres, nombres, "
+"soulignement ('_') et/ou tiret ('-')."
+
+msgid "Pending..."
+msgstr "En attente..."
+
+msgid "Report name is the same as the original one."
+msgstr "Le nom du rapport est le m��me que celui d'origine."
+
+msgid ""
+"This will delete the virtual machine and its virtual disks. This operation "
+"cannot be undone. Would you like to continue?"
+msgstr ""
+"Cela va supprimer la machine virtuelle et tous ses disques virtuels. Cette "
+"op��ration est irr��versible. Voulez-vous continuer ?"
+
+msgid "Power off Confirmation"
+msgstr "Confirmation de mise hors tension"
+
+msgid ""
+"This action may produce undesirable results, for example unflushed disk "
+"cache in the guest. Would you like to continue?"
+msgstr ""
+"Cette action pourrait produire des r��sultats ind��sirables, par exemple un "
+"cache disque non flush�� dans l'invit��. Voulez-vous continuer ?"
+
+msgid "Reset Confirmation"
+msgstr "Confirmation de R��initialisation"
+
+msgid ""
+"There is a risk of data loss caused by reset without the guest OS shutdown. "
+"Would you like to continue?"
+msgstr ""
+"Il y a un risque de perte de donn��es caus��es par une r��initialisation sans
"
+"extinction de l'OS invit��. Voulez-vous continuer ?"
+
+msgid "Shut Down Confirmation"
+msgstr "Confirmation d'Extinction"
+
+msgid "Note the guest OS may ignore this request. Would you like to continue?"
+msgstr ""
+"Noter que l'OS invit�� pourrait ignorer cette requ��te. Voulez-vous continuer
?"
+
+msgid "Virtual Machine delete Confirmation"
+msgstr "Confirmation de suppression de Machine Virtuelle"
+
+msgid ""
+"This virtual machine is not persistent. Power Off will delete it. Continue?"
+msgstr ""
+
+msgid ""
+"When the target guest has SCSI or iSCSI volumes, they will be cloned on "
+"default storage pool. The same will happen when the target pool does not "
+"have enough space to clone the volumes. Do you want to continue?"
+msgstr ""
+
+msgid ""
+"This CDROM will be detached permanently and you can re-attach it. Continue "
+"to detach it?"
+msgstr ""
+"Ce CDROM sera d��tach�� de fa��on permanente et vous pourrez le r��-attacher.
"
+"Continuer le d��tachement ?"
+
+msgid "Attaching..."
+msgstr "En cours d'attachement..."
+
+msgid "Replacing..."
+msgstr "En cours de Remplacement..."
+
+msgid "Successfully attached!"
+msgstr "Attach�� avec succ��s !"
+
+msgid "Successfully replaced!"
+msgstr "Remplac�� avec succ��s !"
+
+msgid "Successfully detached!"
+msgstr "D��tach�� avec Succ��s !"
+
+msgid ""
+"This disk will be detached permanently and you can re-attach it. Continue to
"
+"detach it?"
+msgstr ""
+"Ce disque sera d��finitivement d��tach�� et peut ��tre r��-attach��. Continuer ��
"
+"le d��tacher ?"
+
+msgid "interface:"
+msgstr ""
+
+msgid "address:"
+msgstr ""
+
+msgid "link_type:"
+msgstr ""
+
+msgid "block:"
+msgstr ""
+
+msgid "drive_type:"
+msgstr ""
+
+msgid "model:"
+msgstr ""
+
+msgid "Affected devices:"
+msgstr ""
+
+msgid "The VLAN id must be between 1 and 4094."
+msgstr "L'id du VLAN doit ��tre entre 1 et 4094."
+
+msgid "unavailable"
+msgstr "non disponible"
+
+msgid ""
+"This action will interrupt network connectivity for any virtual machine that
"
+"depend on this network."
+msgstr ""
+"Cette action va interrompre la connectivit�� r��seau pour tout machine "
+"virtuelle qui d��pend de ce r��seau."
+
+msgid "Create a network"
+msgstr "Cr��er un r��seau"
+
+msgid ""
+"This network is not persistent. Instead of stop, this action will "
+"permanently delete it. Would you like to continue?"
+msgstr ""
+"Ce r��seau n'est pas persistant. Au lieu de s'arr��ter, cette actionva le
"
+"suppromer de mani��re permanente. Voulez-vous continuer ?"
+
+msgid ""
+"The bridged VLAN tag may not work well with NetworkManager enabled. You "
+"should consider disabling it."
+msgstr ""
+
+msgid ""
+"This will permanently delete the storage pool. Would you like to continue?"
+msgstr ""
+"Cela va effacer de mani��re permanente le pool de stockage. Voulez-vous "
+"continuer ?"
+
+msgid "This storage pool is empty."
+msgstr "Ce pool de stockage est vide."
+
+msgid ""
+"It will format your disk and you will loose any data in there, are you sure "
+"to continue? "
+msgstr ""
+"Cela va formater votre disque et vous allez perdre toutes les donn��es qui "
+"s'y trouvent, ��tes-vous s��r de continuer ?"
+
+msgid "SCSI Fibre Channel"
+msgstr "Canal Fibre SCSI"
+
+msgid "No SCSI adapters found."
+msgstr "Aucun adaptateur SCSI trouv��."
+
+msgid "Loading iSCSI targets..."
+msgstr ""
+
+msgid "No iSCSI found. Please input one."
+msgstr ""
+
+msgid "Failed to load iSCSI targets."
+msgstr ""
+
+msgid "The storage pool name can not be blank."
+msgstr "Le nom de pool de stockage ne peut ��tre vierge."
+
+msgid "The storage pool path can not be blank."
+msgstr "Le chemin de pool de stockage ne peut ��tre vierge."
+
+msgid "NFS server mount path can not be blank."
+msgstr "Le chemin de montage du serveur NFS ne peut ��tre vierge."
+
+msgid "Invalid NFS mount path."
+msgstr "Chemin de montage NFS invalide."
+
+msgid "No logical device selected."
+msgstr "Aucun p��riph��rique logique s��lectionn��."
+
+msgid "The iSCSI target can not be blank."
+msgstr "La cible iSCSI ne peut ��tre vierge."
+
+msgid "Server name can not be blank."
+msgstr "Le nom de serveur ne peut ��tre vierge."
+
+msgid "This is not a valid Server Name or IP. Please, modify it."
+msgstr ""
+
+msgid "Looking for available partitions ..."
+msgstr "En cours de recherche de partitions disponibles..."
+
+msgid "No available partitions found."
+msgstr "Aucune partition disponible trouv��e."
+
+msgid ""
+"This storage pool is not persistent. Instead of deactivate, this action will
"
+"permanently delete it. Would you like to continue?"
+msgstr ""
+"Le pool de stockage n'est pas persistent. Au lieu de le d��sactiver, cette
"
+"action va le supprimer de mani��re permanente. Voulez-vous continuer ?"
+
+msgid "Unable to retrieve partitions information."
+msgstr "Impossible de r��cup��rer les informations des partitions."
+
+msgid "In progress..."
+msgstr "En cours..."
+
+msgid "Failed!"
+msgstr "��chec!"
+
+msgid "CDROM path needs to be a valid local/remote path and cannot be blank."
+msgstr ""
+"Le chemin de CDROM doit ��tre un chemin local/distant valide et ne peut ��tre
"
+"virge."
+
+msgid "Disk pool or volume cannot be blank."
+msgstr "Le pool de disque ou le volume ne peut ��tre vierge."
+
+#, fuzzy
+msgid "Filter"
+msgstr "Filtre"
+
+msgid "Network Name"
+msgstr "Nom de R��seau"
+
+msgid "State"
+msgstr "��tat"
+
+msgid "Network Type"
+msgstr "Type de R��seau"
+
+msgid "Address Space"
+msgstr "Espace d'adressage"
+
+msgid "Name should not contain '/' and '\"'."
+msgstr "Le nom ne devrait pas contenir '/' et '\"'."
+
+msgid "Isolated: no external network connection"
+msgstr "Isol��: pas de connexion �� un r��seau externe"
+
+msgid "NAT: outbound physical network connection only"
+msgstr "NAT: connexion physique au r��seau sortant uniquement"
+
+msgid "Bridged: Virtual machines are connected to physical network directly"
+msgstr ""
+"Bridg��: Les macines virtuelles sont connect��es directement au r��seau
physique"
+
+msgid "(No interfaces found)"
+msgstr "(Aucune interface trouv��e)"
+
+msgid "Destination"
+msgstr "Destination"
+
+msgid "Enable VLAN"
+msgstr "Activer le VLAN"
+
+msgid "VLAN ID"
+msgstr "ID de VLAN"
+
+msgid "Stop"
+msgstr "Arr��ter"
+
+msgid "Generate a New Debug Report"
+msgstr "G��n��rer un Nouveau Rapport de D��boggage"
+
+msgid "Report Name"
+msgstr "Nom du Rapport"
+
+msgid ""
+"The name used to identify the report. If omitted, a name will be chosen "
+"based on current time. Name can contain: letters, digits, underscore
(\"_\") "
+"and hyphen (\"-\")."
+msgstr ""
+"Le nom utilis�� pour identifier le rapport. Si omis, un nom sera choisi bas��
"
+"sur l'heure courante. Le nom peut contenir des lettres, des nombres, le "
+"soulignement (\"_\") et le tiret (\"-\")."
+
+msgid "Rename a Debug Report"
+msgstr "Renommer un Rapport de D��boggage"
+
+msgid ""
+"The name used to identify the report. Name can contain: letters, digits and "
+"hyphen (\"-\")."
+msgstr ""
+"Le nom utilis�� pour identifer le rapport. Le nom peut contenir des lettres,
"
+"nombres et tirets (\"-\")."
+
+msgid "Submit"
+msgstr "Soumettre"
+
+msgid "Add a Repository"
+msgstr "Ajouter un D��p��t"
+
+msgid "Identifier"
+msgstr "Identificateur"
+
+msgid "Single word, unique identifier for the repository."
+msgstr "Mot unique, identifiant unique pour le d��p��t."
+
+msgid "Textual name for the repository."
+msgstr "Nom textuel pour le d��p��t."
+
+msgid "URL"
+msgstr "URL"
+
+msgid "Required Field"
+msgstr "Champ requis"
+
+msgid "URL to the repository. Supported protocols are http, ftp, and file."
+msgstr "URL du d��p��t. Les protocoles support��s sont http, ftp et ficheir."
+
+msgid "Repository is a mirror"
+msgstr "Le d��p��t est un miroir"
+
+msgid "Distribution"
+msgstr "Distribution"
+
+msgid "Distribution of the DEB repository."
+msgstr "Distribution du d��p��t DEB."
+
+msgid "Components"
+msgstr "Composants"
+
+msgid "List of components in DEB repository."
+msgstr "Liste des composants dans le d��p��t DEB."
+
+msgid "Edit Repository"
+msgstr "Editer le D��p��t"
+
+msgid "Mirror List URL"
+msgstr "URL de Liste de Miroir"
+
+msgid "Yes"
+msgstr "Oui"
+
+msgid "No"
+msgstr "Non"
+
+msgid "Capacity"
+msgstr "Capacit��"
+
+msgid "Allocated"
+msgstr "Allou��"
+
+msgid "Location"
+msgstr "Emplacement"
+
+msgid "Device path"
+msgstr "Chemin du P��riph��rique"
+
+msgid "active"
+msgstr "actif"
+
+msgid "inactive"
+msgstr "inactif"
+
+msgid "Deactivate"
+msgstr "D��sactiver"
+
+msgid "Activate"
+msgstr "Activer"
+
+msgid "Add Volume"
+msgstr "Ajouter un Volume"
+
+msgid "Extend"
+msgstr "��tendre"
+
+msgid "Undefine"
+msgstr "Supprimer"
+
+msgid "Format"
+msgstr "Format"
+
+msgid "Allocation"
+msgstr "Allocation"
+
+msgid "Define a New Storage Pool"
+msgstr "D��finir un Nouveau Pool de Stockage"
+
+msgid "Storage Pool Name"
+msgstr "Nom de Pool de Stockage"
+
+msgid ""
+"The name used to identify the storage pools, and it should not be empty."
+msgstr ""
+"Le nom utilis�� pour identifier les pools de stockage, et il ne doit pas ��tre
"
+"vide."
+
+msgid "Storage Pool Type"
+msgstr "Type de Pool de Stockage"
+
+msgid "Storage Path"
+msgstr "Chemin de Stockage"
+
+msgid ""
+"The path of the Storage Pool. Each Storage Pool must have a unique path."
+msgstr ""
+"Le chemin du Pool de Stockage. Chaque Pool de Stockage doit avoir un chemin "
+"unique."
+
+msgid ""
+"Kimchi will try to create the directory when it does not already exist in "
+"your system."
+msgstr ""
+"Kimchi va essayer de cr��er un r��pertoire quand il n'existe pas d��j�� dans
"
+"votre syst��me."
+
+msgid "NFS Server IP"
+msgstr "IP du Serveur NFS"
+
+msgid "NFS server IP or hostname. It can be input or chosen from history."
+msgstr ""
+"IP du Serveur NFS ou nom d'h��te. Il peut ��tre saisi ou entr�� �� partir de
"
+"l'historique."
+
+msgid "NFS Path"
+msgstr "Chemin NFS"
+
+msgid "The NFS exported path on NFS server."
+msgstr "Le chemin NFS export�� sur le serveur NFS."
+
+msgid "iSCSI Server"
+msgstr "Serveur iSCSI"
+
+msgid "Server"
+msgstr "Serveur"
+
+msgid "Port"
+msgstr "Port"
+
+msgid "iSCSI server IP or hostname. It should not be empty."
+msgstr "IP du Serveur iSCSI ou nom d'h��te. Il ne devrait pas ��tre vide."
+
+msgid "Target"
+msgstr "Cible"
+
+msgid "The iSCSI target on iSCSI server"
+msgstr "La cible iSCSI sur le serveur iSCSI"
+
+msgid "Add iSCSI Authentication"
+msgstr "Ajouter l'Authentification iSCSI"
+
+msgid "iSCSI Authentication"
+msgstr "Authentification iSCSI"
+
+msgid "User Name"
+msgstr "Nom d'Utilisateur"
+
+msgid "Password"
+msgstr "Mot de Passe"
+
+msgid "SCSI Adapter"
+msgstr "Adaptateur SCSI"
+
+msgid "Please, wait..."
+msgstr "Veuillez patienter..."
+
+msgid "Add a Volume to Storage Pool"
+msgstr "iAjouter un Volume au Pool de Stockage"
+
+msgid "Fetch from remote URL"
+msgstr ""
+
+msgid "Enter the remote URL here."
+msgstr "Saisir une URL distante ici"
+
+msgid "Upload a file"
+msgstr "Charger un fichier"
+
+msgid "Choose the file you want to upload."
+msgstr ""
+
+msgid "Add Template"
+msgstr "Ajouter un Mod��le"
+
+msgid "Where is the source media for this template? "
+msgstr "O�� se trouve le media source pour le mod��le ?"
+
+msgid "Local ISO Image"
+msgstr "Image ISO Locale"
+
+msgid "Local Image File"
+msgstr "Fichier Image Local"
+
+msgid "Remote ISO Image"
+msgstr "Image ISO Distante"
+
+msgid "Search ISOs"
+msgstr "Rechercher des ISOs"
+
+msgid "The following ISOs are available:"
+msgstr "Les ISOs suivants sont disponibles:"
+
+msgid "OS: "
+msgstr "OS: "
+
+msgid "Version: "
+msgstr "Version: "
+
+msgid "Size: "
+msgstr "Taille: "
+
+msgid "Search more ISOs"
+msgstr "Chercher plus d'ISOs"
+
+msgid "Create Templates from Selected ISO"
+msgstr "Cr��er des mod��les depuis l'ISO s��lectionn��"
+
+msgid "I want to use a specific ISO file"
+msgstr "Je veux utiliser un fichier ISO sp��cifique"
+
+msgid "Loading default remote ISOs ..."
+msgstr "Chargement des ISOs distants par d��faut en cours..."
+
+msgid "Arch: "
+msgstr "Arch: "
+
+msgid "I want to use a custom URL"
+msgstr "Je veux utiliser une URL personnalis��e"
+
+msgid "Edit Template"
+msgstr "��diter un Mod��le"
+
+msgid "CDROM"
+msgstr "CDROM"
+
+msgid "Image File"
+msgstr "Fichier Image"
+
+msgid "Graphics"
+msgstr "Graphiques"
+
+msgid "Disk(GB)"
+msgstr ""
+
+msgid "Disk Format"
+msgstr ""
+
+msgid "CPU Number"
+msgstr "Nombre de CPU"
+
+msgid "Manually set CPU topology"
+msgstr ""
+
+msgid "Cores"
+msgstr ""
+
+msgid "Threads"
+msgstr ""
+
+msgid "No templates found."
+msgstr "Aucun mod��le trouv��."
+
+#~ msgid "Delete is not allowed for %(resource)s"
+#~ msgstr "La suppression n'est pas autoris��e pour %(resource)s"
+
+#~ msgid "%(resource)s does not implement update method"
+#~ msgstr "%(resource)s n'impl��mente pas de m��thode de mise �� jour"
+
+#~ msgid "Create is not allowed for %(resource)s"
+#~ msgstr "La cr��ation n'est pas autoris��e pour %(resource)s"
+
+#~ msgid "Unable to parse JSON request"
+#~ msgstr "Impossible de parser la requ��te JSON"
+
+#~ msgid "This API only supports JSON"
+#~ msgstr "Cette API supporte uniquement le JSON"
+
+#~ msgid "Parameters does not match requirement in schema: %(err)s"
+#~ msgstr ""
+#~ "Les param��tres ne correspondent pas �� ce qui est requis dans le sch��ma:
%"
+#~ "(err)s"
+
+#~ msgid "You don't have permission to perform this operation."
+#~ msgstr "Vous n'avez pas la permission d'effectuer cette
op��ration."
+
+#~ msgid "Datastore is not initiated in the model object."
+#~ msgstr "Le magasin de donn��es n'est pas initi�� dans l'objet
mod��le."
+
+#~ msgid "Unable to start task due error: %(err)s"
+#~ msgstr "Impossible de d��marrer la t��che �� cause de l'erreur:
%(err)s"
+
+#~ msgid ""
+#~ "Authentication failed for user '%(username)s'. [Error code:
%(code)s]"
+#~ msgstr ""
+#~ "L'authentification a ��chou�� pour l'utilisateur '%(username)s'.
[Code "
+#~ "d'Erreur: %(code)s]"
+
+#~ msgid "You are not authorized to access Kimchi"
+#~ msgstr "Vous n'��tes pas autoris�� �� acc��der �� Kimchi"
+
+#~ msgid "Specify %(item)s to login into Kimchi"
+#~ msgstr "Sp��cifiez %(item)s pour vous logguer dans Kimchi"
+
+#~ msgid "Unable to find %(item)s in datastore"
+#~ msgstr "Impossible de trouver %(item)s dans le magasin de donn��es"
+
+#~ msgid "Timeout while running command '%(cmd)s' after %(seconds)s
seconds"
+#~ msgstr ""
+#~ "Timeout durant l'ex��cution de la commande '%(cmd)s' apr��s
%(seconds)s "
+#~ "secondes"
+
+#~ msgid "Help"
+#~ msgstr "Aide"
+
+#~ msgid "About"
+#~ msgstr "A propos..."
+
+#~ msgid "Log out"
+#~ msgstr "Se d��connecter"
+
+#~ msgid "Version:"
+#~ msgstr "Version:"
+
+#~ msgid "Session timeout, please re-login."
+#~ msgstr "Session expir��e, veuillez vous reconnecter."
diff --git a/src/wok/plugins/kimchi/po/gen-pot.in b/src/wok/plugins/kimchi/po/gen-pot.in
new file mode 100644
index 0000000..0e3cd10
--- /dev/null
+++ b/src/wok/plugins/kimchi/po/gen-pot.in
@@ -0,0 +1,9 @@
+#!/bin/bash
+
+for src in $@; do
+ if [ ${src: -3} == ".py" ]; then
+ cat $src
+ else
+ cat $src | @CHEETAH@ compile -
+ fi
+done | xgettext --no-location -o kimchi.pot -L Python -
diff --git a/src/wok/plugins/kimchi/po/it_IT.po b/src/wok/plugins/kimchi/po/it_IT.po
new file mode 100644
index 0000000..257c306
--- /dev/null
+++ b/src/wok/plugins/kimchi/po/it_IT.po
@@ -0,0 +1,2274 @@
+# English translations for kimchi package.
+# Copyright (C) 2013 ORGANIZATION
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: kimchi 0.1\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2015-07-01 16:11-0300\n"
+"PO-Revision-Date: 2013-07-11 17:32-0400\n"
+"Last-Translator: Cr��stian Viana <vianac(a)linux.vnet.ibm.com>\n"
+"Language-Team: English\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Language: it_IT\n"
+"Generated-By: pygettext.py 1.5\n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+
+#, python-format
+msgid "Unknown parameter %(value)s"
+msgstr ""
+
+#, python-format
+msgid "Timeout of %(seconds)s seconds expired while running task
'%(task)s."
+msgstr ""
+
+#, python-format
+msgid "User %(user_id)s not found with given LDAP settings."
+msgstr ""
+
+msgid "Unknown \"_cap\" specified"
+msgstr ""
+
+msgid "\"_passthrough\" should be \"true\" or
\"false\""
+msgstr ""
+
+msgid "\"_passthrough_affected_by\" should be a device name string"
+msgstr ""
+
+#, python-format
+msgid "Error while getting block devices. Details: %(err)s"
+msgstr ""
+"Errore durante il richiamo dei dispositivi del blocco. Dettagli: %(err)s"
+
+#, python-format
+msgid "Error while getting block device information for %(device)s."
+msgstr ""
+"Errore durante il richiamo delle informazioni sul dispositivo del blocco per
"
+"%(device)s."
+
+#, python-format
+msgid "Unable to find distro file: %(filename)s"
+msgstr "Impossibile trovare il file distro: %(filename)s"
+
+#, python-format
+msgid ""
+"Unable to parse distro file: %(filename)s. Make sure, it is a JSON file."
+msgstr ""
+"Impossibile analizzare il file distro: %(filename)s. Verificare che sia un "
+"file JSON."
+
+#, python-format
+msgid "Unable to login to iSCSI host target %(portal)s. Details: %(err)s"
+msgstr ""
+"Impossibile accedere a %(portal)s di destinazione host iSCSI. Dettagli: %"
+"(err)s"
+
+#, python-format
+msgid "Unable to login to iSCSI host %(host)s target %(target)s"
+msgstr "Impossibile accedere alla destinazione %(target)s host %(host)s iSCSI"
+
+#, python-format
+msgid "Unable to find ISO file %(filename)s"
+msgstr ""
+
+#, python-format
+msgid "The ISO file %(filename)s is not bootable"
+msgstr "Il file ISO %(filename)s non �� avviabile"
+
+#, python-format
+msgid "The ISO file %(filename)s does not have a valid El Torito boot record"
+msgstr "Il file ISO %(filename)s non ha un record di avvio El Torito valido"
+
+#, python-format
+msgid "Invalid El Torito validation entry in ISO %(filename)s"
+msgstr "Voce di convalida El Torito non valida in ISO %(filename)s"
+
+#, python-format
+msgid "Invalid El Torito boot indicator in ISO %(filename)s"
+msgstr "Indicatore di avvio El Torito non valido in ISO %(filename)s"
+
+#, python-format
+msgid "Unexpected volume type for primary volume in ISO %(filename)s"
+msgstr "Tipo di volume imprevisto per il volume primario in ISO %(filename)s"
+
+#, python-format
+msgid "Bad format while reading volume descriptor in ISO %(filename)s"
+msgstr ""
+"Formato non corretto durante la lettura del descrittore volume in ISO %"
+"(filename)s"
+
+#, python-format
+msgid ""
+"The hypervisor doesn't have permission to use this ISO %(filename)s. "
+"Consider moving it under /var/lib/libvirt, or set the search permission to "
+"file access control lists for '%(user)s' user if possible, or add the
'%"
+"(user)s' to the ISO path group, or (not recommended) 'chmod -R o+x "
+"'path_to_iso'.Details: %(err)s"
+msgstr ""
+"L'hypervisor non dispone dell'autorizzazione per utilizzare questo ISO
%"
+"(filename)s. Spostarlo in /var/lib/libvirt o impostare l'autorizzazione di
"
+"ricerca per gli elenchi di controllo accesso ai file per l'utente
'%(user)"
+"s', se possibile, o aggiungere '%(user)s' al gruppo percorso ISO o
(non "
+"consigliato) 'chmod -R o+x 'path_to_iso'. Dettagli: %(err)s"
+
+msgid "An error occurred when probing image OS information."
+msgstr ""
+
+msgid "No OS information found in given image."
+msgstr ""
+
+#, python-format
+msgid "Unable to read image file %(filename)s"
+msgstr ""
+
+#, python-format
+msgid ""
+"Image file must be an existing file on system. %(filename)s is not a valid "
+"input."
+msgstr ""
+
+#, python-format
+msgid "Virtual machine %(name)s already exists"
+msgstr "Macchina virtuale %(name)s gi�� esistente"
+
+#, python-format
+msgid "Virtual machine %(name)s does not exist"
+msgstr "La macchina virtuale %(name)s non esiste"
+
+#, python-format
+msgid ""
+"Unable to rename virtual machine %(name)s. The name %(new_name)s is already "
+"in use or the virtual machine is not powered off."
+msgstr ""
+
+#, python-format
+msgid "Unable to retrieve screenshot for stopped virtual machine %(name)s"
+msgstr ""
+"Impossibile richiamare l'immagine per la macchina virtuale arrestata
%(name)s"
+
+msgid "Remote ISO image is not supported by this server."
+msgstr "L'immagine ISO remota non �� supportata da questo server."
+
+#, python-format
+msgid "Screenshot is not supported on virtual machine %(name)s"
+msgstr ""
+
+#, python-format
+msgid "Unable to create virtual machine %(name)s. Details: %(err)s"
+msgstr "Impossibile creare la macchina virtuale %(name)s. Dettagli: %(err)s"
+
+#, python-format
+msgid "Unable to update virtual machine %(name)s. Details: %(err)s"
+msgstr "Impossibile creare la macchina virtuale %(name)s. Dettagli: %(err)s"
+
+#, python-format
+msgid "Unable to retrieve virtual machine %(name)s. Details: %(err)s"
+msgstr ""
+"Impossibile richiamare la macchina virtuale %(name)s. Dettagli: %(err)s"
+
+#, python-format
+msgid "Unable to connect to powered off virtual machine %(name)s."
+msgstr ""
+
+msgid "Virtual machine name must be a string without slashes (/)"
+msgstr ""
+
+#, python-format
+msgid "Invalid template URI %(value)s specified for virtual machine"
+msgstr ""
+
+#, python-format
+msgid "Invalid storage pool URI %(value)s specified for virtual machine"
+msgstr ""
+
+msgid "Supported virtual machine graphics are Spice or VNC"
+msgstr ""
+
+msgid "Graphics address to listen on must be IPv4 or IPv6"
+msgstr ""
+"L'indirizzo dei grafici su cui rimanere in ascolto deve essere IPv4 o
IPv6"
+
+msgid "Specify a template to create a virtual machine from"
+msgstr "Specificare un modello da cui creare una macchina virtuale"
+
+#, python-format
+msgid "Unable to start virtual machine %(name)s. Details: %(err)s"
+msgstr "Impossibile avviare la macchina virtuale %(name)s. Dettagli: %(err)s"
+
+#, python-format
+msgid "Unable to power off virtual machine %(name)s. Details: %(err)s"
+msgstr "Impossibile arrestare la macchina virtuale %(name)s. Dettagli:
%(err)s"
+
+#, python-format
+msgid "Unable to delete virtual machine %(name)s. Details: %(err)s"
+msgstr "Impossibile eliminare la macchina virtuale %(name)s. Dettagli:
%(err)s"
+
+#, python-format
+msgid "Unable to reset virtual machine %(name)s. Details: %(err)s"
+msgstr ""
+"Impossibile ridenominare la macchina virtuale %(name)s. Dettagli: %(err)s"
+
+msgid "User name list must be an array"
+msgstr ""
+
+msgid "User name must be a string"
+msgstr "Il nome della rete deve essere una stringa"
+
+msgid "Group name list must be an array"
+msgstr ""
+
+msgid "Group name must be a string"
+msgstr "Il nome della rete deve essere una stringa"
+
+#, python-format
+msgid "User(s) '%(users)s' do not exist"
+msgstr "L'utente '%(users)s' non esiste."
+
+#, python-format
+msgid "Group(s) '%(groups)s' do not exist"
+msgstr "L'utente '%(groups)s' non esiste."
+
+#, python-format
+msgid "Unable to shutdown virtual machine %(name)s. Details: %(err)s"
+msgstr "Impossibile arrestare la macchina virtuale %(name)s. Dettagli:
%(err)s"
+
+#, python-format
+msgid ""
+"Unable to get access metadata of virtual machine %(name)s. Details: %(err)s"
+msgstr "Impossibile avviare la macchina virtuale %(name)s. Dettagli: %(err)s"
+
+msgid "The guest console password must be a string."
+msgstr ""
+
+msgid "The life time for the guest console password must be a number."
+msgstr ""
+
+#, python-format
+msgid "Virtual machine '%(name)s' must be stopped before cloning it."
+msgstr ""
+
+#, python-format
+msgid "Insufficient disk space to clone virtual machine '%(name)s'"
+msgstr ""
+
+#, python-format
+msgid "Unable to clone VM '%(name)s'. Details: %(err)s"
+msgstr ""
+
+#, python-format
+msgid "Invalid operation for non-persistent virtual machine %(name)s"
+msgstr ""
+
+#, python-format
+msgid "Cannot suspend VM '%(name)s' because it is not running."
+msgstr ""
+
+#, python-format
+msgid "Unable to suspend VM '%(name)s'. Details: %(err)s"
+msgstr ""
+
+#, python-format
+msgid "Cannot resume VM '%(name)s' because it is not paused."
+msgstr ""
+
+#, python-format
+msgid "Unable to resume VM '%(name)s'. Details: %(err)s"
+msgstr ""
+
+msgid "Memory assigned is higher then the maximum allowed in the host."
+msgstr ""
+
+#, python-format
+msgid ""
+"VM '%(name)s' does not support live memory update. Update the memory with
"
+"the machine offline to enable this feature."
+msgstr ""
+
+msgid "Only increase memory is allowed in active VMs"
+msgstr ""
+
+msgid ""
+"For live memory update, new memory value must be equal old memory value plus
"
+"multiples of 1024 Mib"
+msgstr ""
+
+msgid "There are not enough free slots of 1024 Mib in the guest."
+msgstr ""
+
+msgid ""
+"Host's libvirt version does not support memory devices. Libvirt must be >=
"
+"1.2.14"
+msgstr ""
+
+#, python-format
+msgid "Error attaching memory device. Details: %(error)s"
+msgstr ""
+
+#, python-format
+msgid ""
+"VM %(vmid)s does not contain directly assigned host device %(dev_name)s."
+msgstr ""
+
+#, python-format
+msgid "The host device %(dev_name)s is not allowed to directly assign to VM."
+msgstr ""
+
+msgid ""
+"No IOMMU groups found. Host PCI pass through needs IOMMU group to function "
+"correctly. Please enable Intel VT-d or AMD IOMMU in your BIOS, then verify "
+"the Kernel is compiled with IOMMU support. For Intel CPU, add intel_iommu=on
"
+"to your Kernel parameter in /boot/grub2/grub.conf. For AMD CPU, add iommu=pt
"
+"iommu=1."
+msgstr ""
+
+msgid "\"name\" should be a device name string"
+msgstr ""
+
+#, python-format
+msgid ""
+"The device %(name)s is probably in use by the host. Unable to attach it to "
+"the guest."
+msgstr ""
+
+#, python-format
+msgid "Interface %(iface)s does not exist in virtual machine %(name)s"
+msgstr "L'interfaccia %(iface)s non esiste nella macchina virtuale
%(name)s"
+
+#, python-format
+msgid ""
+"Network %(network)s specified for virtual machine %(name)s does not exist"
+msgstr ""
+"La rete %(network)s specificata per la macchina virtuale %(name)s non esiste"
+
+msgid "Supported virtual machine interfaces type is only network"
+msgstr ""
+"Il tipo supportato per le interfacce della macchina virtuale �� solo rete"
+
+msgid "Network name for virtual machine interface must be a string"
+msgstr ""
+"Il nome di rete per l'interfaccia della macchina virtuale deve essere una
"
+"stringa"
+
+msgid "Invalid network model card specified for virtual machine interface"
+msgstr ""
+"Scheda modello di rete non valida per l'interfaccia della macchina
virtuale"
+
+msgid "Specify type and network to add a new virtual machine interface"
+msgstr ""
+"Specificare il tipo e la rete per aggiungere una nuova interfaccia della "
+"macchina virtuale"
+
+msgid "MAC Address must respect this format FF:FF:FF:FF:FF:FF"
+msgstr ""
+
+#, python-format
+msgid "MAC Address %(mac)s already exists in virtual machine %(name)s"
+msgstr ""
+
+msgid "Invalid MAC Address"
+msgstr ""
+
+msgid "Cannot change MAC address of a running virtual machine"
+msgstr ""
+
+#, python-format
+msgid "Template %(name)s already exists"
+msgstr "Modello %(name)s gi�� esistente"
+
+#, python-format
+msgid ""
+"Network '%(network)s' specified for template %(template)s does not
exist"
+msgstr ""
+"La rete '%(network)s' specificata per il modello %(template)s non
esiste"
+
+#, python-format
+msgid ""
+"Storage pool %(pool)s specified for template %(template)s does not exist"
+msgstr ""
+"Il pool di memoria %(pool)s specificato per il modello %(template)s non "
+"esiste"
+
+#, python-format
+msgid "Storage pool %(pool)s specified for template %(template)s is not
active"
+msgstr ""
+"Il pool di memoria %(pool)s specificato per il modello %(template)s non �� "
+"attivo"
+
+#, python-format
+msgid "Invalid parameter '%(param)s' specified for CDROM."
+msgstr "Parametro non valido %(param)s' specificato per CDROM."
+
+#, python-format
+msgid "Network %(network)s specified for template %(template)s is not active"
+msgstr ""
+"La rete %(network)s specificata per il modello %(template)s non �� attiva"
+
+msgid "Template name must be a string"
+msgstr "Il nome del modello deve essere una stringa"
+
+msgid "Template icon must be a path to the image"
+msgstr "L'icona del modello deve essere un percorso all'immagine"
+
+msgid "Template distribution must be a string"
+msgstr "La distribuzione del modello deve essere una stringa"
+
+msgid "Template distribution version must be a string"
+msgstr "La versione della distribuzione del modello deve essere una stringa"
+
+msgid "The number of CPUs must be an integer greater than 0"
+msgstr "Il numero di CPU deve essere un numero intero"
+
+msgid "Amount of memory (MB) must be an integer greater than 512"
+msgstr ""
+"La quantit�� di memoria (MB) deve essere un numero intero maggiore di 512"
+
+msgid "Template CDROM must be a local or remote ISO file"
+msgstr "Il CDROM del modello deve essere un file ISO locale o remoto"
+
+#, python-format
+msgid "Invalid storage pool URI %(value)s specified for template"
+msgstr "URI pool di memoria non valido: %(value)s specificato per il modello"
+
+msgid "Specify an ISO image as CDROM or a base image to create a template"
+msgstr "Specificare un'immagine ISO come CDROM per creare un modello"
+
+msgid "All networks for the template must be specified in a list."
+msgstr "Tutte le reti per il modello devono essere specificate in un elenco."
+
+msgid "Specify a volume to a template when storage pool is iSCSI or SCSI"
+msgstr ""
+
+#, python-format
+msgid "The volume %(volume)s is not in storage pool %(pool)s"
+msgstr ""
+
+#, python-format
+msgid "Unable to create template due error: %(err)s"
+msgstr "Impossibile creare il modello a causa dell'errore: %(err)s"
+
+#, python-format
+msgid "Unable to delete template due error: %(err)s"
+msgstr "Impossibile eliminare il modello a causa dell'errore: %(err)s"
+
+msgid "Disk size must be an integer greater than 1GB."
+msgstr ""
+
+msgid "Template base image must be a valid local image file"
+msgstr "Il CDROM del modello deve essere un file ISO locale o remoto"
+
+#, python-format
+msgid "Cannot identify base image %(path)s format"
+msgstr ""
+
+msgid ""
+"When specifying CPU topology, VCPUs must be a product of sockets, cores, and
"
+"threads."
+msgstr ""
+
+msgid ""
+"When specifying CPU topology, each element must be an integer greater than "
+"zero."
+msgstr ""
+
+msgid ""
+"Invalid disk image format. Valid formats: bochs, cloop, cow, dmg, qcow, "
+"qcow2, qed, raw, vmdk, vpc."
+msgstr ""
+
+#, python-format
+msgid "Storage pool %(name)s already exists"
+msgstr "Pool di memoria %(name)s gi�� esistente"
+
+#, python-format
+msgid "Storage pool %(name)s does not exist"
+msgstr "Il pool di memoria %(name)s non esiste"
+
+#, python-format
+msgid "Specify %(item)s in order to create the storage pool %(name)s"
+msgstr "Specificare %(item)s per poter creare il pool di memoria %(name)s"
+
+#, python-format
+msgid "Unable to delete active storage pool %(name)s"
+msgstr "Impossibile eliminare il pool di memoria attivo %(name)s"
+
+#, python-format
+msgid "Unable to list storage pools. Details: %(err)s"
+msgstr "Impossibile elencare i pool di memoria. Dettagli: %(err)s"
+
+#, python-format
+msgid "Unable to create storage pool %(name)s. Details: %(err)s"
+msgstr "Impossibile creare il pool di memoria %(name)s. Dettagli: %(err)s"
+
+#, python-format
+msgid ""
+"Unable to get number of storage volumes in storage pool %(name)s. Details: %"
+"(err)s"
+msgstr ""
+"Impossibile ottenere il numero di volumi di memoria nel pool di memoria %"
+"(name)s. Dettagli: %(err)s"
+
+#, python-format
+msgid "Unable to activate storage pool %(name)s. Details: %(err)s"
+msgstr "Impossibile attivare il pool di memoria %(name)s. Dettagli: %(err)s"
+
+#, python-format
+msgid "Unable to deactivate storage pool %(name)s. Details: %(err)s"
+msgstr "Impossibile disattivare il pool di memoria %(name)s. Dettagli:
%(err)s"
+
+#, python-format
+msgid "Unable to delete storage pool %(name)s. Details: %(err)s"
+msgstr "Impossibile eliminare il pool di memoria %(name)s. Dettagli: %(err)s"
+
+#, python-format
+msgid ""
+"Unable to create NFS Pool as export path %(path)s may block during mount"
+msgstr ""
+"Impossibile creare il pool NFS poich�� il percorso di esportazione %(path)s "
+"potrebbe bloccarsi durante il montaggio"
+
+#, python-format
+msgid "Unable to create NFS Pool as export path %(path)s mount failed"
+msgstr ""
+"Impossibile creare il pool NFS poich�� il montaggio del percorso di "
+"esportazione %(path)s ha avuto esito negativo"
+
+#, python-format
+msgid "Unsupported storage pool type: %(type)s"
+msgstr "Tipo di pool di memoria non supportato: %(type)s"
+
+#, python-format
+msgid "Error while retrieving storage pool XML to %(pool)s"
+msgstr ""
+
+msgid "Storage pool name must be a string without slashes (/)"
+msgstr ""
+
+msgid ""
+"Supported storage pool types are dir, netfs, logical, iscsi, isci and
kimchi-"
+"iso"
+msgstr ""
+
+msgid "Storage pool path must be a string"
+msgstr "Il percorso del pool di memoria deve essere una stringa"
+
+msgid "Storage pool host must be a IP or hostname"
+msgstr "L'host del pool di memoria deve essere un nome host o IP"
+
+msgid "Storage pool device must be the absolute path to the block device"
+msgstr ""
+
+msgid "Storage pool devices parameter must be a list"
+msgstr "Il parametro dispositivi pool di memoria deve essere un elenco"
+
+msgid "Target IQN of an iSCSI pool must be a string"
+msgstr "L'IQN di destinazione di un pool iSCSI deve essere una stringa"
+
+msgid "Port of a remote storage server must be an integer between 1 and 65535"
+msgstr ""
+"La porta di un server di memoria remoto deve essere un numero intero tra 1 e
"
+"65535"
+
+msgid "iSCSI target username must be a string"
+msgstr ""
+
+msgid "iSCSI target password must be a string"
+msgstr ""
+
+msgid "Specify name and type to create a storage pool"
+msgstr "Specificare nome e tipo per creare un pool di memoria"
+
+#, python-format
+msgid ""
+"%(disk)s is not a valid disk/partition. Could not add it to the pool %(pool)"
+"s."
+msgstr ""
+"%(disk)s non �� un disco/partizione valido. Impossibile aggiungerlo al pool
%"
+"(pool)s."
+
+#, python-format
+msgid "Unable to extend logical pool %(pool)s. Details: %(err)s"
+msgstr ""
+
+msgid "The parameter disks only can be updated for logical storage pool."
+msgstr ""
+"Solo il parametro dischi pu�� essere aggiornato per il pool di memoria
logico."
+
+msgid "The SCSI host adapter name must be a string."
+msgstr "Il nome adattatore host SCSI deve essere una stringa."
+
+msgid "The storage pool kimchi_isos is reserved for internal use"
+msgstr "Il pool di memoria kimchi_isos �� riservato per uso interno"
+
+#, python-format
+msgid ""
+"Unable to activate NFS storage pool %(name)s. NFS server %(server)s is "
+"unreachable."
+msgstr ""
+"Impossibile attivare il pool di memoria NFS %(name)s. Il server NFS
%(server)"
+"s �� irraggiungibile."
+
+#, python-format
+msgid ""
+"Unable to deactivate NFS storage pool %(name)s. NFS server %(server)s is "
+"unreachable."
+msgstr ""
+"Impossibile disattivare il pool di memoria NFS %(name)s. Il server NFS %"
+"(server)s �� irraggiungibile."
+
+#, python-format
+msgid ""
+"Unable to deactivate pool %(name)s as it is associated with some templates"
+msgstr ""
+"Impossibile disattivare il pool %(name)s poich�� �� associato ad alcuni
modelli"
+
+#, python-format
+msgid "Unable to delete pool %(name)s as it is associated with some templates"
+msgstr ""
+"Impossibile eliminare il pool %(name)s poich�� �� associato ad alcuni
modelli"
+
+#, python-format
+msgid ""
+"A volume group named '%(name)s' already exists. Please, choose another name
"
+"to create the logical pool."
+msgstr ""
+"Un gruppo di volumi denominato '%(name)s' esiste gi��. Scegliere un altro
"
+"nome per creare il pool logico."
+
+#, python-format
+msgid "Unable to update database with deep scan information due error:
%(err)s"
+msgstr ""
+"Impossibile aggiornare il database con informazioni approfondite sulla "
+"scansione a causa dell'errore: %(err)s"
+
+#, python-format
+msgid "Storage volume %(name)s already exists"
+msgstr "Volume di memoria %(name)s gi�� esistente"
+
+#, python-format
+msgid "Storage volume %(name)s does not exist in storage pool %(pool)s"
+msgstr "Il volume di memoria %(name)s non esiste nel pool di memoria %(pool)s"
+
+#, python-format
+msgid ""
+"Unable to create storage volume %(volume)s because storage pool %(pool)s is "
+"not active"
+msgstr ""
+
+#, python-format
+msgid "Specify %(item)s in order to create storage volume %(volume)s"
+msgstr "Specificare %(item)s per poter creare il volume di memoria %(volume)s"
+
+#, python-format
+msgid ""
+"Unable to list storage volumes because storage pool %(pool)s is not active"
+msgstr ""
+"Impossibile elencare i volumi di memoria poich�� il pool di memoria %(pool)s
"
+"non �� attivo"
+
+#, python-format
+msgid ""
+"Unable to create storage volume %(name)s in storage pool %(pool)s. Details:
%"
+"(err)s"
+msgstr ""
+"Impossibile creare il volume di memoria %(name)s nel pool di memoria %(pool)"
+"s. Dettagli: %(err)s"
+
+#, python-format
+msgid ""
+"Unable to list storage volumes in storage pool %(pool)s. Details: %(err)s"
+msgstr ""
+"Impossibile elencare i volumi di memoria nel pool di memoria %(pool)s. "
+"Dettagli: %(err)s"
+
+#, python-format
+msgid "Unable to wipe storage volumes %(name)s. Details: %(err)s"
+msgstr "Impossibile ripulire i volumi di memoria %(name)s. Dettagli: %(err)s"
+
+#, python-format
+msgid "Unable to delete storage volume %(name)s. Details: %(err)s"
+msgstr "Impossibile eliminare il volume di memoria %(name)s. Dettagli:
%(err)s"
+
+#, python-format
+msgid "Unable to resize storage volume %(name)s. Details: %(err)s"
+msgstr ""
+"Impossibile ridimensionare il volume di memoria %(name)s. Dettagli: %(err)s"
+
+#, python-format
+msgid "Storage type %(type)s does not support volume create and delete"
+msgstr ""
+"Il tipo di memoria %(type)s non supporta la creazione ed eliminazione del "
+"volume"
+
+msgid "Storage volume name must be a string"
+msgstr "Il nome del volume di memoria deve essere una stringa"
+
+msgid "Storage volume allocation must be an integer number"
+msgstr "L'assegnazione del volume di memoria deve essere un numero intero"
+
+msgid ""
+"Storage volume format not supported. Valid formats: bochs, cloop, cow, dmg, "
+"qcow, qcow2, qed, raw, vmdk, vpc."
+msgstr ""
+
+msgid "Storage volume requires a volume name"
+msgstr "Il volume di memoria richiede un nome volume"
+
+#, python-format
+msgid ""
+"Unable to update database with storage volume information due error: %(err)s"
+msgstr ""
+"Impossibile aggiornare il database con informazioni sul volume di memoria a "
+"causa dell'errore: %(err)s"
+
+#, python-format
+msgid "Only one of parameter %(param)s can be specified"
+msgstr ""
+
+#, python-format
+msgid "Create volume from %(param)s is not supported"
+msgstr ""
+
+msgid "Storage volume capacity must be an integer number."
+msgstr ""
+
+msgid "Storage volume URL must be http://, https://, ftp:// or ftps://."
+msgstr ""
+
+#, python-format
+msgid "Unable to access file %(url)s. Please, check it."
+msgstr ""
+
+#, python-format
+msgid ""
+"Unable to clone storage volume '%(name)s' in pool '%(pool)s'.
Details: %(err)"
+"s"
+msgstr ""
+
+msgid "Specify chunk data and its size to upload a file."
+msgstr ""
+
+msgid "In order to upload a storage volume, specify the 'upload'
parameter."
+msgstr ""
+
+msgid ""
+"Unable to upload chunk data as it does not match with requested chunk size."
+msgstr ""
+
+#, python-format
+msgid "The storage volume %(vol)s is not under an upload process."
+msgstr ""
+
+msgid "The upload chunk data will exceed the storage volume size."
+msgstr ""
+
+#, python-format
+msgid "Unable to upload chunk data to storage volume. Details: %(err)s."
+msgstr ""
+
+#, python-format
+msgid "Interface %(name)s does not exist"
+msgstr "L'interfaccia %(name)s non esiste"
+
+#, python-format
+msgid "Network %(name)s already exists"
+msgstr "Rete %(name)s gi�� esistente"
+
+#, python-format
+msgid "Network %(name)s does not exist"
+msgstr "La rete %(name)s non esiste"
+
+#, python-format
+msgid "Subnet %(subnet)s specified for network %(network)s is not valid."
+msgstr ""
+"La sottorete %(subnet)s specificata per la rete %(network)s non �� valida ."
+
+#, python-format
+msgid "Specify a network interface to create bridged network %(name)s"
+msgstr ""
+"Specificare un'interfaccia di rete per creare la rete con bridge
%(name)s"
+
+#, python-format
+msgid "Unable to delete active network %(name)s"
+msgstr "Impossibile eliminare la rete attiva %(name)s"
+
+#, python-format
+msgid "Interface %(iface)s specified for network %(network)s is already in
use"
+msgstr ""
+"L'interfaccia %(iface)s specificata per la rete %(network)s �� gi�� in
uso"
+
+msgid "Interface should be bare NIC, bonding or bridge device."
+msgstr ""
+"L'interfaccia deve essere un dispositivo bridge o di collegamento NIC
bare-"
+"metal."
+
+#, python-format
+msgid "Unable to create network %(name)s. Details: %(err)s"
+msgstr "Impossibile creare la rete %(name)s. Dettagli: %(err)s"
+
+#, python-format
+msgid "Unable to find a free IP address for network '%(name)s'"
+msgstr "Impossibile trovare un indirizzo IP libero per la rete
'%(name)s'"
+
+#, python-format
+msgid "The interface %(iface)s already exists."
+msgstr "L'interfaccia %(iface)s gi�� esistente."
+
+msgid "Network name must be a string without slashes (/) or quotes (\")"
+msgstr ""
+
+msgid "Supported network types are isolated, NAT and bridge"
+msgstr "I tipi di rete supportati sono isolata, NAT e bridge"
+
+msgid "Network subnet must be a string with IP address and prefix or netmask"
+msgstr ""
+"La sottorete della rete deve essere una stringa con indirizzo IP e prefisso "
+"o maschera di rete"
+
+msgid "Network interface must be a string"
+msgstr "L'interfaccia di rete deve essere una stringa"
+
+msgid "Network VLAN ID must be an integer between 1 and 4094"
+msgstr "L'ID VLAN di rete deve essere un numero intero tra 1 e 4094"
+
+msgid "Specify name and type to create a Network"
+msgstr "Specificare nome e tipo per creare una rete"
+
+#, python-format
+msgid ""
+"Unable to delete network %(name)s. There are some virtual machines %(vms)s "
+"and/or templates linked to this network."
+msgstr ""
+"Impossibile eliminare la rete %(name)s. Ci sono alcune macchine virtuali %"
+"(vms)s e/o modelli collegati a tale rete."
+
+#, python-format
+msgid ""
+"Unable to deactivate network %(name)s. There are some virtual machines
%(vms)"
+"s and/or templates linked to this network."
+msgstr ""
+"Impossibile disattivare la rete %(name)s. Ci sono alcune macchine virtualie
%"
+"(vms)s e/o modelli collegati a tale rete."
+
+#, python-format
+msgid "Bridge device %(name)s can not be the trunk device of a VLAN."
+msgstr ""
+"Il dispositivo bridge %(name)s non pu�� essere il dispositivo trunk di una "
+"VLAN."
+
+#, python-format
+msgid "Failed to activate interface %(iface)s: %(err)s."
+msgstr "Impossibile attivare l'interfaccia %(iface)s: %(err)s."
+
+#, python-format
+msgid ""
+"Failed to activate interface %(iface)s. Please check the physical link "
+"status."
+msgstr ""
+"Impossibile attivare l'interfaccia %(iface)s. Controllare lo stato del link
"
+"fisico."
+
+#, python-format
+msgid "Failed to start network %(name)s. Details: %(err)s"
+msgstr ""
+
+#, python-format
+msgid "Debug report %(name)s does not exist"
+msgstr "Il report di debug %(name)s non esiste"
+
+msgid "Debug report tool not found in system"
+msgstr "Strumento report di debug non trovato nel sistema"
+
+#, python-format
+msgid "Unable to create debug report %(name)s. Details: %(err)s."
+msgstr "Impossibile creare il report di debug %(name)s. Dettagli: %(err)s."
+
+#, python-format
+msgid "Can not find any debug report with the given name %(name)s"
+msgstr ""
+
+#, python-format
+msgid "Unable to generate debug report %(name)s. Details: %(err)s"
+msgstr "Impossibile generare il report di debug %(name)s. Dettagli: %(err)s"
+
+msgid "You should give a name for the debug report file."
+msgstr ""
+
+msgid ""
+"Debug report name must be a string. Only letters, digits, underscore ('_')
"
+"and hyphen ('-') are allowed."
+msgstr ""
+
+#, python-format
+msgid ""
+"The debug report with specified name \"%(name)s\" already exists. Please
use "
+"another one."
+msgstr ""
+"Un gruppo di volumi denominato '%(name)s' esiste gi��. Scegliere un altro
"
+"nome per creare il pool logico."
+
+#, python-format
+msgid "Storage server %(server)s was not used by Kimchi"
+msgstr "Il server di memoria %(server)s non �� stato utilizzato da Kimchi"
+
+#, python-format
+msgid "Distro '%(name)s' does not exist"
+msgstr "Distro '%(name)s' non esistente"
+
+#, python-format
+msgid "Partition %(name)s does not exist in the host"
+msgstr "La partizione %(name)s non esiste nell'host"
+
+msgid "Unable to shutdown host machine as there are running virtual machines"
+msgstr ""
+"Impossibile arrestare la macchina host poich�� sono presenti macchine "
+"virtuali in esecuzione"
+
+msgid "Unable to reboot host machine as there are running virtual machines"
+msgstr ""
+"Impossibile riavviare la macchina host poich�� sono presenti macchine "
+"virtuali in esecuzione"
+
+#, python-format
+msgid "Node device '%(name)s' not found"
+msgstr "Dispositivo nodo '%(name)s' non trovato"
+
+msgid "Conflicting flag filters specified."
+msgstr ""
+
+msgid "No packages marked for update"
+msgstr "Nessun pacchetto contrassegnato per l'aggiornamento"
+
+#, python-format
+msgid "Package %(name)s is not marked to be updated."
+msgstr "Il pacchetto %(name)s non �� contrassegnato per l'aggiornamento."
+
+#, python-format
+msgid "Error while getting packages marked to be updated. Details: %(err)s"
+msgstr ""
+"Errore durante il richiamo dei pacchetti contrassegnati per l'aggiornamento.
"
+"Dettagli: %(err)s"
+
+msgid "There is no compatible package manager for this system."
+msgstr "Non �� presente un gestore pacchetti compatibile per questo sistema."
+
+#, python-format
+msgid "Invalid URI %(uri)s"
+msgstr "URI %(uri)s non valido"
+
+msgid "Unable to choose a virtual machine name"
+msgstr ""
+
+msgid "Invalid storage type. Types supported: 'cdrom', 'disk'"
+msgstr "Tipo di memoria non valido. I tipi supportati sono: 'cdrom'"
+
+#, python-format
+msgid "The path '%(value)s' is not a valid local/remote path for the
device"
+msgstr ""
+
+msgid "Only CDROM path can be update."
+msgstr ""
+
+#, python-format
+msgid ""
+"The storage device %(dev_name)s does not exist in the virtual machine %"
+"(vm_name)s"
+msgstr ""
+
+#, python-format
+msgid "Error while creating new storage device: %(error)s"
+msgstr ""
+"Errore durante la creazione del nuovo dispositivo di memoria: %(error)s"
+
+#, python-format
+msgid "Error while updating storage device: %(error)s"
+msgstr "Errore durante l'aggiornamento del dispositivo di memoria:
%(error)s"
+
+#, python-format
+msgid "Error while removing storage device: %(error)s"
+msgstr "Errore durante la rimozione del dispositivo di memoria: %(error)s"
+
+msgid "Do not support IDE device hot plug"
+msgstr ""
+
+msgid ""
+"Specify type and path or type and pool/volume to add a new virtual machine "
+"disk"
+msgstr ""
+"Specificare tipo e percorso per aggiungere un nuovo disco della macchina "
+"virtuale"
+
+msgid "Specify path to update virtual machine disk"
+msgstr ""
+"Specificare il percorso per aggiornare il disco della macchina virtuale"
+
+#, python-format
+msgid "Controller type %(type)s limitation of %(limit)s devices reached"
+msgstr ""
+
+#, python-format
+msgid "Cannot retrieve disk path information for given pool/volume: %(error)s"
+msgstr ""
+
+msgid "Volume already in use by other virtual machine."
+msgstr ""
+
+msgid ""
+"Only one of path or pool/volume can be specified to add a new virtual "
+"machine disk"
+msgstr ""
+"Specificare tipo e percorso per aggiungere un nuovo disco della macchina "
+"virtuale"
+
+#, python-format
+msgid ""
+"Volume chosen with format %(format)s does not fit in the storage type
%(type)"
+"s"
+msgstr ""
+
+msgid "YUM Repository ID must be one word only string."
+msgstr "L'ID repository YUM deve essere una stringa di una sola parola."
+
+msgid "Repository URL must be an http://, ftp:// or file:// URL."
+msgstr "L'URL del repository deve essere http://, ftp:// o file:// URL."
+
+msgid ""
+"Repository configuration is a dictionary with specific values according to "
+"repository type."
+msgstr ""
+"La configurazione del repository �� un dizionario con valori specifici in "
+"base al tipo di repository."
+
+msgid "Distribution to DEB repository must be a string"
+msgstr "La distribuzione al repository DEB deve essere una stringa"
+
+msgid "Components to DEB repository must be listed in a array"
+msgstr "I componenti per il repository DEB devono essere elencati in un array"
+
+msgid "Components to DEB repository must be a string"
+msgstr "I componenti per il repository DEB devono essere una stringa"
+
+msgid "Mirror list to repository must be a string"
+msgstr ""
+
+msgid "YUM Repository name must be string."
+msgstr "Il nome del repository YUM deve essere una stringa."
+
+msgid "GPG check must be a boolean value."
+msgstr "Il controllo GPG deve essere un valore booleano."
+
+msgid "GPG key must be a URL pointing to the ASCII-armored file."
+msgstr "La chiave GPG deve essere un URL che punta al file blindato ASCII."
+
+#, python-format
+msgid "Could not update repository %(repo_id)s."
+msgstr "Impossibile aggiornare il repository %(repo_id)s."
+
+#, python-format
+msgid "Repository %(repo_id)s does not exist."
+msgstr "Il repository %(repo_id)s non esiste."
+
+msgid ""
+"Specify repository base URL, mirror list or metalink in order to create or "
+"update a YUM repository."
+msgstr ""
+
+msgid "Repository management tool was not recognized for your system."
+msgstr ""
+"Lo strumento di gestione del repository non �� stato riconosciuto per il "
+"sistema."
+
+#, python-format
+msgid "Repository %(repo_id)s is already enabled."
+msgstr "Il repository %(repo_id)s �� gi�� abilitato."
+
+#, python-format
+msgid "Repository %(repo_id)s is already disabled."
+msgstr "Il repository %(repo_id)s �� gi�� disabilitato."
+
+#, python-format
+msgid "Could not remove repository %(repo_id)s."
+msgstr "Impossibile rimuovere il repository %(repo_id)s."
+
+#, python-format
+msgid "Could not write repository configuration file %(repo_file)s"
+msgstr ""
+"Impossibile scrivere il file di configurazione del repository %(repo_file)s"
+
+msgid "Specify repository distribution in order to create a DEB repository."
+msgstr ""
+"Specificare la distribuzione del repository per poter creare un repository "
+"DEB."
+
+#, python-format
+msgid "Could not enable repository %(repo_id)s."
+msgstr "Impossibile abilitare il repository %(repo_id)s."
+
+#, python-format
+msgid "Could not disable repository %(repo_id)s."
+msgstr "Impossibile disabilitare il repository %(repo_id)s."
+
+msgid "YUM Repository ID already exists"
+msgstr "ID repository YUM gi�� esistente"
+
+msgid "YUM Repository name must be a string"
+msgstr "Il nome del repository YUM deve essere una stringa"
+
+#, python-format
+msgid "Unable to list repositories. Details: '%(err)s'"
+msgstr "Impossibile elencare i repository. Dettagli: '%(err)s'"
+
+#, python-format
+msgid "Unable to retrieve repository information. Details: '%(err)s'"
+msgstr ""
+"Impossibile richiamare le informazioni sul repository. Dettagli:
'%(err)s'"
+
+#, python-format
+msgid "Unable to add repository. Details: '%(err)s'"
+msgstr "Impossibile aggiungere il repository. Dettagli: '%(err)s'"
+
+#, python-format
+msgid "Unable to remove repository. Details: '%(err)s'"
+msgstr "Impossibile rimuovere il repository. Dettagli: '%(err)s'"
+
+#, python-format
+msgid ""
+"Configuration items: '%(items)s' are not supported by repository
manager"
+msgstr ""
+
+msgid "Repository metalink must be an http://, ftp:// or file:// URL."
+msgstr ""
+
+msgid "Cannot specify mirrorlist and metalink at the same time."
+msgstr ""
+
+#, python-format
+msgid ""
+"Virtual machine '%(vm)s' must be stopped before creating a snapshot of
it."
+msgstr ""
+
+#, python-format
+msgid ""
+"Unable to create snapshot '%(name)s' on virtual machine '%(vm)s'.
Details: %"
+"(err)s"
+msgstr ""
+
+#, python-format
+msgid "Snapshot '%(name)s' does not exist on virtual machine
'%(vm)s'."
+msgstr ""
+
+#, python-format
+msgid ""
+"Unable to retrieve snapshot '%(name)s' on virtual machine '%(vm)s'.
Details: "
+"%(err)s"
+msgstr ""
+
+#, python-format
+msgid "Unable to list snapshots on virtual machine '%(vm)s'. Details:
%(err)s"
+msgstr ""
+
+#, python-format
+msgid ""
+"Unable to delete snapshot '%(name)s' on virtual machine '%(vm)s'.
Details: %"
+"(err)s"
+msgstr ""
+
+#, python-format
+msgid ""
+"Unable to retrieve current snapshot of virtual machine '%(vm)s'. Details:
%"
+"(err)s"
+msgstr ""
+
+#, python-format
+msgid ""
+"Unable to revert virtual machine '%(vm)s' to snapshot '%(name)s'.
Details: %"
+"(err)s"
+msgstr ""
+
+#, python-format
+msgid ""
+"Unable to create snapshot of virtual machine '%(vm)s' because it contains a
"
+"disk with format '%(format)s'; only 'qcow2' is supported."
+msgstr ""
+
+msgid "The number of vCPUs is too large for this system."
+msgstr ""
+
+msgid "Invalid vCPU/topology combination."
+msgstr ""
+
+msgid "This host (or current configuration) does not allow CPU topology."
+msgstr ""
+
+msgid "ERROR CODE"
+msgstr "CODICE DI ERRORE"
+
+msgid "REASON"
+msgstr "CAUSA"
+
+msgid "STACK"
+msgstr "STACK"
+
+msgid "Go to Homepage"
+msgstr "Vai alla home page"
+
+msgid "Create a New Virtual Machine"
+msgstr "Crea una nuova macchina virtuale"
+
+msgid "Virtual Machine Name"
+msgstr "Nome macchina virtuale"
+
+msgid ""
+"The name used to identify the virtual machine. If omitted, a name will be "
+"chosen based on the template used."
+msgstr ""
+"Il nome utilizzato per identificare la macchina virtuale. Se il nome viene "
+"omesso ne verr�� scelto uno in base al modello utilizzato."
+
+msgid "Template"
+msgstr "Modello"
+
+msgid "Please create a template first."
+msgstr "Creare prima un modello."
+
+msgid "Create a Template"
+msgstr "Crea un modello"
+
+msgid "Please choose a template."
+msgstr "Scegliere un modello."
+
+msgid "OS"
+msgstr "SO"
+
+msgid "OS Version"
+msgstr "Versione SO"
+
+msgid "CPUS"
+msgstr "CPUS"
+
+msgid "Memory"
+msgstr "Memoria"
+
+msgid "Create"
+msgstr "Crea"
+
+msgid "Creating..."
+msgstr ""
+
+msgid "Cancel"
+msgstr "Annulla"
+
+msgid "Edit Guest"
+msgstr "Modifica guest"
+
+msgid "General"
+msgstr "Generale"
+
+msgid "Storage"
+msgstr "Memoria"
+
+msgid "Interface"
+msgstr "Interfaccia"
+
+msgid "Permission"
+msgstr "Versione"
+
+msgid "Host PCI Device"
+msgstr ""
+
+msgid "Snapshot"
+msgstr ""
+
+msgid "Name"
+msgstr "Nome"
+
+msgid "CPUs"
+msgstr "CPU"
+
+msgid "Memory (MB)"
+msgstr "Memoria"
+
+msgid "Icon"
+msgstr "Icona"
+
+msgid "Device"
+msgstr "Nome dispositivo"
+
+msgid "Path"
+msgstr "Percorso NFS"
+
+msgid "Network"
+msgstr "Rete"
+
+msgid "Type"
+msgstr "Tipo"
+
+msgid "MAC Address"
+msgstr ""
+
+msgid "Available system users and groups"
+msgstr ""
+
+msgid "Selected system users and groups"
+msgstr ""
+
+msgid "User"
+msgstr ""
+
+msgid "All"
+msgstr "Tutti"
+
+msgid "To Add"
+msgstr ""
+
+msgid "Added"
+msgstr ""
+
+msgid "filter"
+msgstr ""
+
+msgid "Product"
+msgstr ""
+
+msgid "Vendor"
+msgstr "Fornitore"
+
+msgid "Created"
+msgstr ""
+
+msgid "Save"
+msgstr "Salva"
+
+msgid "Replace"
+msgstr "Sostituisci"
+
+msgid "Detach"
+msgstr "Scollega"
+
+msgid "revert"
+msgstr ""
+
+msgid "Start"
+msgstr "Avvia"
+
+msgid "Reset"
+msgstr "Reimposta"
+
+msgid "Pause"
+msgstr ""
+
+msgid "Resume"
+msgstr ""
+
+msgid "Power Off"
+msgstr ""
+
+msgid "Actions"
+msgstr "Azioni"
+
+msgid "Connect"
+msgstr "Connetti"
+
+msgid "Clone"
+msgstr ""
+
+msgid "Edit"
+msgstr "Modifica"
+
+msgid "Shut Down"
+msgstr "Arresta"
+
+msgid "Delete"
+msgstr "Elimina"
+
+msgid "CPU"
+msgstr "CPU"
+
+msgid "Disk I/O"
+msgstr "I/O disco"
+
+msgid "Network I/O"
+msgstr "I/O di rete"
+
+msgid "Livetile"
+msgstr "Riquadro animato"
+
+msgid "No guests found."
+msgstr "Nessuna macchina guest trovata."
+
+msgid "Add a Storage Device to VM"
+msgstr "Aggiungi un dispositivo di memoria alla VM"
+
+msgid "Device Type"
+msgstr "Tipo dispositivo"
+
+msgid "The device type. Currently, \"cdrom\" and \"disk\" are
supported."
+msgstr "Il tipo di dispositivo. Attualmente, �� supportato solo
\"cdrom\"."
+
+msgid "Storage Pool"
+msgstr "Pool di memoria"
+
+msgid "Storage pool which volume located in"
+msgstr "Il percorso del pool di memoria deve essere una stringa"
+
+msgid "Storage Volume"
+msgstr "Nome pool di memoria"
+
+msgid "Storage volume to be attached"
+msgstr "Il nome del volume di memoria deve essere una stringa"
+
+msgid "File Path"
+msgstr "Percorso file"
+
+msgid "The ISO file path in the server for CDROM."
+msgstr "Il percorso file ISO nel server per CDROM."
+
+msgid "Attach"
+msgstr "Allega"
+
+msgid "Shut down"
+msgstr "Arresta"
+
+msgid "Restart"
+msgstr "Riavvia"
+
+msgid "Basic Information"
+msgstr "Informazioni di base"
+
+msgid "OS Distro"
+msgstr "Distro SO"
+
+msgid "OS Code Name"
+msgstr "Nome codice SO"
+
+msgid "Processor"
+msgstr "Processore"
+
+msgid "CPU(s)"
+msgstr ""
+
+msgid "System Statistics"
+msgstr "Statistiche di sistema"
+
+msgid "Software Updates"
+msgstr "Aggiornamenti del software"
+
+msgid "Update Progress"
+msgstr "Avanzamento aggiornamento"
+
+msgid "Repositories"
+msgstr "Repository"
+
+msgid "Debug Reports"
+msgstr "Report di debug"
+
+msgid "The username or password you entered is incorrect. Please try again."
+msgstr ""
+"Il nome utente o la password immessi non sono corretti. Ripetere "
+"l'operazione."
+
+msgid "This field is required."
+msgstr "Questo campo �� obbligatorio."
+
+msgid "Log in"
+msgstr "Accedi"
+
+msgid "Logging in..."
+msgstr "Accesso in corso..."
+
+msgid "Host"
+msgstr "Host"
+
+msgid "Guests"
+msgstr "Guest"
+
+msgid "Templates"
+msgstr "Modelli"
+
+msgid "Failed to get application configuration"
+msgstr "Richiamo della configurazione dell'applicazione non riuscito"
+
+msgid "This is not a valid Linux path"
+msgstr "Non �� un percorso Linux valido"
+
+msgid "This is not a valid URL."
+msgstr "Non �� un URL valido."
+
+msgid "No such data available."
+msgstr "Dati indicati non disponibili."
+
+msgid ""
+"Can not contact the host system. Verify the host system is up and that you "
+"have network connectivity to it. HTTP request response %1. "
+msgstr ""
+"Impossibile contattare il sistema host. Verificare che il sistema host sia "
+"attivo e che si disponga della connettivit�� di rete per tale sistema. "
+"Risposta alla richiesta HTTP %1. "
+
+msgid "Unable to read file."
+msgstr ""
+
+msgid "Error while uploading file."
+msgstr ""
+
+msgid "Delete Confirmation"
+msgstr "Conferma eliminazione"
+
+msgid "OK"
+msgstr "OK"
+
+msgid "Confirm"
+msgstr "Conferma"
+
+msgid "Warning"
+msgstr "Avvertenza"
+
+msgid "Cloning..."
+msgstr ""
+
+msgid "Loading..."
+msgstr "Caricamento in corso..."
+
+msgid "An error occurred while retrieving system information."
+msgstr ""
+
+msgid "Retry"
+msgstr "Riprova"
+
+msgid "Detailed message:"
+msgstr "Messaggio dettagliato:"
+
+msgid "No ISO found"
+msgstr ""
+
+msgid "This is not a valid ISO file."
+msgstr "Non �� un file ISO valido."
+
+msgid "This may take a long time. Do you want to continue?"
+msgstr "Richieder�� molto tempo. Continuare?"
+
+msgid "This will permanently delete the template. Would you like to continue?"
+msgstr "L'azione eliminer�� permanentemente il modello. Continuare?"
+
+msgid "Unable to shut down system as there are some virtual machines running!"
+msgstr ""
+"Impossibile arrestare il sistema poich�� sono in esecuzione alcune macchine "
+"virtuali."
+
+msgid "Max:"
+msgstr "Massimo:"
+
+msgid "Utilization"
+msgstr "Utilizzo"
+
+msgid "Available"
+msgstr "Disponibile"
+
+msgid "Read Rate"
+msgstr "Velocit�� di lettura"
+
+msgid "Write Rate"
+msgstr "Velocit�� di scrittura"
+
+msgid "Received"
+msgstr "Ricevuti"
+
+msgid "Sent"
+msgstr "Inviati"
+
+msgid ""
+"Shutting down or restarting host will cause unsaved work lost. Continue to "
+"shut down/restarting?"
+msgstr ""
+"L'arresto o il riavvio dell'host provocher�� la perdita del lavoro non
"
+"salvato. Continuare con l'arresto o il riavvio?"
+
+msgid ""
+"Repository will be removed permanently and can't be recovered. Do you want
"
+"to continue?"
+msgstr ""
+"Il repository verr�� rimosso permanentemente e non potr�� essere ripristinato.
"
+"Si desidera continuare?"
+
+msgid "ID"
+msgstr "ID"
+
+msgid "Base URL"
+msgstr "URL di base"
+
+msgid "Is Mirror"
+msgstr "�� speculare"
+
+msgid "URL Args"
+msgstr "Argomenti URL"
+
+msgid "Enabled"
+msgstr "Abilitato"
+
+msgid "GPG Check"
+msgstr "Controllo GPG"
+
+msgid "GPG Key"
+msgstr "Chiave GPG"
+
+msgid "Add"
+msgstr "Aggiungi"
+
+msgid "Remove"
+msgstr "Rimuovi"
+
+msgid "Enable"
+msgstr "Abilita"
+
+msgid "Disable"
+msgstr "Disabilita"
+
+msgid "Package Name"
+msgstr "Nome pacchetto"
+
+msgid "Version"
+msgstr "Versione"
+
+msgid "Architecture"
+msgstr "Architettura"
+
+msgid "Repository"
+msgstr "Repository"
+
+msgid "Update All"
+msgstr "Aggiorna tutto"
+
+msgid "Updating..."
+msgstr "Aggiornamento in corso..."
+
+msgid "Failed to retrieve packages update information."
+msgstr ""
+
+msgid "Failed to update package(s)."
+msgstr "Aggiornamento dei pacchetti non riuscito."
+
+msgid ""
+"Debug report will be removed permanently and can't be recovered. Do you want
"
+"to continue?"
+msgstr ""
+"Il report del debug verr�� rimosso permanentemente e non potr�� essere "
+"ripristinato. Si desidera continuare?"
+
+msgid "Generated Time"
+msgstr "Ora di creazione"
+
+msgid "Generate"
+msgstr "Crea"
+
+msgid "Generating..."
+msgstr "Creazione in corso..."
+
+msgid "Rename"
+msgstr "Ridenomina"
+
+msgid "Download"
+msgstr "Scarica"
+
+msgid ""
+"Report name should contain only letters, digits, underscore ('_') and/or
"
+"hyphen ('-')."
+msgstr ""
+"Il nome del report pu�� contenere solo lettere, cifre e/o trattini
('-')."
+
+msgid "Pending..."
+msgstr "Caricamento in corso..."
+
+msgid "Report name is the same as the original one."
+msgstr ""
+
+msgid ""
+"This will delete the virtual machine and its virtual disks. This operation "
+"cannot be undone. Would you like to continue?"
+msgstr ""
+"L'operazione eliminer�� la macchina virtuale e i relativi dischi virtuali e
"
+"non �� reversibile. Continuare?"
+
+msgid "Power off Confirmation"
+msgstr "Conferma eliminazione"
+
+msgid ""
+"This action may produce undesirable results, for example unflushed disk "
+"cache in the guest. Would you like to continue?"
+msgstr ""
+
+msgid "Reset Confirmation"
+msgstr "Conferma eliminazione"
+
+msgid ""
+"There is a risk of data loss caused by reset without the guest OS shutdown. "
+"Would you like to continue?"
+msgstr ""
+
+msgid "Shut Down Confirmation"
+msgstr "Conferma eliminazione"
+
+msgid "Note the guest OS may ignore this request. Would you like to continue?"
+msgstr "L'azione eliminer�� permanentemente il modello. Continuare?"
+
+msgid "Virtual Machine delete Confirmation"
+msgstr ""
+
+msgid ""
+"This virtual machine is not persistent. Power Off will delete it. Continue?"
+msgstr ""
+
+msgid ""
+"When the target guest has SCSI or iSCSI volumes, they will be cloned on "
+"default storage pool. The same will happen when the target pool does not "
+"have enough space to clone the volumes. Do you want to continue?"
+msgstr ""
+
+msgid ""
+"This CDROM will be detached permanently and you can re-attach it. Continue "
+"to detach it?"
+msgstr ""
+"Il CDROM verr�� scollegato permanentemente e non sar�� possibile ricollegarlo.
"
+"Continuare con lo scollegamento?"
+
+msgid "Attaching..."
+msgstr "Collegamento in corso..."
+
+msgid "Replacing..."
+msgstr "Sostituzione in corso..."
+
+msgid "Successfully attached!"
+msgstr "Collegamento riuscito."
+
+msgid "Successfully replaced!"
+msgstr "Sostituzione riuscita."
+
+msgid "Successfully detached!"
+msgstr "Scollegamento riuscito."
+
+msgid ""
+"This disk will be detached permanently and you can re-attach it. Continue to
"
+"detach it?"
+msgstr ""
+
+msgid "interface:"
+msgstr ""
+
+msgid "address:"
+msgstr ""
+
+msgid "link_type:"
+msgstr ""
+
+msgid "block:"
+msgstr ""
+
+msgid "drive_type:"
+msgstr ""
+
+msgid "model:"
+msgstr ""
+
+msgid "Affected devices:"
+msgstr ""
+
+msgid "The VLAN id must be between 1 and 4094."
+msgstr "L'ID VLAN deve essere compreso tra 1 e 4094."
+
+msgid "unavailable"
+msgstr "non disponibile"
+
+msgid ""
+"This action will interrupt network connectivity for any virtual machine that
"
+"depend on this network."
+msgstr ""
+"L'azione interromper�� la connettivit�� di rete per qualsiasi macchina "
+"virtuale che dipende da questa rete."
+
+msgid "Create a network"
+msgstr "Crea una rete"
+
+msgid ""
+"This network is not persistent. Instead of stop, this action will "
+"permanently delete it. Would you like to continue?"
+msgstr ""
+"Il pool di memoria non �� permanente. Invece di disattivarlo, l'azione lo
"
+"eliminer�� permanentemente. Continuare?"
+
+msgid ""
+"The bridged VLAN tag may not work well with NetworkManager enabled. You "
+"should consider disabling it."
+msgstr ""
+
+msgid ""
+"This will permanently delete the storage pool. Would you like to continue?"
+msgstr "L'azione eliminer�� permanentemente il pool di memoria.
Continuare?"
+
+msgid "This storage pool is empty."
+msgstr "Il pool di memoria �� vuoto."
+
+msgid ""
+"It will format your disk and you will loose any data in there, are you sure "
+"to continue? "
+msgstr ""
+"Il disco verr�� formattato e tutti i dati su di esso andranno persi, sicuri "
+"di voler continuare? "
+
+msgid "SCSI Fibre Channel"
+msgstr "Canale a fibre ottiche SCSI"
+
+msgid "No SCSI adapters found."
+msgstr "Nessun adattatore SCSI trovato."
+
+msgid "Loading iSCSI targets..."
+msgstr ""
+
+msgid "No iSCSI found. Please input one."
+msgstr ""
+
+msgid "Failed to load iSCSI targets."
+msgstr ""
+
+msgid "The storage pool name can not be blank."
+msgstr "Il campo per il nome del pool di memoria non pu�� essere vuoto."
+
+msgid "The storage pool path can not be blank."
+msgstr "Il campo per il percorso del pool di memoria non pu�� essere vuoto."
+
+msgid "NFS server mount path can not be blank."
+msgstr ""
+"Il campo per il percorso di montaggio del server NFS non pu�� essere vuoto."
+
+msgid "Invalid NFS mount path."
+msgstr "Percorso di montaggio NFS non valido."
+
+msgid "No logical device selected."
+msgstr "Nessun dispositivo logico selezionato."
+
+msgid "The iSCSI target can not be blank."
+msgstr "Il campo per la destinazione iSCSI non pu�� essere vuoto."
+
+msgid "Server name can not be blank."
+msgstr "Il campo per il nome del server non pu�� essere vuoto."
+
+msgid "This is not a valid Server Name or IP. Please, modify it."
+msgstr ""
+
+msgid "Looking for available partitions ..."
+msgstr "Ricerca di partizioni disponibili in corso..."
+
+msgid "No available partitions found."
+msgstr "Nessuna partizione disponibile trovata."
+
+msgid ""
+"This storage pool is not persistent. Instead of deactivate, this action will
"
+"permanently delete it. Would you like to continue?"
+msgstr ""
+"Il pool di memoria non �� permanente. Invece di disattivarlo, l'azione lo
"
+"eliminer�� permanentemente. Continuare?"
+
+msgid "Unable to retrieve partitions information."
+msgstr ""
+"Impossibile richiamare le informazioni sul repository. Dettagli:
'%(err)s'"
+
+msgid "In progress..."
+msgstr ""
+
+msgid "Failed!"
+msgstr ""
+
+msgid "CDROM path needs to be a valid local/remote path and cannot be blank."
+msgstr ""
+
+msgid "Disk pool or volume cannot be blank."
+msgstr "Il campo per il nome del pool di memoria non pu�� essere vuoto."
+
+msgid "Filter"
+msgstr ""
+
+msgid "Network Name"
+msgstr "Nome rete"
+
+msgid "State"
+msgstr "Stato"
+
+msgid "Network Type"
+msgstr "Tipo di Rete"
+
+msgid "Address Space"
+msgstr "Spazio indirizzo"
+
+msgid "Name should not contain '/' and '\"'."
+msgstr "Nome pool di memoria non valido. Non deve contenere '/'."
+
+msgid "Isolated: no external network connection"
+msgstr "Isolata: nessuna connessione di rete fisica"
+
+msgid "NAT: outbound physical network connection only"
+msgstr "NAT: solo connessione di rete fisica in uscita"
+
+msgid "Bridged: Virtual machines are connected to physical network directly"
+msgstr ""
+"Con bridge: le macchine virtuali sono connesse direttamente alla rete fisica"
+
+msgid "(No interfaces found)"
+msgstr ""
+
+msgid "Destination"
+msgstr "Destinazione:"
+
+msgid "Enable VLAN"
+msgstr "Abilita VLAN:"
+
+msgid "VLAN ID"
+msgstr "ID VLAN:"
+
+msgid "Stop"
+msgstr "Arresta"
+
+msgid "Generate a New Debug Report"
+msgstr "Crea un nuovo report di debug"
+
+msgid "Report Name"
+msgstr "Nome report"
+
+msgid ""
+"The name used to identify the report. If omitted, a name will be chosen "
+"based on current time. Name can contain: letters, digits, underscore
(\"_\") "
+"and hyphen (\"-\")."
+msgstr ""
+"Il nome utilizzato per identificare il report. Se il nome viene omesso, ne "
+"viene scelto uno in base all'ora corrente. Il nome pu�� contenere lettere,
"
+"cifre e trattini (\"-\")."
+
+msgid "Rename a Debug Report"
+msgstr "Crea un nuovo report di debug"
+
+msgid ""
+"The name used to identify the report. Name can contain: letters, digits and "
+"hyphen (\"-\")."
+msgstr ""
+"Il nome utilizzato per identificare il report. Se il nome viene omesso, ne "
+"viene scelto uno in base all'ora corrente. Il nome pu�� contenere lettere,
"
+"cifre e trattini (\"-\")."
+
+msgid "Submit"
+msgstr ""
+
+msgid "Add a Repository"
+msgstr "Aggiungi un repository"
+
+msgid "Identifier"
+msgstr "Identificativo"
+
+msgid "Single word, unique identifier for the repository."
+msgstr "Identificativo univoco di una sola parola per il repository."
+
+msgid "Textual name for the repository."
+msgstr "Nome in formato testo per il repository."
+
+msgid "URL"
+msgstr "URL"
+
+msgid "Required Field"
+msgstr "Campo obbligatorio"
+
+msgid "URL to the repository. Supported protocols are http, ftp, and file."
+msgstr "URL al repository. I protocolli supportati sono http, ftp e file."
+
+msgid "Repository is a mirror"
+msgstr "Il repository �� un elemento speculare."
+
+msgid "Distribution"
+msgstr "Distribuzione"
+
+msgid "Distribution of the DEB repository."
+msgstr "Distribuzione del repository DEB."
+
+msgid "Components"
+msgstr "Componenti"
+
+msgid "List of components in DEB repository."
+msgstr "Elenco di componenti nel repository DEB."
+
+msgid "Edit Repository"
+msgstr "Modifica repository"
+
+msgid "Mirror List URL"
+msgstr "URL elenco elementi speculari"
+
+msgid "Yes"
+msgstr "S��"
+
+msgid "No"
+msgstr "No"
+
+msgid "Capacity"
+msgstr "Capacit��"
+
+msgid "Allocated"
+msgstr "Assegnato"
+
+msgid "Location"
+msgstr "Ubicazione"
+
+msgid "Device path"
+msgstr "Percorso dispositivo"
+
+msgid "active"
+msgstr "attivo"
+
+msgid "inactive"
+msgstr "non attivo"
+
+msgid "Deactivate"
+msgstr "Disattiva"
+
+msgid "Activate"
+msgstr "Attiva"
+
+msgid "Add Volume"
+msgstr ""
+
+msgid "Extend"
+msgstr ""
+
+msgid "Undefine"
+msgstr "Rimuovi definizione"
+
+msgid "Format"
+msgstr "Formato:"
+
+msgid "Allocation"
+msgstr "Allocazione:"
+
+msgid "Define a New Storage Pool"
+msgstr "Definisci un nuovo pool di memoria"
+
+msgid "Storage Pool Name"
+msgstr "Nome pool di memoria"
+
+msgid ""
+"The name used to identify the storage pools, and it should not be empty."
+msgstr ""
+"Il nome utilizzato per identificare i pool di memoria; il campo non deve "
+"essere vuoto."
+
+msgid "Storage Pool Type"
+msgstr "Tipo di pool di memoria"
+
+msgid "Storage Path"
+msgstr "Percorso di memoria"
+
+msgid ""
+"The path of the Storage Pool. Each Storage Pool must have a unique path."
+msgstr ""
+"Il percorso del pool di memoria. Ogni pool di memoria deve avere un percorso
"
+"univoco."
+
+msgid ""
+"Kimchi will try to create the directory when it does not already exist in "
+"your system."
+msgstr ""
+"Kimchi tenter�� di creare la directory nel caso non esista ancora sul
sistema."
+
+msgid "NFS Server IP"
+msgstr "IP server NFS"
+
+msgid "NFS server IP or hostname. It can be input or chosen from history."
+msgstr ""
+"Il nome host o l'indirizzo IP del server NFS. �� possibile immetterlo o "
+"sceglierlo dalla cronologia."
+
+msgid "NFS Path"
+msgstr "Percorso NFS"
+
+msgid "The NFS exported path on NFS server."
+msgstr "Il percorso esportato NFS sul server NFS."
+
+msgid "iSCSI Server"
+msgstr "Server iSCSI"
+
+msgid "Server"
+msgstr "Server"
+
+msgid "Port"
+msgstr "Porta"
+
+msgid "iSCSI server IP or hostname. It should not be empty."
+msgstr ""
+"Il nome host o l'indirizzo IP del server iSCSI. Il campo non deve essere
"
+"vuoto."
+
+msgid "Target"
+msgstr "Destinazione"
+
+msgid "The iSCSI target on iSCSI server"
+msgstr "La destinazione iSCSI sul server iSCSI"
+
+msgid "Add iSCSI Authentication"
+msgstr "Aggiungi autenticazione iSCSI"
+
+msgid "iSCSI Authentication"
+msgstr "Autenticazione iSCSI"
+
+msgid "User Name"
+msgstr "Nome utente"
+
+msgid "Password"
+msgstr "Password"
+
+msgid "SCSI Adapter"
+msgstr "Adattatore SCSI"
+
+msgid "Please, wait..."
+msgstr "Attendere..."
+
+msgid "Add a Volume to Storage Pool"
+msgstr ""
+
+msgid "Fetch from remote URL"
+msgstr ""
+
+msgid "Enter the remote URL here."
+msgstr ""
+
+msgid "Upload a file"
+msgstr ""
+
+msgid "Choose the file you want to upload."
+msgstr ""
+
+msgid "Add Template"
+msgstr "Aggiungi modello"
+
+msgid "Where is the source media for this template? "
+msgstr "Dov'�� il supporto di origine per questo modello?"
+
+msgid "Local ISO Image"
+msgstr "Immagine ISO locale"
+
+msgid "Local Image File"
+msgstr ""
+
+msgid "Remote ISO Image"
+msgstr "Immagine ISO remota"
+
+msgid "Search ISOs"
+msgstr "Ricerca ISO"
+
+msgid "The following ISOs are available:"
+msgstr "Sono disponibili i seguenti file ISO:"
+
+msgid "OS: "
+msgstr "SO: "
+
+msgid "Version: "
+msgstr "Versione: "
+
+msgid "Size: "
+msgstr "Dimensione: "
+
+msgid "Search more ISOs"
+msgstr "Ricerca pi�� ISO"
+
+msgid "Create Templates from Selected ISO"
+msgstr "Crea modelli da ISO selezionato"
+
+msgid "I want to use a specific ISO file"
+msgstr "Utilizzare un file ISO specifico"
+
+msgid "Loading default remote ISOs ..."
+msgstr "Caricamento di ISO remoti predefiniti in corso..."
+
+msgid "Arch: "
+msgstr "Arch: "
+
+msgid "I want to use a custom URL"
+msgstr "Utilizzare un URL personalizzato"
+
+msgid "Edit Template"
+msgstr "Modifica modello"
+
+msgid "CDROM"
+msgstr "CDROM"
+
+msgid "Image File"
+msgstr ""
+
+msgid "Graphics"
+msgstr "Grafici"
+
+msgid "Disk(GB)"
+msgstr ""
+
+msgid "Disk Format"
+msgstr ""
+
+msgid "CPU Number"
+msgstr "Numero CPU"
+
+msgid "Manually set CPU topology"
+msgstr ""
+
+msgid "Cores"
+msgstr ""
+
+msgid "Threads"
+msgstr ""
+
+msgid "No templates found."
+msgstr "Nessun modello trovato."
+
+#~ msgid "Delete is not allowed for %(resource)s"
+#~ msgstr "Eliminazione non consentita per %(resource)s"
+
+#~ msgid "%(resource)s does not implement update method"
+#~ msgstr "%(resource)s non implementa il metodo di aggiornamento"
+
+#~ msgid "Create is not allowed for %(resource)s"
+#~ msgstr "Creazione non consentita per %(resource)s"
+
+#~ msgid "Unable to parse JSON request"
+#~ msgstr "Impossibile analizzare la richiesta JSON"
+
+#~ msgid "This API only supports JSON"
+#~ msgstr "L'API supporta solo JSON"
+
+#~ msgid "Datastore is not initiated in the model object."
+#~ msgstr "Archivio dati non inizializzato nell'oggetto modello."
+
+#~ msgid "Unable to start task due error: %(err)s"
+#~ msgstr "Impossibile avviare l'attivit�� a causa dell'errore:
%(err)s"
+
+#~ msgid ""
+#~ "Authentication failed for user '%(username)s'. [Error code:
%(code)s]"
+#~ msgstr ""
+#~ "Autenticazione non riuscita per l'utente '%(username)s'. [Codice di
"
+#~ "errore: %(code)s]"
+
+#~ msgid "You are not authorized to access Kimchi"
+#~ msgstr "Non si dispone dell'autorizzazione ad accedere a Kimchi"
+
+#~ msgid "Specify %(item)s to login into Kimchi"
+#~ msgstr "Specificare %(item)s per accedere a Kimchi"
+
+#~ msgid "Unable to find %(item)s in datastore"
+#~ msgstr "Impossibile trovare %(item)s nell'archivio dati"
+
+#~ msgid "Timeout while running command '%(cmd)s' after %(seconds)s
seconds"
+#~ msgstr ""
+#~ "�� stato raggiunto il timeout durante l'esecuzione del comando
'%(cmd)s' "
+#~ "dopo %(seconds)s secondi"
+
+#~ msgid "Help"
+#~ msgstr "Guida"
+
+#~ msgid "About"
+#~ msgstr "Info su"
+
+#~ msgid "Log out"
+#~ msgstr "Disconnetti"
+
+#~ msgid "Version:"
+#~ msgstr "Versione:"
diff --git a/src/wok/plugins/kimchi/po/ja_JP.po b/src/wok/plugins/kimchi/po/ja_JP.po
new file mode 100644
index 0000000..a3d3be3
--- /dev/null
+++ b/src/wok/plugins/kimchi/po/ja_JP.po
@@ -0,0 +1,2269 @@
+# English translations for kimchi package.
+# Copyright (C) 2013 ORGANIZATION
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: kimchi 0.1\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2015-07-01 16:11-0300\n"
+"PO-Revision-Date: 2013-07-11 17:32-0400\n"
+"Last-Translator: Cr��stian Viana <vianac(a)linux.vnet.ibm.com>\n"
+"Language-Team: English\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Language: ja_JP\n"
+"Generated-By: pygettext.py 1.5\n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+
+#, python-format
+msgid "Unknown parameter %(value)s"
+msgstr ""
+
+#, python-format
+msgid "Timeout of %(seconds)s seconds expired while running task
'%(task)s."
+msgstr ""
+
+#, python-format
+msgid "User %(user_id)s not found with given LDAP settings."
+msgstr ""
+
+msgid "Unknown \"_cap\" specified"
+msgstr ""
+
+msgid "\"_passthrough\" should be \"true\" or
\"false\""
+msgstr ""
+
+msgid "\"_passthrough_affected_by\" should be a device name string"
+msgstr ""
+
+#, python-format
+msgid "Error while getting block devices. Details: %(err)s"
+msgstr ""
+"������������������������������������������������������������������������������������������������:
%(err)s"
+
+#, python-format
+msgid "Error while getting block device information for %(device)s."
+msgstr ""
+"%(device)s
���������������������������������������������������������������������������������������������������"
+
+#, python-format
+msgid "Unable to find distro file: %(filename)s"
+msgstr "������������������������������������������������ %(filename)s
������������������������"
+
+#, python-format
+msgid ""
+"Unable to parse distro file: %(filename)s. Make sure, it is a JSON file."
+msgstr ""
+"������������������������������������������������ %(filename)s
���������������������������JSON ������������"
+"���������������������������������������������"
+
+#, python-format
+msgid "Unable to login to iSCSI host target %(portal)s. Details: %(err)s"
+msgstr ""
+"iSCSI ��������������������������� %(portal)s
���������������������������������������: %(err)s"
+
+#, python-format
+msgid "Unable to login to iSCSI host %(host)s target %(target)s"
+msgstr "iSCSI ��������� %(host)s ��������������� %(target)s
������������������������������"
+
+#, python-format
+msgid "Unable to find ISO file %(filename)s"
+msgstr ""
+
+#, python-format
+msgid "The ISO file %(filename)s is not bootable"
+msgstr "ISO ������������ %(filename)s
������������������������������������������"
+
+#, python-format
+msgid "The ISO file %(filename)s does not have a valid El Torito boot record"
+msgstr ""
+"ISO ������������ %(filename)s ������������������ El Torito
������������������������������������������"
+
+#, python-format
+msgid "Invalid El Torito validation entry in ISO %(filename)s"
+msgstr "��������� El Torito ������������������������ ISO %(filename)s
���������������"
+
+#, python-format
+msgid "Invalid El Torito boot indicator in ISO %(filename)s"
+msgstr "��������� El Torito ������������������������������������ ISO %(filename)s
���������������"
+
+#, python-format
+msgid "Unexpected volume type for primary volume in ISO %(filename)s"
+msgstr ""
+"1 ������������������������������������������������������������������ ISO
%(filename)s ���������������"
+
+#, python-format
+msgid "Bad format while reading volume descriptor in ISO %(filename)s"
+msgstr ""
+"��������������������������������������������� ISO %(filename)s
���������������������������������������"
+"������������������������������������"
+
+#, python-format
+msgid ""
+"The hypervisor doesn't have permission to use this ISO %(filename)s. "
+"Consider moving it under /var/lib/libvirt, or set the search permission to "
+"file access control lists for '%(user)s' user if possible, or add the
'%"
+"(user)s' to the ISO path group, or (not recommended) 'chmod -R o+x "
+"'path_to_iso'.Details: %(err)s"
+msgstr ""
+"��������������������������������� ISO %(filename)s
������������������������������������������/var/lib/"
+"libvirt
���������������������������������������������������������������%(user)s���������������������������"
+"���������������������������������������������������������%(user)s������ISO
���������������������������������"
+"���������������������chmod -R o+x path_to_iso������������ (���������������������)
���������������"
+"������������: %(err)s"
+
+msgid "An error occurred when probing image OS information."
+msgstr ""
+
+msgid "No OS information found in given image."
+msgstr ""
+
+#, python-format
+msgid "Unable to read image file %(filename)s"
+msgstr ""
+
+#, python-format
+msgid ""
+"Image file must be an existing file on system. %(filename)s is not a valid "
+"input."
+msgstr ""
+
+#, python-format
+msgid "Virtual machine %(name)s already exists"
+msgstr "��������������� %(name)s ������������������������"
+
+#, python-format
+msgid "Virtual machine %(name)s does not exist"
+msgstr "��������������� %(name)s ���������������������"
+
+#, python-format
+msgid ""
+"Unable to rename virtual machine %(name)s. The name %(new_name)s is already "
+"in use or the virtual machine is not powered off."
+msgstr ""
+
+#, python-format
+msgid "Unable to retrieve screenshot for stopped virtual machine %(name)s"
+msgstr "��������������������������������� %(name)s
���������������������������������������������������������"
+
+msgid "Remote ISO image is not supported by this server."
+msgstr "������������ ISO
������������������������������������������������������������������������������"
+
+#, python-format
+msgid "Screenshot is not supported on virtual machine %(name)s"
+msgstr ""
+
+#, python-format
+msgid "Unable to create virtual machine %(name)s. Details: %(err)s"
+msgstr "��������������� %(name)s ���������������������������������: %(err)s"
+
+#, python-format
+msgid "Unable to update virtual machine %(name)s. Details: %(err)s"
+msgstr "��������������� %(name)s ���������������������������������: %(err)s"
+
+#, python-format
+msgid "Unable to retrieve virtual machine %(name)s. Details: %(err)s"
+msgstr "��������������� %(name)s ���������������������������������: %(err)s"
+
+#, python-format
+msgid "Unable to connect to powered off virtual machine %(name)s."
+msgstr ""
+
+msgid "Virtual machine name must be a string without slashes (/)"
+msgstr ""
+
+#, python-format
+msgid "Invalid template URI %(value)s specified for virtual machine"
+msgstr ""
+
+#, python-format
+msgid "Invalid storage pool URI %(value)s specified for virtual machine"
+msgstr ""
+
+msgid "Supported virtual machine graphics are Spice or VNC"
+msgstr ""
+
+msgid "Graphics address to listen on must be IPv4 or IPv6"
+msgstr ""
+"listen ���������������������������������������������������IPv4 ��������� IPv6
���������������������������"
+"���"
+
+msgid "Specify a template to create a virtual machine from"
+msgstr
"���������������������������������������������������������������������������������"
+
+#, python-format
+msgid "Unable to start virtual machine %(name)s. Details: %(err)s"
+msgstr "��������������� %(name)s ���������������������������������: %(err)s"
+
+#, python-format
+msgid "Unable to power off virtual machine %(name)s. Details: %(err)s"
+msgstr "��������������� %(name)s ���������������������������������: %(err)s"
+
+#, python-format
+msgid "Unable to delete virtual machine %(name)s. Details: %(err)s"
+msgstr "��������������� %(name)s ���������������������������������: %(err)s"
+
+#, python-format
+msgid "Unable to reset virtual machine %(name)s. Details: %(err)s"
+msgstr "��������������� %(name)s ���������������������������������������:
%(err)s"
+
+msgid "User name list must be an array"
+msgstr ""
+
+msgid "User name must be a string"
+msgstr "���������������������������������������������������������������������"
+
+msgid "Group name list must be an array"
+msgstr ""
+
+msgid "Group name must be a string"
+msgstr "���������������������������������������������������������������������"
+
+#, python-format
+msgid "User(s) '%(users)s' do not exist"
+msgstr "���������������%(users)s���������������������������"
+
+#, python-format
+msgid "Group(s) '%(groups)s' do not exist"
+msgstr "���������������%(groups)s���������������������������"
+
+#, python-format
+msgid "Unable to shutdown virtual machine %(name)s. Details: %(err)s"
+msgstr "��������������� %(name)s ���������������������������������: %(err)s"
+
+#, python-format
+msgid ""
+"Unable to get access metadata of virtual machine %(name)s. Details: %(err)s"
+msgstr "��������������� %(name)s ���������������������������������: %(err)s"
+
+msgid "The guest console password must be a string."
+msgstr ""
+
+msgid "The life time for the guest console password must be a number."
+msgstr ""
+
+#, python-format
+msgid "Virtual machine '%(name)s' must be stopped before cloning it."
+msgstr ""
+
+#, python-format
+msgid "Insufficient disk space to clone virtual machine '%(name)s'"
+msgstr ""
+
+#, python-format
+msgid "Unable to clone VM '%(name)s'. Details: %(err)s"
+msgstr ""
+
+#, python-format
+msgid "Invalid operation for non-persistent virtual machine %(name)s"
+msgstr ""
+
+#, python-format
+msgid "Cannot suspend VM '%(name)s' because it is not running."
+msgstr ""
+
+#, python-format
+msgid "Unable to suspend VM '%(name)s'. Details: %(err)s"
+msgstr ""
+
+#, python-format
+msgid "Cannot resume VM '%(name)s' because it is not paused."
+msgstr ""
+
+#, python-format
+msgid "Unable to resume VM '%(name)s'. Details: %(err)s"
+msgstr ""
+
+msgid "Memory assigned is higher then the maximum allowed in the host."
+msgstr ""
+
+#, python-format
+msgid ""
+"VM '%(name)s' does not support live memory update. Update the memory with
"
+"the machine offline to enable this feature."
+msgstr ""
+
+msgid "Only increase memory is allowed in active VMs"
+msgstr ""
+
+msgid ""
+"For live memory update, new memory value must be equal old memory value plus
"
+"multiples of 1024 Mib"
+msgstr ""
+
+msgid "There are not enough free slots of 1024 Mib in the guest."
+msgstr ""
+
+msgid ""
+"Host's libvirt version does not support memory devices. Libvirt must be >=
"
+"1.2.14"
+msgstr ""
+
+#, python-format
+msgid "Error attaching memory device. Details: %(error)s"
+msgstr ""
+
+#, python-format
+msgid ""
+"VM %(vmid)s does not contain directly assigned host device %(dev_name)s."
+msgstr ""
+
+#, python-format
+msgid "The host device %(dev_name)s is not allowed to directly assign to VM."
+msgstr ""
+
+msgid ""
+"No IOMMU groups found. Host PCI pass through needs IOMMU group to function "
+"correctly. Please enable Intel VT-d or AMD IOMMU in your BIOS, then verify "
+"the Kernel is compiled with IOMMU support. For Intel CPU, add intel_iommu=on
"
+"to your Kernel parameter in /boot/grub2/grub.conf. For AMD CPU, add iommu=pt
"
+"iommu=1."
+msgstr ""
+
+msgid "\"name\" should be a device name string"
+msgstr ""
+
+#, python-format
+msgid ""
+"The device %(name)s is probably in use by the host. Unable to attach it to "
+"the guest."
+msgstr ""
+
+#, python-format
+msgid "Interface %(iface)s does not exist in virtual machine %(name)s"
+msgstr "������������������������ %(iface)s ������������������ %(name)s
������������������������"
+
+#, python-format
+msgid ""
+"Network %(network)s specified for virtual machine %(name)s does not exist"
+msgstr ""
+"��������������� %(name)s ��������������������������������������������� %(network)s
���������������������"
+
+msgid "Supported virtual machine interfaces type is only network"
+msgstr ""
+"������������������������������������������������������������������������������������������������������������������"
+"���"
+
+msgid "Network name for virtual machine interface must be a string"
+msgstr ""
+"������������������������������������������������������������������������������������������������������������������"
+
+msgid "Invalid network model card specified for virtual machine interface"
+msgstr ""
+"������������������������������������������������������������������������������������������������������������������"
+"���������"
+
+msgid "Specify type and network to add a new virtual machine interface"
+msgstr ""
+"������������������������������������������������������������������������������������������������������������������"
+"������"
+
+msgid "MAC Address must respect this format FF:FF:FF:FF:FF:FF"
+msgstr ""
+
+#, python-format
+msgid "MAC Address %(mac)s already exists in virtual machine %(name)s"
+msgstr ""
+
+msgid "Invalid MAC Address"
+msgstr ""
+
+msgid "Cannot change MAC address of a running virtual machine"
+msgstr ""
+
+#, python-format
+msgid "Template %(name)s already exists"
+msgstr "������������������ %(name)s ������������������������"
+
+#, python-format
+msgid ""
+"Network '%(network)s' specified for template %(template)s does not
exist"
+msgstr ""
+"������������������ %(template)s
������������������������������������������������%(network)s������������"
+"������������"
+
+#, python-format
+msgid ""
+"Storage pool %(pool)s specified for template %(template)s does not exist"
+msgstr ""
+"������������������ %(template)s
������������������������������������������������������ %(pool)s ������"
+"���������������"
+
+#, python-format
+msgid "Storage pool %(pool)s specified for template %(template)s is not
active"
+msgstr ""
+"������������������ %(template)s
������������������������������������������������������ %(pool)s ������"
+"���������������������������������"
+
+#, python-format
+msgid "Invalid parameter '%(param)s' specified for CDROM."
+msgstr "CDROM
���������������������������������������������%(param)s���������������������"
+
+#, python-format
+msgid "Network %(network)s specified for template %(template)s is not active"
+msgstr ""
+"������������������ %(template)s ���������������������������������������������
%(network)s ���������"
+"������������������������������"
+
+msgid "Template name must be a string"
+msgstr "���������������������������������������������������������������������"
+
+msgid "Template icon must be a path to the image"
+msgstr
"���������������������������������������������������������������������������������������"
+
+msgid "Template distribution must be a string"
+msgstr
"������������������������������������������������������������������������������������������������������"
+
+msgid "Template distribution version must be a string"
+msgstr ""
+"������������������������������������������������������������������������������������������������������������������"
+"������"
+
+msgid "The number of CPUs must be an integer greater than 0"
+msgstr "CPU ������������������������������������������"
+
+msgid "Amount of memory (MB) must be an integer greater than 512"
+msgstr "������������������ (MB ������) ������512
���������������������������������������������������"
+
+msgid "Template CDROM must be a local or remote ISO file"
+msgstr ""
+"������������������ CDROM ��������������������������������������� ISO
���������������������������������������"
+"���"
+
+#, python-format
+msgid "Invalid storage pool URI %(value)s specified for template"
+msgstr ""
+"������������������������������������ URI %(value)s
������������������������������������������������"
+
+msgid "Specify an ISO image as CDROM or a base image to create a template"
+msgstr ""
+"CDROM ������������������������������������������������������ ISO
���������������������������������������"
+
+msgid "All networks for the template must be specified in a list."
+msgstr
"������������������������������������������������������������������������������������������������������"
+
+msgid "Specify a volume to a template when storage pool is iSCSI or SCSI"
+msgstr ""
+
+#, python-format
+msgid "The volume %(volume)s is not in storage pool %(pool)s"
+msgstr ""
+
+#, python-format
+msgid "Unable to create template due error: %(err)s"
+msgstr "���������������������������������������������������������������������:
%(err)s"
+
+#, python-format
+msgid "Unable to delete template due error: %(err)s"
+msgstr "���������������������������������������������������������������������:
%(err)s"
+
+msgid "Disk size must be an integer greater than 1GB."
+msgstr ""
+
+msgid "Template base image must be a valid local image file"
+msgstr ""
+"������������������ CDROM ��������������������������������������� ISO
���������������������������������������"
+"���"
+
+#, python-format
+msgid "Cannot identify base image %(path)s format"
+msgstr ""
+
+msgid ""
+"When specifying CPU topology, VCPUs must be a product of sockets, cores, and
"
+"threads."
+msgstr ""
+
+msgid ""
+"When specifying CPU topology, each element must be an integer greater than "
+"zero."
+msgstr ""
+
+msgid ""
+"Invalid disk image format. Valid formats: bochs, cloop, cow, dmg, qcow, "
+"qcow2, qed, raw, vmdk, vpc."
+msgstr ""
+
+#, python-format
+msgid "Storage pool %(name)s already exists"
+msgstr "��������������������������� %(name)s ������������������������"
+
+#, python-format
+msgid "Storage pool %(name)s does not exist"
+msgstr "��������������������������� %(name)s ���������������������"
+
+#, python-format
+msgid "Specify %(item)s in order to create the storage pool %(name)s"
+msgstr ""
+"��������������������������� %(name)s ������������������������������%(item)s
���������������������������"
+
+#, python-format
+msgid "Unable to delete active storage pool %(name)s"
+msgstr "��������������������������������������������� %(name)s
������������������������"
+
+#, python-format
+msgid "Unable to list storage pools. Details: %(err)s"
+msgstr "���������������������������������������������������������������:
%(err)s"
+
+#, python-format
+msgid "Unable to create storage pool %(name)s. Details: %(err)s"
+msgstr "��������������������������� %(name)s ���������������������������������:
%(err)s"
+
+#, python-format
+msgid ""
+"Unable to get number of storage volumes in storage pool %(name)s. Details: %"
+"(err)s"
+msgstr ""
+"��������������������������� %(name)s
������������������������������������������������������������������������"
+"���:%(err)s"
+
+#, python-format
+msgid "Unable to activate storage pool %(name)s. Details: %(err)s"
+msgstr "��������������������������� %(name)s
���������������������������������������������: %(err)s"
+
+#, python-format
+msgid "Unable to deactivate storage pool %(name)s. Details: %(err)s"
+msgstr "��������������������������� %(name)s
������������������������������������������������: %(err)s"
+
+#, python-format
+msgid "Unable to delete storage pool %(name)s. Details: %(err)s"
+msgstr "��������������������������� %(name)s ���������������������������������:
%(err)s"
+
+#, python-format
+msgid ""
+"Unable to create NFS Pool as export path %(path)s may block during mount"
+msgstr ""
+"��������������������������������������������� %(path)s
���������������������������������������������������"
+"������NFS ���������������������������������"
+
+#, python-format
+msgid "Unable to create NFS Pool as export path %(path)s mount failed"
+msgstr ""
+"��������������������������� %(path)s ���������������������������������������NFS
���������������������������"
+"������"
+
+#, python-format
+msgid "Unsupported storage pool type: %(type)s"
+msgstr "���������������������������������������������������������������������:
%(type)s"
+
+#, python-format
+msgid "Error while retrieving storage pool XML to %(pool)s"
+msgstr ""
+
+msgid "Storage pool name must be a string without slashes (/)"
+msgstr ""
+
+msgid ""
+"Supported storage pool types are dir, netfs, logical, iscsi, isci and
kimchi-"
+"iso"
+msgstr ""
+
+msgid "Storage pool path must be a string"
+msgstr
"������������������������������������������������������������������������������������"
+
+msgid "Storage pool host must be a IP or hostname"
+msgstr "���������������������������������������������IP
���������������������������������������������������"
+
+msgid "Storage pool device must be the absolute path to the block device"
+msgstr ""
+
+msgid "Storage pool devices parameter must be a list"
+msgstr
"���������������������������������������������������������������������������������������������������������"
+
+msgid "Target IQN of an iSCSI pool must be a string"
+msgstr "iSCSI ��������������������������� IQN
������������������������������������������������"
+
+msgid "Port of a remote storage server must be an integer between 1 and 65535"
+msgstr ""
+"���������������������������������������������������������������1 ������ 65535
���������������������������������"
+"������������"
+
+msgid "iSCSI target username must be a string"
+msgstr ""
+
+msgid "iSCSI target password must be a string"
+msgstr ""
+
+msgid "Specify name and type to create a storage pool"
+msgstr
"������������������������������������������������������������������������������������������������"
+
+#, python-format
+msgid ""
+"%(disk)s is not a valid disk/partition. Could not add it to the pool %(pool)"
+"s."
+msgstr ""
+"%(disk)s
���������������������������/��������������������������������������������������� %(pool)s
������"
+"������������������������������"
+
+#, python-format
+msgid "Unable to extend logical pool %(pool)s. Details: %(err)s"
+msgstr ""
+
+msgid "The parameter disks only can be updated for logical storage pool."
+msgstr ""
+"���������������������������������������������������������������������������������������������������������������"
+"������"
+
+msgid "The SCSI host adapter name must be a string."
+msgstr "SCSI
���������������������������������������������������������������������������������"
+
+msgid "The storage pool kimchi_isos is reserved for internal use"
+msgstr "��������������������������� kimchi_isos
������������������������������������������������������"
+
+#, python-format
+msgid ""
+"Unable to activate NFS storage pool %(name)s. NFS server %(server)s is "
+"unreachable."
+msgstr ""
+"NFS ��������������������������� %(name)s ���������������������������������������NFS
������������ %"
+"(server)s ���������������������������"
+
+#, python-format
+msgid ""
+"Unable to deactivate NFS storage pool %(name)s. NFS server %(server)s is "
+"unreachable."
+msgstr ""
+"NFS ��������������������������� %(name)s
������������������������������������������NFS ������������ %"
+"(server)s ���������������������������"
+
+#, python-format
+msgid ""
+"Unable to deactivate pool %(name)s as it is associated with some templates"
+msgstr ""
+"��������� %(name)s
������������������������������������������������������������������������������������������"
+"���������������������"
+
+#, python-format
+msgid "Unable to delete pool %(name)s as it is associated with some templates"
+msgstr ""
+"��������� %(name)s
������������������������������������������������������������������������������������������"
+"������"
+
+#, python-format
+msgid ""
+"A volume group named '%(name)s' already exists. Please, choose another name
"
+"to create the logical pool."
+msgstr ""
+"���������%(name)s���������������������������������������������������������������������������������������������"
+"���������������������������������������������������"
+
+#, python-format
+msgid "Unable to update database with deep scan information due error:
%(err)s"
+msgstr ""
+"���������������������������������������������������������������������������������������������������������:
%"
+"(err)s"
+
+#, python-format
+msgid "Storage volume %(name)s already exists"
+msgstr "��������������������������������� %(name)s ������������������������"
+
+#, python-format
+msgid "Storage volume %(name)s does not exist in storage pool %(pool)s"
+msgstr ""
+"��������������������������������� %(name)s ���������������������������������
%(pool)s ������������������"
+"���"
+
+#, python-format
+msgid ""
+"Unable to create storage volume %(volume)s because storage pool %(pool)s is "
+"not active"
+msgstr ""
+
+#, python-format
+msgid "Specify %(item)s in order to create storage volume %(volume)s"
+msgstr ""
+"��������������������������������� %(volume)s ������������������������������%(item)s
���������������������"
+"������"
+
+#, python-format
+msgid ""
+"Unable to list storage volumes because storage pool %(pool)s is not active"
+msgstr ""
+"��������������������������� %(pool)s
������������������������������������������������������������������������"
+"���������������������������"
+
+#, python-format
+msgid ""
+"Unable to create storage volume %(name)s in storage pool %(pool)s. Details:
%"
+"(err)s"
+msgstr ""
+"��������������������������������� %(name)s ������������������������������ %(pool)s
���������������������"
+"������������: %(err)s"
+
+#, python-format
+msgid ""
+"Unable to list storage volumes in storage pool %(pool)s. Details: %(err)s"
+msgstr ""
+"��������������������������� %(pool)s
���������������������������������������������������������������������"
+"���: %(err)s"
+
+#, python-format
+msgid "Unable to wipe storage volumes %(name)s. Details: %(err)s"
+msgstr "��������������������������� %(name)s ������������������������������������:
%(err)s"
+
+#, python-format
+msgid "Unable to delete storage volume %(name)s. Details: %(err)s"
+msgstr "��������������������������������� %(name)s
���������������������������������: %(err)s"
+
+#, python-format
+msgid "Unable to resize storage volume %(name)s. Details: %(err)s"
+msgstr "��������������������������������� %(name)s
������������������������������������������: %(err)s"
+
+#, python-format
+msgid "Storage type %(type)s does not support volume create and delete"
+msgstr ""
+"��������������������������� %(type)s
������������������������������������������������������������������������"
+"���������"
+
+msgid "Storage volume name must be a string"
+msgstr
"������������������������������������������������������������������������������������"
+
+msgid "Storage volume allocation must be an integer number"
+msgstr
"������������������������������������������������������������������������������������"
+
+msgid ""
+"Storage volume format not supported. Valid formats: bochs, cloop, cow, dmg, "
+"qcow, qcow2, qed, raw, vmdk, vpc."
+msgstr ""
+
+msgid "Storage volume requires a volume name"
+msgstr
"������������������������������������������������������������������������"
+
+#, python-format
+msgid ""
+"Unable to update database with storage volume information due error: %(err)s"
+msgstr ""
+"���������������������������������������������������������������������������������������������������������������:
%"
+"(err)s"
+
+#, python-format
+msgid "Only one of parameter %(param)s can be specified"
+msgstr ""
+
+#, python-format
+msgid "Create volume from %(param)s is not supported"
+msgstr ""
+
+msgid "Storage volume capacity must be an integer number."
+msgstr ""
+
+msgid "Storage volume URL must be http://, https://, ftp:// or ftps://."
+msgstr ""
+
+#, python-format
+msgid "Unable to access file %(url)s. Please, check it."
+msgstr ""
+
+#, python-format
+msgid ""
+"Unable to clone storage volume '%(name)s' in pool '%(pool)s'.
Details: %(err)"
+"s"
+msgstr ""
+
+msgid "Specify chunk data and its size to upload a file."
+msgstr ""
+
+msgid "In order to upload a storage volume, specify the 'upload'
parameter."
+msgstr ""
+
+msgid ""
+"Unable to upload chunk data as it does not match with requested chunk size."
+msgstr ""
+
+#, python-format
+msgid "The storage volume %(vol)s is not under an upload process."
+msgstr ""
+
+msgid "The upload chunk data will exceed the storage volume size."
+msgstr ""
+
+#, python-format
+msgid "Unable to upload chunk data to storage volume. Details: %(err)s."
+msgstr ""
+
+#, python-format
+msgid "Interface %(name)s does not exist"
+msgstr "������������������������ %(name)s ���������������������"
+
+#, python-format
+msgid "Network %(name)s already exists"
+msgstr "������������������ %(name)s ������������������������"
+
+#, python-format
+msgid "Network %(name)s does not exist"
+msgstr "������������������ %(name)s ���������������������"
+
+#, python-format
+msgid "Subnet %(subnet)s specified for network %(network)s is not valid."
+msgstr ""
+"������������������ %(network)s ������������������������������������������
%(subnet)s ������������������"
+
+#, python-format
+msgid "Specify a network interface to create bridged network %(name)s"
+msgstr ""
+"������������������������������������ %(name)s
���������������������������������������������������������"
+"���������������������������������������"
+
+#, python-format
+msgid "Unable to delete active network %(name)s"
+msgstr "������������������������������������ %(name)s
������������������������"
+
+#, python-format
+msgid "Interface %(iface)s specified for network %(network)s is already in
use"
+msgstr ""
+"������������������ %(network)s ���������������������������������������������������
%(iface)s ���������"
+"���������������������������"
+
+msgid "Interface should be bare NIC, bonding or bridge device."
+msgstr ""
+"���������������������������������
NIC���������������������������������������������������������������������������"
+"������"
+
+#, python-format
+msgid "Unable to create network %(name)s. Details: %(err)s"
+msgstr "������������������ %(name)s ���������������������������������:
%(err)s"
+
+#, python-format
+msgid "Unable to find a free IP address for network '%(name)s'"
+msgstr "���������������������%(name)s��������������� IP
���������������������������������������"
+
+#, python-format
+msgid "The interface %(iface)s already exists."
+msgstr ""
+
+msgid "Network name must be a string without slashes (/) or quotes (\")"
+msgstr ""
+
+msgid "Supported network types are isolated, NAT and bridge"
+msgstr
"���������������������������������������������������������������������NAT������������������������������"
+
+msgid "Network subnet must be a string with IP address and prefix or netmask"
+msgstr ""
+"������������������������������������������IP
������������������������������������������������������������������"
+"������������������������������������������������������"
+
+msgid "Network interface must be a string"
+msgstr
"���������������������������������������������������������������������������������������������"
+
+msgid "Network VLAN ID must be an integer between 1 and 4094"
+msgstr "������������������ VLAN ID ������1 ������ 4094
���������������������������������������������"
+
+msgid "Specify name and type to create a Network"
+msgstr
"���������������������������������������������������������������������������������������"
+
+#, python-format
+msgid ""
+"Unable to delete network %(name)s. There are some virtual machines %(vms)s "
+"and/or templates linked to this network."
+msgstr ""
+
+#, python-format
+msgid ""
+"Unable to deactivate network %(name)s. There are some virtual machines
%(vms)"
+"s and/or templates linked to this network."
+msgstr ""
+
+#, python-format
+msgid "Bridge device %(name)s can not be the trunk device of a VLAN."
+msgstr ""
+"��������������������������� %(name)s ������VLAN
������������������������������������������������������������"
+"������"
+
+#, python-format
+msgid "Failed to activate interface %(iface)s: %(err)s."
+msgstr "������������������������ %(iface)s ���������������������������������:
%(err)s���"
+
+#, python-format
+msgid ""
+"Failed to activate interface %(iface)s. Please check the physical link "
+"status."
+msgstr ""
+"������������������������ %(iface)s
���������������������������������������������������������������������������"
+"������������"
+
+#, python-format
+msgid "Failed to start network %(name)s. Details: %(err)s"
+msgstr ""
+
+#, python-format
+msgid "Debug report %(name)s does not exist"
+msgstr "��������������������������� %(name)s ������������������������"
+
+msgid "Debug report tool not found in system"
+msgstr
"������������������������������������������������������������������������������"
+
+#, python-format
+msgid "Unable to create debug report %(name)s. Details: %(err)s."
+msgstr "��������������������������� %(name)s ���������������������������������:
%(err)s"
+
+#, python-format
+msgid "Can not find any debug report with the given name %(name)s"
+msgstr ""
+
+#, python-format
+msgid "Unable to generate debug report %(name)s. Details: %(err)s"
+msgstr "��������������������������� %(name)s ���������������������������������:
%(err)s"
+
+msgid "You should give a name for the debug report file."
+msgstr ""
+
+msgid ""
+"Debug report name must be a string. Only letters, digits, underscore ('_')
"
+"and hyphen ('-') are allowed."
+msgstr ""
+
+#, python-format
+msgid ""
+"The debug report with specified name \"%(name)s\" already exists. Please
use "
+"another one."
+msgstr ""
+"���������%(name)s���������������������������������������������������������������������������������������������"
+"���������������������������������������������������"
+
+#, python-format
+msgid "Storage server %(server)s was not used by Kimchi"
+msgstr ""
+"������������������������������ %(server)s ������Kimchi
������������������������������������������������"
+
+#, python-format
+msgid "Distro '%(name)s' does not exist"
+msgstr "������������������������������������%(name)s������������������������"
+
+#, python-format
+msgid "Partition %(name)s does not exist in the host"
+msgstr "��������������������� %(name)s ������������������������������������"
+
+msgid "Unable to shutdown host machine as there are running virtual machines"
+msgstr
"���������������������������������������������������������������������������������������������������������"
+
+msgid "Unable to reboot host machine as there are running virtual machines"
+msgstr
"������������������������������������������������������������������������������������������������"
+
+#, python-format
+msgid "Node device '%(name)s' not found"
+msgstr "���������������������������%(name)s���������������������������"
+
+msgid "Conflicting flag filters specified."
+msgstr ""
+
+msgid "No packages marked for update"
+msgstr
"���������������������������������������������������������������������������������"
+
+#, python-format
+msgid "Package %(name)s is not marked to be updated."
+msgstr "��������������� %(name)s
���������������������������������������������������������������"
+
+#, python-format
+msgid "Error while getting packages marked to be updated. Details: %(err)s"
+msgstr ""
+"������������������������������������������������������������������������������������������������������������������"
+"������������: %(err)s"
+
+msgid "There is no compatible package manager for this system."
+msgstr
"���������������������������������������������������������������������������������������"
+
+#, python-format
+msgid "Invalid URI %(uri)s"
+msgstr "��������� URI %(uri)s"
+
+msgid "Unable to choose a virtual machine name"
+msgstr ""
+
+msgid "Invalid storage type. Types supported: 'cdrom', 'disk'"
+msgstr ""
+"���������������������������������������������������������������������������������������cdrom������������"
+
+#, python-format
+msgid "The path '%(value)s' is not a valid local/remote path for the
device"
+msgstr ""
+
+msgid "Only CDROM path can be update."
+msgstr ""
+
+#, python-format
+msgid ""
+"The storage device %(dev_name)s does not exist in the virtual machine %"
+"(vm_name)s"
+msgstr ""
+
+#, python-format
+msgid "Error while creating new storage device: %(error)s"
+msgstr ""
+"���������������������������������������������������������������������������������������������������:
%(error)s"
+
+#, python-format
+msgid "Error while updating storage device: %(error)s"
+msgstr ""
+"������������������������������������������������������������������������������������������:
%(error)s"
+
+#, python-format
+msgid "Error while removing storage device: %(error)s"
+msgstr ""
+"������������������������������������������������������������������������������������������:
%(error)s"
+
+msgid "Do not support IDE device hot plug"
+msgstr ""
+
+msgid ""
+"Specify type and path or type and pool/volume to add a new virtual machine "
+"disk"
+msgstr
"������������������������������������������������������������������������������������������������"
+
+msgid "Specify path to update virtual machine disk"
+msgstr
"���������������������������������������������������������������������������������������"
+
+#, python-format
+msgid "Controller type %(type)s limitation of %(limit)s devices reached"
+msgstr ""
+
+#, python-format
+msgid "Cannot retrieve disk path information for given pool/volume: %(error)s"
+msgstr ""
+
+msgid "Volume already in use by other virtual machine."
+msgstr ""
+
+msgid ""
+"Only one of path or pool/volume can be specified to add a new virtual "
+"machine disk"
+msgstr
"������������������������������������������������������������������������������������������������"
+
+#, python-format
+msgid ""
+"Volume chosen with format %(format)s does not fit in the storage type
%(type)"
+"s"
+msgstr ""
+
+msgid "YUM Repository ID must be one word only string."
+msgstr "YUM ������������������ ID ������1
���������������������������������������������������������������"
+
+msgid "Repository URL must be an http://, ftp:// or file:// URL."
+msgstr ""
+"������������������ URL ��� http://���ftp://������������ file:// URL
���������������������������"
+"������"
+
+msgid ""
+"Repository configuration is a dictionary with specific values according to "
+"repository type."
+msgstr ""
+"������������������������������������������������������������������������������������������������������������������"
+"������������������"
+
+msgid "Distribution to DEB repository must be a string"
+msgstr ""
+"DEB
������������������������������������������������������������������������������������������������������������"
+
+msgid "Components to DEB repository must be listed in a array"
+msgstr ""
+"DEB
������������������������������������������������������������������������������������������������������������"
+"������"
+
+msgid "Components to DEB repository must be a string"
+msgstr "DEB
������������������������������������������������������������������������������������������������"
+
+msgid "Mirror list to repository must be a string"
+msgstr ""
+
+msgid "YUM Repository name must be string."
+msgstr "YUM
������������������������������������������������������������������������"
+
+msgid "GPG check must be a boolean value."
+msgstr "GPG ������������������������������������������������������������"
+
+msgid "GPG key must be a URL pointing to the ASCII-armored file."
+msgstr "GPG ���������ASCII ��������������������������������������� URL
���������������������������������"
+
+#, python-format
+msgid "Could not update repository %(repo_id)s."
+msgstr "������������������ %(repo_id)s ������������������������������������"
+
+#, python-format
+msgid "Repository %(repo_id)s does not exist."
+msgstr "������������������ %(repo_id)s ������������������������"
+
+msgid ""
+"Specify repository base URL, mirror list or metalink in order to create or "
+"update a YUM repository."
+msgstr ""
+
+msgid "Repository management tool was not recognized for your system."
+msgstr
"���������������������������������������������������������������������������������������"
+
+#, python-format
+msgid "Repository %(repo_id)s is already enabled."
+msgstr "������������������ %(repo_id)s
���������������������������������������"
+
+#, python-format
+msgid "Repository %(repo_id)s is already disabled."
+msgstr "������������������ %(repo_id)s
���������������������������������������"
+
+#, python-format
+msgid "Could not remove repository %(repo_id)s."
+msgstr "������������������ %(repo_id)s ������������������������������������"
+
+#, python-format
+msgid "Could not write repository configuration file %(repo_file)s"
+msgstr ""
+"������������������������������������ %(repo_file)s
������������������������������������������������"
+
+msgid "Specify repository distribution in order to create a DEB repository."
+msgstr ""
+"DEB
������������������������������������������������������������������������������������������������������������"
+"������������������������"
+
+#, python-format
+msgid "Could not enable repository %(repo_id)s."
+msgstr "������������������ %(repo_id)s
���������������������������������������"
+
+#, python-format
+msgid "Could not disable repository %(repo_id)s."
+msgstr "������������������ %(repo_id)s
���������������������������������������"
+
+msgid "YUM Repository ID already exists"
+msgstr "YUM ������������������ ID ������������������������"
+
+msgid "YUM Repository name must be a string"
+msgstr "YUM
���������������������������������������������������������������������"
+
+#, python-format
+msgid "Unable to list repositories. Details: '%(err)s'"
+msgstr "������������������������������������������������������: ���%(err)s���"
+
+#, python-format
+msgid "Unable to retrieve repository information. Details: '%(err)s'"
+msgstr "���������������������������������������������������������:
���%(err)s���"
+
+#, python-format
+msgid "Unable to add repository. Details: '%(err)s'"
+msgstr "���������������������������������������������������: ���%(err)s���"
+
+#, python-format
+msgid "Unable to remove repository. Details: '%(err)s'"
+msgstr "���������������������������������������������������: ���%(err)s���"
+
+#, python-format
+msgid ""
+"Configuration items: '%(items)s' are not supported by repository
manager"
+msgstr ""
+
+msgid "Repository metalink must be an http://, ftp:// or file:// URL."
+msgstr ""
+
+msgid "Cannot specify mirrorlist and metalink at the same time."
+msgstr ""
+
+#, python-format
+msgid ""
+"Virtual machine '%(vm)s' must be stopped before creating a snapshot of
it."
+msgstr ""
+
+#, python-format
+msgid ""
+"Unable to create snapshot '%(name)s' on virtual machine '%(vm)s'.
Details: %"
+"(err)s"
+msgstr ""
+
+#, python-format
+msgid "Snapshot '%(name)s' does not exist on virtual machine
'%(vm)s'."
+msgstr ""
+
+#, python-format
+msgid ""
+"Unable to retrieve snapshot '%(name)s' on virtual machine '%(vm)s'.
Details: "
+"%(err)s"
+msgstr ""
+
+#, python-format
+msgid "Unable to list snapshots on virtual machine '%(vm)s'. Details:
%(err)s"
+msgstr ""
+
+#, python-format
+msgid ""
+"Unable to delete snapshot '%(name)s' on virtual machine '%(vm)s'.
Details: %"
+"(err)s"
+msgstr ""
+
+#, python-format
+msgid ""
+"Unable to retrieve current snapshot of virtual machine '%(vm)s'. Details:
%"
+"(err)s"
+msgstr ""
+
+#, python-format
+msgid ""
+"Unable to revert virtual machine '%(vm)s' to snapshot '%(name)s'.
Details: %"
+"(err)s"
+msgstr ""
+
+#, python-format
+msgid ""
+"Unable to create snapshot of virtual machine '%(vm)s' because it contains a
"
+"disk with format '%(format)s'; only 'qcow2' is supported."
+msgstr ""
+
+msgid "The number of vCPUs is too large for this system."
+msgstr ""
+
+msgid "Invalid vCPU/topology combination."
+msgstr ""
+
+msgid "This host (or current configuration) does not allow CPU topology."
+msgstr ""
+
+msgid "ERROR CODE"
+msgstr "���������������������"
+
+msgid "REASON"
+msgstr "������"
+
+msgid "STACK"
+msgstr "������������"
+
+msgid "Go to Homepage"
+msgstr "������������������������������������"
+
+msgid "Create a New Virtual Machine"
+msgstr "������������������������������"
+
+msgid "Virtual Machine Name"
+msgstr "������������������"
+
+msgid ""
+"The name used to identify the virtual machine. If omitted, a name will be "
+"chosen based on the template used."
+msgstr ""
+"������������������������������������������������������������������������������������������������������������������"
+"������������������������������������������������"
+
+msgid "Template"
+msgstr "������������������"
+
+msgid "Please create a template first."
+msgstr "������������������������������������������������������"
+
+msgid "Create a Template"
+msgstr "���������������������������"
+
+msgid "Please choose a template."
+msgstr "������������������������������������������������"
+
+msgid "OS"
+msgstr "OS"
+
+msgid "OS Version"
+msgstr "OS ���������������"
+
+msgid "CPUS"
+msgstr "CPU"
+
+msgid "Memory"
+msgstr "������������"
+
+msgid "Create"
+msgstr "������"
+
+msgid "Creating..."
+msgstr ""
+
+msgid "Cancel"
+msgstr "������"
+
+msgid "Edit Guest"
+msgstr "������������������"
+
+msgid "General"
+msgstr "������"
+
+msgid "Storage"
+msgstr "���������������"
+
+msgid "Interface"
+msgstr "������������������������"
+
+msgid "Permission"
+msgstr "���������������"
+
+msgid "Host PCI Device"
+msgstr ""
+
+msgid "Snapshot"
+msgstr ""
+
+msgid "Name"
+msgstr "������"
+
+msgid "CPUs"
+msgstr "CPU"
+
+msgid "Memory (MB)"
+msgstr "������������"
+
+msgid "Icon"
+msgstr "������������"
+
+msgid "Device"
+msgstr "���������������"
+
+msgid "Path"
+msgstr "NFS ������"
+
+msgid "Network"
+msgstr " ������������������"
+
+msgid "Type"
+msgstr "���������"
+
+msgid "MAC Address"
+msgstr ""
+
+msgid "Available system users and groups"
+msgstr ""
+
+msgid "Selected system users and groups"
+msgstr ""
+
+msgid "User"
+msgstr ""
+
+msgid "All"
+msgstr "���������"
+
+msgid "To Add"
+msgstr ""
+
+msgid "Added"
+msgstr ""
+
+msgid "filter"
+msgstr ""
+
+msgid "Product"
+msgstr ""
+
+msgid "Vendor"
+msgstr "������������"
+
+msgid "Created"
+msgstr ""
+
+msgid "Save"
+msgstr "������"
+
+msgid "Replace"
+msgstr "������"
+
+msgid "Detach"
+msgstr "������������"
+
+msgid "revert"
+msgstr ""
+
+msgid "Start"
+msgstr "������"
+
+msgid "Reset"
+msgstr "������������"
+
+msgid "Pause"
+msgstr ""
+
+msgid "Resume"
+msgstr ""
+
+msgid "Power Off"
+msgstr ""
+
+msgid "Actions"
+msgstr "���������������"
+
+msgid "Connect"
+msgstr "������"
+
+msgid "Clone"
+msgstr ""
+
+msgid "Edit"
+msgstr "������"
+
+msgid "Shut Down"
+msgstr "���������������������"
+
+msgid "Delete"
+msgstr "������"
+
+msgid "CPU"
+msgstr "CPU"
+
+msgid "Disk I/O"
+msgstr "���������������������"
+
+msgid "Network I/O"
+msgstr "���������������������������"
+
+msgid "Livetile"
+msgstr "������������������"
+
+msgid "No guests found."
+msgstr "������������������������������������"
+
+msgid "Add a Storage Device to VM"
+msgstr "VM ������������������������������������������"
+
+msgid "Device Type"
+msgstr "������������������������"
+
+msgid "The device type. Currently, \"cdrom\" and \"disk\" are
supported."
+msgstr "������������������������������������������������������������������
\"cdrom\" ���������������"
+
+msgid "Storage Pool"
+msgstr "���������������������������"
+
+msgid "Storage pool which volume located in"
+msgstr
"������������������������������������������������������������������������������������"
+
+msgid "Storage Volume"
+msgstr "������������������������������"
+
+msgid "Storage volume to be attached"
+msgstr
"������������������������������������������������������������������������������������"
+
+msgid "File Path"
+msgstr "���������������������"
+
+msgid "The ISO file path in the server for CDROM."
+msgstr "��������������������� CDROM ��� ISO ������������������������"
+
+msgid "Attach"
+msgstr "������"
+
+msgid "Shut down"
+msgstr "���������������������"
+
+msgid "Restart"
+msgstr "���������"
+
+msgid "Basic Information"
+msgstr "������������"
+
+msgid "OS Distro"
+msgstr "OS ���������������������������������"
+
+msgid "OS Code Name"
+msgstr "OS ������������"
+
+msgid "Processor"
+msgstr "������������������"
+
+msgid "CPU(s)"
+msgstr ""
+
+msgid "System Statistics"
+msgstr "������������������������"
+
+msgid "Software Updates"
+msgstr "������������������������"
+
+msgid "Update Progress"
+msgstr "���������������������"
+
+msgid "Repositories"
+msgstr "������������������"
+
+msgid "Debug Reports"
+msgstr "���������������������������"
+
+msgid "The username or password you entered is incorrect. Please try again."
+msgstr
"���������������������������������������������������������������������������������������������������������"
+
+msgid "This field is required."
+msgstr "���������������������������������������"
+
+msgid "Log in"
+msgstr "������������"
+
+msgid "Logging in..."
+msgstr "���������������������������..."
+
+msgid "Host"
+msgstr "���������"
+
+msgid "Guests"
+msgstr "���������"
+
+msgid "Templates"
+msgstr "������������������"
+
+msgid "Failed to get application configuration"
+msgstr "���������������������������������������������������������������"
+
+msgid "This is not a valid Linux path"
+msgstr "��������� Linux ���������������������������"
+
+msgid "This is not a valid URL."
+msgstr "��������� URL ������������������������"
+
+msgid "No such data available."
+msgstr "���������������������������������������������"
+
+msgid ""
+"Can not contact the host system. Verify the host system is up and that you "
+"have network connectivity to it. HTTP request response %1. "
+msgstr ""
+"������������������������������������������������������������������������������������������������������������������"
+"������������������������������������������������������������������HTTP ������������
%1"
+
+msgid "Unable to read file."
+msgstr ""
+
+msgid "Error while uploading file."
+msgstr ""
+
+msgid "Delete Confirmation"
+msgstr "���������������"
+
+msgid "OK"
+msgstr "OK"
+
+msgid "Confirm"
+msgstr "������"
+
+msgid "Warning"
+msgstr "������"
+
+msgid "Cloning..."
+msgstr ""
+
+msgid "Loading..."
+msgstr "������������������������..."
+
+msgid "An error occurred while retrieving system information."
+msgstr ""
+
+msgid "Retry"
+msgstr "���������"
+
+msgid "Detailed message:"
+msgstr "���������������������:"
+
+msgid "No ISO found"
+msgstr ""
+
+msgid "This is not a valid ISO file."
+msgstr "��������� ISO ������������������������������������"
+
+msgid "This may take a long time. Do you want to continue?"
+msgstr
"������������������������������������������������������������������������?"
+
+msgid "This will permanently delete the template. Would you like to continue?"
+msgstr
"���������������������������������������������������������������������?"
+
+msgid "Unable to shut down system as there are some virtual machines running!"
+msgstr ""
+"������������������������������������������������������������������������������������������������������������������!"
+
+msgid "Max:"
+msgstr "������:"
+
+msgid "Utilization"
+msgstr "���������"
+
+msgid "Available"
+msgstr "������������"
+
+msgid "Read Rate"
+msgstr "������������������"
+
+msgid "Write Rate"
+msgstr "������������������"
+
+msgid "Received"
+msgstr "������������"
+
+msgid "Sent"
+msgstr "������������"
+
+msgid ""
+"Shutting down or restarting host will cause unsaved work lost. Continue to "
+"shut down/restarting?"
+msgstr ""
+"������������������������������������������������������������������������������������������������������������������"
+"���������������������/������������������������������?"
+
+msgid ""
+"Repository will be removed permanently and can't be recovered. Do you want
"
+"to continue?"
+msgstr ""
+"���������������������������������������������������������������������������������������������������������?"
+
+msgid "ID"
+msgstr "ID"
+
+msgid "Base URL"
+msgstr "��������� URL"
+
+msgid "Is Mirror"
+msgstr "���������"
+
+msgid "URL Args"
+msgstr "URL ������"
+
+msgid "Enabled"
+msgstr "������������"
+
+msgid "GPG Check"
+msgstr "GPG ������������"
+
+msgid "GPG Key"
+msgstr "GPG ���"
+
+msgid "Add"
+msgstr "������"
+
+msgid "Remove"
+msgstr "������"
+
+msgid "Enable"
+msgstr "������������"
+
+msgid "Disable"
+msgstr "������������"
+
+msgid "Package Name"
+msgstr "������������������"
+
+msgid "Version"
+msgstr "���������������"
+
+msgid "Architecture"
+msgstr "������������������������"
+
+msgid "Repository"
+msgstr "������������������"
+
+msgid "Update All"
+msgstr "���������������"
+
+msgid "Updating..."
+msgstr "���������������������..."
+
+msgid "Failed to retrieve packages update information."
+msgstr ""
+
+msgid "Failed to update package(s)."
+msgstr "���������������������������������������������������"
+
+msgid ""
+"Debug report will be removed permanently and can't be recovered. Do you want
"
+"to continue?"
+msgstr ""
+"������������������������������������������������������������������������������������������������������������������?"
+
+msgid "Generated Time"
+msgstr "������������"
+
+msgid "Generate"
+msgstr "������"
+
+msgid "Generating..."
+msgstr "���������������������..."
+
+msgid "Rename"
+msgstr "������������"
+
+msgid "Download"
+msgstr "������������������"
+
+msgid ""
+"Report name should contain only letters, digits, underscore ('_') and/or
"
+"hyphen ('-')."
+msgstr
"���������������������������������������������������������������������������������
(-) ���������������"
+
+msgid "Pending..."
+msgstr "������������������������..."
+
+msgid "Report name is the same as the original one."
+msgstr ""
+
+msgid ""
+"This will delete the virtual machine and its virtual disks. This operation "
+"cannot be undone. Would you like to continue?"
+msgstr ""
+"������������������������������������������������������������������������������������������������������������������"
+"������������������������?"
+
+msgid "Power off Confirmation"
+msgstr "���������������"
+
+msgid ""
+"This action may produce undesirable results, for example unflushed disk "
+"cache in the guest. Would you like to continue?"
+msgstr ""
+
+msgid "Reset Confirmation"
+msgstr "���������������"
+
+msgid ""
+"There is a risk of data loss caused by reset without the guest OS shutdown. "
+"Would you like to continue?"
+msgstr ""
+
+msgid "Shut Down Confirmation"
+msgstr "���������������"
+
+msgid "Note the guest OS may ignore this request. Would you like to continue?"
+msgstr
"���������������������������������������������������������������������?"
+
+msgid "Virtual Machine delete Confirmation"
+msgstr ""
+
+msgid ""
+"This virtual machine is not persistent. Power Off will delete it. Continue?"
+msgstr ""
+
+msgid ""
+"When the target guest has SCSI or iSCSI volumes, they will be cloned on "
+"default storage pool. The same will happen when the target pool does not "
+"have enough space to clone the volumes. Do you want to continue?"
+msgstr ""
+
+msgid ""
+"This CDROM will be detached permanently and you can re-attach it. Continue "
+"to detach it?"
+msgstr ""
+"������ CDROM
������������������������������������������������������������������������������������������������?"
+
+msgid "Attaching..."
+msgstr "���������������������..."
+
+msgid "Replacing..."
+msgstr "���������������������..."
+
+msgid "Successfully attached!"
+msgstr "���������������������������!"
+
+msgid "Successfully replaced!"
+msgstr "���������������������������!"
+
+msgid "Successfully detached!"
+msgstr "������������������������������!"
+
+msgid ""
+"This disk will be detached permanently and you can re-attach it. Continue to
"
+"detach it?"
+msgstr ""
+
+msgid "interface:"
+msgstr ""
+
+msgid "address:"
+msgstr ""
+
+msgid "link_type:"
+msgstr ""
+
+msgid "block:"
+msgstr ""
+
+msgid "drive_type:"
+msgstr ""
+
+msgid "model:"
+msgstr ""
+
+msgid "Affected devices:"
+msgstr ""
+
+msgid "The VLAN id must be between 1 and 4094."
+msgstr "VLAN ID ������1 ������ 4094 ���������������������������������������"
+
+msgid "unavailable"
+msgstr "������������"
+
+msgid ""
+"This action will interrupt network connectivity for any virtual machine that
"
+"depend on this network."
+msgstr ""
+"������������������������������������������������������������������������������������������������������������������"
+"������������������"
+
+msgid "Create a network"
+msgstr "���������������������������"
+
+msgid ""
+"This network is not persistent. Instead of stop, this action will "
+"permanently delete it. Would you like to continue?"
+msgstr ""
+"������������������������������������������������������������������������������������������������������������������"
+"���������������������������������������������������������������������������������?"
+
+msgid ""
+"The bridged VLAN tag may not work well with NetworkManager enabled. You "
+"should consider disabling it."
+msgstr ""
+
+msgid ""
+"This will permanently delete the storage pool. Would you like to continue?"
+msgstr
"������������������������������������������������������������������������������?"
+
+msgid "This storage pool is empty."
+msgstr "������������������������������������������������"
+
+msgid ""
+"It will format your disk and you will loose any data in there, are you sure "
+"to continue? "
+msgstr ""
+"���������������������������������������������������������������������������������������������������������������?"
+
+msgid "SCSI Fibre Channel"
+msgstr "SCSI ������������������������������"
+
+msgid "No SCSI adapters found."
+msgstr "SCSI ������������������������������������������"
+
+msgid "Loading iSCSI targets..."
+msgstr ""
+
+msgid "No iSCSI found. Please input one."
+msgstr ""
+
+msgid "Failed to load iSCSI targets."
+msgstr ""
+
+msgid "The storage pool name can not be blank."
+msgstr
"���������������������������������������������������������������������������������"
+
+msgid "The storage pool path can not be blank."
+msgstr
"���������������������������������������������������������������������������������������"
+
+msgid "NFS server mount path can not be blank."
+msgstr "NFS
���������������������������������������������������������������������������������������"
+
+msgid "Invalid NFS mount path."
+msgstr "NFS ���������������������������������������"
+
+msgid "No logical device selected."
+msgstr "���������������������������������������������������"
+
+msgid "The iSCSI target can not be blank."
+msgstr "iSCSI
������������������������������������������������������������������"
+
+msgid "Server name can not be blank."
+msgstr "������������������������������������������������������������������"
+
+msgid "This is not a valid Server Name or IP. Please, modify it."
+msgstr ""
+
+msgid "Looking for available partitions ..."
+msgstr "���������������������������������������������������������..."
+
+msgid "No available partitions found."
+msgstr "���������������������������������������������������������������"
+
+msgid ""
+"This storage pool is not persistent. Instead of deactivate, this action will
"
+"permanently delete it. Would you like to continue?"
+msgstr ""
+"������������������������������������������������������������������������������������������������������������������"
+"���������������������������������������������������������������������������������?"
+
+msgid "Unable to retrieve partitions information."
+msgstr "���������������������������������������������������������:
���%(err)s���"
+
+msgid "In progress..."
+msgstr ""
+
+msgid "Failed!"
+msgstr ""
+
+msgid "CDROM path needs to be a valid local/remote path and cannot be blank."
+msgstr ""
+
+msgid "Disk pool or volume cannot be blank."
+msgstr
"���������������������������������������������������������������������������������"
+
+msgid "Filter"
+msgstr ""
+
+msgid "Network Name"
+msgstr "���������������������"
+
+msgid "State"
+msgstr "������"
+
+msgid "Network Type"
+msgstr "������������������������������"
+
+msgid "Address Space"
+msgstr "���������������������������"
+
+msgid "Name should not contain '/' and '\"'."
+msgstr ""
+
+msgid "Isolated: no external network connection"
+msgstr "������: ������������������������������������"
+
+msgid "NAT: outbound physical network connection only"
+msgstr "NAT: ���������������������������������������������������������"
+
+msgid "Bridged: Virtual machines are connected to physical network directly"
+msgstr "������������:
������������������������������������������������������������������"
+
+msgid "(No interfaces found)"
+msgstr ""
+
+msgid "Destination"
+msgstr "������:"
+
+msgid "Enable VLAN"
+msgstr "VLAN ������������������������:"
+
+msgid "VLAN ID"
+msgstr "VLAN ID:"
+
+msgid "Stop"
+msgstr "������"
+
+msgid "Generate a New Debug Report"
+msgstr "������������������������������������������"
+
+msgid "Report Name"
+msgstr "���������������"
+
+msgid ""
+"The name used to identify the report. If omitted, a name will be chosen "
+"based on current time. Name can contain: letters, digits, underscore
(\"_\") "
+"and hyphen (\"-\")."
+msgstr ""
+"������������������������������������������������������������������������������������������������������������������"
+"��������������������������������������������������������������������� (-)
������������������������"
+
+msgid "Rename a Debug Report"
+msgstr "������������������������������������������"
+
+msgid ""
+"The name used to identify the report. Name can contain: letters, digits and "
+"hyphen (\"-\")."
+msgstr ""
+"������������������������������������������������������������������������������������������������������������������"
+"��������������������������������������������������������������������� (-)
������������������������"
+
+msgid "Submit"
+msgstr ""
+
+msgid "Add a Repository"
+msgstr "���������������������������"
+
+msgid "Identifier"
+msgstr "ID"
+
+msgid "Single word, unique identifier for the repository."
+msgstr "��������������������������� ID ������������������������������"
+
+msgid "Textual name for the repository."
+msgstr "���������������������������������������"
+
+msgid "URL"
+msgstr "URL"
+
+msgid "Required Field"
+msgstr "���������������������"
+
+msgid "URL to the repository. Supported protocols are http, ftp, and file."
+msgstr ""
+"��������������������� URL ���������������������������������������������������
http���ftp������������ file "
+"���������"
+
+msgid "Repository is a mirror"
+msgstr "���������������������������������������"
+
+msgid "Distribution"
+msgstr "���������������������������������"
+
+msgid "Distribution of the DEB repository."
+msgstr "DEB ���������������������������������������������������������"
+
+msgid "Components"
+msgstr "���������������������"
+
+msgid "List of components in DEB repository."
+msgstr "DEB ������������������������������������������������������������"
+
+msgid "Edit Repository"
+msgstr "���������������������������"
+
+msgid "Mirror List URL"
+msgstr "��������������������� URL"
+
+msgid "Yes"
+msgstr " ������"
+
+msgid "No"
+msgstr " ���������"
+
+msgid "Capacity"
+msgstr "������"
+
+msgid "Allocated"
+msgstr "������������������"
+
+msgid "Location"
+msgstr "������������������"
+
+msgid "Device path"
+msgstr "���������������������"
+
+msgid "active"
+msgstr "���������������"
+
+msgid "inactive"
+msgstr "������������������"
+
+msgid "Deactivate"
+msgstr "���������������������������"
+
+msgid "Activate"
+msgstr "������������������������"
+
+msgid "Add Volume"
+msgstr ""
+
+msgid "Extend"
+msgstr ""
+
+msgid "Undefine"
+msgstr "���������������������"
+
+msgid "Format"
+msgstr "������������������:"
+
+msgid "Allocation"
+msgstr "������������:"
+
+msgid "Define a New Storage Pool"
+msgstr "������������������������������������������"
+
+msgid "Storage Pool Name"
+msgstr "������������������������������"
+
+msgid ""
+"The name used to identify the storage pools, and it should not be empty."
+msgstr ""
+"������������������������������������������������������������������������������������������������������������������"
+"������"
+
+msgid "Storage Pool Type"
+msgstr "���������������������������������������"
+
+msgid "Storage Path"
+msgstr "������������������������"
+
+msgid ""
+"The path of the Storage Pool. Each Storage Pool must have a unique path."
+msgstr ""
+"���������������������������������������������������������������������������������������������������������������"
+"������"
+
+msgid ""
+"Kimchi will try to create the directory when it does not already exist in "
+"your system."
+msgstr ""
+"���������������������������������������������������������������Kimchi
���������������������������������"
+
+msgid "NFS Server IP"
+msgstr "NFS ������������ IP"
+
+msgid "NFS server IP or hostname. It can be input or chosen from history."
+msgstr ""
+"NFS ������������ IP
������������������������������������������������������������������������������������������"
+"���������������"
+
+msgid "NFS Path"
+msgstr "NFS ������"
+
+msgid "The NFS exported path on NFS server."
+msgstr "NFS ������������ NFS ������������������������������������������������"
+
+msgid "iSCSI Server"
+msgstr "iSCSI ������������"
+
+msgid "Server"
+msgstr "������������"
+
+msgid "Port"
+msgstr "���������"
+
+msgid "iSCSI server IP or hostname. It should not be empty."
+msgstr "iSCSI ������������ IP
���������������������������������������������������������������"
+
+msgid "Target"
+msgstr "���������������"
+
+msgid "The iSCSI target on iSCSI server"
+msgstr "iSCSI ������������������ iSCSI ���������������"
+
+msgid "Add iSCSI Authentication"
+msgstr "iSCSI ���������������"
+
+msgid "iSCSI Authentication"
+msgstr "iSCSI ������"
+
+msgid "User Name"
+msgstr "���������������"
+
+msgid "Password"
+msgstr "���������������"
+
+msgid "SCSI Adapter"
+msgstr "SCSI ���������������"
+
+msgid "Please, wait..."
+msgstr "���������������������..."
+
+msgid "Add a Volume to Storage Pool"
+msgstr ""
+
+msgid "Fetch from remote URL"
+msgstr ""
+
+msgid "Enter the remote URL here."
+msgstr ""
+
+msgid "Upload a file"
+msgstr ""
+
+msgid "Choose the file you want to upload."
+msgstr ""
+
+msgid "Add Template"
+msgstr "���������������������������"
+
+msgid "Where is the source media for this template? "
+msgstr
"������������������������������������������������������������������������������?"
+
+msgid "Local ISO Image"
+msgstr "������������ ISO ������������"
+
+msgid "Local Image File"
+msgstr ""
+
+msgid "Remote ISO Image"
+msgstr "������������ ISO ������������"
+
+msgid "Search ISOs"
+msgstr "ISO ���������"
+
+msgid "The following ISOs are available:"
+msgstr "������ ISO ���������������������:"
+
+msgid "OS: "
+msgstr "OS: "
+
+msgid "Version: "
+msgstr "���������������: "
+
+msgid "Size: "
+msgstr "���������: "
+
+msgid "Search more ISOs"
+msgstr "ISO ������������������"
+
+msgid "Create Templates from Selected ISO"
+msgstr "������������ ISO ���������������������������������"
+
+msgid "I want to use a specific ISO file"
+msgstr "��������� ISO ���������������������������"
+
+msgid "Loading default remote ISOs ..."
+msgstr "������������������������������ ISO ���������������������������..."
+
+msgid "Arch: "
+msgstr "������������������������: "
+
+msgid "I want to use a custom URL"
+msgstr "������������ URL ���������������"
+
+msgid "Edit Template"
+msgstr "���������������������������"
+
+msgid "CDROM"
+msgstr "CDROM"
+
+msgid "Image File"
+msgstr ""
+
+msgid "Graphics"
+msgstr "���������������������"
+
+msgid "Disk(GB)"
+msgstr ""
+
+msgid "Disk Format"
+msgstr ""
+
+msgid "CPU Number"
+msgstr "CPU ���"
+
+msgid "Manually set CPU topology"
+msgstr ""
+
+msgid "Cores"
+msgstr ""
+
+msgid "Threads"
+msgstr ""
+
+msgid "No templates found."
+msgstr "���������������������������������������������"
+
+#~ msgid "Delete is not allowed for %(resource)s"
+#~ msgstr "%(resource)s ���������������������������������"
+
+#~ msgid "%(resource)s does not implement update method"
+#~ msgstr "%(resource)s ������������������������������������������������"
+
+#~ msgid "Create is not allowed for %(resource)s"
+#~ msgstr "%(resource)s ���������������������������������"
+
+#~ msgid "Unable to parse JSON request"
+#~ msgstr "JSON ������������������������������"
+
+#~ msgid "This API only supports JSON"
+#~ msgstr "������ API ��� JSON ���������������������������"
+
+#~ msgid "Datastore is not initiated in the model object."
+#~ msgstr
"������������������������������������������������������������������������������������������"
+
+#~ msgid "Unable to start task due error: %(err)s"
+#~ msgstr "������������������������������������������������������������:
%(err)s"
+
+#~ msgid ""
+#~ "Authentication failed for user '%(username)s'. [Error code:
%(code)s]"
+#~ msgstr ""
+#~
"���������������%(username)s������������������������������������[���������������������:
%(code)s]"
+
+#~ msgid "You are not authorized to access Kimchi"
+#~ msgstr "Kimchi ������������������������������������������������"
+
+#~ msgid "Specify %(item)s to login into Kimchi"
+#~ msgstr "Kimchi ������������������������������%(item)s ������������������"
+
+#~ msgid "Unable to find %(item)s in datastore"
+#~ msgstr "%(item)s ������������������������������������������������"
+
+#~ msgid "Timeout while running command '%(cmd)s' after %(seconds)s
seconds"
+#~ msgstr ""
+#~ "���������������%(cmd)s������������������������������������%(seconds)s
������������������������������"
+#~ "������������������������"
+
+#~ msgid "Help"
+#~ msgstr "���������"
+
+#~ msgid "About"
+#~ msgstr "������������"
+
+#~ msgid "Log out"
+#~ msgstr "���������������"
+
+#~ msgid "Version:"
+#~ msgstr "���������������: "
diff --git a/src/wok/plugins/kimchi/po/kimchi.pot b/src/wok/plugins/kimchi/po/kimchi.pot
new file mode 100755
index 0000000..d4605c7
--- /dev/null
+++ b/src/wok/plugins/kimchi/po/kimchi.pot
@@ -0,0 +1,2074 @@
+# SOME DESCRIPTIVE TITLE.
+# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
+# This file is distributed under the same license as the PACKAGE package.
+# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
+#
+#, fuzzy
+msgid ""
+msgstr ""
+"Project-Id-Version: PACKAGE VERSION\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2015-07-01 16:11-0300\n"
+"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
+"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
+"Language-Team: LANGUAGE <LL(a)li.org>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=CHARSET\n"
+"Content-Transfer-Encoding: 8bit\n"
+
+#, python-format
+msgid "Unknown parameter %(value)s"
+msgstr ""
+
+#, python-format
+msgid "Timeout of %(seconds)s seconds expired while running task
'%(task)s."
+msgstr ""
+
+#, python-format
+msgid "User %(user_id)s not found with given LDAP settings."
+msgstr ""
+
+msgid "Unknown \"_cap\" specified"
+msgstr ""
+
+msgid "\"_passthrough\" should be \"true\" or
\"false\""
+msgstr ""
+
+msgid "\"_passthrough_affected_by\" should be a device name string"
+msgstr ""
+
+#, python-format
+msgid "Error while getting block devices. Details: %(err)s"
+msgstr ""
+
+#, python-format
+msgid "Error while getting block device information for %(device)s."
+msgstr ""
+
+#, python-format
+msgid "Unable to find distro file: %(filename)s"
+msgstr ""
+
+#, python-format
+msgid ""
+"Unable to parse distro file: %(filename)s. Make sure, it is a JSON file."
+msgstr ""
+
+#, python-format
+msgid "Unable to login to iSCSI host target %(portal)s. Details: %(err)s"
+msgstr ""
+
+#, python-format
+msgid "Unable to login to iSCSI host %(host)s target %(target)s"
+msgstr ""
+
+#, python-format
+msgid "Unable to find ISO file %(filename)s"
+msgstr ""
+
+#, python-format
+msgid "The ISO file %(filename)s is not bootable"
+msgstr ""
+
+#, python-format
+msgid "The ISO file %(filename)s does not have a valid El Torito boot record"
+msgstr ""
+
+#, python-format
+msgid "Invalid El Torito validation entry in ISO %(filename)s"
+msgstr ""
+
+#, python-format
+msgid "Invalid El Torito boot indicator in ISO %(filename)s"
+msgstr ""
+
+#, python-format
+msgid "Unexpected volume type for primary volume in ISO %(filename)s"
+msgstr ""
+
+#, python-format
+msgid "Bad format while reading volume descriptor in ISO %(filename)s"
+msgstr ""
+
+#, python-format
+msgid ""
+"The hypervisor doesn't have permission to use this ISO %(filename)s. "
+"Consider moving it under /var/lib/libvirt, or set the search permission to "
+"file access control lists for '%(user)s' user if possible, or add the
'%"
+"(user)s' to the ISO path group, or (not recommended) 'chmod -R o+x "
+"'path_to_iso'.Details: %(err)s"
+msgstr ""
+
+msgid "An error occurred when probing image OS information."
+msgstr ""
+
+msgid "No OS information found in given image."
+msgstr ""
+
+#, python-format
+msgid "Unable to read image file %(filename)s"
+msgstr ""
+
+#, python-format
+msgid ""
+"Image file must be an existing file on system. %(filename)s is not a valid "
+"input."
+msgstr ""
+
+#, python-format
+msgid "Virtual machine %(name)s already exists"
+msgstr ""
+
+#, python-format
+msgid "Virtual machine %(name)s does not exist"
+msgstr ""
+
+#, python-format
+msgid ""
+"Unable to rename virtual machine %(name)s. The name %(new_name)s is already "
+"in use or the virtual machine is not powered off."
+msgstr ""
+
+#, python-format
+msgid "Unable to retrieve screenshot for stopped virtual machine %(name)s"
+msgstr ""
+
+msgid "Remote ISO image is not supported by this server."
+msgstr ""
+
+#, python-format
+msgid "Screenshot is not supported on virtual machine %(name)s"
+msgstr ""
+
+#, python-format
+msgid "Unable to create virtual machine %(name)s. Details: %(err)s"
+msgstr ""
+
+#, python-format
+msgid "Unable to update virtual machine %(name)s. Details: %(err)s"
+msgstr ""
+
+#, python-format
+msgid "Unable to retrieve virtual machine %(name)s. Details: %(err)s"
+msgstr ""
+
+#, python-format
+msgid "Unable to connect to powered off virtual machine %(name)s."
+msgstr ""
+
+msgid "Virtual machine name must be a string without slashes (/)"
+msgstr ""
+
+#, python-format
+msgid "Invalid template URI %(value)s specified for virtual machine"
+msgstr ""
+
+#, python-format
+msgid "Invalid storage pool URI %(value)s specified for virtual machine"
+msgstr ""
+
+msgid "Supported virtual machine graphics are Spice or VNC"
+msgstr ""
+
+msgid "Graphics address to listen on must be IPv4 or IPv6"
+msgstr ""
+
+msgid "Specify a template to create a virtual machine from"
+msgstr ""
+
+#, python-format
+msgid "Unable to start virtual machine %(name)s. Details: %(err)s"
+msgstr ""
+
+#, python-format
+msgid "Unable to power off virtual machine %(name)s. Details: %(err)s"
+msgstr ""
+
+#, python-format
+msgid "Unable to delete virtual machine %(name)s. Details: %(err)s"
+msgstr ""
+
+#, python-format
+msgid "Unable to reset virtual machine %(name)s. Details: %(err)s"
+msgstr ""
+
+msgid "User name list must be an array"
+msgstr ""
+
+msgid "User name must be a string"
+msgstr ""
+
+msgid "Group name list must be an array"
+msgstr ""
+
+msgid "Group name must be a string"
+msgstr ""
+
+#, python-format
+msgid "User(s) '%(users)s' do not exist"
+msgstr ""
+
+#, python-format
+msgid "Group(s) '%(groups)s' do not exist"
+msgstr ""
+
+#, python-format
+msgid "Unable to shutdown virtual machine %(name)s. Details: %(err)s"
+msgstr ""
+
+#, python-format
+msgid ""
+"Unable to get access metadata of virtual machine %(name)s. Details: %(err)s"
+msgstr ""
+
+msgid "The guest console password must be a string."
+msgstr ""
+
+msgid "The life time for the guest console password must be a number."
+msgstr ""
+
+#, python-format
+msgid "Virtual machine '%(name)s' must be stopped before cloning it."
+msgstr ""
+
+#, python-format
+msgid "Insufficient disk space to clone virtual machine '%(name)s'"
+msgstr ""
+
+#, python-format
+msgid "Unable to clone VM '%(name)s'. Details: %(err)s"
+msgstr ""
+
+#, python-format
+msgid "Invalid operation for non-persistent virtual machine %(name)s"
+msgstr ""
+
+#, python-format
+msgid "Cannot suspend VM '%(name)s' because it is not running."
+msgstr ""
+
+#, python-format
+msgid "Unable to suspend VM '%(name)s'. Details: %(err)s"
+msgstr ""
+
+#, python-format
+msgid "Cannot resume VM '%(name)s' because it is not paused."
+msgstr ""
+
+#, python-format
+msgid "Unable to resume VM '%(name)s'. Details: %(err)s"
+msgstr ""
+
+msgid "Memory assigned is higher then the maximum allowed in the host."
+msgstr ""
+
+#, python-format
+msgid ""
+"VM '%(name)s' does not support live memory update. Update the memory with
"
+"the machine offline to enable this feature."
+msgstr ""
+
+msgid "Only increase memory is allowed in active VMs"
+msgstr ""
+
+msgid ""
+"For live memory update, new memory value must be equal old memory value plus
"
+"multiples of 1024 Mib"
+msgstr ""
+
+msgid "There are not enough free slots of 1024 Mib in the guest."
+msgstr ""
+
+msgid ""
+"Host's libvirt version does not support memory devices. Libvirt must be >=
"
+"1.2.14"
+msgstr ""
+
+#, python-format
+msgid "Error attaching memory device. Details: %(error)s"
+msgstr ""
+
+#, python-format
+msgid ""
+"VM %(vmid)s does not contain directly assigned host device %(dev_name)s."
+msgstr ""
+
+#, python-format
+msgid "The host device %(dev_name)s is not allowed to directly assign to VM."
+msgstr ""
+
+msgid ""
+"No IOMMU groups found. Host PCI pass through needs IOMMU group to function "
+"correctly. Please enable Intel VT-d or AMD IOMMU in your BIOS, then verify "
+"the Kernel is compiled with IOMMU support. For Intel CPU, add intel_iommu=on
"
+"to your Kernel parameter in /boot/grub2/grub.conf. For AMD CPU, add iommu=pt
"
+"iommu=1."
+msgstr ""
+
+msgid "\"name\" should be a device name string"
+msgstr ""
+
+#, python-format
+msgid ""
+"The device %(name)s is probably in use by the host. Unable to attach it to "
+"the guest."
+msgstr ""
+
+#, python-format
+msgid "Interface %(iface)s does not exist in virtual machine %(name)s"
+msgstr ""
+
+#, python-format
+msgid ""
+"Network %(network)s specified for virtual machine %(name)s does not exist"
+msgstr ""
+
+msgid "Supported virtual machine interfaces type is only network"
+msgstr ""
+
+msgid "Network name for virtual machine interface must be a string"
+msgstr ""
+
+msgid "Invalid network model card specified for virtual machine interface"
+msgstr ""
+
+msgid "Specify type and network to add a new virtual machine interface"
+msgstr ""
+
+msgid "MAC Address must respect this format FF:FF:FF:FF:FF:FF"
+msgstr ""
+
+#, python-format
+msgid "MAC Address %(mac)s already exists in virtual machine %(name)s"
+msgstr ""
+
+msgid "Invalid MAC Address"
+msgstr ""
+
+msgid "Cannot change MAC address of a running virtual machine"
+msgstr ""
+
+#, python-format
+msgid "Template %(name)s already exists"
+msgstr ""
+
+#, python-format
+msgid ""
+"Network '%(network)s' specified for template %(template)s does not
exist"
+msgstr ""
+
+#, python-format
+msgid ""
+"Storage pool %(pool)s specified for template %(template)s does not exist"
+msgstr ""
+
+#, python-format
+msgid "Storage pool %(pool)s specified for template %(template)s is not
active"
+msgstr ""
+
+#, python-format
+msgid "Invalid parameter '%(param)s' specified for CDROM."
+msgstr ""
+
+#, python-format
+msgid "Network %(network)s specified for template %(template)s is not active"
+msgstr ""
+
+msgid "Template name must be a string"
+msgstr ""
+
+msgid "Template icon must be a path to the image"
+msgstr ""
+
+msgid "Template distribution must be a string"
+msgstr ""
+
+msgid "Template distribution version must be a string"
+msgstr ""
+
+msgid "The number of CPUs must be an integer greater than 0"
+msgstr ""
+
+msgid "Amount of memory (MB) must be an integer greater than 512"
+msgstr ""
+
+msgid "Template CDROM must be a local or remote ISO file"
+msgstr ""
+
+#, python-format
+msgid "Invalid storage pool URI %(value)s specified for template"
+msgstr ""
+
+msgid "Specify an ISO image as CDROM or a base image to create a template"
+msgstr ""
+
+msgid "All networks for the template must be specified in a list."
+msgstr ""
+
+msgid "Specify a volume to a template when storage pool is iSCSI or SCSI"
+msgstr ""
+
+#, python-format
+msgid "The volume %(volume)s is not in storage pool %(pool)s"
+msgstr ""
+
+#, python-format
+msgid "Unable to create template due error: %(err)s"
+msgstr ""
+
+#, python-format
+msgid "Unable to delete template due error: %(err)s"
+msgstr ""
+
+msgid "Disk size must be an integer greater than 1GB."
+msgstr ""
+
+msgid "Template base image must be a valid local image file"
+msgstr ""
+
+#, python-format
+msgid "Cannot identify base image %(path)s format"
+msgstr ""
+
+msgid ""
+"When specifying CPU topology, VCPUs must be a product of sockets, cores, and
"
+"threads."
+msgstr ""
+
+msgid ""
+"When specifying CPU topology, each element must be an integer greater than "
+"zero."
+msgstr ""
+
+msgid ""
+"Invalid disk image format. Valid formats: bochs, cloop, cow, dmg, qcow, "
+"qcow2, qed, raw, vmdk, vpc."
+msgstr ""
+
+#, python-format
+msgid "Storage pool %(name)s already exists"
+msgstr ""
+
+#, python-format
+msgid "Storage pool %(name)s does not exist"
+msgstr ""
+
+#, python-format
+msgid "Specify %(item)s in order to create the storage pool %(name)s"
+msgstr ""
+
+#, python-format
+msgid "Unable to delete active storage pool %(name)s"
+msgstr ""
+
+#, python-format
+msgid "Unable to list storage pools. Details: %(err)s"
+msgstr ""
+
+#, python-format
+msgid "Unable to create storage pool %(name)s. Details: %(err)s"
+msgstr ""
+
+#, python-format
+msgid ""
+"Unable to get number of storage volumes in storage pool %(name)s. Details: %"
+"(err)s"
+msgstr ""
+
+#, python-format
+msgid "Unable to activate storage pool %(name)s. Details: %(err)s"
+msgstr ""
+
+#, python-format
+msgid "Unable to deactivate storage pool %(name)s. Details: %(err)s"
+msgstr ""
+
+#, python-format
+msgid "Unable to delete storage pool %(name)s. Details: %(err)s"
+msgstr ""
+
+#, python-format
+msgid ""
+"Unable to create NFS Pool as export path %(path)s may block during mount"
+msgstr ""
+
+#, python-format
+msgid "Unable to create NFS Pool as export path %(path)s mount failed"
+msgstr ""
+
+#, python-format
+msgid "Unsupported storage pool type: %(type)s"
+msgstr ""
+
+#, python-format
+msgid "Error while retrieving storage pool XML to %(pool)s"
+msgstr ""
+
+msgid "Storage pool name must be a string without slashes (/)"
+msgstr ""
+
+msgid ""
+"Supported storage pool types are dir, netfs, logical, iscsi, isci and
kimchi-"
+"iso"
+msgstr ""
+
+msgid "Storage pool path must be a string"
+msgstr ""
+
+msgid "Storage pool host must be a IP or hostname"
+msgstr ""
+
+msgid "Storage pool device must be the absolute path to the block device"
+msgstr ""
+
+msgid "Storage pool devices parameter must be a list"
+msgstr ""
+
+msgid "Target IQN of an iSCSI pool must be a string"
+msgstr ""
+
+msgid "Port of a remote storage server must be an integer between 1 and 65535"
+msgstr ""
+
+msgid "iSCSI target username must be a string"
+msgstr ""
+
+msgid "iSCSI target password must be a string"
+msgstr ""
+
+msgid "Specify name and type to create a storage pool"
+msgstr ""
+
+#, python-format
+msgid ""
+"%(disk)s is not a valid disk/partition. Could not add it to the pool %(pool)"
+"s."
+msgstr ""
+
+#, python-format
+msgid "Unable to extend logical pool %(pool)s. Details: %(err)s"
+msgstr ""
+
+msgid "The parameter disks only can be updated for logical storage pool."
+msgstr ""
+
+msgid "The SCSI host adapter name must be a string."
+msgstr ""
+
+msgid "The storage pool kimchi_isos is reserved for internal use"
+msgstr ""
+
+#, python-format
+msgid ""
+"Unable to activate NFS storage pool %(name)s. NFS server %(server)s is "
+"unreachable."
+msgstr ""
+
+#, python-format
+msgid ""
+"Unable to deactivate NFS storage pool %(name)s. NFS server %(server)s is "
+"unreachable."
+msgstr ""
+
+#, python-format
+msgid ""
+"Unable to deactivate pool %(name)s as it is associated with some templates"
+msgstr ""
+
+#, python-format
+msgid "Unable to delete pool %(name)s as it is associated with some templates"
+msgstr ""
+
+#, python-format
+msgid ""
+"A volume group named '%(name)s' already exists. Please, choose another name
"
+"to create the logical pool."
+msgstr ""
+
+#, python-format
+msgid "Unable to update database with deep scan information due error:
%(err)s"
+msgstr ""
+
+#, python-format
+msgid "Storage volume %(name)s already exists"
+msgstr ""
+
+#, python-format
+msgid "Storage volume %(name)s does not exist in storage pool %(pool)s"
+msgstr ""
+
+#, python-format
+msgid ""
+"Unable to create storage volume %(volume)s because storage pool %(pool)s is "
+"not active"
+msgstr ""
+
+#, python-format
+msgid "Specify %(item)s in order to create storage volume %(volume)s"
+msgstr ""
+
+#, python-format
+msgid ""
+"Unable to list storage volumes because storage pool %(pool)s is not active"
+msgstr ""
+
+#, python-format
+msgid ""
+"Unable to create storage volume %(name)s in storage pool %(pool)s. Details:
%"
+"(err)s"
+msgstr ""
+
+#, python-format
+msgid ""
+"Unable to list storage volumes in storage pool %(pool)s. Details: %(err)s"
+msgstr ""
+
+#, python-format
+msgid "Unable to wipe storage volumes %(name)s. Details: %(err)s"
+msgstr ""
+
+#, python-format
+msgid "Unable to delete storage volume %(name)s. Details: %(err)s"
+msgstr ""
+
+#, python-format
+msgid "Unable to resize storage volume %(name)s. Details: %(err)s"
+msgstr ""
+
+#, python-format
+msgid "Storage type %(type)s does not support volume create and delete"
+msgstr ""
+
+msgid "Storage volume name must be a string"
+msgstr ""
+
+msgid "Storage volume allocation must be an integer number"
+msgstr ""
+
+msgid ""
+"Storage volume format not supported. Valid formats: bochs, cloop, cow, dmg, "
+"qcow, qcow2, qed, raw, vmdk, vpc."
+msgstr ""
+
+msgid "Storage volume requires a volume name"
+msgstr ""
+
+#, python-format
+msgid ""
+"Unable to update database with storage volume information due error: %(err)s"
+msgstr ""
+
+#, python-format
+msgid "Only one of parameter %(param)s can be specified"
+msgstr ""
+
+#, python-format
+msgid "Create volume from %(param)s is not supported"
+msgstr ""
+
+msgid "Storage volume capacity must be an integer number."
+msgstr ""
+
+msgid "Storage volume URL must be http://, https://, ftp:// or ftps://."
+msgstr ""
+
+#, python-format
+msgid "Unable to access file %(url)s. Please, check it."
+msgstr ""
+
+#, python-format
+msgid ""
+"Unable to clone storage volume '%(name)s' in pool '%(pool)s'.
Details: %(err)"
+"s"
+msgstr ""
+
+msgid "Specify chunk data and its size to upload a file."
+msgstr ""
+
+msgid "In order to upload a storage volume, specify the 'upload'
parameter."
+msgstr ""
+
+msgid ""
+"Unable to upload chunk data as it does not match with requested chunk size."
+msgstr ""
+
+#, python-format
+msgid "The storage volume %(vol)s is not under an upload process."
+msgstr ""
+
+msgid "The upload chunk data will exceed the storage volume size."
+msgstr ""
+
+#, python-format
+msgid "Unable to upload chunk data to storage volume. Details: %(err)s."
+msgstr ""
+
+#, python-format
+msgid "Interface %(name)s does not exist"
+msgstr ""
+
+#, python-format
+msgid "Network %(name)s already exists"
+msgstr ""
+
+#, python-format
+msgid "Network %(name)s does not exist"
+msgstr ""
+
+#, python-format
+msgid "Subnet %(subnet)s specified for network %(network)s is not valid."
+msgstr ""
+
+#, python-format
+msgid "Specify a network interface to create bridged network %(name)s"
+msgstr ""
+
+#, python-format
+msgid "Unable to delete active network %(name)s"
+msgstr ""
+
+#, python-format
+msgid "Interface %(iface)s specified for network %(network)s is already in
use"
+msgstr ""
+
+msgid "Interface should be bare NIC, bonding or bridge device."
+msgstr ""
+
+#, python-format
+msgid "Unable to create network %(name)s. Details: %(err)s"
+msgstr ""
+
+#, python-format
+msgid "Unable to find a free IP address for network '%(name)s'"
+msgstr ""
+
+#, python-format
+msgid "The interface %(iface)s already exists."
+msgstr ""
+
+msgid "Network name must be a string without slashes (/) or quotes (\")"
+msgstr ""
+
+msgid "Supported network types are isolated, NAT and bridge"
+msgstr ""
+
+msgid "Network subnet must be a string with IP address and prefix or netmask"
+msgstr ""
+
+msgid "Network interface must be a string"
+msgstr ""
+
+msgid "Network VLAN ID must be an integer between 1 and 4094"
+msgstr ""
+
+msgid "Specify name and type to create a Network"
+msgstr ""
+
+#, python-format
+msgid ""
+"Unable to delete network %(name)s. There are some virtual machines %(vms)s "
+"and/or templates linked to this network."
+msgstr ""
+
+#, python-format
+msgid ""
+"Unable to deactivate network %(name)s. There are some virtual machines
%(vms)"
+"s and/or templates linked to this network."
+msgstr ""
+
+#, python-format
+msgid "Bridge device %(name)s can not be the trunk device of a VLAN."
+msgstr ""
+
+#, python-format
+msgid "Failed to activate interface %(iface)s: %(err)s."
+msgstr ""
+
+#, python-format
+msgid ""
+"Failed to activate interface %(iface)s. Please check the physical link "
+"status."
+msgstr ""
+
+#, python-format
+msgid "Failed to start network %(name)s. Details: %(err)s"
+msgstr ""
+
+#, python-format
+msgid "Debug report %(name)s does not exist"
+msgstr ""
+
+msgid "Debug report tool not found in system"
+msgstr ""
+
+#, python-format
+msgid "Unable to create debug report %(name)s. Details: %(err)s."
+msgstr ""
+
+#, python-format
+msgid "Can not find any debug report with the given name %(name)s"
+msgstr ""
+
+#, python-format
+msgid "Unable to generate debug report %(name)s. Details: %(err)s"
+msgstr ""
+
+msgid "You should give a name for the debug report file."
+msgstr ""
+
+msgid ""
+"Debug report name must be a string. Only letters, digits, underscore ('_')
"
+"and hyphen ('-') are allowed."
+msgstr ""
+
+#, python-format
+msgid ""
+"The debug report with specified name \"%(name)s\" already exists. Please
use "
+"another one."
+msgstr ""
+
+#, python-format
+msgid "Storage server %(server)s was not used by Kimchi"
+msgstr ""
+
+#, python-format
+msgid "Distro '%(name)s' does not exist"
+msgstr ""
+
+#, python-format
+msgid "Partition %(name)s does not exist in the host"
+msgstr ""
+
+msgid "Unable to shutdown host machine as there are running virtual machines"
+msgstr ""
+
+msgid "Unable to reboot host machine as there are running virtual machines"
+msgstr ""
+
+#, python-format
+msgid "Node device '%(name)s' not found"
+msgstr ""
+
+msgid "Conflicting flag filters specified."
+msgstr ""
+
+msgid "No packages marked for update"
+msgstr ""
+
+#, python-format
+msgid "Package %(name)s is not marked to be updated."
+msgstr ""
+
+#, python-format
+msgid "Error while getting packages marked to be updated. Details: %(err)s"
+msgstr ""
+
+msgid "There is no compatible package manager for this system."
+msgstr ""
+
+#, python-format
+msgid "Invalid URI %(uri)s"
+msgstr ""
+
+msgid "Unable to choose a virtual machine name"
+msgstr ""
+
+msgid "Invalid storage type. Types supported: 'cdrom', 'disk'"
+msgstr ""
+
+#, python-format
+msgid "The path '%(value)s' is not a valid local/remote path for the
device"
+msgstr ""
+
+msgid "Only CDROM path can be update."
+msgstr ""
+
+#, python-format
+msgid ""
+"The storage device %(dev_name)s does not exist in the virtual machine %"
+"(vm_name)s"
+msgstr ""
+
+#, python-format
+msgid "Error while creating new storage device: %(error)s"
+msgstr ""
+
+#, python-format
+msgid "Error while updating storage device: %(error)s"
+msgstr ""
+
+#, python-format
+msgid "Error while removing storage device: %(error)s"
+msgstr ""
+
+msgid "Do not support IDE device hot plug"
+msgstr ""
+
+msgid ""
+"Specify type and path or type and pool/volume to add a new virtual machine "
+"disk"
+msgstr ""
+
+msgid "Specify path to update virtual machine disk"
+msgstr ""
+
+#, python-format
+msgid "Controller type %(type)s limitation of %(limit)s devices reached"
+msgstr ""
+
+#, python-format
+msgid "Cannot retrieve disk path information for given pool/volume: %(error)s"
+msgstr ""
+
+msgid "Volume already in use by other virtual machine."
+msgstr ""
+
+msgid ""
+"Only one of path or pool/volume can be specified to add a new virtual "
+"machine disk"
+msgstr ""
+
+#, python-format
+msgid ""
+"Volume chosen with format %(format)s does not fit in the storage type
%(type)"
+"s"
+msgstr ""
+
+msgid "YUM Repository ID must be one word only string."
+msgstr ""
+
+msgid "Repository URL must be an http://, ftp:// or file:// URL."
+msgstr ""
+
+msgid ""
+"Repository configuration is a dictionary with specific values according to "
+"repository type."
+msgstr ""
+
+msgid "Distribution to DEB repository must be a string"
+msgstr ""
+
+msgid "Components to DEB repository must be listed in a array"
+msgstr ""
+
+msgid "Components to DEB repository must be a string"
+msgstr ""
+
+msgid "Mirror list to repository must be a string"
+msgstr ""
+
+msgid "YUM Repository name must be string."
+msgstr ""
+
+msgid "GPG check must be a boolean value."
+msgstr ""
+
+msgid "GPG key must be a URL pointing to the ASCII-armored file."
+msgstr ""
+
+#, python-format
+msgid "Could not update repository %(repo_id)s."
+msgstr ""
+
+#, python-format
+msgid "Repository %(repo_id)s does not exist."
+msgstr ""
+
+msgid ""
+"Specify repository base URL, mirror list or metalink in order to create or "
+"update a YUM repository."
+msgstr ""
+
+msgid "Repository management tool was not recognized for your system."
+msgstr ""
+
+#, python-format
+msgid "Repository %(repo_id)s is already enabled."
+msgstr ""
+
+#, python-format
+msgid "Repository %(repo_id)s is already disabled."
+msgstr ""
+
+#, python-format
+msgid "Could not remove repository %(repo_id)s."
+msgstr ""
+
+#, python-format
+msgid "Could not write repository configuration file %(repo_file)s"
+msgstr ""
+
+msgid "Specify repository distribution in order to create a DEB repository."
+msgstr ""
+
+#, python-format
+msgid "Could not enable repository %(repo_id)s."
+msgstr ""
+
+#, python-format
+msgid "Could not disable repository %(repo_id)s."
+msgstr ""
+
+msgid "YUM Repository ID already exists"
+msgstr ""
+
+msgid "YUM Repository name must be a string"
+msgstr ""
+
+#, python-format
+msgid "Unable to list repositories. Details: '%(err)s'"
+msgstr ""
+
+#, python-format
+msgid "Unable to retrieve repository information. Details: '%(err)s'"
+msgstr ""
+
+#, python-format
+msgid "Unable to add repository. Details: '%(err)s'"
+msgstr ""
+
+#, python-format
+msgid "Unable to remove repository. Details: '%(err)s'"
+msgstr ""
+
+#, python-format
+msgid ""
+"Configuration items: '%(items)s' are not supported by repository
manager"
+msgstr ""
+
+msgid "Repository metalink must be an http://, ftp:// or file:// URL."
+msgstr ""
+
+msgid "Cannot specify mirrorlist and metalink at the same time."
+msgstr ""
+
+#, python-format
+msgid ""
+"Virtual machine '%(vm)s' must be stopped before creating a snapshot of
it."
+msgstr ""
+
+#, python-format
+msgid ""
+"Unable to create snapshot '%(name)s' on virtual machine '%(vm)s'.
Details: %"
+"(err)s"
+msgstr ""
+
+#, python-format
+msgid "Snapshot '%(name)s' does not exist on virtual machine
'%(vm)s'."
+msgstr ""
+
+#, python-format
+msgid ""
+"Unable to retrieve snapshot '%(name)s' on virtual machine '%(vm)s'.
Details: "
+"%(err)s"
+msgstr ""
+
+#, python-format
+msgid "Unable to list snapshots on virtual machine '%(vm)s'. Details:
%(err)s"
+msgstr ""
+
+#, python-format
+msgid ""
+"Unable to delete snapshot '%(name)s' on virtual machine '%(vm)s'.
Details: %"
+"(err)s"
+msgstr ""
+
+#, python-format
+msgid ""
+"Unable to retrieve current snapshot of virtual machine '%(vm)s'. Details:
%"
+"(err)s"
+msgstr ""
+
+#, python-format
+msgid ""
+"Unable to revert virtual machine '%(vm)s' to snapshot '%(name)s'.
Details: %"
+"(err)s"
+msgstr ""
+
+#, python-format
+msgid ""
+"Unable to create snapshot of virtual machine '%(vm)s' because it contains a
"
+"disk with format '%(format)s'; only 'qcow2' is supported."
+msgstr ""
+
+msgid "The number of vCPUs is too large for this system."
+msgstr ""
+
+msgid "Invalid vCPU/topology combination."
+msgstr ""
+
+msgid "This host (or current configuration) does not allow CPU topology."
+msgstr ""
+
+msgid "ERROR CODE"
+msgstr ""
+
+msgid "REASON"
+msgstr ""
+
+msgid "STACK"
+msgstr ""
+
+msgid "Go to Homepage"
+msgstr ""
+
+msgid "Create a New Virtual Machine"
+msgstr ""
+
+msgid "Virtual Machine Name"
+msgstr ""
+
+msgid ""
+"The name used to identify the virtual machine. If omitted, a name will be "
+"chosen based on the template used."
+msgstr ""
+
+msgid "Template"
+msgstr ""
+
+msgid "Please create a template first."
+msgstr ""
+
+msgid "Create a Template"
+msgstr ""
+
+msgid "Please choose a template."
+msgstr ""
+
+msgid "OS"
+msgstr ""
+
+msgid "OS Version"
+msgstr ""
+
+msgid "CPUS"
+msgstr ""
+
+msgid "Memory"
+msgstr ""
+
+msgid "Create"
+msgstr ""
+
+msgid "Creating..."
+msgstr ""
+
+msgid "Cancel"
+msgstr ""
+
+msgid "Edit Guest"
+msgstr ""
+
+msgid "General"
+msgstr ""
+
+msgid "Storage"
+msgstr ""
+
+msgid "Interface"
+msgstr ""
+
+msgid "Permission"
+msgstr ""
+
+msgid "Host PCI Device"
+msgstr ""
+
+msgid "Snapshot"
+msgstr ""
+
+msgid "Name"
+msgstr ""
+
+msgid "CPUs"
+msgstr ""
+
+msgid "Memory (MB)"
+msgstr ""
+
+msgid "Icon"
+msgstr ""
+
+msgid "Device"
+msgstr ""
+
+msgid "Path"
+msgstr ""
+
+msgid "Network"
+msgstr ""
+
+msgid "Type"
+msgstr ""
+
+msgid "MAC Address"
+msgstr ""
+
+msgid "Available system users and groups"
+msgstr ""
+
+msgid "Selected system users and groups"
+msgstr ""
+
+msgid "User"
+msgstr ""
+
+msgid "All"
+msgstr ""
+
+msgid "To Add"
+msgstr ""
+
+msgid "Added"
+msgstr ""
+
+msgid "filter"
+msgstr ""
+
+msgid "Product"
+msgstr ""
+
+msgid "Vendor"
+msgstr ""
+
+msgid "Created"
+msgstr ""
+
+msgid "Save"
+msgstr ""
+
+msgid "Replace"
+msgstr ""
+
+msgid "Detach"
+msgstr ""
+
+msgid "revert"
+msgstr ""
+
+msgid "Start"
+msgstr ""
+
+msgid "Reset"
+msgstr ""
+
+msgid "Pause"
+msgstr ""
+
+msgid "Resume"
+msgstr ""
+
+msgid "Power Off"
+msgstr ""
+
+msgid "Actions"
+msgstr ""
+
+msgid "Connect"
+msgstr ""
+
+msgid "Clone"
+msgstr ""
+
+msgid "Edit"
+msgstr ""
+
+msgid "Shut Down"
+msgstr ""
+
+msgid "Delete"
+msgstr ""
+
+msgid "CPU"
+msgstr ""
+
+msgid "Disk I/O"
+msgstr ""
+
+msgid "Network I/O"
+msgstr ""
+
+msgid "Livetile"
+msgstr ""
+
+msgid "No guests found."
+msgstr ""
+
+msgid "Add a Storage Device to VM"
+msgstr ""
+
+msgid "Device Type"
+msgstr ""
+
+msgid "The device type. Currently, \"cdrom\" and \"disk\" are
supported."
+msgstr ""
+
+msgid "Storage Pool"
+msgstr ""
+
+msgid "Storage pool which volume located in"
+msgstr ""
+
+msgid "Storage Volume"
+msgstr ""
+
+msgid "Storage volume to be attached"
+msgstr ""
+
+msgid "File Path"
+msgstr ""
+
+msgid "The ISO file path in the server for CDROM."
+msgstr ""
+
+msgid "Attach"
+msgstr ""
+
+msgid "Shut down"
+msgstr ""
+
+msgid "Restart"
+msgstr ""
+
+msgid "Basic Information"
+msgstr ""
+
+msgid "OS Distro"
+msgstr ""
+
+msgid "OS Code Name"
+msgstr ""
+
+msgid "Processor"
+msgstr ""
+
+msgid "CPU(s)"
+msgstr ""
+
+msgid "System Statistics"
+msgstr ""
+
+msgid "Software Updates"
+msgstr ""
+
+msgid "Update Progress"
+msgstr ""
+
+msgid "Repositories"
+msgstr ""
+
+msgid "Debug Reports"
+msgstr ""
+
+msgid "The username or password you entered is incorrect. Please try again."
+msgstr ""
+
+msgid "This field is required."
+msgstr ""
+
+msgid "Log in"
+msgstr ""
+
+msgid "Logging in..."
+msgstr ""
+
+msgid "Host"
+msgstr ""
+
+msgid "Guests"
+msgstr ""
+
+msgid "Templates"
+msgstr ""
+
+msgid "Failed to get application configuration"
+msgstr ""
+
+msgid "This is not a valid Linux path"
+msgstr ""
+
+msgid "This is not a valid URL."
+msgstr ""
+
+msgid "No such data available."
+msgstr ""
+
+msgid ""
+"Can not contact the host system. Verify the host system is up and that you "
+"have network connectivity to it. HTTP request response %1. "
+msgstr ""
+
+msgid "Unable to read file."
+msgstr ""
+
+msgid "Error while uploading file."
+msgstr ""
+
+msgid "Delete Confirmation"
+msgstr ""
+
+msgid "OK"
+msgstr ""
+
+msgid "Confirm"
+msgstr ""
+
+msgid "Warning"
+msgstr ""
+
+msgid "Cloning..."
+msgstr ""
+
+msgid "Loading..."
+msgstr ""
+
+msgid "An error occurred while retrieving system information."
+msgstr ""
+
+msgid "Retry"
+msgstr ""
+
+msgid "Detailed message:"
+msgstr ""
+
+msgid "No ISO found"
+msgstr ""
+
+msgid "This is not a valid ISO file."
+msgstr ""
+
+msgid "This may take a long time. Do you want to continue?"
+msgstr ""
+
+msgid "This will permanently delete the template. Would you like to continue?"
+msgstr ""
+
+msgid "Unable to shut down system as there are some virtual machines running!"
+msgstr ""
+
+msgid "Max:"
+msgstr ""
+
+msgid "Utilization"
+msgstr ""
+
+msgid "Available"
+msgstr ""
+
+msgid "Read Rate"
+msgstr ""
+
+msgid "Write Rate"
+msgstr ""
+
+msgid "Received"
+msgstr ""
+
+msgid "Sent"
+msgstr ""
+
+msgid ""
+"Shutting down or restarting host will cause unsaved work lost. Continue to "
+"shut down/restarting?"
+msgstr ""
+
+msgid ""
+"Repository will be removed permanently and can't be recovered. Do you want
"
+"to continue?"
+msgstr ""
+
+msgid "ID"
+msgstr ""
+
+msgid "Base URL"
+msgstr ""
+
+msgid "Is Mirror"
+msgstr ""
+
+msgid "URL Args"
+msgstr ""
+
+msgid "Enabled"
+msgstr ""
+
+msgid "GPG Check"
+msgstr ""
+
+msgid "GPG Key"
+msgstr ""
+
+msgid "Add"
+msgstr ""
+
+msgid "Remove"
+msgstr ""
+
+msgid "Enable"
+msgstr ""
+
+msgid "Disable"
+msgstr ""
+
+msgid "Package Name"
+msgstr ""
+
+msgid "Version"
+msgstr ""
+
+msgid "Architecture"
+msgstr ""
+
+msgid "Repository"
+msgstr ""
+
+msgid "Update All"
+msgstr ""
+
+msgid "Updating..."
+msgstr ""
+
+msgid "Failed to retrieve packages update information."
+msgstr ""
+
+msgid "Failed to update package(s)."
+msgstr ""
+
+msgid ""
+"Debug report will be removed permanently and can't be recovered. Do you want
"
+"to continue?"
+msgstr ""
+
+msgid "Generated Time"
+msgstr ""
+
+msgid "Generate"
+msgstr ""
+
+msgid "Generating..."
+msgstr ""
+
+msgid "Rename"
+msgstr ""
+
+msgid "Download"
+msgstr ""
+
+msgid ""
+"Report name should contain only letters, digits, underscore ('_') and/or
"
+"hyphen ('-')."
+msgstr ""
+
+msgid "Pending..."
+msgstr ""
+
+msgid "Report name is the same as the original one."
+msgstr ""
+
+msgid ""
+"This will delete the virtual machine and its virtual disks. This operation "
+"cannot be undone. Would you like to continue?"
+msgstr ""
+
+msgid "Power off Confirmation"
+msgstr ""
+
+msgid ""
+"This action may produce undesirable results, for example unflushed disk "
+"cache in the guest. Would you like to continue?"
+msgstr ""
+
+msgid "Reset Confirmation"
+msgstr ""
+
+msgid ""
+"There is a risk of data loss caused by reset without the guest OS shutdown. "
+"Would you like to continue?"
+msgstr ""
+
+msgid "Shut Down Confirmation"
+msgstr ""
+
+msgid "Note the guest OS may ignore this request. Would you like to continue?"
+msgstr ""
+
+msgid "Virtual Machine delete Confirmation"
+msgstr ""
+
+msgid ""
+"This virtual machine is not persistent. Power Off will delete it. Continue?"
+msgstr ""
+
+msgid ""
+"When the target guest has SCSI or iSCSI volumes, they will be cloned on "
+"default storage pool. The same will happen when the target pool does not "
+"have enough space to clone the volumes. Do you want to continue?"
+msgstr ""
+
+msgid ""
+"This CDROM will be detached permanently and you can re-attach it. Continue "
+"to detach it?"
+msgstr ""
+
+msgid "Attaching..."
+msgstr ""
+
+msgid "Replacing..."
+msgstr ""
+
+msgid "Successfully attached!"
+msgstr ""
+
+msgid "Successfully replaced!"
+msgstr ""
+
+msgid "Successfully detached!"
+msgstr ""
+
+msgid ""
+"This disk will be detached permanently and you can re-attach it. Continue to
"
+"detach it?"
+msgstr ""
+
+msgid "interface:"
+msgstr ""
+
+msgid "address:"
+msgstr ""
+
+msgid "link_type:"
+msgstr ""
+
+msgid "block:"
+msgstr ""
+
+msgid "drive_type:"
+msgstr ""
+
+msgid "model:"
+msgstr ""
+
+msgid "Affected devices:"
+msgstr ""
+
+msgid "The VLAN id must be between 1 and 4094."
+msgstr ""
+
+msgid "unavailable"
+msgstr ""
+
+msgid ""
+"This action will interrupt network connectivity for any virtual machine that
"
+"depend on this network."
+msgstr ""
+
+msgid "Create a network"
+msgstr ""
+
+msgid ""
+"This network is not persistent. Instead of stop, this action will "
+"permanently delete it. Would you like to continue?"
+msgstr ""
+
+msgid ""
+"The bridged VLAN tag may not work well with NetworkManager enabled. You "
+"should consider disabling it."
+msgstr ""
+
+msgid ""
+"This will permanently delete the storage pool. Would you like to continue?"
+msgstr ""
+
+msgid "This storage pool is empty."
+msgstr ""
+
+msgid ""
+"It will format your disk and you will loose any data in there, are you sure "
+"to continue? "
+msgstr ""
+
+msgid "SCSI Fibre Channel"
+msgstr ""
+
+msgid "No SCSI adapters found."
+msgstr ""
+
+msgid "Loading iSCSI targets..."
+msgstr ""
+
+msgid "No iSCSI found. Please input one."
+msgstr ""
+
+msgid "Failed to load iSCSI targets."
+msgstr ""
+
+msgid "The storage pool name can not be blank."
+msgstr ""
+
+msgid "The storage pool path can not be blank."
+msgstr ""
+
+msgid "NFS server mount path can not be blank."
+msgstr ""
+
+msgid "Invalid NFS mount path."
+msgstr ""
+
+msgid "No logical device selected."
+msgstr ""
+
+msgid "The iSCSI target can not be blank."
+msgstr ""
+
+msgid "Server name can not be blank."
+msgstr ""
+
+msgid "This is not a valid Server Name or IP. Please, modify it."
+msgstr ""
+
+msgid "Looking for available partitions ..."
+msgstr ""
+
+msgid "No available partitions found."
+msgstr ""
+
+msgid ""
+"This storage pool is not persistent. Instead of deactivate, this action will
"
+"permanently delete it. Would you like to continue?"
+msgstr ""
+
+msgid "Unable to retrieve partitions information."
+msgstr ""
+
+msgid "In progress..."
+msgstr ""
+
+msgid "Failed!"
+msgstr ""
+
+msgid "CDROM path needs to be a valid local/remote path and cannot be blank."
+msgstr ""
+
+msgid "Disk pool or volume cannot be blank."
+msgstr ""
+
+msgid "Filter"
+msgstr ""
+
+msgid "Network Name"
+msgstr ""
+
+msgid "State"
+msgstr ""
+
+msgid "Network Type"
+msgstr ""
+
+msgid "Address Space"
+msgstr ""
+
+msgid "Name should not contain '/' and '\"'."
+msgstr ""
+
+msgid "Isolated: no external network connection"
+msgstr ""
+
+msgid "NAT: outbound physical network connection only"
+msgstr ""
+
+msgid "Bridged: Virtual machines are connected to physical network directly"
+msgstr ""
+
+msgid "(No interfaces found)"
+msgstr ""
+
+msgid "Destination"
+msgstr ""
+
+msgid "Enable VLAN"
+msgstr ""
+
+msgid "VLAN ID"
+msgstr ""
+
+msgid "Stop"
+msgstr ""
+
+msgid "Generate a New Debug Report"
+msgstr ""
+
+msgid "Report Name"
+msgstr ""
+
+msgid ""
+"The name used to identify the report. If omitted, a name will be chosen "
+"based on current time. Name can contain: letters, digits, underscore
(\"_\") "
+"and hyphen (\"-\")."
+msgstr ""
+
+msgid "Rename a Debug Report"
+msgstr ""
+
+msgid ""
+"The name used to identify the report. Name can contain: letters, digits and "
+"hyphen (\"-\")."
+msgstr ""
+
+msgid "Submit"
+msgstr ""
+
+msgid "Add a Repository"
+msgstr ""
+
+msgid "Identifier"
+msgstr ""
+
+msgid "Single word, unique identifier for the repository."
+msgstr ""
+
+msgid "Textual name for the repository."
+msgstr ""
+
+msgid "URL"
+msgstr ""
+
+msgid "Required Field"
+msgstr ""
+
+msgid "URL to the repository. Supported protocols are http, ftp, and file."
+msgstr ""
+
+msgid "Repository is a mirror"
+msgstr ""
+
+msgid "Distribution"
+msgstr ""
+
+msgid "Distribution of the DEB repository."
+msgstr ""
+
+msgid "Components"
+msgstr ""
+
+msgid "List of components in DEB repository."
+msgstr ""
+
+msgid "Edit Repository"
+msgstr ""
+
+msgid "Mirror List URL"
+msgstr ""
+
+msgid "Yes"
+msgstr ""
+
+msgid "No"
+msgstr ""
+
+msgid "Capacity"
+msgstr ""
+
+msgid "Allocated"
+msgstr ""
+
+msgid "Location"
+msgstr ""
+
+msgid "Device path"
+msgstr ""
+
+msgid "active"
+msgstr ""
+
+msgid "inactive"
+msgstr ""
+
+msgid "Deactivate"
+msgstr ""
+
+msgid "Activate"
+msgstr ""
+
+msgid "Add Volume"
+msgstr ""
+
+msgid "Extend"
+msgstr ""
+
+msgid "Undefine"
+msgstr ""
+
+msgid "Format"
+msgstr ""
+
+msgid "Allocation"
+msgstr ""
+
+msgid "Define a New Storage Pool"
+msgstr ""
+
+msgid "Storage Pool Name"
+msgstr ""
+
+msgid ""
+"The name used to identify the storage pools, and it should not be empty."
+msgstr ""
+
+msgid "Storage Pool Type"
+msgstr ""
+
+msgid "Storage Path"
+msgstr ""
+
+msgid ""
+"The path of the Storage Pool. Each Storage Pool must have a unique path."
+msgstr ""
+
+msgid ""
+"Kimchi will try to create the directory when it does not already exist in "
+"your system."
+msgstr ""
+
+msgid "NFS Server IP"
+msgstr ""
+
+msgid "NFS server IP or hostname. It can be input or chosen from history."
+msgstr ""
+
+msgid "NFS Path"
+msgstr ""
+
+msgid "The NFS exported path on NFS server."
+msgstr ""
+
+msgid "iSCSI Server"
+msgstr ""
+
+msgid "Server"
+msgstr ""
+
+msgid "Port"
+msgstr ""
+
+msgid "iSCSI server IP or hostname. It should not be empty."
+msgstr ""
+
+msgid "Target"
+msgstr ""
+
+msgid "The iSCSI target on iSCSI server"
+msgstr ""
+
+msgid "Add iSCSI Authentication"
+msgstr ""
+
+msgid "iSCSI Authentication"
+msgstr ""
+
+msgid "User Name"
+msgstr ""
+
+msgid "Password"
+msgstr ""
+
+msgid "SCSI Adapter"
+msgstr ""
+
+msgid "Please, wait..."
+msgstr ""
+
+msgid "Add a Volume to Storage Pool"
+msgstr ""
+
+msgid "Fetch from remote URL"
+msgstr ""
+
+msgid "Enter the remote URL here."
+msgstr ""
+
+msgid "Upload a file"
+msgstr ""
+
+msgid "Choose the file you want to upload."
+msgstr ""
+
+msgid "Add Template"
+msgstr ""
+
+msgid "Where is the source media for this template? "
+msgstr ""
+
+msgid "Local ISO Image"
+msgstr ""
+
+msgid "Local Image File"
+msgstr ""
+
+msgid "Remote ISO Image"
+msgstr ""
+
+msgid "Search ISOs"
+msgstr ""
+
+msgid "The following ISOs are available:"
+msgstr ""
+
+msgid "OS: "
+msgstr ""
+
+msgid "Version: "
+msgstr ""
+
+msgid "Size: "
+msgstr ""
+
+msgid "Search more ISOs"
+msgstr ""
+
+msgid "Create Templates from Selected ISO"
+msgstr ""
+
+msgid "I want to use a specific ISO file"
+msgstr ""
+
+msgid "Loading default remote ISOs ..."
+msgstr ""
+
+msgid "Arch: "
+msgstr ""
+
+msgid "I want to use a custom URL"
+msgstr ""
+
+msgid "Edit Template"
+msgstr ""
+
+msgid "CDROM"
+msgstr ""
+
+msgid "Image File"
+msgstr ""
+
+msgid "Graphics"
+msgstr ""
+
+msgid "Disk(GB)"
+msgstr ""
+
+msgid "Disk Format"
+msgstr ""
+
+msgid "CPU Number"
+msgstr ""
+
+msgid "Manually set CPU topology"
+msgstr ""
+
+msgid "Cores"
+msgstr ""
+
+msgid "Threads"
+msgstr ""
+
+msgid "No templates found."
+msgstr ""
diff --git a/src/wok/plugins/kimchi/po/ko_KR.po b/src/wok/plugins/kimchi/po/ko_KR.po
new file mode 100644
index 0000000..08bf222
--- /dev/null
+++ b/src/wok/plugins/kimchi/po/ko_KR.po
@@ -0,0 +1,2197 @@
+# English translations for kimchi package.
+# Copyright (C) 2013 ORGANIZATION
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: kimchi 0.1\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2015-07-01 16:11-0300\n"
+"PO-Revision-Date: 2013-07-11 17:32-0400\n"
+"Last-Translator: Cr��stian Viana <vianac(a)linux.vnet.ibm.com>\n"
+"Language-Team: English\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Language: ko_KR\n"
+"Generated-By: pygettext.py 1.5\n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+
+#, python-format
+msgid "Unknown parameter %(value)s"
+msgstr ""
+
+#, python-format
+msgid "Timeout of %(seconds)s seconds expired while running task
'%(task)s."
+msgstr ""
+
+#, python-format
+msgid "User %(user_id)s not found with given LDAP settings."
+msgstr ""
+
+msgid "Unknown \"_cap\" specified"
+msgstr ""
+
+msgid "\"_passthrough\" should be \"true\" or
\"false\""
+msgstr ""
+
+msgid "\"_passthrough_affected_by\" should be a device name string"
+msgstr ""
+
+#, python-format
+msgid "Error while getting block devices. Details: %(err)s"
+msgstr "������ ��������� ������������ ������ ��������� ������������������.
������������: %(err)s"
+
+#, python-format
+msgid "Error while getting block device information for %(device)s."
+msgstr "%(device)s��� ������ ������ ������ ��������� ������������ ������ ���������
������������������."
+
+#, python-format
+msgid "Unable to find distro file: %(filename)s"
+msgstr "distro ��������� ������ ��� ������: %(filename)s"
+
+#, python-format
+msgid ""
+"Unable to parse distro file: %(filename)s. Make sure, it is a JSON file."
+msgstr ""
+"distro ������(%(filename)s)��� ������ ��������� ��� ������������. JSON ������������
���������������"
+"���."
+
+#, python-format
+msgid "Unable to login to iSCSI host target %(portal)s. Details: %(err)s"
+msgstr "iSCSI ��������� ������ %(portal)s��� ������������ ��� ������������.
������������: %(err)s"
+
+#, python-format
+msgid "Unable to login to iSCSI host %(host)s target %(target)s"
+msgstr "iSCSI host %(host)s ������ %(target)s��� ������������ ���
������������."
+
+#, python-format
+msgid "Unable to find ISO file %(filename)s"
+msgstr ""
+
+#, python-format
+msgid "The ISO file %(filename)s is not bootable"
+msgstr "ISO ������ %(filename)s���(���) ������ ������������ ������������."
+
+#, python-format
+msgid "The ISO file %(filename)s does not have a valid El Torito boot record"
+msgstr "ISO ������ %(filename)s��� ��������� El Torito ������ ������������
������������."
+
+#, python-format
+msgid "Invalid El Torito validation entry in ISO %(filename)s"
+msgstr ""
+"ISO %(filename)s��� ������������ ������ El Torito ��������� ������ ���������
������������."
+
+#, python-format
+msgid "Invalid El Torito boot indicator in ISO %(filename)s"
+msgstr "ISO %(filename)s��� ������������ ������ El Torito ������ ������������
������������."
+
+#, python-format
+msgid "Unexpected volume type for primary volume in ISO %(filename)s"
+msgstr "ISO %(filename)s������ ������ ��������� ��������� ������ ������
���������������."
+
+#, python-format
+msgid "Bad format while reading volume descriptor in ISO %(filename)s"
+msgstr ""
+"ISO %(filename)s������ ������ ������������������ ������ ������ ��������� ���������
������������������"
+"���."
+
+#, python-format
+msgid ""
+"The hypervisor doesn't have permission to use this ISO %(filename)s. "
+"Consider moving it under /var/lib/libvirt, or set the search permission to "
+"file access control lists for '%(user)s' user if possible, or add the
'%"
+"(user)s' to the ISO path group, or (not recommended) 'chmod -R o+x "
+"'path_to_iso'.Details: %(err)s"
+msgstr ""
+"��������������������� ��� ISO %(filename)s���(���) ��������� ���������
������������. ������ /var/"
+"lib/libvirt ��������� ������������������, (��������� ������) ������ ���������
'%(user)s' ���������"
+"��� ������ ��������� ������ ��������� ���������������, '%(user)s'���(���)
ISO ������ ��������� ������"
+"���������, 'chmod -R o+x 'path_to_iso'(������������ ������)���
������������������. ������������: "
+"%(err)s"
+
+msgid "An error occurred when probing image OS information."
+msgstr ""
+
+msgid "No OS information found in given image."
+msgstr ""
+
+#, python-format
+msgid "Unable to read image file %(filename)s"
+msgstr ""
+
+#, python-format
+msgid ""
+"Image file must be an existing file on system. %(filename)s is not a valid "
+"input."
+msgstr ""
+
+#, python-format
+msgid "Virtual machine %(name)s already exists"
+msgstr "������ ������ %(name)s���(���) ������ ���������������."
+
+#, python-format
+msgid "Virtual machine %(name)s does not exist"
+msgstr "������ ������ %(name)s���(���) ������������."
+
+#, python-format
+msgid ""
+"Unable to rename virtual machine %(name)s. The name %(new_name)s is already "
+"in use or the virtual machine is not powered off."
+msgstr ""
+
+#, python-format
+msgid "Unable to retrieve screenshot for stopped virtual machine %(name)s"
+msgstr "��������� ������ ������ %(name)s��� ������ ��������������� ��������� ���
������������."
+
+msgid "Remote ISO image is not supported by this server."
+msgstr "������ ISO ������������ ��� ������������ ������������ ������������."
+
+#, python-format
+msgid "Screenshot is not supported on virtual machine %(name)s"
+msgstr ""
+
+#, python-format
+msgid "Unable to create virtual machine %(name)s. Details: %(err)s"
+msgstr "������ ������ %(name)s���(���) ��������� ��� ������������. ������������:
%(err)s"
+
+#, python-format
+msgid "Unable to update virtual machine %(name)s. Details: %(err)s"
+msgstr "������ ������ %(name)s���(���) ��������� ��� ������������. ������������:
%(err)s"
+
+#, python-format
+msgid "Unable to retrieve virtual machine %(name)s. Details: %(err)s"
+msgstr "������ ������ %(name)s���(���) ��������� ��� ������������. ������������:
%(err)s"
+
+#, python-format
+msgid "Unable to connect to powered off virtual machine %(name)s."
+msgstr ""
+
+msgid "Virtual machine name must be a string without slashes (/)"
+msgstr ""
+
+#, python-format
+msgid "Invalid template URI %(value)s specified for virtual machine"
+msgstr ""
+
+#, python-format
+msgid "Invalid storage pool URI %(value)s specified for virtual machine"
+msgstr ""
+
+msgid "Supported virtual machine graphics are Spice or VNC"
+msgstr ""
+
+msgid "Graphics address to listen on must be IPv4 or IPv6"
+msgstr "������ ������ ��������� ��������� IPv4 ������ IPv6������ ���������."
+
+msgid "Specify a template to create a virtual machine from"
+msgstr "������ ��������� ������������ ������ ���������������
������������������."
+
+#, python-format
+msgid "Unable to start virtual machine %(name)s. Details: %(err)s"
+msgstr "������ ������ %(name)s���(���) ��������� ��� ������������. ������������:
%(err)s"
+
+#, python-format
+msgid "Unable to power off virtual machine %(name)s. Details: %(err)s"
+msgstr "������ ������ %(name)s���(���) ��������� ��� ������������. ������������:
%(err)s"
+
+#, python-format
+msgid "Unable to delete virtual machine %(name)s. Details: %(err)s"
+msgstr "������ ������ %(name)s���(���) ��������� ��� ������������. ������������:
%(err)s"
+
+#, python-format
+msgid "Unable to reset virtual machine %(name)s. Details: %(err)s"
+msgstr "������ ������ %(name)s��� ��������� ������ ��� ������������. ������������:
%(err)s"
+
+msgid "User name list must be an array"
+msgstr ""
+
+msgid "User name must be a string"
+msgstr "������������ ��������� ������������������ ���������."
+
+msgid "Group name list must be an array"
+msgstr ""
+
+msgid "Group name must be a string"
+msgstr "������������ ��������� ������������������ ���������."
+
+#, python-format
+msgid "User(s) '%(users)s' do not exist"
+msgstr "'%(users)s' ������������ ������������."
+
+#, python-format
+msgid "Group(s) '%(groups)s' do not exist"
+msgstr "'%(groups)s' ������������ ������������."
+
+#, python-format
+msgid "Unable to shutdown virtual machine %(name)s. Details: %(err)s"
+msgstr "������ ������ %(name)s���(���) ��������� ��� ������������. ������������:
%(err)s"
+
+#, python-format
+msgid ""
+"Unable to get access metadata of virtual machine %(name)s. Details: %(err)s"
+msgstr "������ ������ %(name)s���(���) ��������� ��� ������������. ������������:
%(err)s"
+
+msgid "The guest console password must be a string."
+msgstr ""
+
+msgid "The life time for the guest console password must be a number."
+msgstr ""
+
+#, python-format
+msgid "Virtual machine '%(name)s' must be stopped before cloning it."
+msgstr ""
+
+#, python-format
+msgid "Insufficient disk space to clone virtual machine '%(name)s'"
+msgstr ""
+
+#, python-format
+msgid "Unable to clone VM '%(name)s'. Details: %(err)s"
+msgstr ""
+
+#, python-format
+msgid "Invalid operation for non-persistent virtual machine %(name)s"
+msgstr ""
+
+#, python-format
+msgid "Cannot suspend VM '%(name)s' because it is not running."
+msgstr ""
+
+#, python-format
+msgid "Unable to suspend VM '%(name)s'. Details: %(err)s"
+msgstr ""
+
+#, python-format
+msgid "Cannot resume VM '%(name)s' because it is not paused."
+msgstr ""
+
+#, python-format
+msgid "Unable to resume VM '%(name)s'. Details: %(err)s"
+msgstr ""
+
+msgid "Memory assigned is higher then the maximum allowed in the host."
+msgstr ""
+
+#, python-format
+msgid ""
+"VM '%(name)s' does not support live memory update. Update the memory with
"
+"the machine offline to enable this feature."
+msgstr ""
+
+msgid "Only increase memory is allowed in active VMs"
+msgstr ""
+
+msgid ""
+"For live memory update, new memory value must be equal old memory value plus
"
+"multiples of 1024 Mib"
+msgstr ""
+
+msgid "There are not enough free slots of 1024 Mib in the guest."
+msgstr ""
+
+msgid ""
+"Host's libvirt version does not support memory devices. Libvirt must be >=
"
+"1.2.14"
+msgstr ""
+
+#, python-format
+msgid "Error attaching memory device. Details: %(error)s"
+msgstr ""
+
+#, python-format
+msgid ""
+"VM %(vmid)s does not contain directly assigned host device %(dev_name)s."
+msgstr ""
+
+#, python-format
+msgid "The host device %(dev_name)s is not allowed to directly assign to VM."
+msgstr ""
+
+msgid ""
+"No IOMMU groups found. Host PCI pass through needs IOMMU group to function "
+"correctly. Please enable Intel VT-d or AMD IOMMU in your BIOS, then verify "
+"the Kernel is compiled with IOMMU support. For Intel CPU, add intel_iommu=on
"
+"to your Kernel parameter in /boot/grub2/grub.conf. For AMD CPU, add iommu=pt
"
+"iommu=1."
+msgstr ""
+
+msgid "\"name\" should be a device name string"
+msgstr ""
+
+#, python-format
+msgid ""
+"The device %(name)s is probably in use by the host. Unable to attach it to "
+"the guest."
+msgstr ""
+
+#, python-format
+msgid "Interface %(iface)s does not exist in virtual machine %(name)s"
+msgstr "������ ������ %(name)s��� %(iface)s ������������������ ������������."
+
+#, python-format
+msgid ""
+"Network %(network)s specified for virtual machine %(name)s does not exist"
+msgstr "������ ������ %(name)s��� ������ ��������� %(network)s ���������������
������������."
+
+msgid "Supported virtual machine interfaces type is only network"
+msgstr "������������ ������ ������ ��������������� ���������
������������������������."
+
+msgid "Network name for virtual machine interface must be a string"
+msgstr "������ ������ ������������������ ������������ ��������� ������������������
���������."
+
+msgid "Invalid network model card specified for virtual machine interface"
+msgstr ""
+"������ ������ ������������������ ������ ������������ ������ ������������ ������
��������� ������������������"
+"���."
+
+msgid "Specify type and network to add a new virtual machine interface"
+msgstr "��� ������ ������ ������������������ ��������� ������ ��� ���������������
������������������."
+
+msgid "MAC Address must respect this format FF:FF:FF:FF:FF:FF"
+msgstr ""
+
+#, python-format
+msgid "MAC Address %(mac)s already exists in virtual machine %(name)s"
+msgstr ""
+
+msgid "Invalid MAC Address"
+msgstr ""
+
+msgid "Cannot change MAC address of a running virtual machine"
+msgstr ""
+
+#, python-format
+msgid "Template %(name)s already exists"
+msgstr "������������ %(name)s���(���) ������ ���������������."
+
+#, python-format
+msgid ""
+"Network '%(network)s' specified for template %(template)s does not
exist"
+msgstr "������������ %(template)s��� ������ ��������� '%(network)s'
��������������� ������������."
+
+#, python-format
+msgid ""
+"Storage pool %(pool)s specified for template %(template)s does not exist"
+msgstr ""
+"������������ %(template)s��� ������ ��������� ������������ ��� %(pool)s���(���)
������������."
+
+#, python-format
+msgid "Storage pool %(pool)s specified for template %(template)s is not
active"
+msgstr ""
+"������������ %(template)s��� ������ ��������� ������������ ��� %(pool)s���(���)
��������� ���������"
+"���."
+
+#, python-format
+msgid "Invalid parameter '%(param)s' specified for CDROM."
+msgstr "CDROM��� ������ ������������ ������ ������������ '%(param)s'���(���)
���������������������."
+
+#, python-format
+msgid "Network %(network)s specified for template %(template)s is not active"
+msgstr ""
+"������������ %(template)s��� ������ ��������� %(network)s ��������������� ���������
������������."
+
+msgid "Template name must be a string"
+msgstr "������������ ��������� ������������������ ���������."
+
+msgid "Template icon must be a path to the image"
+msgstr "������������ ������������ ������������ ������������ ���������."
+
+msgid "Template distribution must be a string"
+msgstr "������������ ��������� ������������������ ���������."
+
+msgid "Template distribution version must be a string"
+msgstr "������������ ������ ��������� ������������������ ���������."
+
+msgid "The number of CPUs must be an integer greater than 0"
+msgstr "CPU ������ ������������ ���������."
+
+msgid "Amount of memory (MB) must be an integer greater than 512"
+msgstr "��������� ������(MB)��� 512������ ��� ������������ ���������."
+
+msgid "Template CDROM must be a local or remote ISO file"
+msgstr "������������ CDROM��� ������ ������ ������ ISO ���������������
���������."
+
+#, python-format
+msgid "Invalid storage pool URI %(value)s specified for template"
+msgstr ""
+"��������������� ������ ������������ ������ ������������ ��� URI %(value)s���(���)
���������������������."
+
+msgid "Specify an ISO image as CDROM or a base image to create a template"
+msgstr "��������������� ��������������� ISO ������������ CDROM������
������������������."
+
+msgid "All networks for the template must be specified in a list."
+msgstr "��������������� ������ ��������������� ��������� ���������������
���������."
+
+msgid "Specify a volume to a template when storage pool is iSCSI or SCSI"
+msgstr ""
+
+#, python-format
+msgid "The volume %(volume)s is not in storage pool %(pool)s"
+msgstr ""
+
+#, python-format
+msgid "Unable to create template due error: %(err)s"
+msgstr "������ ��������� ��������������� ��������� ��� ������: %(err)s"
+
+#, python-format
+msgid "Unable to delete template due error: %(err)s"
+msgstr "������ ��������� ��������������� ��������� ��� ������: %(err)s"
+
+msgid "Disk size must be an integer greater than 1GB."
+msgstr ""
+
+msgid "Template base image must be a valid local image file"
+msgstr "������������ CDROM��� ������ ������ ������ ISO ���������������
���������."
+
+#, python-format
+msgid "Cannot identify base image %(path)s format"
+msgstr ""
+
+msgid ""
+"When specifying CPU topology, VCPUs must be a product of sockets, cores, and
"
+"threads."
+msgstr ""
+
+msgid ""
+"When specifying CPU topology, each element must be an integer greater than "
+"zero."
+msgstr ""
+
+msgid ""
+"Invalid disk image format. Valid formats: bochs, cloop, cow, dmg, qcow, "
+"qcow2, qed, raw, vmdk, vpc."
+msgstr ""
+
+#, python-format
+msgid "Storage pool %(name)s already exists"
+msgstr "������������ ��� %(name)s���(���) ������ ���������������."
+
+#, python-format
+msgid "Storage pool %(name)s does not exist"
+msgstr "������������ ��� %(name)s���(���) ������������."
+
+#, python-format
+msgid "Specify %(item)s in order to create the storage pool %(name)s"
+msgstr "������������ ��� %(name)s���(���) ��������������� %(item)s���(���)
������������������."
+
+#, python-format
+msgid "Unable to delete active storage pool %(name)s"
+msgstr "������ ������������ ��� %(name)s���(���) ��������� ��� ������������."
+
+#, python-format
+msgid "Unable to list storage pools. Details: %(err)s"
+msgstr "������������ ������ ��������� ��� ������������. ������������: %(err)s"
+
+#, python-format
+msgid "Unable to create storage pool %(name)s. Details: %(err)s"
+msgstr "������������ ��� %(name)s���(���) ��������� ��� ������������. ������������:
%(err)s"
+
+#, python-format
+msgid ""
+"Unable to get number of storage volumes in storage pool %(name)s. Details: %"
+"(err)s"
+msgstr ""
+"������������ ��� %(name)s��� ������ ������������ ��������� ������ ��������� ���
������������. ���������"
+"���: %(err)s"
+
+#, python-format
+msgid "Unable to activate storage pool %(name)s. Details: %(err)s"
+msgstr "������������ ��� %(name)s���(���) ������������ ��� ������������.
������������: %(err)s"
+
+#, python-format
+msgid "Unable to deactivate storage pool %(name)s. Details: %(err)s"
+msgstr "������������ ��� %(name)s���(���) ��������������� ��� ������������.
������������: %(err)s"
+
+#, python-format
+msgid "Unable to delete storage pool %(name)s. Details: %(err)s"
+msgstr "������������ ��� %(name)s���(���) ��������� ��� ������������. ������������:
%(err)s"
+
+#, python-format
+msgid ""
+"Unable to create NFS Pool as export path %(path)s may block during mount"
+msgstr ""
+"������������ ������ %(path)s���(���) ��������� ������ ��������� ��� ������������
NFS ������ ��������� "
+"��� ������������."
+
+#, python-format
+msgid "Unable to create NFS Pool as export path %(path)s mount failed"
+msgstr ""
+"������������ ������ %(path)s ������������ ������������������ NFS ������ ���������
��� ������������."
+
+#, python-format
+msgid "Unsupported storage pool type: %(type)s"
+msgstr "������������ ������ ������������ ��� ������: %(type)s"
+
+#, python-format
+msgid "Error while retrieving storage pool XML to %(pool)s"
+msgstr ""
+
+msgid "Storage pool name must be a string without slashes (/)"
+msgstr ""
+
+msgid ""
+"Supported storage pool types are dir, netfs, logical, iscsi, isci and
kimchi-"
+"iso"
+msgstr ""
+
+msgid "Storage pool path must be a string"
+msgstr "������������ ��� ��������� ������������������ ���������."
+
+msgid "Storage pool host must be a IP or hostname"
+msgstr "������������ ��� ������������ IP ������ ��������� ���������������
���������."
+
+msgid "Storage pool device must be the absolute path to the block device"
+msgstr ""
+
+msgid "Storage pool devices parameter must be a list"
+msgstr "������������ ��� ��������� ��������������� ���������."
+
+msgid "Target IQN of an iSCSI pool must be a string"
+msgstr "iSCSI ������ ������ IQN��� ������������������ ���������."
+
+msgid "Port of a remote storage server must be an integer between 1 and 65535"
+msgstr "������ ������������ ��������� ��������� 1��� 65535 ��������� ������������
���������."
+
+msgid "iSCSI target username must be a string"
+msgstr ""
+
+msgid "iSCSI target password must be a string"
+msgstr ""
+
+msgid "Specify name and type to create a storage pool"
+msgstr "������������ ������ ��������������� ������ ��� ���������
������������������."
+
+#, python-format
+msgid ""
+"%(disk)s is not a valid disk/partition. Could not add it to the pool %(pool)"
+"s."
+msgstr ""
+"%(disk)s���(���) ��������� ���������/������������ ������������. ������ %(pool)s
������ ��������� ��� "
+"������������."
+
+#, python-format
+msgid "Unable to extend logical pool %(pool)s. Details: %(err)s"
+msgstr ""
+
+msgid "The parameter disks only can be updated for logical storage pool."
+msgstr "������ ������������ ������ ������������ ������������ ��������������� ���
������������."
+
+msgid "The SCSI host adapter name must be a string."
+msgstr "SCSI ��������� ��������� ��������� ������������������ ���������."
+
+msgid "The storage pool kimchi_isos is reserved for internal use"
+msgstr "������������ ��� kimchi_isos��� ������ ���������
���������������������."
+
+#, python-format
+msgid ""
+"Unable to activate NFS storage pool %(name)s. NFS server %(server)s is "
+"unreachable."
+msgstr ""
+"NFS ������������ ��� %(name)s���(���) ������������ ��� ������������. NFS ������
%(server)s��� ���"
+"������ ��� ������������."
+
+#, python-format
+msgid ""
+"Unable to deactivate NFS storage pool %(name)s. NFS server %(server)s is "
+"unreachable."
+msgstr ""
+"NFS ������������ ��� %(name)s���(���) ��������������� ��� ������������. NFS ������
%(server)s��� "
+"��������� ��� ������������."
+
+#, python-format
+msgid ""
+"Unable to deactivate pool %(name)s as it is associated with some templates"
+msgstr ""
+"������ ��������������� ������������ ������������ %(name)s ������ ���������������
��� ������������."
+
+#, python-format
+msgid "Unable to delete pool %(name)s as it is associated with some templates"
+msgstr "������ ��������������� ������������ ������������ %(name)s ������ ���������
��� ������������."
+
+#, python-format
+msgid ""
+"A volume group named '%(name)s' already exists. Please, choose another name
"
+"to create the logical pool."
+msgstr ""
+"��������� '%(name)s'��� ������ ��������� ������ ���������������. ������
������ ��������������� ������ ���"
+"������ ������������������."
+
+#, python-format
+msgid "Unable to update database with deep scan information due error:
%(err)s"
+msgstr ""
+"������ ��������� ��������� ������ ��������� ��������������������� ���������������
��� ������: %(err)s"
+
+#, python-format
+msgid "Storage volume %(name)s already exists"
+msgstr "������������ ������ %(name)s���(���) ������ ���������������."
+
+#, python-format
+msgid "Storage volume %(name)s does not exist in storage pool %(pool)s"
+msgstr "������������ ������ %(name)s���(���) ������������ ��� %(pool)s���
������������."
+
+#, python-format
+msgid ""
+"Unable to create storage volume %(volume)s because storage pool %(pool)s is "
+"not active"
+msgstr ""
+
+#, python-format
+msgid "Specify %(item)s in order to create storage volume %(volume)s"
+msgstr "������������ ������ %(volume)s���(���) ��������������� %(item)s���(���)
������������������."
+
+#, python-format
+msgid ""
+"Unable to list storage volumes because storage pool %(pool)s is not active"
+msgstr ""
+"������������ ��� %(pool)s���(���) ��������� ������������ ������������ ���������
��������� ��� ���������"
+"���."
+
+#, python-format
+msgid ""
+"Unable to create storage volume %(name)s in storage pool %(pool)s. Details:
%"
+"(err)s"
+msgstr ""
+"������������ ������ %(name)s���(���) ������������ ��� %(pool)s��� ��������� ���
������������. ������"
+"������: %(err)s"
+
+#, python-format
+msgid ""
+"Unable to list storage volumes in storage pool %(pool)s. Details: %(err)s"
+msgstr ""
+"������������ ��� %(pool)s��� ������������ ��������� ��������� ��� ������������.
������������: %(err)s"
+
+#, python-format
+msgid "Unable to wipe storage volumes %(name)s. Details: %(err)s"
+msgstr "������������ ��� %(name)s���(���) ��������� ��� ������������. ������������:
%(err)s"
+
+#, python-format
+msgid "Unable to delete storage volume %(name)s. Details: %(err)s"
+msgstr "������������ ������ %(name)s���(���) ��������� ��� ������������.
������������: %(err)s"
+
+#, python-format
+msgid "Unable to resize storage volume %(name)s. Details: %(err)s"
+msgstr "������������ ������ %(name)s��� ��������� ��������� ��� ������������.
������������: %(err)s"
+
+#, python-format
+msgid "Storage type %(type)s does not support volume create and delete"
+msgstr "������������ ������ %(type)s���(���) ������ ������ ��� ���������
������������ ������������."
+
+msgid "Storage volume name must be a string"
+msgstr "������������ ������ ��������� ������������������ ���������."
+
+msgid "Storage volume allocation must be an integer number"
+msgstr "������������ ������ ��������� ������������ ���������."
+
+msgid ""
+"Storage volume format not supported. Valid formats: bochs, cloop, cow, dmg, "
+"qcow, qcow2, qed, raw, vmdk, vpc."
+msgstr ""
+
+msgid "Storage volume requires a volume name"
+msgstr "������������ ��������� ������ ��������� ���������������."
+
+#, python-format
+msgid ""
+"Unable to update database with storage volume information due error: %(err)s"
+msgstr ""
+"������ ��������� ������������ ������ ��������� ���������������������
��������������� ��� ������: %(err)s"
+
+#, python-format
+msgid "Only one of parameter %(param)s can be specified"
+msgstr ""
+
+#, python-format
+msgid "Create volume from %(param)s is not supported"
+msgstr ""
+
+msgid "Storage volume capacity must be an integer number."
+msgstr ""
+
+msgid "Storage volume URL must be http://, https://, ftp:// or ftps://."
+msgstr ""
+
+#, python-format
+msgid "Unable to access file %(url)s. Please, check it."
+msgstr ""
+
+#, python-format
+msgid ""
+"Unable to clone storage volume '%(name)s' in pool '%(pool)s'.
Details: %(err)"
+"s"
+msgstr ""
+
+msgid "Specify chunk data and its size to upload a file."
+msgstr ""
+
+msgid "In order to upload a storage volume, specify the 'upload'
parameter."
+msgstr ""
+
+msgid ""
+"Unable to upload chunk data as it does not match with requested chunk size."
+msgstr ""
+
+#, python-format
+msgid "The storage volume %(vol)s is not under an upload process."
+msgstr ""
+
+msgid "The upload chunk data will exceed the storage volume size."
+msgstr ""
+
+#, python-format
+msgid "Unable to upload chunk data to storage volume. Details: %(err)s."
+msgstr ""
+
+#, python-format
+msgid "Interface %(name)s does not exist"
+msgstr "��������������� %(name)s���(���) ������������."
+
+#, python-format
+msgid "Network %(name)s already exists"
+msgstr "������������ %(name)s���(���) ������ ���������������."
+
+#, python-format
+msgid "Network %(name)s does not exist"
+msgstr "������������ %(name)s���(���) ������������."
+
+#, python-format
+msgid "Subnet %(subnet)s specified for network %(network)s is not valid."
+msgstr ""
+"������������ %(network)s��� ������ ��������� ��������� %(subnet)s���(���)
������������ ������������."
+
+#, python-format
+msgid "Specify a network interface to create bridged network %(name)s"
+msgstr ""
+"������������ ������������ %(name)s���(���) ��������� ������������
������������������ ������������������."
+
+#, python-format
+msgid "Unable to delete active network %(name)s"
+msgstr "������ ������������ %(name)s���(���) ��������� ��� ������������."
+
+#, python-format
+msgid "Interface %(iface)s specified for network %(network)s is already in
use"
+msgstr ""
+"������������ %(network)s��� ������ ��������� ��������������� %(iface)s���(���)
������ ������ ������"
+"������."
+
+msgid "Interface should be bare NIC, bonding or bridge device."
+msgstr "������������������ ������ NIC, ������ ������ ��������� ������������
���������."
+
+#, python-format
+msgid "Unable to create network %(name)s. Details: %(err)s"
+msgstr "������������ %(name)s���(���) ��������� ��� ������������. ������������:
%(err)s"
+
+#, python-format
+msgid "Unable to find a free IP address for network '%(name)s'"
+msgstr "������������ '%(name)s'��� ������ ������ IP ��������� ������ ���
������������."
+
+#, python-format
+msgid "The interface %(iface)s already exists."
+msgstr ""
+
+msgid "Network name must be a string without slashes (/) or quotes (\")"
+msgstr ""
+
+msgid "Supported network types are isolated, NAT and bridge"
+msgstr "������������ ������������ ��������� ������, NAT ���
������������������."
+
+msgid "Network subnet must be a string with IP address and prefix or netmask"
+msgstr ""
+"������������ ������������ IP ������ ��� ��������� ������ ��������������� ������
������������������ ���������."
+
+msgid "Network interface must be a string"
+msgstr "������������ ������������������ ������������������ ���������."
+
+msgid "Network VLAN ID must be an integer between 1 and 4094"
+msgstr "������������ VLAN ID��� 1��� 4094 ��������� ������������ ���������."
+
+msgid "Specify name and type to create a Network"
+msgstr "��������������� ��������������� ������ ��� ���������
������������������."
+
+#, python-format
+msgid ""
+"Unable to delete network %(name)s. There are some virtual machines %(vms)s "
+"and/or templates linked to this network."
+msgstr ""
+
+#, python-format
+msgid ""
+"Unable to deactivate network %(name)s. There are some virtual machines
%(vms)"
+"s and/or templates linked to this network."
+msgstr ""
+
+#, python-format
+msgid "Bridge device %(name)s can not be the trunk device of a VLAN."
+msgstr "��������� ������ %(name)s���(���) VLAN��� ��������� ��������� ��� ���
������������."
+
+#, python-format
+msgid "Failed to activate interface %(iface)s: %(err)s."
+msgstr "%(iface)s ������������������ ��������������� ������: %(err)s."
+
+#, python-format
+msgid ""
+"Failed to activate interface %(iface)s. Please check the physical link "
+"status."
+msgstr ""
+"%(iface)s ������������������ ��������������� ���������������. ��������� ������
��������� ���������������"
+"���."
+
+#, python-format
+msgid "Failed to start network %(name)s. Details: %(err)s"
+msgstr ""
+
+#, python-format
+msgid "Debug report %(name)s does not exist"
+msgstr "��������� ��������� %(name)s���(���) ������������."
+
+msgid "Debug report tool not found in system"
+msgstr "��������� ��������� ��������� ������������ ������������."
+
+#, python-format
+msgid "Unable to create debug report %(name)s. Details: %(err)s."
+msgstr "��������� ��������� %(name)s���(���) ��������� ��� ������������.
������������: %(err)s"
+
+#, python-format
+msgid "Can not find any debug report with the given name %(name)s"
+msgstr ""
+
+#, python-format
+msgid "Unable to generate debug report %(name)s. Details: %(err)s"
+msgstr "��������� ��������� %(name)s���(���) ��������� ��� ������������.
������������: %(err)s"
+
+msgid "You should give a name for the debug report file."
+msgstr ""
+
+msgid ""
+"Debug report name must be a string. Only letters, digits, underscore ('_')
"
+"and hyphen ('-') are allowed."
+msgstr ""
+
+#, python-format
+msgid ""
+"The debug report with specified name \"%(name)s\" already exists. Please
use "
+"another one."
+msgstr ""
+"��������� '%(name)s'��� ������ ��������� ������ ���������������. ������
������ ��������������� ������ ���"
+"������ ������������������."
+
+#, python-format
+msgid "Storage server %(server)s was not used by Kimchi"
+msgstr "������������ ������ %(server)s���(���) Kimchi������ ������������
���������������."
+
+#, python-format
+msgid "Distro '%(name)s' does not exist"
+msgstr "Distro '%(name)s'���(���) ������������."
+
+#, python-format
+msgid "Partition %(name)s does not exist in the host"
+msgstr "��������� %(name)s���(���) ������������ ������������."
+
+msgid "Unable to shutdown host machine as there are running virtual machines"
+msgstr "������ ��������� ������ ������ ��������� ��������� ��������� ���
������������."
+
+msgid "Unable to reboot host machine as there are running virtual machines"
+msgstr "������ ��������� ������ ������ ��������� ��������� ������ ��������� ���
������������."
+
+#, python-format
+msgid "Node device '%(name)s' not found"
+msgstr "������ ������ '%(name)s'���(���) ������������."
+
+msgid "Conflicting flag filters specified."
+msgstr ""
+
+msgid "No packages marked for update"
+msgstr "������������ ��������� ������������ ������������."
+
+#, python-format
+msgid "Package %(name)s is not marked to be updated."
+msgstr "��������� %(name)s���(���) ��������������������� ������������
���������������."
+
+#, python-format
+msgid "Error while getting packages marked to be updated. Details: %(err)s"
+msgstr ""
+"��������������������� ��������� ������������ ������������ ������ ���������
������������������. ������������: %"
+"(err)s"
+
+msgid "There is no compatible package manager for this system."
+msgstr "��� ������������ ������ ������ ��������� ��������� ������������
������������."
+
+#, python-format
+msgid "Invalid URI %(uri)s"
+msgstr "������������ ������ URI %(uri)s"
+
+msgid "Unable to choose a virtual machine name"
+msgstr ""
+
+msgid "Invalid storage type. Types supported: 'cdrom', 'disk'"
+msgstr "������������ ������ ������������ ���������������. ������������ ������:
'cdrom'"
+
+#, python-format
+msgid "The path '%(value)s' is not a valid local/remote path for the
device"
+msgstr ""
+
+msgid "Only CDROM path can be update."
+msgstr ""
+
+#, python-format
+msgid ""
+"The storage device %(dev_name)s does not exist in the virtual machine %"
+"(vm_name)s"
+msgstr ""
+
+#, python-format
+msgid "Error while creating new storage device: %(error)s"
+msgstr "��� ������������ ��������� ������������ ������ ������ ������:
%(error)s"
+
+#, python-format
+msgid "Error while updating storage device: %(error)s"
+msgstr "������������ ��������� ������������������ ������ ������ ������:
%(error)s"
+
+#, python-format
+msgid "Error while removing storage device: %(error)s"
+msgstr "������������ ��������� ������������ ������ ������ ������: %(error)s"
+
+msgid "Do not support IDE device hot plug"
+msgstr ""
+
+msgid ""
+"Specify type and path or type and pool/volume to add a new virtual machine "
+"disk"
+msgstr "��� ������ ������ ������������ ��������� ������ ��� ���������
������������������."
+
+msgid "Specify path to update virtual machine disk"
+msgstr "������ ������ ������������ ��������������� ���������
������������������."
+
+#, python-format
+msgid "Controller type %(type)s limitation of %(limit)s devices reached"
+msgstr ""
+
+#, python-format
+msgid "Cannot retrieve disk path information for given pool/volume: %(error)s"
+msgstr ""
+
+msgid "Volume already in use by other virtual machine."
+msgstr ""
+
+msgid ""
+"Only one of path or pool/volume can be specified to add a new virtual "
+"machine disk"
+msgstr "��� ������ ������ ������������ ��������� ������ ��� ���������
������������������."
+
+#, python-format
+msgid ""
+"Volume chosen with format %(format)s does not fit in the storage type
%(type)"
+"s"
+msgstr ""
+
+msgid "YUM Repository ID must be one word only string."
+msgstr "YUM ��������� ID��� ������ ��������� ������������������ ���������."
+
+msgid "Repository URL must be an http://, ftp:// or file:// URL."
+msgstr "��������� URL��� http://, ftp:// ������ file:// URL���������
���������."
+
+msgid ""
+"Repository configuration is a dictionary with specific values according to "
+"repository type."
+msgstr "��������� ��������� ��������� ��������� ������ ������ ������ ������
���������������."
+
+msgid "Distribution to DEB repository must be a string"
+msgstr "DEB ������������ ������ ��������� ������������������ ���������."
+
+msgid "Components to DEB repository must be listed in a array"
+msgstr "DEB ������������ ������ ��������������� ��������� ���������������
���������."
+
+msgid "Components to DEB repository must be a string"
+msgstr "DEB ������������ ������ ��������������� ������������������ ���������."
+
+msgid "Mirror list to repository must be a string"
+msgstr ""
+
+msgid "YUM Repository name must be string."
+msgstr "YUM ��������� ��������� ������������������ ���������."
+
+msgid "GPG check must be a boolean value."
+msgstr "GPG ��������� ������ ������������ ���������."
+
+msgid "GPG key must be a URL pointing to the ASCII-armored file."
+msgstr "GPG ������ ASCII ������ ��������� ������������ URL���������
���������."
+
+#, python-format
+msgid "Could not update repository %(repo_id)s."
+msgstr "%(repo_id)s ������������ ��������������� ��� ������������."
+
+#, python-format
+msgid "Repository %(repo_id)s does not exist."
+msgstr "%(repo_id)s ������������ ������������."
+
+msgid ""
+"Specify repository base URL, mirror list or metalink in order to create or "
+"update a YUM repository."
+msgstr ""
+
+msgid "Repository management tool was not recognized for your system."
+msgstr "������ ������������ ������ ��������� ������ ��������� ������������
���������������."
+
+#, python-format
+msgid "Repository %(repo_id)s is already enabled."
+msgstr "%(repo_id)s ������������ ������ ������������ ������������
������������."
+
+#, python-format
+msgid "Repository %(repo_id)s is already disabled."
+msgstr "%(repo_id)s ������������ ������ ������ ������������ ������������
������������."
+
+#, python-format
+msgid "Could not remove repository %(repo_id)s."
+msgstr "%(repo_id)s ������������ ��������� ��� ������������."
+
+#, python-format
+msgid "Could not write repository configuration file %(repo_file)s"
+msgstr "��������� ������ ������ %(repo_file)s���(���) ��������� ���
������������."
+
+msgid "Specify repository distribution in order to create a DEB repository."
+msgstr "DEB ������������ ��������������� ��������� ���������
������������������."
+
+#, python-format
+msgid "Could not enable repository %(repo_id)s."
+msgstr "%(repo_id)s ������������ ������������ ��������� ��� ������������."
+
+#, python-format
+msgid "Could not disable repository %(repo_id)s."
+msgstr "%(repo_id)s ������������ ������ ������������ ��������� ���
������������."
+
+msgid "YUM Repository ID already exists"
+msgstr "YUM ��������� ID��� ������ ���������������."
+
+msgid "YUM Repository name must be a string"
+msgstr "YUM ��������� ��������� ������������������ ���������."
+
+#, python-format
+msgid "Unable to list repositories. Details: '%(err)s'"
+msgstr "������������ ��������� ��� ������������. ������������:
'%(err)s'"
+
+#, python-format
+msgid "Unable to retrieve repository information. Details: '%(err)s'"
+msgstr "��������� ��������� ��������� ��� ������������. ������������:
'%(err)s'"
+
+#, python-format
+msgid "Unable to add repository. Details: '%(err)s'"
+msgstr "������������ ��������� ��� ������������. ������������:
'%(err)s'"
+
+#, python-format
+msgid "Unable to remove repository. Details: '%(err)s'"
+msgstr "������������ ��������� ��� ������������. ������������:
'%(err)s'"
+
+#, python-format
+msgid ""
+"Configuration items: '%(items)s' are not supported by repository
manager"
+msgstr ""
+
+msgid "Repository metalink must be an http://, ftp:// or file:// URL."
+msgstr ""
+
+msgid "Cannot specify mirrorlist and metalink at the same time."
+msgstr ""
+
+#, python-format
+msgid ""
+"Virtual machine '%(vm)s' must be stopped before creating a snapshot of
it."
+msgstr ""
+
+#, python-format
+msgid ""
+"Unable to create snapshot '%(name)s' on virtual machine '%(vm)s'.
Details: %"
+"(err)s"
+msgstr ""
+
+#, python-format
+msgid "Snapshot '%(name)s' does not exist on virtual machine
'%(vm)s'."
+msgstr ""
+
+#, python-format
+msgid ""
+"Unable to retrieve snapshot '%(name)s' on virtual machine '%(vm)s'.
Details: "
+"%(err)s"
+msgstr ""
+
+#, python-format
+msgid "Unable to list snapshots on virtual machine '%(vm)s'. Details:
%(err)s"
+msgstr ""
+
+#, python-format
+msgid ""
+"Unable to delete snapshot '%(name)s' on virtual machine '%(vm)s'.
Details: %"
+"(err)s"
+msgstr ""
+
+#, python-format
+msgid ""
+"Unable to retrieve current snapshot of virtual machine '%(vm)s'. Details:
%"
+"(err)s"
+msgstr ""
+
+#, python-format
+msgid ""
+"Unable to revert virtual machine '%(vm)s' to snapshot '%(name)s'.
Details: %"
+"(err)s"
+msgstr ""
+
+#, python-format
+msgid ""
+"Unable to create snapshot of virtual machine '%(vm)s' because it contains a
"
+"disk with format '%(format)s'; only 'qcow2' is supported."
+msgstr ""
+
+msgid "The number of vCPUs is too large for this system."
+msgstr ""
+
+msgid "Invalid vCPU/topology combination."
+msgstr ""
+
+msgid "This host (or current configuration) does not allow CPU topology."
+msgstr ""
+
+msgid "ERROR CODE"
+msgstr "������ ������"
+
+msgid "REASON"
+msgstr "������"
+
+msgid "STACK"
+msgstr "������"
+
+msgid "Go to Homepage"
+msgstr "��� ������������ ������"
+
+msgid "Create a New Virtual Machine"
+msgstr "��� ������ ������ ������"
+
+msgid "Virtual Machine Name"
+msgstr "������ ������ ������"
+
+msgid ""
+"The name used to identify the virtual machine. If omitted, a name will be "
+"chosen based on the template used."
+msgstr ""
+"������ ��������� ������������ ��� ������������ ���������������. ������������
��������� ��������� ������������"
+"��� ������������ ���������������."
+
+msgid "Template"
+msgstr "������������"
+
+msgid "Please create a template first."
+msgstr "��������������� ������ ������������������."
+
+msgid "Create a Template"
+msgstr "������������ ������"
+
+msgid "Please choose a template."
+msgstr "��������������� ������������������."
+
+msgid "OS"
+msgstr "OS"
+
+msgid "OS Version"
+msgstr "OS ������"
+
+msgid "CPUS"
+msgstr "CPUS"
+
+msgid "Memory"
+msgstr "���������"
+
+msgid "Create"
+msgstr "������"
+
+msgid "Creating..."
+msgstr ""
+
+msgid "Cancel"
+msgstr "������"
+
+msgid "Edit Guest"
+msgstr "��������� ������"
+
+msgid "General"
+msgstr "������"
+
+msgid "Storage"
+msgstr "������������"
+
+msgid "Interface"
+msgstr "���������������"
+
+msgid "Permission"
+msgstr "������"
+
+msgid "Host PCI Device"
+msgstr ""
+
+msgid "Snapshot"
+msgstr ""
+
+msgid "Name"
+msgstr "������"
+
+msgid "CPUs"
+msgstr "CPU"
+
+msgid "Memory (MB)"
+msgstr "���������"
+
+msgid "Icon"
+msgstr "���������"
+
+msgid "Device"
+msgstr "������ ������"
+
+msgid "Path"
+msgstr "NFS ������"
+
+msgid "Network"
+msgstr "������������"
+
+msgid "Type"
+msgstr "������"
+
+msgid "MAC Address"
+msgstr ""
+
+msgid "Available system users and groups"
+msgstr ""
+
+msgid "Selected system users and groups"
+msgstr ""
+
+msgid "User"
+msgstr ""
+
+msgid "All"
+msgstr "������"
+
+msgid "To Add"
+msgstr ""
+
+msgid "Added"
+msgstr ""
+
+msgid "filter"
+msgstr ""
+
+msgid "Product"
+msgstr ""
+
+msgid "Vendor"
+msgstr "������������"
+
+msgid "Created"
+msgstr ""
+
+msgid "Save"
+msgstr "������"
+
+msgid "Replace"
+msgstr "������"
+
+msgid "Detach"
+msgstr "������"
+
+msgid "revert"
+msgstr ""
+
+msgid "Start"
+msgstr "������"
+
+msgid "Reset"
+msgstr "������ ������"
+
+msgid "Pause"
+msgstr ""
+
+msgid "Resume"
+msgstr ""
+
+msgid "Power Off"
+msgstr ""
+
+msgid "Actions"
+msgstr "������"
+
+msgid "Connect"
+msgstr "������"
+
+msgid "Clone"
+msgstr ""
+
+msgid "Edit"
+msgstr "������"
+
+msgid "Shut Down"
+msgstr "��������� ������"
+
+msgid "Delete"
+msgstr "������"
+
+msgid "CPU"
+msgstr "CPU"
+
+msgid "Disk I/O"
+msgstr "��������� I/O"
+
+msgid "Network I/O"
+msgstr "������������ I/O"
+
+msgid "Livetile"
+msgstr "���������������"
+
+msgid "No guests found."
+msgstr "������������ ������������."
+
+msgid "Add a Storage Device to VM"
+msgstr "������������ ��������� VM��� ������"
+
+msgid "Device Type"
+msgstr "������ ������"
+
+msgid "The device type. Currently, \"cdrom\" and \"disk\" are
supported."
+msgstr "������ ���������������. ������ \"cdrom\"���
���������������."
+
+msgid "Storage Pool"
+msgstr "������������ ���"
+
+msgid "Storage pool which volume located in"
+msgstr "������������ ��� ��������� ������������������ ���������."
+
+msgid "Storage Volume"
+msgstr "������������ ��� ������"
+
+msgid "Storage volume to be attached"
+msgstr "������������ ������ ��������� ������������������ ���������."
+
+msgid "File Path"
+msgstr "������ ������"
+
+msgid "The ISO file path in the server for CDROM."
+msgstr "CDROM��� ������ ��������� ISO ������ ���������������."
+
+msgid "Attach"
+msgstr "������"
+
+msgid "Shut down"
+msgstr "��������� ������"
+
+msgid "Restart"
+msgstr "������ ������"
+
+msgid "Basic Information"
+msgstr "������ ������"
+
+msgid "OS Distro"
+msgstr "OS Distro"
+
+msgid "OS Code Name"
+msgstr "OS ������ ������"
+
+msgid "Processor"
+msgstr "������������"
+
+msgid "CPU(s)"
+msgstr ""
+
+msgid "System Statistics"
+msgstr "��������� ������"
+
+msgid "Software Updates"
+msgstr "��������������� ������������"
+
+msgid "Update Progress"
+msgstr "������������ ������������"
+
+msgid "Repositories"
+msgstr "���������"
+
+msgid "Debug Reports"
+msgstr "��������� ���������"
+
+msgid "The username or password you entered is incorrect. Please try again."
+msgstr ""
+"��������� ��������� ������ ������ ��������������� ������������ ������������. ������
������������������."
+
+msgid "This field is required."
+msgstr "��� ��������� ���������������."
+
+msgid "Log in"
+msgstr "���������"
+
+msgid "Logging in..."
+msgstr "��������� ���..."
+
+msgid "Host"
+msgstr "���������"
+
+msgid "Guests"
+msgstr "���������"
+
+msgid "Templates"
+msgstr "������������"
+
+msgid "Failed to get application configuration"
+msgstr "������������������ ��������� ������������ ���������������."
+
+msgid "This is not a valid Linux path"
+msgstr "��������� Linux ��������� ������������."
+
+msgid "This is not a valid URL."
+msgstr "��������� URL��� ������������."
+
+msgid "No such data available."
+msgstr "������ ������������ ������������."
+
+msgid ""
+"Can not contact the host system. Verify the host system is up and that you "
+"have network connectivity to it. HTTP request response %1. "
+msgstr ""
+"��������� ������������ ��������� ��� ������������. ��������� ������������
��������������� ������ ������ ������"
+"������ ��������� ��������� ������������������. HTTP ������ ������ %1. "
+
+msgid "Unable to read file."
+msgstr ""
+
+msgid "Error while uploading file."
+msgstr ""
+
+msgid "Delete Confirmation"
+msgstr "������ ������"
+
+msgid "OK"
+msgstr "������"
+
+msgid "Confirm"
+msgstr "������"
+
+msgid "Warning"
+msgstr "������"
+
+msgid "Cloning..."
+msgstr ""
+
+msgid "Loading..."
+msgstr "������ ���..."
+
+msgid "An error occurred while retrieving system information."
+msgstr ""
+
+msgid "Retry"
+msgstr "���������"
+
+msgid "Detailed message:"
+msgstr "������ ���������:"
+
+msgid "No ISO found"
+msgstr ""
+
+msgid "This is not a valid ISO file."
+msgstr "��������� ISO ��������� ������������."
+
+msgid "This may take a long time. Do you want to continue?"
+msgstr "��������� ������ ������������. ������������������������?"
+
+msgid "This will permanently delete the template. Would you like to continue?"
+msgstr "��������������� ��������������� ���������������.
������������������������?"
+
+msgid "Unable to shut down system as there are some virtual machines running!"
+msgstr "������ ������ ��������� ������ ������������ ������������ ��������� ���
������������."
+
+msgid "Max:"
+msgstr "������:"
+
+msgid "Utilization"
+msgstr "���������"
+
+msgid "Available"
+msgstr "������ ������"
+
+msgid "Read Rate"
+msgstr "������ ������"
+
+msgid "Write Rate"
+msgstr "������ ������"
+
+msgid "Received"
+msgstr "������"
+
+msgid "Sent"
+msgstr "������"
+
+msgid ""
+"Shutting down or restarting host will cause unsaved work lost. Continue to "
+"shut down/restarting?"
+msgstr ""
+"������������ ��������������� ������ ������������ ������������ ������ ���������
���������������. ��������� ���"
+"���/������ ��������� ������������������������?"
+
+msgid ""
+"Repository will be removed permanently and can't be recovered. Do you want
"
+"to continue?"
+msgstr "������������ ��������������� ������������ ��������� ��� ������������.
������������������������?"
+
+msgid "ID"
+msgstr "ID"
+
+msgid "Base URL"
+msgstr "������ URL"
+
+msgid "Is Mirror"
+msgstr "���������"
+
+msgid "URL Args"
+msgstr "URL ������"
+
+msgid "Enabled"
+msgstr "���������"
+
+msgid "GPG Check"
+msgstr "GPG ������"
+
+msgid "GPG Key"
+msgstr "GPG ���"
+
+msgid "Add"
+msgstr "������"
+
+msgid "Remove"
+msgstr "������"
+
+msgid "Enable"
+msgstr "������"
+
+msgid "Disable"
+msgstr "������ ������"
+
+msgid "Package Name"
+msgstr "��������� ������"
+
+msgid "Version"
+msgstr "������"
+
+msgid "Architecture"
+msgstr "������������"
+
+msgid "Repository"
+msgstr "���������"
+
+msgid "Update All"
+msgstr "������ ������������"
+
+msgid "Updating..."
+msgstr "������������ ���..."
+
+msgid "Failed to retrieve packages update information."
+msgstr ""
+
+msgid "Failed to update package(s)."
+msgstr "������������ ������������������ ���������������."
+
+msgid ""
+"Debug report will be removed permanently and can't be recovered. Do you want
"
+"to continue?"
+msgstr ""
+"��������� ������������ ��������������� ������������ ��������� ��� ������������.
������������������������?"
+
+msgid "Generated Time"
+msgstr "������ ������"
+
+msgid "Generate"
+msgstr "������"
+
+msgid "Generating..."
+msgstr "������ ���..."
+
+msgid "Rename"
+msgstr "������ ���������"
+
+msgid "Download"
+msgstr "������������"
+
+msgid ""
+"Report name should contain only letters, digits, underscore ('_') and/or
"
+"hyphen ('-')."
+msgstr "��������� ������������ ������, ������ ���/������ ���������('-')���
��������������� ���������."
+
+msgid "Pending..."
+msgstr "������ ���..."
+
+msgid "Report name is the same as the original one."
+msgstr ""
+
+msgid ""
+"This will delete the virtual machine and its virtual disks. This operation "
+"cannot be undone. Would you like to continue?"
+msgstr ""
+"������ ������ ��� ������ ������ ������������ ���������������. ��� ��������� ������
��������� ��� ���������"
+"���. ������������������������?"
+
+msgid "Power off Confirmation"
+msgstr "������ ������"
+
+msgid ""
+"This action may produce undesirable results, for example unflushed disk "
+"cache in the guest. Would you like to continue?"
+msgstr ""
+
+msgid "Reset Confirmation"
+msgstr "������ ������"
+
+msgid ""
+"There is a risk of data loss caused by reset without the guest OS shutdown. "
+"Would you like to continue?"
+msgstr ""
+
+msgid "Shut Down Confirmation"
+msgstr "������ ������"
+
+msgid "Note the guest OS may ignore this request. Would you like to continue?"
+msgstr "��������������� ��������������� ���������������.
������������������������?"
+
+msgid "Virtual Machine delete Confirmation"
+msgstr ""
+
+msgid ""
+"This virtual machine is not persistent. Power Off will delete it. Continue?"
+msgstr ""
+
+msgid ""
+"When the target guest has SCSI or iSCSI volumes, they will be cloned on "
+"default storage pool. The same will happen when the target pool does not "
+"have enough space to clone the volumes. Do you want to continue?"
+msgstr ""
+
+msgid ""
+"This CDROM will be detached permanently and you can re-attach it. Continue "
+"to detach it?"
+msgstr ""
+"��� CDROM��� ��������������� ������������ ������ ��������� ��� ������������.
��������� ���������������������"
+"���?"
+
+msgid "Attaching..."
+msgstr "������ ���..."
+
+msgid "Replacing..."
+msgstr "������ ���..."
+
+msgid "Successfully attached!"
+msgstr "���������������������."
+
+msgid "Successfully replaced!"
+msgstr "���������������������."
+
+msgid "Successfully detached!"
+msgstr "���������������������."
+
+msgid ""
+"This disk will be detached permanently and you can re-attach it. Continue to
"
+"detach it?"
+msgstr ""
+
+msgid "interface:"
+msgstr ""
+
+msgid "address:"
+msgstr ""
+
+msgid "link_type:"
+msgstr ""
+
+msgid "block:"
+msgstr ""
+
+msgid "drive_type:"
+msgstr ""
+
+msgid "model:"
+msgstr ""
+
+msgid "Affected devices:"
+msgstr ""
+
+msgid "The VLAN id must be between 1 and 4094."
+msgstr "VLAN ID��� 1��� 4094 ������������ ���������."
+
+msgid "unavailable"
+msgstr "������ ���������"
+
+msgid ""
+"This action will interrupt network connectivity for any virtual machine that
"
+"depend on this network."
+msgstr ""
+"��� ��������� ��� ��������������� ������������ ������ ��������� ������������
��������� ���������������������."
+
+msgid "Create a network"
+msgstr "������������ ������"
+
+msgid ""
+"This network is not persistent. Instead of stop, this action will "
+"permanently delete it. Would you like to continue?"
+msgstr ""
+"��� ������������ ������ ��������������� ������������. ��� ��������� ������
������������������ ������ ���������"
+"������ ���������������. ������������������������?"
+
+msgid ""
+"The bridged VLAN tag may not work well with NetworkManager enabled. You "
+"should consider disabling it."
+msgstr ""
+
+msgid ""
+"This will permanently delete the storage pool. Would you like to continue?"
+msgstr "������������ ������ ��������������� ���������������.
������������������������?"
+
+msgid "This storage pool is empty."
+msgstr "��� ������������ ������ ������ ������������."
+
+msgid ""
+"It will format your disk and you will loose any data in there, are you sure "
+"to continue? "
+msgstr "������������ ������������ ������������ ���������������.
������������������������? "
+
+msgid "SCSI Fibre Channel"
+msgstr "SCSI ��������� ������"
+
+msgid "No SCSI adapters found."
+msgstr "SCSI ������������ ������������."
+
+msgid "Loading iSCSI targets..."
+msgstr ""
+
+msgid "No iSCSI found. Please input one."
+msgstr ""
+
+msgid "Failed to load iSCSI targets."
+msgstr ""
+
+msgid "The storage pool name can not be blank."
+msgstr "������������ ��� ��������� ��������� ��� ������������."
+
+msgid "The storage pool path can not be blank."
+msgstr "������������ ��� ��������� ��������� ��� ������������."
+
+msgid "NFS server mount path can not be blank."
+msgstr "NFS ������ ��������� ��������� ��������� ��� ������������."
+
+msgid "Invalid NFS mount path."
+msgstr "������������ ������ NFS ��������� ���������������."
+
+msgid "No logical device selected."
+msgstr "������ ��������� ������������ ���������������."
+
+msgid "The iSCSI target can not be blank."
+msgstr "iSCSI ��������� ��������� ��� ������������."
+
+msgid "Server name can not be blank."
+msgstr "������ ��������� ��������� ��� ������������."
+
+msgid "This is not a valid Server Name or IP. Please, modify it."
+msgstr ""
+
+msgid "Looking for available partitions ..."
+msgstr "������ ��������� ������������ ������ ���..."
+
+msgid "No available partitions found."
+msgstr "������ ��������� ������������ ������������."
+
+msgid ""
+"This storage pool is not persistent. Instead of deactivate, this action will
"
+"permanently delete it. Would you like to continue?"
+msgstr ""
+"��� ������������ ������ ��������������� ������������. ��� ��������� ������
������������������ ������ ���������"
+"������ ���������������. ������������������������?"
+
+msgid "Unable to retrieve partitions information."
+msgstr "��������� ��������� ��������� ��� ������������. ������������:
'%(err)s'"
+
+msgid "In progress..."
+msgstr ""
+
+msgid "Failed!"
+msgstr ""
+
+msgid "CDROM path needs to be a valid local/remote path and cannot be blank."
+msgstr ""
+
+msgid "Disk pool or volume cannot be blank."
+msgstr "������������ ��� ��������� ��������� ��� ������������."
+
+msgid "Filter"
+msgstr ""
+
+msgid "Network Name"
+msgstr "������������ ������"
+
+msgid "State"
+msgstr "������"
+
+msgid "Network Type"
+msgstr "������������ ������"
+
+msgid "Address Space"
+msgstr "������ ������"
+
+msgid "Name should not contain '/' and '\"'."
+msgstr "������������ ������ ������������ ��� ���������������. '/'���
������������ ��������� ���������."
+
+msgid "Isolated: no external network connection"
+msgstr "���������: ��������� ������������ ������ ������"
+
+msgid "NAT: outbound physical network connection only"
+msgstr "NAT: ��������������� ��������� ������������ ���������"
+
+msgid "Bridged: Virtual machines are connected to physical network directly"
+msgstr "������������: ������ ��������� ��������� ��������������� ������
���������"
+
+msgid "(No interfaces found)"
+msgstr ""
+
+msgid "Destination"
+msgstr "������:"
+
+msgid "Enable VLAN"
+msgstr "VLAN ������:"
+
+msgid "VLAN ID"
+msgstr "VLAN ID:"
+
+msgid "Stop"
+msgstr "������"
+
+msgid "Generate a New Debug Report"
+msgstr "��� ��������� ��������� ������"
+
+msgid "Report Name"
+msgstr "��������� ������"
+
+msgid ""
+"The name used to identify the report. If omitted, a name will be chosen "
+"based on current time. Name can contain: letters, digits, underscore
(\"_\") "
+"and hyphen (\"-\")."
+msgstr ""
+"������������ ������������ ��� ������������ ���������������. ������������ ���������
������ ��������� ���������"
+"��� ���������������. ��������� ������, ������ ��� ���������(\"-\")���
��������� ��� ������������."
+
+msgid "Rename a Debug Report"
+msgstr "��� ��������� ��������� ������"
+
+msgid ""
+"The name used to identify the report. Name can contain: letters, digits and "
+"hyphen (\"-\")."
+msgstr ""
+"������������ ������������ ��� ������������ ���������������. ������������ ���������
������ ��������� ���������"
+"��� ���������������. ��������� ������, ������ ��� ���������(\"-\")���
��������� ��� ������������."
+
+msgid "Submit"
+msgstr ""
+
+msgid "Add a Repository"
+msgstr "��������� ������"
+
+msgid "Identifier"
+msgstr "ID"
+
+msgid "Single word, unique identifier for the repository."
+msgstr "������������ ������ ������ ��������� ������ ID���������."
+
+msgid "Textual name for the repository."
+msgstr "������������ ������ ��������� ���������������."
+
+msgid "URL"
+msgstr "URL"
+
+msgid "Required Field"
+msgstr "������ ������"
+
+msgid "URL to the repository. Supported protocols are http, ftp, and file."
+msgstr "������������ ������ URL���������. ������������ ��������������� http, ftp ���
file���������."
+
+msgid "Repository is a mirror"
+msgstr "������������ ���������������."
+
+msgid "Distribution"
+msgstr "������"
+
+msgid "Distribution of the DEB repository."
+msgstr "DEB ������������ ���������������."
+
+msgid "Components"
+msgstr "������������"
+
+msgid "List of components in DEB repository."
+msgstr "DEB ������������ ������������ ���������������."
+
+msgid "Edit Repository"
+msgstr "��������� ������"
+
+msgid "Mirror List URL"
+msgstr "������ ������ URL"
+
+msgid "Yes"
+msgstr "���"
+
+msgid "No"
+msgstr "���������"
+
+msgid "Capacity"
+msgstr "������"
+
+msgid "Allocated"
+msgstr "���������"
+
+msgid "Location"
+msgstr "������"
+
+msgid "Device path"
+msgstr "������ ������"
+
+msgid "active"
+msgstr "������"
+
+msgid "inactive"
+msgstr "���������"
+
+msgid "Deactivate"
+msgstr "������������"
+
+msgid "Activate"
+msgstr "���������"
+
+msgid "Add Volume"
+msgstr ""
+
+msgid "Extend"
+msgstr ""
+
+msgid "Undefine"
+msgstr "������ ������"
+
+msgid "Format"
+msgstr "������:"
+
+msgid "Allocation"
+msgstr "������:"
+
+msgid "Define a New Storage Pool"
+msgstr "��� ������������ ��� ������"
+
+msgid "Storage Pool Name"
+msgstr "������������ ��� ������"
+
+msgid ""
+"The name used to identify the storage pools, and it should not be empty."
+msgstr "������������ ������ ������������ ��� ������������ ������������ ������ ������
��������� ���������."
+
+msgid "Storage Pool Type"
+msgstr "������������ ��� ������"
+
+msgid "Storage Path"
+msgstr "������������ ������"
+
+msgid ""
+"The path of the Storage Pool. Each Storage Pool must have a unique path."
+msgstr "������������ ������ ���������������. ��� ������������ ������ ������
��������� ��������� ���������."
+
+msgid ""
+"Kimchi will try to create the directory when it does not already exist in "
+"your system."
+msgstr ""
+"��������������� ������������ ������ ������������ ��������� Kimchi��� ������������
��������� ���������������."
+
+msgid "NFS Server IP"
+msgstr "NFS ������ IP"
+
+msgid "NFS server IP or hostname. It can be input or chosen from history."
+msgstr ""
+"NFS ������ IP ������ ��������� ���������������. ��������� ���������������
������������������ ��������� ��� "
+"������������."
+
+msgid "NFS Path"
+msgstr "NFS ������"
+
+msgid "The NFS exported path on NFS server."
+msgstr "NFS ������������ NFS��� ��������� ���������������."
+
+msgid "iSCSI Server"
+msgstr "iSCSI ������"
+
+msgid "Server"
+msgstr "������"
+
+msgid "Port"
+msgstr "������"
+
+msgid "iSCSI server IP or hostname. It should not be empty."
+msgstr "iSCSI ������ IP ������ ��������� ���������������. ������ ������ ���������
���������."
+
+msgid "Target"
+msgstr "������"
+
+msgid "The iSCSI target on iSCSI server"
+msgstr "iSCSI ��������� iSCSI ������"
+
+msgid "Add iSCSI Authentication"
+msgstr "iSCSI ������ ������"
+
+msgid "iSCSI Authentication"
+msgstr "iSCSI ������"
+
+msgid "User Name"
+msgstr "��������� ������"
+
+msgid "Password"
+msgstr "������������"
+
+msgid "SCSI Adapter"
+msgstr "SCSI ���������"
+
+msgid "Please, wait..."
+msgstr "������ ��������� ������������."
+
+msgid "Add a Volume to Storage Pool"
+msgstr ""
+
+msgid "Fetch from remote URL"
+msgstr ""
+
+msgid "Enter the remote URL here."
+msgstr ""
+
+msgid "Upload a file"
+msgstr ""
+
+msgid "Choose the file you want to upload."
+msgstr ""
+
+msgid "Add Template"
+msgstr "������������ ������"
+
+msgid "Where is the source media for this template? "
+msgstr "��� ��������������� ������ ��������� ��������� ������������?"
+
+msgid "Local ISO Image"
+msgstr "������ ISO ���������"
+
+msgid "Local Image File"
+msgstr ""
+
+msgid "Remote ISO Image"
+msgstr "������ ISO ���������"
+
+msgid "Search ISOs"
+msgstr "ISO ������"
+
+msgid "The following ISOs are available:"
+msgstr "������ ISO��� ������ ���������������."
+
+msgid "OS: "
+msgstr "OS: "
+
+msgid "Version: "
+msgstr "������: "
+
+msgid "Size: "
+msgstr "������: "
+
+msgid "Search more ISOs"
+msgstr "������ ISO ������"
+
+msgid "Create Templates from Selected ISO"
+msgstr "��������� ISO��������� ������������ ������"
+
+msgid "I want to use a specific ISO file"
+msgstr "������ ISO ��������� ��������������� ���������."
+
+msgid "Loading default remote ISOs ..."
+msgstr "������ ������ ISO ������ ���..."
+
+msgid "Arch: "
+msgstr "Arch: "
+
+msgid "I want to use a custom URL"
+msgstr "��������� ������ URL��� ��������������� ���������."
+
+msgid "Edit Template"
+msgstr "������������ ������"
+
+msgid "CDROM"
+msgstr "CDROM"
+
+msgid "Image File"
+msgstr ""
+
+msgid "Graphics"
+msgstr "���������"
+
+msgid "Disk(GB)"
+msgstr ""
+
+msgid "Disk Format"
+msgstr ""
+
+msgid "CPU Number"
+msgstr "CPU ������"
+
+msgid "Manually set CPU topology"
+msgstr ""
+
+msgid "Cores"
+msgstr ""
+
+msgid "Threads"
+msgstr ""
+
+msgid "No templates found."
+msgstr "��������������� ������������."
+
+#~ msgid "Delete is not allowed for %(resource)s"
+#~ msgstr "%(resource)s��� ��������� ������������ ������"
+
+#~ msgid "%(resource)s does not implement update method"
+#~ msgstr "%(resource)s��������� ������������ ������������ ������������
������"
+
+#~ msgid "Create is not allowed for %(resource)s"
+#~ msgstr "%(resource)s��� ��������� ������������ ������"
+
+#~ msgid "Unable to parse JSON request"
+#~ msgstr "JSON ��������� ������ ��������� ��� ������������."
+
+#~ msgid "This API only supports JSON"
+#~ msgstr "��� API��� JSON��� ���������������."
+
+#~ msgid "Datastore is not initiated in the model object."
+#~ msgstr "��������� ������������ ������ ������������������ ������������
���������������."
+
+#~ msgid "Unable to start task due error: %(err)s"
+#~ msgstr "������ ��������� ��������� ��������� ��� ������: %(err)s"
+
+#~ msgid ""
+#~ "Authentication failed for user '%(username)s'. [Error code:
%(code)s]"
+#~ msgstr "��������� '%(username)s'��� ��������� ������������������. [������
������: %(code)s]"
+
+#~ msgid "You are not authorized to access Kimchi"
+#~ msgstr "Kimchi��� ������������ ��������� ������������."
+
+#~ msgid "Specify %(item)s to login into Kimchi"
+#~ msgstr "Kimchi��� ������������������ %(item)s���(���) ������������������."
+
+#~ msgid "Unable to find %(item)s in datastore"
+#~ msgstr "��������� ��������������� %(item)s���(���) ������ ���
������������."
+
+#~ msgid "Timeout while running command '%(cmd)s' after %(seconds)s
seconds"
+#~ msgstr ""
+#~ "%(seconds)s��� ������ '%(cmd)s' ������ ������ ��� ���������������
���������������������."
+
+#~ msgid "Help"
+#~ msgstr "���������"
+
+#~ msgid "About"
+#~ msgstr "������"
+
+#~ msgid "Log out"
+#~ msgstr "������������"
+
+#~ msgid "Version:"
+#~ msgstr "������: "
diff --git a/src/wok/plugins/kimchi/po/pt_BR.po b/src/wok/plugins/kimchi/po/pt_BR.po
new file mode 100644
index 0000000..c2cb4e9
--- /dev/null
+++ b/src/wok/plugins/kimchi/po/pt_BR.po
@@ -0,0 +1,2369 @@
+# i18n portable object for kimchi.
+# Copyright (C) IBM, Corp. 2013-2014
+# ShaoHe Feng <shaohef(a)linux.vnet.ibm.com>, 2013-04-18.
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: kimchi 1.0\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2015-07-01 16:11-0300\n"
+"PO-Revision-Date: 2015-03-23 12:57+0000\n"
+"Last-Translator: Cr��stian Deives dos Santos Viana <cristiandeives(a)gmail."
+"com>\n"
+"Language-Team: Portuguese (Brazil) (
http://www.transifex.com/projects/p/"
+"kimchi/language/pt_BR/)\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Language: pt_BR\n"
+"Plural-Forms: nplurals=2; plural=(n > 1);\n"
+
+#, python-format
+msgid "Unknown parameter %(value)s"
+msgstr "Par��metro desconhecido: %(value)s"
+
+#, python-format
+msgid "Timeout of %(seconds)s seconds expired while running task
'%(task)s."
+msgstr ""
+"Limite de tempo de %(seconds)s segundos expirado ao executar a tarefa '%"
+"(task)s'."
+
+#, python-format
+msgid "User %(user_id)s not found with given LDAP settings."
+msgstr "Usu��rio %(user_id)s n��o encontrado com as configura����es LDAP
dadas."
+
+msgid "Unknown \"_cap\" specified"
+msgstr "\"_cap\" desconhecido especificado"
+
+msgid "\"_passthrough\" should be \"true\" or
\"false\""
+msgstr "\"_passthrough\" deve ser \"true\" ou
\"false\""
+
+msgid "\"_passthrough_affected_by\" should be a device name string"
+msgstr "\"_passthrough_affected_by\" deve ser um texto do nome do
dispositivo"
+
+#, python-format
+msgid "Error while getting block devices. Details: %(err)s"
+msgstr "Erro ao consultar block devices. Detalhes %(err)s"
+
+#, python-format
+msgid "Error while getting block device information for %(device)s."
+msgstr "Erro ao consultar informa����es de block devices para %(device)s."
+
+#, python-format
+msgid "Unable to find distro file: %(filename)s"
+msgstr "N��o foi poss��vel encontrar o arquivo da distribui����o:
%(filename)s"
+
+#, python-format
+msgid ""
+"Unable to parse distro file: %(filename)s. Make sure, it is a JSON file."
+msgstr ""
+"N��o foi poss��vel ler o arquivo da distribui����o: %(filename)s. Confirme se ��
"
+"um arquivo JSON."
+
+#, python-format
+msgid "Unable to login to iSCSI host target %(portal)s. Details: %(err)s"
+msgstr ""
+"N��o foi poss��vel logar na m��quina alvo do iSCSI %(portal)s. Detalhes:
%(err)s"
+
+#, python-format
+msgid "Unable to login to iSCSI host %(host)s target %(target)s"
+msgstr "N��o foi poss��vel logar na m��quina %(host)s alvo %(target)s do
iSCSI"
+
+#, python-format
+msgid "Unable to find ISO file %(filename)s"
+msgstr "N��o foi poss��vel encontrar a ISO %(filename)s"
+
+#, python-format
+msgid "The ISO file %(filename)s is not bootable"
+msgstr "A ISO %(filename)s n��o �� boot��vel"
+
+#, python-format
+msgid "The ISO file %(filename)s does not have a valid El Torito boot record"
+msgstr "A ISO %(filename)s n��o possui uma grava����o v��lida de boot El
Torito"
+
+#, python-format
+msgid "Invalid El Torito validation entry in ISO %(filename)s"
+msgstr "Valida����o El Torito inv��lida na ISO %(filename)s"
+
+#, python-format
+msgid "Invalid El Torito boot indicator in ISO %(filename)s"
+msgstr "Indicador de boot El Torito inv��lido na ISO %(filename)s"
+
+#, python-format
+msgid "Unexpected volume type for primary volume in ISO %(filename)s"
+msgstr ""
+"Tipo de volume n��o esperado para um volume prim��rio na ISO %(filename)s"
+
+#, python-format
+msgid "Bad format while reading volume descriptor in ISO %(filename)s"
+msgstr "Formato errado na leitura do descritor de volume na ISO %(filename)s"
+
+#, python-format
+msgid ""
+"The hypervisor doesn't have permission to use this ISO %(filename)s. "
+"Consider moving it under /var/lib/libvirt, or set the search permission to "
+"file access control lists for '%(user)s' user if possible, or add the
'%"
+"(user)s' to the ISO path group, or (not recommended) 'chmod -R o+x "
+"'path_to_iso'.Details: %(err)s"
+msgstr ""
+"O servidor n��o tem permiss��o para acessar a ISO %(filename)s. Considere
mud��-"
+"la para o diret��rio /var/lib/libvirt, ou mude as permiss��es para que o "
+"usu��rio '%(user)s' tenha acesso, ou, adicione o usu��rio
'%(user)s' no grupo "
+"do caminho da ISO, ou (n��o recomendado) 'chmod -R o+x
'caminho_para_iso'. "
+"Detalhes: %(err)s"
+
+msgid "An error occurred when probing image OS information."
+msgstr "Ocorreu um erro ao identificar o sistema operacional da imagem."
+
+msgid "No OS information found in given image."
+msgstr ""
+"Nenhuma informa����o de sistema operacional encontrada na imagem fornecida."
+
+#, python-format
+msgid "Unable to read image file %(filename)s"
+msgstr "N��o foi poss��vel ler o arquivo de imagem %(filename)s."
+
+#, python-format
+msgid ""
+"Image file must be an existing file on system. %(filename)s is not a valid "
+"input."
+msgstr ""
+"Arquivo de imagem deve ser um arquivo existente no sistema. %(filename)s n��o
"
+"�� uma entrada v��lida."
+
+#, python-format
+msgid "Virtual machine %(name)s already exists"
+msgstr "M��quina virtual %(name)s j�� existe"
+
+#, python-format
+msgid "Virtual machine %(name)s does not exist"
+msgstr "M��quina virtual %(name)s n��o existe"
+
+#, python-format
+msgid ""
+"Unable to rename virtual machine %(name)s. The name %(new_name)s is already "
+"in use or the virtual machine is not powered off."
+msgstr ""
+"N��o foi poss��vel renomear a m��quina virtual %(name)s. O nome %(new_name)s j��
"
+"est�� em uso ou a m��quina virtual n��o est�� ligada."
+
+#, python-format
+msgid "Unable to retrieve screenshot for stopped virtual machine %(name)s"
+msgstr ""
+"N��o foi poss��vel tirar uma foto da tela para a m��quina virtual %(name)s que
"
+"est�� desligada"
+
+msgid "Remote ISO image is not supported by this server."
+msgstr "Imagem de ISO remota n��o �� suportada por esse servidor."
+
+#, python-format
+msgid "Screenshot is not supported on virtual machine %(name)s"
+msgstr "Foto da tela n��o �� suportado na m��quina virtual %(name)s"
+
+#, python-format
+msgid "Unable to create virtual machine %(name)s. Details: %(err)s"
+msgstr "N��o foi poss��vel criar a m��quina virtual %(name)s. Detalhes:
%(err)s"
+
+#, python-format
+msgid "Unable to update virtual machine %(name)s. Details: %(err)s"
+msgstr ""
+"N��o foi poss��vel atualizar a m��quina virtual %(name)s. Detalhes: %(err)s"
+
+#, python-format
+msgid "Unable to retrieve virtual machine %(name)s. Details: %(err)s"
+msgstr ""
+"N��o foi poss��vel encontrar a m��quina virtual %(name)s. Detalhes: %(err)s"
+
+#, python-format
+msgid "Unable to connect to powered off virtual machine %(name)s."
+msgstr "N��o foi poss��vel conectar �� m��quina virtual desligada %(name)s."
+
+msgid "Virtual machine name must be a string without slashes (/)"
+msgstr ""
+
+#, python-format
+msgid "Invalid template URI %(value)s specified for virtual machine"
+msgstr "URI do Modelo inv��lida %(value)s especificada para m��quina virtual"
+
+#, python-format
+msgid "Invalid storage pool URI %(value)s specified for virtual machine"
+msgstr ""
+"URI do Storage pool URI inv��lida %(value)s especificada para m��quina
virtual"
+
+msgid "Supported virtual machine graphics are Spice or VNC"
+msgstr "Gr��ficos suportados para a m��quina virtual s��o Spice ou VNC"
+
+msgid "Graphics address to listen on must be IPv4 or IPv6"
+msgstr "Endere��o para receber eventos gr��ficos deve ser IPv4 ou IPv6"
+
+msgid "Specify a template to create a virtual machine from"
+msgstr "Especifique um modelo para ser base da cria����o da m��quina virtual"
+
+#, python-format
+msgid "Unable to start virtual machine %(name)s. Details: %(err)s"
+msgstr "N��o foi poss��vel iniciar a m��quina virtual %(name)s. Detalhes:
%(err)s"
+
+#, python-format
+msgid "Unable to power off virtual machine %(name)s. Details: %(err)s"
+msgstr ""
+"N��o foi poss��vel for��ar o desligamento da m��quina virtual %(name)s. "
+"Detalhes: %(err)s"
+
+#, python-format
+msgid "Unable to delete virtual machine %(name)s. Details: %(err)s"
+msgstr "N��o foi poss��vel remover a m��quina virtual %(name)s. Detalhes:
%(err)s"
+
+#, python-format
+msgid "Unable to reset virtual machine %(name)s. Details: %(err)s"
+msgstr ""
+"N��o foi poss��vel reiniciar a m��quina virtual %(name)s. Detalhes: %(err)s"
+
+msgid "User name list must be an array"
+msgstr "Lista de nomes de usu��rio deve ser um array"
+
+msgid "User name must be a string"
+msgstr "Nome de usu��rio deve ser um texto"
+
+msgid "Group name list must be an array"
+msgstr "Lista de nomes de grupo deve ser um array"
+
+msgid "Group name must be a string"
+msgstr "Nome de grupo deve ser um texto"
+
+#, python-format
+msgid "User(s) '%(users)s' do not exist"
+msgstr "Usu��rio(s) '%(users)s' n��o existe(m)"
+
+#, python-format
+msgid "Group(s) '%(groups)s' do not exist"
+msgstr "Grupo(s) '%(groups)s' n��o existe(m)"
+
+#, python-format
+msgid "Unable to shutdown virtual machine %(name)s. Details: %(err)s"
+msgstr ""
+"N��o foi poss��vel desligar a m��quina virtual %(name)s. Detalhes: %(err)s"
+
+#, python-format
+msgid ""
+"Unable to get access metadata of virtual machine %(name)s. Details: %(err)s"
+msgstr ""
+"N��o foi poss��vel acessar os metadados da m��quina virtual %(name)s. Detalhes:
"
+"%(err)s"
+
+msgid "The guest console password must be a string."
+msgstr "A senha para o console do guest deve ser um texto."
+
+msgid "The life time for the guest console password must be a number."
+msgstr "O tempo de vida da senha do console do guest deve ser um n��mero."
+
+#, python-format
+msgid "Virtual machine '%(name)s' must be stopped before cloning it."
+msgstr "A m��quina virtual '%(name)s' deve estar parada antes de
clon��-la."
+
+#, python-format
+msgid "Insufficient disk space to clone virtual machine '%(name)s'"
+msgstr "Espa��o em disco insuficiente para clonar a m��quina virtual
'%(name)s'"
+
+#, python-format
+msgid "Unable to clone VM '%(name)s'. Details: %(err)s"
+msgstr "N��o foi poss��vel clonar a VM '%(name)s'. Detalhes: %(err)s"
+
+#, python-format
+msgid "Invalid operation for non-persistent virtual machine %(name)s"
+msgstr "Opera����o inv��lida para m��quina virtual n��o-persistente %(name)s"
+
+#, python-format
+msgid "Cannot suspend VM '%(name)s' because it is not running."
+msgstr ""
+
+#, python-format
+msgid "Unable to suspend VM '%(name)s'. Details: %(err)s"
+msgstr ""
+
+#, python-format
+msgid "Cannot resume VM '%(name)s' because it is not paused."
+msgstr ""
+
+#, python-format
+msgid "Unable to resume VM '%(name)s'. Details: %(err)s"
+msgstr ""
+
+msgid "Memory assigned is higher then the maximum allowed in the host."
+msgstr ""
+
+#, python-format
+msgid ""
+"VM '%(name)s' does not support live memory update. Update the memory with
"
+"the machine offline to enable this feature."
+msgstr ""
+
+msgid "Only increase memory is allowed in active VMs"
+msgstr ""
+
+msgid ""
+"For live memory update, new memory value must be equal old memory value plus
"
+"multiples of 1024 Mib"
+msgstr ""
+
+msgid "There are not enough free slots of 1024 Mib in the guest."
+msgstr ""
+
+msgid ""
+"Host's libvirt version does not support memory devices. Libvirt must be >=
"
+"1.2.14"
+msgstr ""
+
+#, python-format
+msgid "Error attaching memory device. Details: %(error)s"
+msgstr ""
+
+#, python-format
+msgid ""
+"VM %(vmid)s does not contain directly assigned host device %(dev_name)s."
+msgstr ""
+"A VM %(vmid)s n��o cont��m o dispositivo de host atribu��do diretamente %"
+"(dev_name)s."
+
+#, python-format
+msgid "The host device %(dev_name)s is not allowed to directly assign to VM."
+msgstr ""
+"N��o �� permitido atribuir diretamente o dispositivo de host %(dev_name)s."
+
+msgid ""
+"No IOMMU groups found. Host PCI pass through needs IOMMU group to function "
+"correctly. Please enable Intel VT-d or AMD IOMMU in your BIOS, then verify "
+"the Kernel is compiled with IOMMU support. For Intel CPU, add intel_iommu=on
"
+"to your Kernel parameter in /boot/grub2/grub.conf. For AMD CPU, add iommu=pt
"
+"iommu=1."
+msgstr ""
+"Nenhum grupo IOMMU encontrado. Passthrough de host PCI necessita do grupo "
+"IOMMU para funcionar corretamente. Por favor, habilite o suporte ao Intel
VT-"
+"d ou AMD IOMMU. Para uma CPU Intel, adicione \"intel_iommu=on\" nos seus
"
+"par��metros de kernel em \"/boot/grub2/grub.conf\". Para uma CPU AMD,
"
+"adicione \"iommu=pt iommu=1\"."
+
+msgid "\"name\" should be a device name string"
+msgstr "\"nome\" deve ser um texto do nome do dispositivo."
+
+#, python-format
+msgid ""
+"The device %(name)s is probably in use by the host. Unable to attach it to "
+"the guest."
+msgstr ""
+
+#, python-format
+msgid "Interface %(iface)s does not exist in virtual machine %(name)s"
+msgstr "Interface %(iface)s n��o existe na m��quina virtual %(name)s"
+
+#, python-format
+msgid ""
+"Network %(network)s specified for virtual machine %(name)s does not exist"
+msgstr ""
+"Rede %(network)s especificada para a m��quina virtual %(name)s n��o existe"
+
+msgid "Supported virtual machine interfaces type is only network"
+msgstr "Tipo de interface suportado das m��quinas virtuais �� somente rede"
+
+msgid "Network name for virtual machine interface must be a string"
+msgstr "Nome da rede para a interface da m��quina virtual deve ser texto"
+
+msgid "Invalid network model card specified for virtual machine interface"
+msgstr "Modelo de placa de rede inv��lido para a interface da m��quina
virtual"
+
+msgid "Specify type and network to add a new virtual machine interface"
+msgstr ""
+"Especifique o tipo e a rede para adicionar uma nova interface da m��quina "
+"virtual"
+
+msgid "MAC Address must respect this format FF:FF:FF:FF:FF:FF"
+msgstr ""
+
+#, python-format
+msgid "MAC Address %(mac)s already exists in virtual machine %(name)s"
+msgstr ""
+
+msgid "Invalid MAC Address"
+msgstr ""
+
+msgid "Cannot change MAC address of a running virtual machine"
+msgstr ""
+
+#, python-format
+msgid "Template %(name)s already exists"
+msgstr "Modelo %(name)s j�� existe"
+
+#, python-format
+msgid ""
+"Network '%(network)s' specified for template %(template)s does not
exist"
+msgstr "Rede '%(network)s' especificada para o modelo %(template)s n��o
existe"
+
+#, python-format
+msgid ""
+"Storage pool %(pool)s specified for template %(template)s does not exist"
+msgstr ""
+"Storage pool %(pool)s especificado para o modelo %(template)s n��o existe"
+
+#, python-format
+msgid "Storage pool %(pool)s specified for template %(template)s is not
active"
+msgstr ""
+"Storage pool %(pool)s especificado para o modelo %(template)s n��o est��
ativo"
+
+#, python-format
+msgid "Invalid parameter '%(param)s' specified for CDROM."
+msgstr "Par��metro inv��lido '%(param)s' especificado para CDROM"
+
+#, python-format
+msgid "Network %(network)s specified for template %(template)s is not active"
+msgstr "Rede %(network)s especificada para modelo %(template)s n��o est��
ativa"
+
+msgid "Template name must be a string"
+msgstr "Nome do modelo deve ser um texto"
+
+msgid "Template icon must be a path to the image"
+msgstr "��cone do modelo deve ser um caminho para uma imagem"
+
+msgid "Template distribution must be a string"
+msgstr "Distribui����o do modelo deve ser um texto"
+
+msgid "Template distribution version must be a string"
+msgstr "Vers��o da distribui����o do modelo deve ser um texto"
+
+msgid "The number of CPUs must be an integer greater than 0"
+msgstr "O n��mero de CPUs deve ser um inteiro maior do que 0"
+
+msgid "Amount of memory (MB) must be an integer greater than 512"
+msgstr "Quantidade de mem��ria (MB) deve ser um inteiro maior que 512"
+
+msgid "Template CDROM must be a local or remote ISO file"
+msgstr "Modelo do CDROM deve ser um arquivo ISO local ou remoto"
+
+#, python-format
+msgid "Invalid storage pool URI %(value)s specified for template"
+msgstr "URI de storage pool inv��lido %(value)s especificado para modelo"
+
+msgid "Specify an ISO image as CDROM or a base image to create a template"
+msgstr ""
+"Especifique uma imagem ISO como CD-ROM ou uma imagem base para criar um "
+"modelo"
+
+msgid "All networks for the template must be specified in a list."
+msgstr "Todas redes para o modelo devem ser especificadas em uma lista"
+
+msgid "Specify a volume to a template when storage pool is iSCSI or SCSI"
+msgstr ""
+"Especifique um volume para o template quando o storage pool for iSCSI or
SCSI"
+
+#, python-format
+msgid "The volume %(volume)s is not in storage pool %(pool)s"
+msgstr "O volume %(volume)s n��o est�� no storage pool %(pool)s"
+
+#, python-format
+msgid "Unable to create template due error: %(err)s"
+msgstr "N��o foi poss��vel criar o modelo devido a um erro: %(err)s"
+
+#, python-format
+msgid "Unable to delete template due error: %(err)s"
+msgstr "N��o foi poss��vel remover o modelo devido a um erro: %(err)s"
+
+msgid "Disk size must be an integer greater than 1GB."
+msgstr "O tamanho do disco deve ser um n��mero inteiro maior que 1GB."
+
+msgid "Template base image must be a valid local image file"
+msgstr "Imagem base do modelo deve ser um arquivo de imagem local v��lido"
+
+#, python-format
+msgid "Cannot identify base image %(path)s format"
+msgstr "N��o foi poss��vel identificar o formato da imagem base %(path)s"
+
+msgid ""
+"When specifying CPU topology, VCPUs must be a product of sockets, cores, and
"
+"threads."
+msgstr ""
+"Ao especificar a topologia de CPU, VCPUs deve ser um produto de sockets, "
+"cores e threads."
+
+msgid ""
+"When specifying CPU topology, each element must be an integer greater than "
+"zero."
+msgstr ""
+"Ao especificar a topologia de CPU, cada elemento deve ser um n��mero inteiro
"
+"maior do que zero."
+
+msgid ""
+"Invalid disk image format. Valid formats: bochs, cloop, cow, dmg, qcow, "
+"qcow2, qed, raw, vmdk, vpc."
+msgstr ""
+"Formato de imagem de disco inv��lido. Formatos v��lidos: bochs, cloop, cow, "
+"dmg, qcow, qcow2, qed, raw, vmdk, vpc."
+
+#, python-format
+msgid "Storage pool %(name)s already exists"
+msgstr "Storage pool %(name)s j�� existe"
+
+#, python-format
+msgid "Storage pool %(name)s does not exist"
+msgstr "Storage pool %(name)s n��o existe"
+
+#, python-format
+msgid "Specify %(item)s in order to create the storage pool %(name)s"
+msgstr "Especifique %(item)s para criar o storage pool %(name)s"
+
+#, python-format
+msgid "Unable to delete active storage pool %(name)s"
+msgstr "N��o foi poss��vel remover o storage pool ativo %(name)s"
+
+#, python-format
+msgid "Unable to list storage pools. Details: %(err)s"
+msgstr "N��o foi poss��vel listar os storage pools. Detalhes: %(err)s"
+
+#, python-format
+msgid "Unable to create storage pool %(name)s. Details: %(err)s"
+msgstr "N��o foi poss��vel criar o storage pool %(name)s. Detalhes: %(err)s"
+
+#, python-format
+msgid ""
+"Unable to get number of storage volumes in storage pool %(name)s. Details: %"
+"(err)s"
+msgstr ""
+"N��o foi poss��vel saber o n��mero de volumes no storage pool %(name)s. "
+"Detalhes: %(err)s"
+
+#, python-format
+msgid "Unable to activate storage pool %(name)s. Details: %(err)s"
+msgstr "N��o foi possivel ativar o storage pool %(name)s. Detalhes: %(err)s"
+
+#, python-format
+msgid "Unable to deactivate storage pool %(name)s. Details: %(err)s"
+msgstr "N��o foi possivel desativar o storage pool %(name)s. Detalhes:
%(err)s"
+
+#, python-format
+msgid "Unable to delete storage pool %(name)s. Details: %(err)s"
+msgstr "N��o foi possivel remover o storage pool %(name)s. Detalhes: %(err)s"
+
+#, python-format
+msgid ""
+"Unable to create NFS Pool as export path %(path)s may block during mount"
+msgstr ""
+"N��o foi poss��vel criar Pool NFS uma vez que o caminho de exporta����o %(path)s
"
+"pode bloquear durante a montagem"
+
+#, python-format
+msgid "Unable to create NFS Pool as export path %(path)s mount failed"
+msgstr ""
+"N��o foi poss��vel criar NFS Pool uma vez que a montagem do caminho de "
+"exporta����o %(path)s falhou"
+
+#, python-format
+msgid "Unsupported storage pool type: %(type)s"
+msgstr "Tipo de storage pool n��o suportado: %(type)s"
+
+#, python-format
+msgid "Error while retrieving storage pool XML to %(pool)s"
+msgstr "Erro durante a leitura do XML do storage pool %(pool)s"
+
+msgid "Storage pool name must be a string without slashes (/)"
+msgstr ""
+
+msgid ""
+"Supported storage pool types are dir, netfs, logical, iscsi, isci and
kimchi-"
+"iso"
+msgstr ""
+"Tipos de storage pool supportados s��o dir, netfs, logical, iscsi, scsi e "
+"kimchi-iso"
+
+msgid "Storage pool path must be a string"
+msgstr "Caminho para storage pool deve ser um texto"
+
+msgid "Storage pool host must be a IP or hostname"
+msgstr "Host do storage pool deve ser um IP ou um hostname"
+
+msgid "Storage pool device must be the absolute path to the block device"
+msgstr ""
+"Dispositivo do storage pool deve ser o caminho absoluto para o block device"
+
+msgid "Storage pool devices parameter must be a list"
+msgstr "Par��metro dos dispositivos do storage pool devem ser uma lista"
+
+msgid "Target IQN of an iSCSI pool must be a string"
+msgstr "Alvo IQN de um pool iSCSI deve ser um texto"
+
+msgid "Port of a remote storage server must be an integer between 1 and 65535"
+msgstr ""
+"Porta de um servidor remoto de storage deve ser um inteiro entre 1 e 65535"
+
+msgid "iSCSI target username must be a string"
+msgstr "Usu��rio do iSCSI target deve ser um texto"
+
+msgid "iSCSI target password must be a string"
+msgstr "Senha do iSCSI target deve ser um texto"
+
+msgid "Specify name and type to create a storage pool"
+msgstr "Especifique o nome e o tipo para criar um storage pool"
+
+#, python-format
+msgid ""
+"%(disk)s is not a valid disk/partition. Could not add it to the pool %(pool)"
+"s."
+msgstr ""
+"%(disk)s n��o �� um disco/parti����o v��lido. N��o foi poss��vel adicion��-lo ao
"
+"pool %(pool)s."
+
+#, python-format
+msgid "Unable to extend logical pool %(pool)s. Details: %(err)s"
+msgstr "N��o foi poss��vel extender o pool l��gico %(pool)s. Detalhes:
%(err)s"
+
+msgid "The parameter disks only can be updated for logical storage pool."
+msgstr ""
+"O par��metro discos somente pode ser atualizado para storage pool l��gicos."
+
+msgid "The SCSI host adapter name must be a string."
+msgstr "O nome do adaptador SCSI host deve ser um texto"
+
+msgid "The storage pool kimchi_isos is reserved for internal use"
+msgstr "O storage pool kimchi_isos �� reservado para uso interno"
+
+#, python-format
+msgid ""
+"Unable to activate NFS storage pool %(name)s. NFS server %(server)s is "
+"unreachable."
+msgstr ""
+"N��o foi poss��vel ativar o storage pool NFS %(name)s. Servidor NFS %(server)s
"
+"est�� inacess��vel."
+
+#, python-format
+msgid ""
+"Unable to deactivate NFS storage pool %(name)s. NFS server %(server)s is "
+"unreachable."
+msgstr ""
+"N��o foi poss��vel desativar o storage pool NFS %(name)s. Servidor NFS %"
+"(server)s est�� inacess��vel."
+
+#, python-format
+msgid ""
+"Unable to deactivate pool %(name)s as it is associated with some templates"
+msgstr ""
+"N��o foi poss��vel desativar o pool %(name)s uma vez que ele est�� associado
"
+"com algum dos modelos"
+
+#, python-format
+msgid "Unable to delete pool %(name)s as it is associated with some templates"
+msgstr ""
+"N��o foi poss��vel remover o pool %(name)s uma vez que ele est�� associado com
"
+"algum dos modelos"
+
+#, python-format
+msgid ""
+"A volume group named '%(name)s' already exists. Please, choose another name
"
+"to create the logical pool."
+msgstr ""
+"Um grupo de volume chamado '%(name)s' j�� existe. Por favor, escolha outro
"
+"nome para criar o pool l��gico."
+
+#, python-format
+msgid "Unable to update database with deep scan information due error:
%(err)s"
+msgstr ""
+"N��o foi poss��vel atualizar a base de dados com informa����es de mais ISOs "
+"devido a um erro: %(err)s"
+
+#, python-format
+msgid "Storage volume %(name)s already exists"
+msgstr "Volume de storage %(name)s j�� existe"
+
+#, python-format
+msgid "Storage volume %(name)s does not exist in storage pool %(pool)s"
+msgstr "Volume de storage %(name)s n��o existe no storage pool %(pool)s"
+
+#, python-format
+msgid ""
+"Unable to create storage volume %(volume)s because storage pool %(pool)s is "
+"not active"
+msgstr ""
+"N��o foi poss��vel criar o storaget volume %(volume)s pois o storage pool %"
+"(pool)s n��o est�� ativo"
+
+#, python-format
+msgid "Specify %(item)s in order to create storage volume %(volume)s"
+msgstr "Especifique %(item)s para poder criar o volume %(volume)s"
+
+#, python-format
+msgid ""
+"Unable to list storage volumes because storage pool %(pool)s is not active"
+msgstr ""
+"N��o foi poss��vel listar volumes pois o storage pool %(pool)s n��o est��
ativo"
+
+#, python-format
+msgid ""
+"Unable to create storage volume %(name)s in storage pool %(pool)s. Details:
%"
+"(err)s"
+msgstr ""
+"N��o foi poss��vel criar o volume %(name)s no storage pool %(pool)s. Detalhes:
"
+"%(err)s"
+
+#, python-format
+msgid ""
+"Unable to list storage volumes in storage pool %(pool)s. Details: %(err)s"
+msgstr ""
+"N��o foi poss��vel listar os volumes do storage pool %(pool)s. Detalhes:
%(err)"
+"s"
+
+#, python-format
+msgid "Unable to wipe storage volumes %(name)s. Details: %(err)s"
+msgstr "N��o foi poss��vel limpar o volume %(name)s. Detalhes: %(err)s"
+
+#, python-format
+msgid "Unable to delete storage volume %(name)s. Details: %(err)s"
+msgstr "N��o foi poss��vel remover o volume %(name)s. Detalhes: %(err)s"
+
+#, python-format
+msgid "Unable to resize storage volume %(name)s. Details: %(err)s"
+msgstr "N��o foi poss��vel redimensionar o volume %(name)s. Detalhes: %(err)s"
+
+#, python-format
+msgid "Storage type %(type)s does not support volume create and delete"
+msgstr "Storage do tipo %(type)s n��o suporta cria����o ou remo����o de
volume"
+
+msgid "Storage volume name must be a string"
+msgstr "Nome do volume deve ser um texto"
+
+msgid "Storage volume allocation must be an integer number"
+msgstr "Aloca����o do volume de storage deve ser um n��mero inteiro"
+
+msgid ""
+"Storage volume format not supported. Valid formats: bochs, cloop, cow, dmg, "
+"qcow, qcow2, qed, raw, vmdk, vpc."
+msgstr ""
+"Formato de volume de storage inv��lido. Formatos v��lidos: bochs, cloop, cow,
"
+"dmg, qcow, qcow2, qed, raw, vmdk, vpc."
+
+msgid "Storage volume requires a volume name"
+msgstr "Volume de storage requer um nome"
+
+#, python-format
+msgid ""
+"Unable to update database with storage volume information due error: %(err)s"
+msgstr ""
+"N��o foi poss��vel atualizar a base de dados com informa����es de volume de "
+"storage devido a um erro: %(err)s"
+
+#, python-format
+msgid "Only one of parameter %(param)s can be specified"
+msgstr "Somente um par��metro %(param)s pode ser especificado"
+
+#, python-format
+msgid "Create volume from %(param)s is not supported"
+msgstr "Criar um volume a partir de %(param)s n��o �� suportado"
+
+msgid "Storage volume capacity must be an integer number."
+msgstr "A capacidade do storage volume deve ser um n��mero inteiro."
+
+msgid "Storage volume URL must be http://, https://, ftp:// or ftps://."
+msgstr ""
+"URL para o storage volume deve ser http://, https://, ftp:// ou ftps://."
+
+#, python-format
+msgid "Unable to access file %(url)s. Please, check it."
+msgstr "Erro ao acessar arquivo %(url)s. Por favor, verifique isso."
+
+#, python-format
+msgid ""
+"Unable to clone storage volume '%(name)s' in pool '%(pool)s'.
Details: %(err)"
+"s"
+msgstr ""
+"N��o foi poss��vel clonar o volume de storage '%(name)s' no pool
'%(pool)s'. "
+"Detalhes: %(err)s"
+
+msgid "Specify chunk data and its size to upload a file."
+msgstr ""
+
+msgid "In order to upload a storage volume, specify the 'upload'
parameter."
+msgstr ""
+
+msgid ""
+"Unable to upload chunk data as it does not match with requested chunk size."
+msgstr ""
+
+#, python-format
+msgid "The storage volume %(vol)s is not under an upload process."
+msgstr ""
+
+msgid "The upload chunk data will exceed the storage volume size."
+msgstr ""
+
+#, python-format
+msgid "Unable to upload chunk data to storage volume. Details: %(err)s."
+msgstr ""
+
+#, python-format
+msgid "Interface %(name)s does not exist"
+msgstr "Interface %(name)s n��o existe"
+
+#, python-format
+msgid "Network %(name)s already exists"
+msgstr "Rede %(name)s j�� existe"
+
+#, python-format
+msgid "Network %(name)s does not exist"
+msgstr "Rede %(name)s n��o existe"
+
+#, python-format
+msgid "Subnet %(subnet)s specified for network %(network)s is not valid."
+msgstr ""
+"A subrede %(subnet)s especificada para a rede %(network)s n��o �� v��lida."
+
+#, python-format
+msgid "Specify a network interface to create bridged network %(name)s"
+msgstr "Especifique uma interface de rede para criar a rede de bridge
%(name)s"
+
+#, python-format
+msgid "Unable to delete active network %(name)s"
+msgstr "N��o foi poss��vel remover a rede ativa %(name)s"
+
+#, python-format
+msgid "Interface %(iface)s specified for network %(network)s is already in
use"
+msgstr ""
+"A interface %(iface)s especificada para a rede %(network)s j�� est�� em uso"
+
+msgid "Interface should be bare NIC, bonding or bridge device."
+msgstr "Interface deve ser 'bare NIC', 'bonding' ou 'dispositivo
de bridge'."
+
+#, python-format
+msgid "Unable to create network %(name)s. Details: %(err)s"
+msgstr "N��o foi poss��vel criar a rede %(name)s. Detalhes: %(err)s"
+
+#, python-format
+msgid "Unable to find a free IP address for network '%(name)s'"
+msgstr "N��o foi poss��vel encontrar um endere��o IP livre para a rede
'%(name)s'"
+
+#, python-format
+msgid "The interface %(iface)s already exists."
+msgstr "A interface %(iface)s j�� existe"
+
+msgid "Network name must be a string without slashes (/) or quotes (\")"
+msgstr ""
+
+msgid "Supported network types are isolated, NAT and bridge"
+msgstr "Tipos de rede suportados s��o isolada, NAT e bridge"
+
+msgid "Network subnet must be a string with IP address and prefix or netmask"
+msgstr ""
+"Subrede deve ser um texto com endere��o IP e prefixo, ou m��scara de rede"
+
+msgid "Network interface must be a string"
+msgstr "Interface de rede deve ser um texto"
+
+msgid "Network VLAN ID must be an integer between 1 and 4094"
+msgstr "ID da rede VLAN deve ser um inteiro entre 1 e 4094"
+
+msgid "Specify name and type to create a Network"
+msgstr "Especifique o nome e o tipo para criar uma rede"
+
+#, python-format
+msgid ""
+"Unable to delete network %(name)s. There are some virtual machines %(vms)s "
+"and/or templates linked to this network."
+msgstr ""
+"N��o foi poss��vel desativar a rede %(name)s. H�� alguma m��quina virtual
%(vms)"
+"s e/ou modelo associados a esta rede."
+
+#, python-format
+msgid ""
+"Unable to deactivate network %(name)s. There are some virtual machines
%(vms)"
+"s and/or templates linked to this network."
+msgstr ""
+"N��o foi poss��vel desativar a rede %(name)s. H�� alguma m��quina virtual
%(vms)"
+"s e/ou modelo associados a esta rede."
+
+#, python-format
+msgid "Bridge device %(name)s can not be the trunk device of a VLAN."
+msgstr ""
+"Dispositivo da bridge %(name)s n��o pode ser um dispositivo vinculado a uma "
+"VLAN."
+
+#, python-format
+msgid "Failed to activate interface %(iface)s: %(err)s."
+msgstr "N��o foi poss��vel ativar a interface %(iface)s: %(err)s."
+
+#, python-format
+msgid ""
+"Failed to activate interface %(iface)s. Please check the physical link "
+"status."
+msgstr ""
+"N��o foi poss��vel ativar a interface %(iface)s. Por favor, verifique o status
"
+"da conex��o f��sica."
+
+#, python-format
+msgid "Failed to start network %(name)s. Details: %(err)s"
+msgstr "N��o foi poss��vel iniciar a rede %(name)s. Detalhes: %(err)s"
+
+#, python-format
+msgid "Debug report %(name)s does not exist"
+msgstr "Relat��rio de debug %(name)s n��o existe"
+
+msgid "Debug report tool not found in system"
+msgstr "Ferramenta de relat��rio de debug n��o encontrada no sistema"
+
+#, python-format
+msgid "Unable to create debug report %(name)s. Details: %(err)s."
+msgstr ""
+"N��o foi poss��vel criar o relat��rio de debug %(name)s. Detalhes: %(err)s."
+
+#, python-format
+msgid "Can not find any debug report with the given name %(name)s"
+msgstr "N��o foi poss��vel encontrar nenhum relat��rio com o nome %(name)s"
+
+#, python-format
+msgid "Unable to generate debug report %(name)s. Details: %(err)s"
+msgstr ""
+"N��o foi poss��vel gerar o relat��rio de debug %(name)s. Detalhes: %(err)s"
+
+msgid "You should give a name for the debug report file."
+msgstr "Voc�� deve dar um nome para o arquivo do relat��rio de debug."
+
+msgid ""
+"Debug report name must be a string. Only letters, digits, underscore ('_')
"
+"and hyphen ('-') are allowed."
+msgstr ""
+"Nome do relat��rio deve ser um texto. Somente letras, digitos, underscore "
+"('_') e h��fem ('-') s��o permitidos."
+
+#, python-format
+msgid ""
+"The debug report with specified name \"%(name)s\" already exists. Please
use "
+"another one."
+msgstr ""
+"O relat��rio de debug com o nome especificado \"%(name)s\" j�� existe.
Por "
+"favor, use outro nome."
+
+#, python-format
+msgid "Storage server %(server)s was not used by Kimchi"
+msgstr "Servidor de storage %(server)s n��o foi usado pelo Kimchi"
+
+#, python-format
+msgid "Distro '%(name)s' does not exist"
+msgstr "Distribui����o '%(name)s' n��o existe"
+
+#, python-format
+msgid "Partition %(name)s does not exist in the host"
+msgstr "Parti����o %(name)s n��o existe no host"
+
+msgid "Unable to shutdown host machine as there are running virtual machines"
+msgstr ""
+"N��o foi poss��vel desligar o host uma vez que h�� m��quinas virtuais
ligadas"
+
+msgid "Unable to reboot host machine as there are running virtual machines"
+msgstr ""
+"N��o foi poss��vel resetar o host uma vez que h�� m��quinas virtuais ligadas"
+
+#, python-format
+msgid "Node device '%(name)s' not found"
+msgstr "Dispositivo de n�� '%(name)s' n��o encontrado"
+
+msgid "Conflicting flag filters specified."
+msgstr "Foram especificados filtros de flag com conflito."
+
+msgid "No packages marked for update"
+msgstr "Nenhum pacote marcado para atualiza����o"
+
+#, python-format
+msgid "Package %(name)s is not marked to be updated."
+msgstr "Pacote %(name)s n��o est�� marcado para atualiza����o."
+
+#, python-format
+msgid "Error while getting packages marked to be updated. Details: %(err)s"
+msgstr "Erro ao buscar pacotes marcados para atualiza����o. Detalhes: %(err)s"
+
+msgid "There is no compatible package manager for this system."
+msgstr "N��o h�� gerenciador de pacotes compat��vel para este sistema."
+
+#, python-format
+msgid "Invalid URI %(uri)s"
+msgstr "URI %(uri)s inv��lida"
+
+msgid "Unable to choose a virtual machine name"
+msgstr "N��o foi poss��vel escolher um nome para a m��quina virtual"
+
+msgid "Invalid storage type. Types supported: 'cdrom', 'disk'"
+msgstr "Tipo de storage inv��lido. Tipos suportados: 'cdrom',
'disco'"
+
+#, python-format
+msgid "The path '%(value)s' is not a valid local/remote path for the
device"
+msgstr ""
+"O caminho '%(value)s' n��o �� um caminho local/remoto v��lido para este
"
+"dispositivo"
+
+msgid "Only CDROM path can be update."
+msgstr "Apenas o caminho do CD-ROM pode ser atualizado."
+
+#, python-format
+msgid ""
+"The storage device %(dev_name)s does not exist in the virtual machine %"
+"(vm_name)s"
+msgstr "O disco %(dev_name)s n��o existe na m��quina virtual %(vm_name)s"
+
+#, python-format
+msgid "Error while creating new storage device: %(error)s"
+msgstr "Erro ao criar novo dispositivo de storage: %(error)s"
+
+#, python-format
+msgid "Error while updating storage device: %(error)s"
+msgstr "Erro ao atualizar dispositivo de storage: %(error)s"
+
+#, python-format
+msgid "Error while removing storage device: %(error)s"
+msgstr "Erro ao remover dispositivo de storage: %(error)s"
+
+msgid "Do not support IDE device hot plug"
+msgstr "Dispositivo IDE hot plug n��o �� suportado"
+
+msgid ""
+"Specify type and path or type and pool/volume to add a new virtual machine "
+"disk"
+msgstr ""
+"Especifique o tipo e o caminho, ou o tipo e o pool/volume, para adicionar um
"
+"novo disco da m��quina virtual"
+
+msgid "Specify path to update virtual machine disk"
+msgstr "Especifique o caminho para atualizar o disco da m��quina virtual"
+
+#, python-format
+msgid "Controller type %(type)s limitation of %(limit)s devices reached"
+msgstr ""
+"Limita����o do tipo do controlador %(type)s de %(limit)s dispositivos foi "
+"alcan��ada"
+
+#, python-format
+msgid "Cannot retrieve disk path information for given pool/volume: %(error)s"
+msgstr ""
+"N��o foi poss��vel buscar informa����es do caminho do disco para o pool/volume
"
+"dado: %(error)s"
+
+msgid "Volume already in use by other virtual machine."
+msgstr "Volume j�� em uso por outra m��quina virtual."
+
+msgid ""
+"Only one of path or pool/volume can be specified to add a new virtual "
+"machine disk"
+msgstr ""
+"Somente um caminho ou pool/volume pode ser especificado para adicionar um "
+"novo disco da m��quina virtual."
+
+#, python-format
+msgid ""
+"Volume chosen with format %(format)s does not fit in the storage type
%(type)"
+"s"
+msgstr ""
+"Volume escolhido com formato %(format)s n��o se enquadra no tipo de storage
%"
+"(type)s"
+
+msgid "YUM Repository ID must be one word only string."
+msgstr "ID do reposit��rio YUM deve ser apenas uma palavra."
+
+msgid "Repository URL must be an http://, ftp:// or file:// URL."
+msgstr "URL do reposit��rio deve ser uma URL http://, ftp:// ou file://."
+
+msgid ""
+"Repository configuration is a dictionary with specific values according to "
+"repository type."
+msgstr ""
+"Configura����o do reposit��rio �� um dicion��rio com valores espec��ficos de
"
+"acordo com o tipo do reposit��rio."
+
+msgid "Distribution to DEB repository must be a string"
+msgstr "Distribui����o para o reposit��rio DEB deve ser um texto"
+
+msgid "Components to DEB repository must be listed in a array"
+msgstr "Componentes para o reposit��rio DEB deve ser um array"
+
+msgid "Components to DEB repository must be a string"
+msgstr "Componentes para o reposit��rio DEB deve ser um texto"
+
+msgid "Mirror list to repository must be a string"
+msgstr ""
+
+msgid "YUM Repository name must be string."
+msgstr "Nome do reposit��rio YUM deve ser um texto."
+
+msgid "GPG check must be a boolean value."
+msgstr "Verifica����o de GPG deve ser um valor booleano."
+
+msgid "GPG key must be a URL pointing to the ASCII-armored file."
+msgstr ""
+"Chave GPG deve ser uma URL apontando para o arquivo no formato ASCII-armor."
+
+#, python-format
+msgid "Could not update repository %(repo_id)s."
+msgstr "N��o foi poss��vel atualizar o reposit��rio %(repo_id)s."
+
+#, python-format
+msgid "Repository %(repo_id)s does not exist."
+msgstr "Reposit��rio %(repo_id)s n��o existe."
+
+msgid ""
+"Specify repository base URL, mirror list or metalink in order to create or "
+"update a YUM repository."
+msgstr ""
+
+msgid "Repository management tool was not recognized for your system."
+msgstr ""
+"Ferramenta de gerenciamento de reposit��rio n��o foi reconhecida no seu "
+"sistema."
+
+#, python-format
+msgid "Repository %(repo_id)s is already enabled."
+msgstr "Reposit��rio %(repo_id)s j�� est�� habilitado."
+
+#, python-format
+msgid "Repository %(repo_id)s is already disabled."
+msgstr "Reposit��rio %(repo_id)s j�� est�� desabilitado."
+
+#, python-format
+msgid "Could not remove repository %(repo_id)s."
+msgstr "N��o foi poss��vel remover o reposit��rio %(repo_id)s."
+
+#, python-format
+msgid "Could not write repository configuration file %(repo_file)s"
+msgstr ""
+"N��o foi poss��vel gravar o arquivo de configura����o do reposit��rio
%(repo_file)"
+"s"
+
+msgid "Specify repository distribution in order to create a DEB repository."
+msgstr ""
+"Especificar o reposit��rio de distribui����o para poder criar o reposit��rio
DEB."
+
+#, python-format
+msgid "Could not enable repository %(repo_id)s."
+msgstr "N��o foi poss��vel habilitar o reposit��rio %(repo_id)s."
+
+#, python-format
+msgid "Could not disable repository %(repo_id)s."
+msgstr "N��o foi poss��vel desabilitar o reposit��rio %(repo_id)s."
+
+msgid "YUM Repository ID already exists"
+msgstr "ID do reposit��rio YUM j�� existe"
+
+msgid "YUM Repository name must be a string"
+msgstr "Nome do reposit��rio YUM deve ser um texto"
+
+#, python-format
+msgid "Unable to list repositories. Details: '%(err)s'"
+msgstr "N��o �� poss��vel listar os reposit��rios. Detalhes:
'%(err)s'"
+
+#, python-format
+msgid "Unable to retrieve repository information. Details: '%(err)s'"
+msgstr ""
+"N��o foi poss��vel carregar as informa����es do reposit��rio. Detalhes:
'%(err)s'"
+
+#, python-format
+msgid "Unable to add repository. Details: '%(err)s'"
+msgstr "N��o foi poss��vel adicionar o reposit��rio. Detalhes:
'%(err)s'"
+
+#, python-format
+msgid "Unable to remove repository. Details: '%(err)s'"
+msgstr "N��o foi poss��vel remover o reposit��rio. Detalhes:
'%(err)s'"
+
+#, python-format
+msgid ""
+"Configuration items: '%(items)s' are not supported by repository
manager"
+msgstr ""
+"Itens de configura����o '%(items)s' n��o s��o suportados pelo gerenciador
de "
+"reposit��rios."
+
+msgid "Repository metalink must be an http://, ftp:// or file:// URL."
+msgstr ""
+
+msgid "Cannot specify mirrorlist and metalink at the same time."
+msgstr ""
+
+#, python-format
+msgid ""
+"Virtual machine '%(vm)s' must be stopped before creating a snapshot of
it."
+msgstr ""
+"A m��quina virtual '%(vm)s' deve estar parada antes de criar um snapshot
dela"
+
+#, python-format
+msgid ""
+"Unable to create snapshot '%(name)s' on virtual machine '%(vm)s'.
Details: %"
+"(err)s"
+msgstr ""
+"N��o foi poss��vel criar o snapshot '%(name)s' na m��quina virtual
'%(vm)s'. "
+"Detalhes: %(err)s"
+
+#, python-format
+msgid "Snapshot '%(name)s' does not exist on virtual machine
'%(vm)s'."
+msgstr "O snapshot '%(name)s' n��o existe na m��quina virtual
'%(vm)s'."
+
+#, python-format
+msgid ""
+"Unable to retrieve snapshot '%(name)s' on virtual machine '%(vm)s'.
Details: "
+"%(err)s"
+msgstr ""
+"N��o foi poss��vel recuperar o snapshot '%(name)s' da m��quina virtual
'%(vm)"
+"s'. Detalhes: %(err)s"
+
+#, python-format
+msgid "Unable to list snapshots on virtual machine '%(vm)s'. Details:
%(err)s"
+msgstr ""
+"N��o foi poss��vel listar os snapshots da m��quina virtual '%(vm)s'.
Detalhes: %"
+"(err)s"
+
+#, python-format
+msgid ""
+"Unable to delete snapshot '%(name)s' on virtual machine '%(vm)s'.
Details: %"
+"(err)s"
+msgstr ""
+"N��o foi poss��vel remover o snapshot '%(name)s' da m��quina virtual
'%(vm)s'. "
+"Detalhes: %(err)s"
+
+#, python-format
+msgid ""
+"Unable to retrieve current snapshot of virtual machine '%(vm)s'. Details:
%"
+"(err)s"
+msgstr ""
+"N��o foi poss��vel recuperar o snapshot atual da m��quina virtual '%(vm)s'.
"
+"Detalhes: %(err)s."
+
+#, python-format
+msgid ""
+"Unable to revert virtual machine '%(vm)s' to snapshot '%(name)s'.
Details: %"
+"(err)s"
+msgstr ""
+"N��o foi poss��vel reverter a m��quina virtual '%(vm)s' para o snapshot
'%(name)"
+"s'. Detalhes: %(err)s"
+
+#, python-format
+msgid ""
+"Unable to create snapshot of virtual machine '%(vm)s' because it contains a
"
+"disk with format '%(format)s'; only 'qcow2' is supported."
+msgstr ""
+"N��o foi poss��vel criar o snapshot para a m��quina virtual '%(vm)s' porque
ela "
+"cont��m discos no formato '%(format)s'; somente 'qcow2' ��
suportado."
+
+msgid "The number of vCPUs is too large for this system."
+msgstr "O n��mero de VCPUs �� grande demais para esse sistema."
+
+msgid "Invalid vCPU/topology combination."
+msgstr "Combina����o inv��lida de VCPU/topologia."
+
+msgid "This host (or current configuration) does not allow CPU topology."
+msgstr "Este host (ou configura����o atual) n��o permite topologia de CPU."
+
+msgid "ERROR CODE"
+msgstr "C��DIGO DE ERRO"
+
+msgid "REASON"
+msgstr "MOTIVO"
+
+msgid "STACK"
+msgstr "PILHA"
+
+msgid "Go to Homepage"
+msgstr "Ir para a P��gina Inicial"
+
+msgid "Create a New Virtual Machine"
+msgstr "Criar nova M��quina Virtual"
+
+msgid "Virtual Machine Name"
+msgstr "Nome da M��quina Virtual"
+
+msgid ""
+"The name used to identify the virtual machine. If omitted, a name will be "
+"chosen based on the template used."
+msgstr ""
+"O nome usado para identificar a m��quina virtual. Se ele for omitido, a "
+"escolha ser�� baseada no modelo selecionado."
+
+msgid "Template"
+msgstr "Modelo"
+
+msgid "Please create a template first."
+msgstr "Por favor, crie um modelo primeiro."
+
+msgid "Create a Template"
+msgstr "Criar um Modelo"
+
+msgid "Please choose a template."
+msgstr "Por favor, escolha um modelo."
+
+msgid "OS"
+msgstr "Sistema Operacional"
+
+msgid "OS Version"
+msgstr "Vers��o do Sistema Speracional"
+
+msgid "CPUS"
+msgstr "CPUS"
+
+msgid "Memory"
+msgstr "Mem��ria"
+
+msgid "Create"
+msgstr "Criar"
+
+msgid "Creating..."
+msgstr "Criando..."
+
+msgid "Cancel"
+msgstr "Cancelar"
+
+msgid "Edit Guest"
+msgstr "Editar Guest"
+
+msgid "General"
+msgstr "Geral"
+
+msgid "Storage"
+msgstr "Storage"
+
+msgid "Interface"
+msgstr "Interface"
+
+msgid "Permission"
+msgstr "Permiss��o"
+
+msgid "Host PCI Device"
+msgstr "Dispositivo de host PCI"
+
+msgid "Snapshot"
+msgstr "Snapshot"
+
+msgid "Name"
+msgstr "Nome"
+
+msgid "CPUs"
+msgstr "CPUs"
+
+msgid "Memory (MB)"
+msgstr "Mem��ria (MB)"
+
+msgid "Icon"
+msgstr "��cone"
+
+msgid "Device"
+msgstr "Dispositivo"
+
+msgid "Path"
+msgstr "Caminho"
+
+msgid "Network"
+msgstr "Rede"
+
+msgid "Type"
+msgstr "Tipo"
+
+msgid "MAC Address"
+msgstr ""
+
+msgid "Available system users and groups"
+msgstr "Usu��rios e grupos de sistema dispon��veis"
+
+msgid "Selected system users and groups"
+msgstr "Usu��rios e grupos de sistema selecionados"
+
+msgid "User"
+msgstr "Usu��rio"
+
+msgid "All"
+msgstr "Todos"
+
+msgid "To Add"
+msgstr "Para adicionar"
+
+msgid "Added"
+msgstr "Adicionado"
+
+msgid "filter"
+msgstr "filtro"
+
+msgid "Product"
+msgstr "Produto"
+
+msgid "Vendor"
+msgstr "Vendor"
+
+msgid "Created"
+msgstr "Criado"
+
+msgid "Save"
+msgstr "Salvar"
+
+msgid "Replace"
+msgstr "Substituir"
+
+msgid "Detach"
+msgstr "Remover"
+
+msgid "revert"
+msgstr "Reverter"
+
+msgid "Start"
+msgstr "Iniciar"
+
+msgid "Reset"
+msgstr "Reiniciar"
+
+msgid "Pause"
+msgstr ""
+
+msgid "Resume"
+msgstr ""
+
+msgid "Power Off"
+msgstr "For��ar desligamento"
+
+msgid "Actions"
+msgstr "A����es"
+
+msgid "Connect"
+msgstr "Conectar"
+
+msgid "Clone"
+msgstr "Clonar"
+
+msgid "Edit"
+msgstr "Editar"
+
+msgid "Shut Down"
+msgstr "Desligar"
+
+msgid "Delete"
+msgstr "Remover"
+
+msgid "CPU"
+msgstr "CPU"
+
+msgid "Disk I/O"
+msgstr "Disco E/S"
+
+msgid "Network I/O"
+msgstr "Rede E/S"
+
+msgid "Livetile"
+msgstr "Tela ao vivo"
+
+msgid "No guests found."
+msgstr "Nenhum guest encontrado."
+
+msgid "Add a Storage Device to VM"
+msgstr "Adicionar um dispositivo de storage �� VM"
+
+msgid "Device Type"
+msgstr "Tipo do Dispositivo"
+
+msgid "The device type. Currently, \"cdrom\" and \"disk\" are
supported."
+msgstr ""
+"O tipo do dispositivo. Atualmente, \"cdrom\" e \"disco\" s��o
suportados."
+
+msgid "Storage Pool"
+msgstr "Storage Pool"
+
+msgid "Storage pool which volume located in"
+msgstr "Storage pool no qual o volume est�� localizado"
+
+msgid "Storage Volume"
+msgstr "Volume de storage"
+
+msgid "Storage volume to be attached"
+msgstr "Volume de storage a ser adicionado"
+
+msgid "File Path"
+msgstr "Caminho do Arquivo"
+
+msgid "The ISO file path in the server for CDROM."
+msgstr "O caminho do arquivo ISO para o CDROM no servidor."
+
+msgid "Attach"
+msgstr "Adicionar"
+
+msgid "Shut down"
+msgstr "Desligar"
+
+msgid "Restart"
+msgstr "Reiniciar"
+
+msgid "Basic Information"
+msgstr "Informa����es b��sicas"
+
+msgid "OS Distro"
+msgstr "Distribui����o"
+
+msgid "OS Code Name"
+msgstr "Nome-c��digo do sistema operacional"
+
+msgid "Processor"
+msgstr "Processador"
+
+msgid "CPU(s)"
+msgstr "CPU(s)"
+
+msgid "System Statistics"
+msgstr "Estat��sticas do sistema"
+
+msgid "Software Updates"
+msgstr "Atualiza����es de software"
+
+msgid "Update Progress"
+msgstr "Progresso da atualiza����o"
+
+msgid "Repositories"
+msgstr "Reposit��rios"
+
+msgid "Debug Reports"
+msgstr "Relat��rios de Debug"
+
+msgid "The username or password you entered is incorrect. Please try again."
+msgstr ""
+"O usu��rio ou senha inseridos est��o incorretos. Por favor, tente novamente."
+
+msgid "This field is required."
+msgstr "Esse campo �� obrigat��rio."
+
+msgid "Log in"
+msgstr "Entrar"
+
+msgid "Logging in..."
+msgstr "Entrando..."
+
+msgid "Host"
+msgstr "Host"
+
+msgid "Guests"
+msgstr "Guests"
+
+msgid "Templates"
+msgstr "Modelos"
+
+msgid "Failed to get application configuration"
+msgstr "N��o foi poss��vel carregar as configura����es da aplica����o"
+
+msgid "This is not a valid Linux path"
+msgstr "Este n��o �� um caminho v��lido no Linux"
+
+msgid "This is not a valid URL."
+msgstr "Essa n��o �� uma URL v��lida."
+
+msgid "No such data available."
+msgstr "N��o h�� dados dispon��veis."
+
+msgid ""
+"Can not contact the host system. Verify the host system is up and that you "
+"have network connectivity to it. HTTP request response %1. "
+msgstr ""
+"N��o foi poss��vel contactar o sistema host. Verique se o sistema do host est��
"
+"ligado e se voc�� possui conectividade de rede com ele. Resposta da "
+"requisi����o HTTP %1. "
+
+msgid "Unable to read file."
+msgstr ""
+
+msgid "Error while uploading file."
+msgstr ""
+
+msgid "Delete Confirmation"
+msgstr "Confirma����o de remo����o"
+
+msgid "OK"
+msgstr "OK"
+
+msgid "Confirm"
+msgstr "Confirmar"
+
+msgid "Warning"
+msgstr "Aviso"
+
+msgid "Cloning..."
+msgstr ""
+
+msgid "Loading..."
+msgstr "Carregando..."
+
+msgid "An error occurred while retrieving system information."
+msgstr "Ocorreu um erro ao recuperar informa����es do sistema."
+
+msgid "Retry"
+msgstr "Tentar novamente"
+
+msgid "Detailed message:"
+msgstr "Mensagem detalhada:"
+
+msgid "No ISO found"
+msgstr "Nenhuma ISO encontrada"
+
+msgid "This is not a valid ISO file."
+msgstr "Esse n��o �� um arquivo ISO v��lido."
+
+msgid "This may take a long time. Do you want to continue?"
+msgstr "Isso vai levar um longo tempo. Deseja continuar?"
+
+msgid "This will permanently delete the template. Would you like to continue?"
+msgstr "O modelo vai ser permanentemente removido. Deseja continuar?"
+
+msgid "Unable to shut down system as there are some virtual machines running!"
+msgstr ""
+"N��o foi poss��vel desligar o sistema porque algumas m��quinas virtuais est��o
"
+"ligadas!"
+
+msgid "Max:"
+msgstr "M��ximo:"
+
+msgid "Utilization"
+msgstr "Utiliza����o"
+
+msgid "Available"
+msgstr "Dispon��vel"
+
+msgid "Read Rate"
+msgstr "Taxa de leitura"
+
+msgid "Write Rate"
+msgstr "Taxa de escrita"
+
+msgid "Received"
+msgstr "Recebido"
+
+msgid "Sent"
+msgstr "Enviado"
+
+msgid ""
+"Shutting down or restarting host will cause unsaved work lost. Continue to "
+"shut down/restarting?"
+msgstr ""
+"Desligar ou reiniciar o host causar�� perda de trabalho que n��o foi salvo. "
+"Continuar o processo de desligar/reiniciar?"
+
+msgid ""
+"Repository will be removed permanently and can't be recovered. Do you want
"
+"to continue?"
+msgstr ""
+"Reposit��rio ser�� removido permanentemente e n��o poder�� ser recuperado. "
+"Deseja continuar?"
+
+msgid "ID"
+msgstr "ID"
+
+msgid "Base URL"
+msgstr "URL Base"
+
+msgid "Is Mirror"
+msgstr "�� mirror"
+
+msgid "URL Args"
+msgstr "Argumentos da URL"
+
+msgid "Enabled"
+msgstr "Ativado"
+
+msgid "GPG Check"
+msgstr "Verifica����o GPG"
+
+msgid "GPG Key"
+msgstr "Chave GPG"
+
+msgid "Add"
+msgstr "Adicionar"
+
+msgid "Remove"
+msgstr "Remover"
+
+msgid "Enable"
+msgstr "Ativar"
+
+msgid "Disable"
+msgstr "Desativar"
+
+msgid "Package Name"
+msgstr "Nome do pacote"
+
+msgid "Version"
+msgstr "Vers��o"
+
+msgid "Architecture"
+msgstr "Arquitetura"
+
+msgid "Repository"
+msgstr "Reposit��rio"
+
+msgid "Update All"
+msgstr "Atualizar todos"
+
+msgid "Updating..."
+msgstr "Atualizando..."
+
+msgid "Failed to retrieve packages update information."
+msgstr "N��o foi poss��vel recuperar as informa����es de atualiza����o de
pacoates."
+
+msgid "Failed to update package(s)."
+msgstr "Erro ao atualizar pacote(s)."
+
+msgid ""
+"Debug report will be removed permanently and can't be recovered. Do you want
"
+"to continue?"
+msgstr ""
+"Relat��rio de debug ser�� permanentemente removido e n��o poder�� ser "
+"recuperado. Deseja continuar?"
+
+msgid "Generated Time"
+msgstr "Tempo gerado"
+
+msgid "Generate"
+msgstr "Gerar"
+
+msgid "Generating..."
+msgstr "Gerando..."
+
+msgid "Rename"
+msgstr "Renomear"
+
+msgid "Download"
+msgstr "Baixar"
+
+msgid ""
+"Report name should contain only letters, digits, underscore ('_') and/or
"
+"hyphen ('-')."
+msgstr ""
+"Nome do relat��rio deve apenas conter letras, n��meros, underscore ('_')
e/ou "
+"h��fen ('-')."
+
+msgid "Pending..."
+msgstr "Pendente..."
+
+msgid "Report name is the same as the original one."
+msgstr "Nome do relat��rio �� o mesmo que o original."
+
+msgid ""
+"This will delete the virtual machine and its virtual disks. This operation "
+"cannot be undone. Would you like to continue?"
+msgstr ""
+"A m��quina virtual vai ser removida com todos seus discos. Essa opera����o ��
"
+"irrevers��vel. Deseja continuar?"
+
+msgid "Power off Confirmation"
+msgstr "Confirma����o de desligamento for��ado"
+
+msgid ""
+"This action may produce undesirable results, for example unflushed disk "
+"cache in the guest. Would you like to continue?"
+msgstr ""
+"Essa a����o pode produzir resultados n��o desej��veis, como por exemplo cache de
"
+"disco n��o-atualizado no guest. Deseja continuar?"
+
+msgid "Reset Confirmation"
+msgstr "Confirma����o de reinicializa����o"
+
+msgid ""
+"There is a risk of data loss caused by reset without the guest OS shutdown. "
+"Would you like to continue?"
+msgstr ""
+"Existe um risco de perda de dados causado pela reinicializa����o sem o "
+"desligamento do sistema operacional do guest. Deseja continuar?"
+
+msgid "Shut Down Confirmation"
+msgstr "Confirma����o de desligamento"
+
+msgid "Note the guest OS may ignore this request. Would you like to continue?"
+msgstr ""
+"O sistema operacional do guest pode ignorar essa requisi����o. Deseja "
+"continuar?"
+
+msgid "Virtual Machine delete Confirmation"
+msgstr "Confirma����o de Remo����o da M��quina Virtual"
+
+msgid ""
+"This virtual machine is not persistent. Power Off will delete it. Continue?"
+msgstr ""
+"Essa m��quina virtual n��o �� persistente. O desligamento ir�� remov��-la. Deseja
"
+"continuar?"
+
+msgid ""
+"When the target guest has SCSI or iSCSI volumes, they will be cloned on "
+"default storage pool. The same will happen when the target pool does not "
+"have enough space to clone the volumes. Do you want to continue?"
+msgstr ""
+"Quando o guest de destino tiver volumes SCSI ou iSCSI, eles ser��o clonados "
+"no storage pool padr��o. O mesmo vai acontecer quando o pool de destino n��o
"
+"tiver espa��o suficiente para clonar os volumes. Voc�� deseja continuar?"
+
+msgid ""
+"This CDROM will be detached permanently and you can re-attach it. Continue "
+"to detach it?"
+msgstr ""
+"Esse CDROM ser�� desconectado permanentemente e voc�� pode reconect��-lo. "
+"Deseja continuar a remo����o? "
+
+msgid "Attaching..."
+msgstr "Adicionando..."
+
+msgid "Replacing..."
+msgstr "Substituindo..."
+
+msgid "Successfully attached!"
+msgstr "Adicionado com sucesso!"
+
+msgid "Successfully replaced!"
+msgstr "Substitu��do com sucesso!"
+
+msgid "Successfully detached!"
+msgstr "Removido com sucesso!"
+
+msgid ""
+"This disk will be detached permanently and you can re-attach it. Continue to
"
+"detach it?"
+msgstr ""
+"Esse disco ser�� desconectado permanentemente e voc�� pode reconect��-lo. "
+"Deseja continuar a remo����o? "
+
+msgid "interface:"
+msgstr "interface:"
+
+msgid "address:"
+msgstr "endere��o:"
+
+msgid "link_type:"
+msgstr "tipo do link:"
+
+msgid "block:"
+msgstr "bloco:"
+
+msgid "drive_type:"
+msgstr "tipo do drive:"
+
+msgid "model:"
+msgstr "modelo:"
+
+msgid "Affected devices:"
+msgstr "Dispositivos afetados:"
+
+msgid "The VLAN id must be between 1 and 4094."
+msgstr "ID da VLAN deve ser um n��mero entre 1 e 4094."
+
+msgid "unavailable"
+msgstr "indispon��vel"
+
+msgid ""
+"This action will interrupt network connectivity for any virtual machine that
"
+"depend on this network."
+msgstr ""
+"Esta a����o ir�� interromper a conectividade da rede para qualquer m��quina "
+"virtual que depende dessa rede."
+
+msgid "Create a network"
+msgstr "Criar uma rede"
+
+msgid ""
+"This network is not persistent. Instead of stop, this action will "
+"permanently delete it. Would you like to continue?"
+msgstr ""
+"Essa rede n��o �� persistente. Ao inv��s de parar, essa a����o ir�� remov��-la
"
+"permantemente. Deseja continuar?"
+
+msgid ""
+"The bridged VLAN tag may not work well with NetworkManager enabled. You "
+"should consider disabling it."
+msgstr ""
+
+msgid ""
+"This will permanently delete the storage pool. Would you like to continue?"
+msgstr "O storage pool vai ser permanentemente removido. Deseja continuar?"
+
+msgid "This storage pool is empty."
+msgstr "Esse storage pool est�� vazio."
+
+msgid ""
+"It will format your disk and you will loose any data in there, are you sure "
+"to continue? "
+msgstr ""
+"Isso formatar�� seu disco e voc�� perder�� toda informa����o, voc�� tem certeza
"
+"que quer continuar?"
+
+msgid "SCSI Fibre Channel"
+msgstr "SCSI Fibre Channel"
+
+msgid "No SCSI adapters found."
+msgstr "Nenhum adaptador SCSI encontrado."
+
+msgid "Loading iSCSI targets..."
+msgstr "Carregando iSCSI targets..."
+
+msgid "No iSCSI found. Please input one."
+msgstr "Nenhum iSCSI encontrado. Por favor, forne��a um."
+
+msgid "Failed to load iSCSI targets."
+msgstr "Erro ao carregar iSCSI targets."
+
+msgid "The storage pool name can not be blank."
+msgstr "O nome do storage pool n��o pode ser vazio."
+
+msgid "The storage pool path can not be blank."
+msgstr "O caminho do storage pool n��o pode ser vazio."
+
+msgid "NFS server mount path can not be blank."
+msgstr "Caminho de montagem do servidor de NFS n��o pode ser vazio."
+
+msgid "Invalid NFS mount path."
+msgstr "Caminho de montagem do NFS inv��lido."
+
+msgid "No logical device selected."
+msgstr "Nenhum dispositivo l��gico selecionado."
+
+msgid "The iSCSI target can not be blank."
+msgstr "O alvo iSCSI n��o pode ser vazio."
+
+msgid "Server name can not be blank."
+msgstr "Nome do servidor n��o pode ser vazio."
+
+msgid "This is not a valid Server Name or IP. Please, modify it."
+msgstr "Este n��o �� um nome ou IP de servidor v��lido. Por favor,
modifique-o."
+
+msgid "Looking for available partitions ..."
+msgstr "Procurando por parti����es dispon��veis ..."
+
+msgid "No available partitions found."
+msgstr "Nenhuma parti����o dispon��vel encontrada."
+
+msgid ""
+"This storage pool is not persistent. Instead of deactivate, this action will
"
+"permanently delete it. Would you like to continue?"
+msgstr ""
+"O storage pool n��o �� persistente. Ao inv��s de desativar, essa a����o vai "
+"remov��-lo permanentemente. Deseja continuar?"
+
+msgid "Unable to retrieve partitions information."
+msgstr "N��o foi poss��vel recuperar as informa����es das parti����es."
+
+msgid "In progress..."
+msgstr "Em progresso..."
+
+msgid "Failed!"
+msgstr "Falhou!"
+
+msgid "CDROM path needs to be a valid local/remote path and cannot be blank."
+msgstr ""
+"Caminho do CDROM precisa ser um caminho local v��lido e n��o pode ser vazio."
+
+msgid "Disk pool or volume cannot be blank."
+msgstr "Pool ou volume do disco n��o pode ser vazio."
+
+#, fuzzy
+msgid "Filter"
+msgstr "filtro"
+
+msgid "Network Name"
+msgstr "Nome da rede"
+
+msgid "State"
+msgstr "Estado"
+
+msgid "Network Type"
+msgstr "Tipo da rede"
+
+msgid "Address Space"
+msgstr "Espa��o de endere��o"
+
+msgid "Name should not contain '/' and '\"'."
+msgstr "O nome n��o deve conter '/' and '\"'."
+
+msgid "Isolated: no external network connection"
+msgstr "Isolada: nenhuma conex��o externa"
+
+msgid "NAT: outbound physical network connection only"
+msgstr "NAT: somente conex��o de rede f��sica de sa��da"
+
+msgid "Bridged: Virtual machines are connected to physical network directly"
+msgstr ""
+"Bridged: M��quinas virtuais est��o conectadas diretamente com a rede f��sica"
+
+msgid "(No interfaces found)"
+msgstr "(Nenhuma interface encontrada)"
+
+msgid "Destination"
+msgstr "Destino"
+
+msgid "Enable VLAN"
+msgstr "Habilitar VLAN"
+
+msgid "VLAN ID"
+msgstr "ID da VLAN"
+
+msgid "Stop"
+msgstr "Parar"
+
+msgid "Generate a New Debug Report"
+msgstr "Gerar um novo Relat��rio de Debug"
+
+msgid "Report Name"
+msgstr "Nome do Relat��rio"
+
+msgid ""
+"The name used to identify the report. If omitted, a name will be chosen "
+"based on current time. Name can contain: letters, digits, underscore
(\"_\") "
+"and hyphen (\"-\")."
+msgstr ""
+"O nome usado para identificar o relat��rio. Se omitido, um nome ser�� "
+"escolhido baseado no hor��rio atual. O nome pode conter: letras, n��meros, "
+"underscore ('_') e h��fen ('-')."
+
+msgid "Rename a Debug Report"
+msgstr "Renomear um Relat��rio de Debug"
+
+msgid ""
+"The name used to identify the report. Name can contain: letters, digits and "
+"hyphen (\"-\")."
+msgstr ""
+"O nome usado para identificar o relat��rio. O nome pode conter: letras, "
+"d��gitos e h��fen (\"-\")."
+
+msgid "Submit"
+msgstr "Enviar"
+
+msgid "Add a Repository"
+msgstr "Adicionar um Reposit��rio"
+
+msgid "Identifier"
+msgstr "Identificador"
+
+msgid "Single word, unique identifier for the repository."
+msgstr "Uma ��nica palavra, identificador ��nico para o reposit��rio."
+
+msgid "Textual name for the repository."
+msgstr "Nome textual para o reposit��rio."
+
+msgid "URL"
+msgstr "URL"
+
+msgid "Required Field"
+msgstr "Campo Obrigat��rio"
+
+msgid "URL to the repository. Supported protocols are http, ftp, and file."
+msgstr "URL para o reposit��rio. Protocolos suportados s��o http, ftp e file."
+
+msgid "Repository is a mirror"
+msgstr "Reposit��rio �� um mirror"
+
+msgid "Distribution"
+msgstr "Distribui����o"
+
+msgid "Distribution of the DEB repository."
+msgstr "Distribui����o para o reposit��rio DEB."
+
+msgid "Components"
+msgstr "Componentes"
+
+msgid "List of components in DEB repository."
+msgstr "Lista de componentes para o reposit��rio DEB."
+
+msgid "Edit Repository"
+msgstr "Editar Reposit��rio"
+
+msgid "Mirror List URL"
+msgstr "URL para a lista de mirror"
+
+msgid "Yes"
+msgstr "Sim"
+
+msgid "No"
+msgstr "N��o"
+
+msgid "Capacity"
+msgstr "Capacidade"
+
+msgid "Allocated"
+msgstr "Alocado"
+
+msgid "Location"
+msgstr "Localiza����o"
+
+msgid "Device path"
+msgstr "Caminho do dispositivo"
+
+msgid "active"
+msgstr "ativo"
+
+msgid "inactive"
+msgstr "inativo"
+
+msgid "Deactivate"
+msgstr "Desativar"
+
+msgid "Activate"
+msgstr "Ativar"
+
+msgid "Add Volume"
+msgstr "Adicionar volume"
+
+msgid "Extend"
+msgstr "Aumentar"
+
+msgid "Undefine"
+msgstr "Indefinir"
+
+msgid "Format"
+msgstr "Formato"
+
+msgid "Allocation"
+msgstr "Aloca����o"
+
+msgid "Define a New Storage Pool"
+msgstr "Definir novo Storage Pool"
+
+msgid "Storage Pool Name"
+msgstr "Nome do Storage Pool"
+
+msgid ""
+"The name used to identify the storage pools, and it should not be empty."
+msgstr "O nome usado para identificar o storage pool e n��o deve ser vazio."
+
+msgid "Storage Pool Type"
+msgstr "Tipo do Storage Pool"
+
+msgid "Storage Path"
+msgstr "Caminho do storage"
+
+msgid ""
+"The path of the Storage Pool. Each Storage Pool must have a unique path."
+msgstr ""
+"O caminho do Storage Pool. Cada Storage Pool deve ter um caminho ��nico."
+
+msgid ""
+"Kimchi will try to create the directory when it does not already exist in "
+"your system."
+msgstr ""
+"O Kimchi vai tentar criar o diret��rio se ainda n��o existir no seu sistema."
+
+msgid "NFS Server IP"
+msgstr "IP do servidor NFS"
+
+msgid "NFS server IP or hostname. It can be input or chosen from history."
+msgstr ""
+"IP ou hostname do servidor NFS. Pode ser inserido ou escolhido do
hist��rico."
+
+msgid "NFS Path"
+msgstr "Caminho do NFS"
+
+msgid "The NFS exported path on NFS server."
+msgstr "O caminho exportado do servidor NFS."
+
+msgid "iSCSI Server"
+msgstr "Servidor iSCSI"
+
+msgid "Server"
+msgstr "Servidor"
+
+msgid "Port"
+msgstr "Porta"
+
+msgid "iSCSI server IP or hostname. It should not be empty."
+msgstr "IP ou hostname do servidor iSCSI. N��o deve ser vazio."
+
+msgid "Target"
+msgstr "Alvo"
+
+msgid "The iSCSI target on iSCSI server"
+msgstr "O alvo iSCSI no servidor iSCSI"
+
+msgid "Add iSCSI Authentication"
+msgstr "Adicionar as credenciais do iSCSI"
+
+msgid "iSCSI Authentication"
+msgstr "Credenciais do iSCSI"
+
+msgid "User Name"
+msgstr "Usu��rio"
+
+msgid "Password"
+msgstr "Senha"
+
+msgid "SCSI Adapter"
+msgstr "Adaptador SCSI"
+
+msgid "Please, wait..."
+msgstr "Por favor, aguarde..."
+
+msgid "Add a Volume to Storage Pool"
+msgstr "Adicionar um volume ao Storage Pool"
+
+msgid "Fetch from remote URL"
+msgstr "Fazer download de uma URL remota"
+
+msgid "Enter the remote URL here."
+msgstr "Digite a URL remota aqui."
+
+msgid "Upload a file"
+msgstr "Fazer upload de um arquivo"
+
+msgid "Choose the file you want to upload."
+msgstr "Escolha o arquivo que voc�� quer fazer upload."
+
+msgid "Add Template"
+msgstr "Adicionar Modelo"
+
+msgid "Where is the source media for this template? "
+msgstr "Onde est�� a m��dia de origem desse modelo? "
+
+msgid "Local ISO Image"
+msgstr "Imagem ISO Local"
+
+msgid "Local Image File"
+msgstr "Arquivo de Imagem Local"
+
+msgid "Remote ISO Image"
+msgstr "Imagem ISO Remota"
+
+msgid "Search ISOs"
+msgstr "Procurar ISOs"
+
+msgid "The following ISOs are available:"
+msgstr "As seguintes ISOs est��o dispon��veis:"
+
+msgid "OS: "
+msgstr "Sistema Operacional: "
+
+msgid "Version: "
+msgstr "Vers��o: "
+
+msgid "Size: "
+msgstr "Tamanho: "
+
+msgid "Search more ISOs"
+msgstr "Procurar por mais ISOs"
+
+msgid "Create Templates from Selected ISO"
+msgstr "Criar Modelos a partir das ISOs selecionadas"
+
+msgid "I want to use a specific ISO file"
+msgstr "Eu quero usar um arquivo ISO espec��fico"
+
+msgid "Loading default remote ISOs ..."
+msgstr "Carregando ISOs remotas ..."
+
+msgid "Arch: "
+msgstr "Arquitetura: "
+
+msgid "I want to use a custom URL"
+msgstr "Eu quero usar uma URL personalizada"
+
+msgid "Edit Template"
+msgstr "Editar Modelo"
+
+msgid "CDROM"
+msgstr "CD-ROM"
+
+msgid "Image File"
+msgstr "Arquivo de imagem"
+
+msgid "Graphics"
+msgstr "Gr��ficos"
+
+msgid "Disk(GB)"
+msgstr "Disco (GB)"
+
+msgid "Disk Format"
+msgstr ""
+
+msgid "CPU Number"
+msgstr "Quantidade de CPUs"
+
+msgid "Manually set CPU topology"
+msgstr "Configurar manualmente a topologia de CPU"
+
+msgid "Cores"
+msgstr "Cores"
+
+msgid "Threads"
+msgstr "Threads"
+
+msgid "No templates found."
+msgstr "Nenhum modelo encontrado."
+
+#~ msgid "Delete is not allowed for %(resource)s"
+#~ msgstr "M��todo de remo����o n��o �� permitido em %(resource)s"
+
+#~ msgid "%(resource)s does not implement update method"
+#~ msgstr "%(resource)s n��o implementa m��todo de atualiza����o"
+
+#~ msgid "Create is not allowed for %(resource)s"
+#~ msgstr "M��todo de cria����o n��o �� permitido em %(resource)s"
+
+#~ msgid "Unable to parse JSON request"
+#~ msgstr "N��o �� poss��vel realizar a leitura da requisi����o do JSON"
+
+#~ msgid "This API only supports JSON"
+#~ msgstr "Essa API suporta apenas JSON"
+
+#~ msgid "Parameters does not match requirement in schema: %(err)s"
+#~ msgstr "Par��metros n��o correspondem �� especifica����o do esquema:
%(err)s"
+
+#~ msgid "You don't have permission to perform this operation."
+#~ msgstr "Voc�� n��o tem permiss��o para executar esta opera����o."
+
+#~ msgid "Datastore is not initiated in the model object."
+#~ msgstr "Datastore n��o est�� inicializado no objeto modelo."
+
+#~ msgid "Unable to start task due error: %(err)s"
+#~ msgstr "N��o foi poss��vel iniciar a tarefa devido a um erro: %(err)s"
+
+#~ msgid ""
+#~ "Authentication failed for user '%(username)s'. [Error code:
%(code)s]"
+#~ msgstr ""
+#~ "Autentica����o falhou para o usu��rio '%(username)s'. [C��digo de erro:
%"
+#~ "(code)s]"
+
+#~ msgid "You are not authorized to access Kimchi"
+#~ msgstr "Voc�� n��o est�� autorizado para acessar o Kimchi"
+
+#~ msgid "Specify %(item)s to login into Kimchi"
+#~ msgstr "Especifique %(item)s para autenticar no Kimchi"
+
+#~ msgid "Invalid LDAP configuration: %(item)s : %(value)s"
+#~ msgstr "Configura����es LDAP inv��lidas: %(item)s : %(value)s"
+
+#~ msgid "Unable to find %(item)s in datastore"
+#~ msgstr "N��o foi poss��vel encontrar %(item)s no datastore"
+
+#~ msgid "Timeout while running command '%(cmd)s' after %(seconds)s
seconds"
+#~ msgstr ""
+#~ "Fim do limite de tempo ao rodar comando '%(cmd)s' ap��s %(seconds)s
"
+#~ "segundos"
+
+#~ msgid "Invalid data value '%(value)s'"
+#~ msgstr "Valor inv��lido '%(value)s'"
+
+#~ msgid "Invalid data unit '%(unit)s'"
+#~ msgstr "Unidade inv��lida '%(unit)s'"
+
+#~ msgid "Peers"
+#~ msgstr "Peers"
+
+#~ msgid "Searching"
+#~ msgstr "Procurando"
+
+#~ msgid "No peers found."
+#~ msgstr "Nenhum peer encontrado."
+
+#~ msgid "Help"
+#~ msgstr "Ajuda"
+
+#~ msgid "About"
+#~ msgstr "Sobre"
+
+#~ msgid "Log out"
+#~ msgstr "Sair"
+
+#~ msgid "Version:"
+#~ msgstr "Vers��o:"
+
+#~ msgid "Session timeout, please re-login."
+#~ msgstr ""
+#~ "Fim do limite do tempo da sess��o, por favor se autentique novamente."
diff --git a/src/wok/plugins/kimchi/po/ru_RU.po b/src/wok/plugins/kimchi/po/ru_RU.po
new file mode 100644
index 0000000..a5dec2e
--- /dev/null
+++ b/src/wok/plugins/kimchi/po/ru_RU.po
@@ -0,0 +1,2198 @@
+# English translations for kimchi package.
+# Copyright (C) 2013 ORGANIZATION
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: kimchi 0.1\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2015-07-01 16:11-0300\n"
+"PO-Revision-Date: 2014-08-28 17:32+0000\n"
+"Last-Translator: Aline Manera <aline.manera(a)gmail.com>\n"
+"Language-Team: Russian (
http://www.transifex.com/projects/p/kimchi/language/"
+"ru/)\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Language: ru_RU\n"
+"Generated-By: pygettext.py 1.5\n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+
+#, python-format
+msgid "Unknown parameter %(value)s"
+msgstr ""
+
+#, python-format
+msgid "Timeout of %(seconds)s seconds expired while running task
'%(task)s."
+msgstr ""
+
+#, python-format
+msgid "User %(user_id)s not found with given LDAP settings."
+msgstr ""
+
+msgid "Unknown \"_cap\" specified"
+msgstr ""
+
+msgid "\"_passthrough\" should be \"true\" or
\"false\""
+msgstr ""
+
+msgid "\"_passthrough_affected_by\" should be a device name string"
+msgstr ""
+
+#, python-format
+msgid "Error while getting block devices. Details: %(err)s"
+msgstr "������������ ������������������ �������������� ������������������.
����������������: %(err)s"
+
+#, python-format
+msgid "Error while getting block device information for %(device)s."
+msgstr "������������ ������������������ �������������������� �� ��������������
���������������������� ������ %(device)s."
+
+#, python-format
+msgid "Unable to find distro file: %(filename)s"
+msgstr "���� ������������ �������� ���������������� ����: %(filename)s"
+
+#, python-format
+msgid ""
+"Unable to parse distro file: %(filename)s. Make sure, it is a JSON file."
+msgstr ""
+"������������ �������������� ���������� ���������������� ���� %(filename)s.
������������������, ������ ������ �������� JSON."
+
+#, python-format
+msgid "Unable to login to iSCSI host target %(portal)s. Details: %(err)s"
+msgstr "���� �������������� ���������� �� �������������� %(portal)s ����������
iSCSI. ����������������: %(err)s"
+
+#, python-format
+msgid "Unable to login to iSCSI host %(host)s target %(target)s"
+msgstr "���� �������������� ���������� �� �������������� %(target)s ���������� iSCSI
%(host)s"
+
+#, python-format
+msgid "Unable to find ISO file %(filename)s"
+msgstr ""
+
+#, python-format
+msgid "The ISO file %(filename)s is not bootable"
+msgstr "�������� ISO %(filename)s ���� ����������������������"
+
+#, python-format
+msgid "The ISO file %(filename)s does not have a valid El Torito boot record"
+msgstr ""
+"�������� ISO %(filename)s ���� ���������������� ��������������������
���������������������� ������������ El Torito"
+
+#, python-format
+msgid "Invalid El Torito validation entry in ISO %(filename)s"
+msgstr "������������������������ ������������ ���������������� El Torito ��
������������ ISO %(filename)s"
+
+#, python-format
+msgid "Invalid El Torito boot indicator in ISO %(filename)s"
+msgstr "������������������������ ������������������ ���������������� El Torito ��
������������ ISO %(filename)s"
+
+#, python-format
+msgid "Unexpected volume type for primary volume in ISO %(filename)s"
+msgstr "���������������������� ������ �������� ������ ���������������� �������� ��
������������ ISO %(filename)s"
+
+#, python-format
+msgid "Bad format while reading volume descriptor in ISO %(filename)s"
+msgstr "���������������� ������������ ���������������������� �������� ��
������������ ISO %(filename)s"
+
+#, python-format
+msgid ""
+"The hypervisor doesn't have permission to use this ISO %(filename)s. "
+"Consider moving it under /var/lib/libvirt, or set the search permission to "
+"file access control lists for '%(user)s' user if possible, or add the
'%"
+"(user)s' to the ISO path group, or (not recommended) 'chmod -R o+x "
+"'path_to_iso'.Details: %(err)s"
+msgstr ""
+"�� ���������������������� ������ �������� �������������� ������
�������������������������� ���������� ������������ ISO %(filename)"
+"s. ���������������������� ������ �� �������������� /var/lib/libvirt,
���������������� �������������������� ���� ���������� "
+"�� ������������ ���������������� �������������� ������ ������������������������
%(user)s, �������� ������ ����������������, "
+"���������������� %(user)s �� ������������ �������� �� ������������ ISO ������ (����
��������������������������) "
+"������������������ �������������� 'chmod -R o+x 'path_to_iso'.
����������������: %(err)s"
+
+msgid "An error occurred when probing image OS information."
+msgstr ""
+
+msgid "No OS information found in given image."
+msgstr ""
+
+#, python-format
+msgid "Unable to read image file %(filename)s"
+msgstr ""
+
+#, python-format
+msgid ""
+"Image file must be an existing file on system. %(filename)s is not a valid "
+"input."
+msgstr ""
+
+#, python-format
+msgid "Virtual machine %(name)s already exists"
+msgstr "���������������������� ������������ %(name)s ������
��������������������"
+
+#, python-format
+msgid "Virtual machine %(name)s does not exist"
+msgstr "���������������������� ������������ %(name)s ����
��������������������"
+
+#, python-format
+msgid ""
+"Unable to rename virtual machine %(name)s. The name %(new_name)s is already "
+"in use or the virtual machine is not powered off."
+msgstr ""
+
+#, python-format
+msgid "Unable to retrieve screenshot for stopped virtual machine %(name)s"
+msgstr ""
+"���� �������������� ���������������� ������������ ������������ ������
�������������������������� ���������������������� ������������ %"
+"(name)s"
+
+msgid "Remote ISO image is not supported by this server."
+msgstr "������������������ ���������� ISO ���� ���������������������������� ��������
����������������."
+
+#, python-format
+msgid "Screenshot is not supported on virtual machine %(name)s"
+msgstr ""
+
+#, python-format
+msgid "Unable to create virtual machine %(name)s. Details: %(err)s"
+msgstr "���� �������������� �������������� ���������������������� ������������
%(name)s. ����������������: %(err)s"
+
+#, python-format
+msgid "Unable to update virtual machine %(name)s. Details: %(err)s"
+msgstr "���� �������������� �������������� ���������������������� ������������
%(name)s. ����������������: %(err)s"
+
+#, python-format
+msgid "Unable to retrieve virtual machine %(name)s. Details: %(err)s"
+msgstr "���� �������������� ���������������� ���������������������� ������������
%(name)s. ����������������: %(err)s"
+
+#, python-format
+msgid "Unable to connect to powered off virtual machine %(name)s."
+msgstr ""
+
+msgid "Virtual machine name must be a string without slashes (/)"
+msgstr ""
+
+#, python-format
+msgid "Invalid template URI %(value)s specified for virtual machine"
+msgstr ""
+
+#, python-format
+msgid "Invalid storage pool URI %(value)s specified for virtual machine"
+msgstr ""
+
+msgid "Supported virtual machine graphics are Spice or VNC"
+msgstr ""
+
+msgid "Graphics address to listen on must be IPv4 or IPv6"
+msgstr ""
+"���������� ������������ ���������������� ������ ����������������������
�������������������� ������������ �������� IPv4 ������ IPv6"
+
+msgid "Specify a template to create a virtual machine from"
+msgstr "�������������� ������������ ������ ���������������� ����������������������
������������"
+
+#, python-format
+msgid "Unable to start virtual machine %(name)s. Details: %(err)s"
+msgstr "���� �������������� ������������������ ���������������������� ������������
%(name)s. ����������������: %(err)s"
+
+#, python-format
+msgid "Unable to power off virtual machine %(name)s. Details: %(err)s"
+msgstr "���� �������������� �������������������� ���������������������� ������������
%(name)s. ����������������: %(err)s"
+
+#, python-format
+msgid "Unable to delete virtual machine %(name)s. Details: %(err)s"
+msgstr "���� �������������� �������������� ���������������������� ������������
%(name)s. ����������������: %(err)s"
+
+#, python-format
+msgid "Unable to reset virtual machine %(name)s. Details: %(err)s"
+msgstr ""
+"���� �������������� �������������������������� ���������������������� ������������
%(name)s. ����������������: %(err)s"
+
+msgid "User name list must be an array"
+msgstr ""
+
+msgid "User name must be a string"
+msgstr "������ �������� ������������ �������� ��������������"
+
+msgid "Group name list must be an array"
+msgstr ""
+
+msgid "Group name must be a string"
+msgstr "������ �������� ������������ �������� ��������������"
+
+#, python-format
+msgid "User(s) '%(users)s' do not exist"
+msgstr "������������������������ %(users)s ���� ��������������������."
+
+#, python-format
+msgid "Group(s) '%(groups)s' do not exist"
+msgstr "������������������������ %(groups)s ���� ��������������������."
+
+#, python-format
+msgid "Unable to shutdown virtual machine %(name)s. Details: %(err)s"
+msgstr "���� �������������� �������������������� ���������������������� ������������
%(name)s. ����������������: %(err)s"
+
+#, python-format
+msgid ""
+"Unable to get access metadata of virtual machine %(name)s. Details: %(err)s"
+msgstr "���� �������������� ������������������ ���������������������� ������������
%(name)s. ����������������: %(err)s"
+
+msgid "The guest console password must be a string."
+msgstr ""
+
+msgid "The life time for the guest console password must be a number."
+msgstr ""
+
+#, python-format
+msgid "Virtual machine '%(name)s' must be stopped before cloning it."
+msgstr ""
+
+#, python-format
+msgid "Insufficient disk space to clone virtual machine '%(name)s'"
+msgstr ""
+
+#, python-format
+msgid "Unable to clone VM '%(name)s'. Details: %(err)s"
+msgstr ""
+
+#, python-format
+msgid "Invalid operation for non-persistent virtual machine %(name)s"
+msgstr ""
+
+#, python-format
+msgid "Cannot suspend VM '%(name)s' because it is not running."
+msgstr ""
+
+#, python-format
+msgid "Unable to suspend VM '%(name)s'. Details: %(err)s"
+msgstr ""
+
+#, python-format
+msgid "Cannot resume VM '%(name)s' because it is not paused."
+msgstr ""
+
+#, python-format
+msgid "Unable to resume VM '%(name)s'. Details: %(err)s"
+msgstr ""
+
+msgid "Memory assigned is higher then the maximum allowed in the host."
+msgstr ""
+
+#, python-format
+msgid ""
+"VM '%(name)s' does not support live memory update. Update the memory with
"
+"the machine offline to enable this feature."
+msgstr ""
+
+msgid "Only increase memory is allowed in active VMs"
+msgstr ""
+
+msgid ""
+"For live memory update, new memory value must be equal old memory value plus
"
+"multiples of 1024 Mib"
+msgstr ""
+
+msgid "There are not enough free slots of 1024 Mib in the guest."
+msgstr ""
+
+msgid ""
+"Host's libvirt version does not support memory devices. Libvirt must be >=
"
+"1.2.14"
+msgstr ""
+
+#, python-format
+msgid "Error attaching memory device. Details: %(error)s"
+msgstr ""
+
+#, python-format
+msgid ""
+"VM %(vmid)s does not contain directly assigned host device %(dev_name)s."
+msgstr ""
+
+#, python-format
+msgid "The host device %(dev_name)s is not allowed to directly assign to VM."
+msgstr ""
+
+msgid ""
+"No IOMMU groups found. Host PCI pass through needs IOMMU group to function "
+"correctly. Please enable Intel VT-d or AMD IOMMU in your BIOS, then verify "
+"the Kernel is compiled with IOMMU support. For Intel CPU, add intel_iommu=on
"
+"to your Kernel parameter in /boot/grub2/grub.conf. For AMD CPU, add iommu=pt
"
+"iommu=1."
+msgstr ""
+
+msgid "\"name\" should be a device name string"
+msgstr ""
+
+#, python-format
+msgid ""
+"The device %(name)s is probably in use by the host. Unable to attach it to "
+"the guest."
+msgstr ""
+
+#, python-format
+msgid "Interface %(iface)s does not exist in virtual machine %(name)s"
+msgstr "������������������ %(iface)s ���� �������������������� ��
���������������������� ������������ %(name)s"
+
+#, python-format
+msgid ""
+"Network %(network)s specified for virtual machine %(name)s does not exist"
+msgstr ""
+"�������� %(network)s, ������������������ ������ ���������������������� ������������
%(name)s, ���� ��������������������"
+
+msgid "Supported virtual machine interfaces type is only network"
+msgstr "���������������������������� ������������ �������� ������
���������������������� ���������������������� ������������ - ��������"
+
+msgid "Network name for virtual machine interface must be a string"
+msgstr "������ �������� ������ �������������������� ����������������������
������������ ������������ �������� ��������������"
+
+msgid "Invalid network model card specified for virtual machine interface"
+msgstr ""
+"�������������� ������������������������ ���������� ������������ �������� ������
�������������������� ���������������������� ������������"
+
+msgid "Specify type and network to add a new virtual machine interface"
+msgstr "�������������� ������ �� �������� ������ �������������������� ������������
�������������������� ���������������������� ������������"
+
+msgid "MAC Address must respect this format FF:FF:FF:FF:FF:FF"
+msgstr ""
+
+#, python-format
+msgid "MAC Address %(mac)s already exists in virtual machine %(name)s"
+msgstr ""
+
+msgid "Invalid MAC Address"
+msgstr ""
+
+msgid "Cannot change MAC address of a running virtual machine"
+msgstr ""
+
+#, python-format
+msgid "Template %(name)s already exists"
+msgstr "������������ %(name)s ������ ��������������������"
+
+#, python-format
+msgid ""
+"Network '%(network)s' specified for template %(template)s does not
exist"
+msgstr "�������� %(network)s, ������������������ ������ �������������� %(template)s,
���� ��������������������"
+
+#, python-format
+msgid ""
+"Storage pool %(pool)s specified for template %(template)s does not exist"
+msgstr "������ ������������ %(pool)s, ������������������ ������ ��������������
%(template)s, ���� ��������������������"
+
+#, python-format
+msgid "Storage pool %(pool)s specified for template %(template)s is not
active"
+msgstr "������ ������������ %(pool)s, ������������������ ������ ��������������
%(template)s, ���� ��������������"
+
+#, python-format
+msgid "Invalid parameter '%(param)s' specified for CDROM."
+msgstr "������������ ������������������������ ���������������� %(param)s ������
CDROM."
+
+#, python-format
+msgid "Network %(network)s specified for template %(template)s is not active"
+msgstr "�������� %(network)s, ������������������ ������ �������������� %(template)s,
���� ��������������"
+
+msgid "Template name must be a string"
+msgstr "������ �������������� ������������ �������� ��������������"
+
+msgid "Template icon must be a path to the image"
+msgstr "������������ �������������� ������������ �������� ���������� ��
������������"
+
+msgid "Template distribution must be a string"
+msgstr "�������������� �������������� ������������ �������� ��������������"
+
+msgid "Template distribution version must be a string"
+msgstr "������������ ���������������� �������������� ������������ ��������
��������������"
+
+msgid "The number of CPUs must be an integer greater than 0"
+msgstr "���������� ���������������������� ������������ �������� ����������
������������"
+
+msgid "Amount of memory (MB) must be an integer greater than 512"
+msgstr "���������� ������������ (����) ������������ �������� ���������� ������������
������������ 512"
+
+msgid "Template CDROM must be a local or remote ISO file"
+msgstr "CDROM �������������� ������������ �������� ������������������ ������
������������������ ������������ ISO"
+
+#, python-format
+msgid "Invalid storage pool URI %(value)s specified for template"
+msgstr "������ �������������� ������������ ������������������������ URI ��������
������������ %(value)s"
+
+msgid "Specify an ISO image as CDROM or a base image to create a template"
+msgstr "�������������� ���������� ISO �� ���������������� CDROM ������
���������������� ��������������"
+
+msgid "All networks for the template must be specified in a list."
+msgstr "������ �������� ������ �������������� ������������ �������� ��������������
�� ������������."
+
+msgid "Specify a volume to a template when storage pool is iSCSI or SCSI"
+msgstr ""
+
+#, python-format
+msgid "The volume %(volume)s is not in storage pool %(pool)s"
+msgstr ""
+
+#, python-format
+msgid "Unable to create template due error: %(err)s"
+msgstr "���� �������������� �������������� ������������ ����-���� ������������
%(err)s"
+
+#, python-format
+msgid "Unable to delete template due error: %(err)s"
+msgstr "���� �������������� �������������� ������������ ����-���� ������������
%(err)s"
+
+msgid "Disk size must be an integer greater than 1GB."
+msgstr ""
+
+msgid "Template base image must be a valid local image file"
+msgstr "CDROM �������������� ������������ �������� ������������������ ������
������������������ ������������ ISO"
+
+#, python-format
+msgid "Cannot identify base image %(path)s format"
+msgstr ""
+
+msgid ""
+"When specifying CPU topology, VCPUs must be a product of sockets, cores, and
"
+"threads."
+msgstr ""
+
+msgid ""
+"When specifying CPU topology, each element must be an integer greater than "
+"zero."
+msgstr ""
+
+msgid ""
+"Invalid disk image format. Valid formats: bochs, cloop, cow, dmg, qcow, "
+"qcow2, qed, raw, vmdk, vpc."
+msgstr ""
+
+#, python-format
+msgid "Storage pool %(name)s already exists"
+msgstr "������ ������������ %(name)s ������ ��������������������"
+
+#, python-format
+msgid "Storage pool %(name)s does not exist"
+msgstr "������ ������������ %(name)s ���� ��������������������"
+
+#, python-format
+msgid "Specify %(item)s in order to create the storage pool %(name)s"
+msgstr "�������������� %(item)s ������ ���������������� �������� ������������
%(name)s"
+
+#, python-format
+msgid "Unable to delete active storage pool %(name)s"
+msgstr "���� �������������� �������������� ���������������� ������ ������������
%(name)s"
+
+#, python-format
+msgid "Unable to list storage pools. Details: %(err)s"
+msgstr "���� �������������� �������������� ������������ ���������� ������������.
����������������: %(err)s"
+
+#, python-format
+msgid "Unable to create storage pool %(name)s. Details: %(err)s"
+msgstr "���� �������������� �������������� ������ ������������ %(name)s.
����������������: %(err)s"
+
+#, python-format
+msgid ""
+"Unable to get number of storage volumes in storage pool %(name)s. Details: %"
+"(err)s"
+msgstr ""
+"���� �������������� ���������������� ���������� ���������� �� �������� ������������
%(name)s. ����������������: %(err)s"
+
+#, python-format
+msgid "Unable to activate storage pool %(name)s. Details: %(err)s"
+msgstr "���� �������������� ������������������������ ������ ������������ %(name)s.
����������������: %(err)s"
+
+#, python-format
+msgid "Unable to deactivate storage pool %(name)s. Details: %(err)s"
+msgstr "���� �������������� ���������������������������� ������ ������������
%(name)s. ����������������: %(err)s"
+
+#, python-format
+msgid "Unable to delete storage pool %(name)s. Details: %(err)s"
+msgstr "���� �������������� �������������� ������ ������������ %(name)s.
����������������: %(err)s"
+
+#, python-format
+msgid ""
+"Unable to create NFS Pool as export path %(path)s may block during mount"
+msgstr ""
+"���� �������������� �������������� ������ NFS: ��������������������������������
�������� %(path)s ������ �������� "
+"������������������������ ���� ���������� ������������������������"
+
+#, python-format
+msgid "Unable to create NFS Pool as export path %(path)s mount failed"
+msgstr ""
+"���� �������������� �������������� ������ NFS: ���� ��������������
������������������������ �������������������������������� �������� %"
+"(path)s"
+
+#, python-format
+msgid "Unsupported storage pool type: %(type)s"
+msgstr "�������������������������������� ������ �������� ������������:
%(type)s"
+
+#, python-format
+msgid "Error while retrieving storage pool XML to %(pool)s"
+msgstr ""
+
+msgid "Storage pool name must be a string without slashes (/)"
+msgstr ""
+
+msgid ""
+"Supported storage pool types are dir, netfs, logical, iscsi, isci and
kimchi-"
+"iso"
+msgstr ""
+
+msgid "Storage pool path must be a string"
+msgstr "�������� �� �������� ������������ ������������ ��������
��������������"
+
+msgid "Storage pool host must be a IP or hostname"
+msgstr "�������� �������� ������������ ������������ �������� IP-��������������
������ ������������ ����������"
+
+msgid "Storage pool device must be the absolute path to the block device"
+msgstr ""
+
+msgid "Storage pool devices parameter must be a list"
+msgstr "���������������� ������������������ �������� ������������ ������������
�������� ��������������"
+
+msgid "Target IQN of an iSCSI pool must be a string"
+msgstr "�������������� IQN �������� iSCSI ������������ ��������
��������������"
+
+msgid "Port of a remote storage server must be an integer between 1 and 65535"
+msgstr "�������� �������������������� �������������� ������������ ������������
�������� ���������� ������������ ���� 1 ���� 65535"
+
+msgid "iSCSI target username must be a string"
+msgstr ""
+
+msgid "iSCSI target password must be a string"
+msgstr ""
+
+msgid "Specify name and type to create a storage pool"
+msgstr "�������������� ������ �� ������ ������ ���������������� ��������
������������"
+
+#, python-format
+msgid ""
+"%(disk)s is not a valid disk/partition. Could not add it to the pool %(pool)"
+"s."
+msgstr ""
+"%(disk)s ���� ���������������� �������������������� ������������/����������������.
���� �������������� ���������������� ������ �� "
+"������ %(pool)s."
+
+#, python-format
+msgid "Unable to extend logical pool %(pool)s. Details: %(err)s"
+msgstr ""
+
+msgid "The parameter disks only can be updated for logical storage pool."
+msgstr "���������� �������������������� ���������� ������������������ ������������
������ ���������������������� �������� ������������."
+
+msgid "The SCSI host adapter name must be a string."
+msgstr "������ ���������������� ���������� SCSI ������������ ��������
��������������."
+
+msgid "The storage pool kimchi_isos is reserved for internal use"
+msgstr "kimchi_isos �������� ������������ ���������������������������� ������
���������������������� ��������������������������"
+
+#, python-format
+msgid ""
+"Unable to activate NFS storage pool %(name)s. NFS server %(server)s is "
+"unreachable."
+msgstr ""
+"���� �������������� ������������������������ ������ ������������ NFS %(name)s.
������������ NFS %(server)s "
+"��������������������."
+
+#, python-format
+msgid ""
+"Unable to deactivate NFS storage pool %(name)s. NFS server %(server)s is "
+"unreachable."
+msgstr ""
+"���� �������������� ���������������������������� ������ ������������ NFS %(name)s.
������������ NFS %(server)s "
+"��������������������."
+
+#, python-format
+msgid ""
+"Unable to deactivate pool %(name)s as it is associated with some templates"
+msgstr ""
+"���� �������������� ���������������������������� ������ %(name)s: ������
������������ �� �������������������� ������������������"
+
+#, python-format
+msgid "Unable to delete pool %(name)s as it is associated with some templates"
+msgstr "���� �������������� �������������� ������ %(name)s: ������ ������������ ��
�������������������� ������������������"
+
+#, python-format
+msgid ""
+"A volume group named '%(name)s' already exists. Please, choose another name
"
+"to create the logical pool."
+msgstr ""
+"������������ ���������� �� ������������ %(name)s ������ ��������������������.
���������������� ������������ ������ ������ "
+"���������������� ���������������������� ��������."
+
+#, python-format
+msgid "Unable to update database with deep scan information due error:
%(err)s"
+msgstr ""
+"���� �������������� ���������������� �������� ������������ ��
���������������������� ������������������ ������������������������ ����-���� "
+"������������ %(err)s"
+
+#, python-format
+msgid "Storage volume %(name)s already exists"
+msgstr "������ %(name)s ������ ��������������������"
+
+#, python-format
+msgid "Storage volume %(name)s does not exist in storage pool %(pool)s"
+msgstr "������ %(name)s ���� �������������������� �� �������� ������������
%(pool)s"
+
+#, python-format
+msgid ""
+"Unable to create storage volume %(volume)s because storage pool %(pool)s is "
+"not active"
+msgstr ""
+
+#, python-format
+msgid "Specify %(item)s in order to create storage volume %(volume)s"
+msgstr "�������������� %(item)s ������ ���������������� �������� %(volume)s"
+
+#, python-format
+msgid ""
+"Unable to list storage volumes because storage pool %(pool)s is not active"
+msgstr "���� �������������� �������������� ������������ ����������: ������
������������ %(pool)s ���� ��������������"
+
+#, python-format
+msgid ""
+"Unable to create storage volume %(name)s in storage pool %(pool)s. Details:
%"
+"(err)s"
+msgstr ""
+"���� �������������� �������������� ������ %(name)s �� �������� ������������
%(pool)s. ����������������: %(err)s"
+
+#, python-format
+msgid ""
+"Unable to list storage volumes in storage pool %(pool)s. Details: %(err)s"
+msgstr ""
+"���� �������������� �������������� ������������ ���������� �� �������� ������������
%(pool)s. ����������������: %(err)s"
+
+#, python-format
+msgid "Unable to wipe storage volumes %(name)s. Details: %(err)s"
+msgstr "���� �������������� �������������� �������� %(name)s. ����������������:
%(err)s"
+
+#, python-format
+msgid "Unable to delete storage volume %(name)s. Details: %(err)s"
+msgstr "���� �������������� �������������� ������ %(name)s. ����������������:
%(err)s"
+
+#, python-format
+msgid "Unable to resize storage volume %(name)s. Details: %(err)s"
+msgstr "���� �������������� ���������������� ������������ �������� %(name)s.
����������������: %(err)s"
+
+#, python-format
+msgid "Storage type %(type)s does not support volume create and delete"
+msgstr "������ ������������ %(type)s ���� ������������������������ ����������������
�� ���������������� ����������"
+
+msgid "Storage volume name must be a string"
+msgstr "������ �������� ������������ �������� ��������������"
+
+msgid "Storage volume allocation must be an integer number"
+msgstr "������������������ �������� ������������ �������� ����������
������������"
+
+msgid ""
+"Storage volume format not supported. Valid formats: bochs, cloop, cow, dmg, "
+"qcow, qcow2, qed, raw, vmdk, vpc."
+msgstr ""
+
+msgid "Storage volume requires a volume name"
+msgstr "�������� ������������������ ������"
+
+#, python-format
+msgid ""
+"Unable to update database with storage volume information due error: %(err)s"
+msgstr ""
+"���� �������������� ���������������� �������� ������������ ��
���������������������� �� ���������� ����-���� ������������ %(err)s"
+
+#, python-format
+msgid "Only one of parameter %(param)s can be specified"
+msgstr ""
+
+#, python-format
+msgid "Create volume from %(param)s is not supported"
+msgstr ""
+
+msgid "Storage volume capacity must be an integer number."
+msgstr ""
+
+msgid "Storage volume URL must be http://, https://, ftp:// or ftps://."
+msgstr ""
+
+#, python-format
+msgid "Unable to access file %(url)s. Please, check it."
+msgstr ""
+
+#, python-format
+msgid ""
+"Unable to clone storage volume '%(name)s' in pool '%(pool)s'.
Details: %(err)"
+"s"
+msgstr ""
+
+msgid "Specify chunk data and its size to upload a file."
+msgstr ""
+
+msgid "In order to upload a storage volume, specify the 'upload'
parameter."
+msgstr ""
+
+msgid ""
+"Unable to upload chunk data as it does not match with requested chunk size."
+msgstr ""
+
+#, python-format
+msgid "The storage volume %(vol)s is not under an upload process."
+msgstr ""
+
+msgid "The upload chunk data will exceed the storage volume size."
+msgstr ""
+
+#, python-format
+msgid "Unable to upload chunk data to storage volume. Details: %(err)s."
+msgstr ""
+
+#, python-format
+msgid "Interface %(name)s does not exist"
+msgstr "������������������ %(name)s ���� ��������������������"
+
+#, python-format
+msgid "Network %(name)s already exists"
+msgstr "�������� %(name)s ������ ��������������������"
+
+#, python-format
+msgid "Network %(name)s does not exist"
+msgstr "�������� %(name)s ���� ��������������������"
+
+#, python-format
+msgid "Subnet %(subnet)s specified for network %(network)s is not valid."
+msgstr "�������������� %(subnet)s, ������������������ ������ �������� %(network)s,
����������������������."
+
+#, python-format
+msgid "Specify a network interface to create bridged network %(name)s"
+msgstr ""
+"�������������� �������������� ������������������ ������ ���������������� ��������
%(name)s �� ���������������� ���������� ��������"
+
+#, python-format
+msgid "Unable to delete active network %(name)s"
+msgstr "���� �������������� �������������� ���������������� �������� %(name)s"
+
+#, python-format
+msgid "Interface %(iface)s specified for network %(network)s is already in
use"
+msgstr "������������������ %(iface)s, ������������������ ������ ��������
%(network)s, ������ ������������������������"
+
+msgid "Interface should be bare NIC, bonding or bridge device."
+msgstr ""
+"������������������ ������������ �������� �������������� ������������,
���������������������� ���������� ������ ������������������ "
+"����������������������."
+
+#, python-format
+msgid "Unable to create network %(name)s. Details: %(err)s"
+msgstr "���� �������������� �������������� �������� %(name)s. ����������������:
%(err)s"
+
+#, python-format
+msgid "Unable to find a free IP address for network '%(name)s'"
+msgstr "���� ������������ ������������������ IP-���������� ������ ��������
%(name)s"
+
+#, python-format
+msgid "The interface %(iface)s already exists."
+msgstr ""
+
+msgid "Network name must be a string without slashes (/) or quotes (\")"
+msgstr ""
+
+msgid "Supported network types are isolated, NAT and bridge"
+msgstr "���������������������������� �������� ����������: isolated, NAT ��
bridge"
+
+msgid "Network subnet must be a string with IP address and prefix or netmask"
+msgstr ""
+"�������������� �������� ������������ �������� ��������������, ��������������������
IP-����������, �������������� ������ ���������� ��������"
+
+msgid "Network interface must be a string"
+msgstr "�������������� ������������������ ������������ ��������
��������������"
+
+msgid "Network VLAN ID must be an integer between 1 and 4094"
+msgstr "�������������� ���� VLAN ������������ �������� ���������� ������������ ����
1 ���� 4094"
+
+msgid "Specify name and type to create a Network"
+msgstr "�������������� ������ �� ������ ������ ���������������� ��������"
+
+#, python-format
+msgid ""
+"Unable to delete network %(name)s. There are some virtual machines %(vms)s "
+"and/or templates linked to this network."
+msgstr ""
+
+#, python-format
+msgid ""
+"Unable to deactivate network %(name)s. There are some virtual machines
%(vms)"
+"s and/or templates linked to this network."
+msgstr ""
+
+#, python-format
+msgid "Bridge device %(name)s can not be the trunk device of a VLAN."
+msgstr ""
+"�������������������� ���������� %(name)s ���� ���������� ��������
�������������������������� ���������������������� VLAN."
+
+#, python-format
+msgid "Failed to activate interface %(iface)s: %(err)s."
+msgstr "���� �������������� ������������������������ ������������������ %(iface)s:
%(err)s."
+
+#, python-format
+msgid ""
+"Failed to activate interface %(iface)s. Please check the physical link "
+"status."
+msgstr ""
+"���� ������������ ������������������������ ������������������ %(iface)s.
������������������ ������������������ �������������������� "
+"���������� ����������. "
+
+#, python-format
+msgid "Failed to start network %(name)s. Details: %(err)s"
+msgstr ""
+
+#, python-format
+msgid "Debug report %(name)s does not exist"
+msgstr "�������������������� ���������� %(name)s ���� ��������������������"
+
+msgid "Debug report tool not found in system"
+msgstr "�������������������� ���������������������� ������������ ���� ������������
�� ��������������"
+
+#, python-format
+msgid "Unable to create debug report %(name)s. Details: %(err)s."
+msgstr "���� �������������� �������������� �������������������� ���������� %(name)s.
����������������: %(err)s."
+
+#, python-format
+msgid "Can not find any debug report with the given name %(name)s"
+msgstr ""
+
+#, python-format
+msgid "Unable to generate debug report %(name)s. Details: %(err)s"
+msgstr "���� �������������� �������������� �������������������� ���������� %(name)s.
����������������: %(err)s"
+
+msgid "You should give a name for the debug report file."
+msgstr ""
+
+msgid ""
+"Debug report name must be a string. Only letters, digits, underscore ('_')
"
+"and hyphen ('-') are allowed."
+msgstr ""
+
+#, python-format
+msgid ""
+"The debug report with specified name \"%(name)s\" already exists. Please
use "
+"another one."
+msgstr ""
+"������������ ���������� �� ������������ %(name)s ������ ��������������������.
���������������� ������������ ������ ������ "
+"���������������� ���������������������� ��������."
+
+#, python-format
+msgid "Storage server %(server)s was not used by Kimchi"
+msgstr "������������ ������������ %(server)s ���� ��������������������������
Kimchi"
+
+#, python-format
+msgid "Distro '%(name)s' does not exist"
+msgstr "�������������� ���� %(name)s ���� ��������������������"
+
+#, python-format
+msgid "Partition %(name)s does not exist in the host"
+msgstr "������������ %(name)s ���� �������������������� ���� ����������"
+
+msgid "Unable to shutdown host machine as there are running virtual machines"
+msgstr ""
+"���� �������������� ������������������ ������������ �������������� ����������:
���������������������� ���������������������� ������������"
+
+msgid "Unable to reboot host machine as there are running virtual machines"
+msgstr "���� �������������� �������������������������� �������������� ����������:
���������������������� ���������������������� ������������"
+
+#, python-format
+msgid "Node device '%(name)s' not found"
+msgstr "�������������������� %(name)s �������� ���� ��������������"
+
+msgid "Conflicting flag filters specified."
+msgstr ""
+
+msgid "No packages marked for update"
+msgstr "������ ��������������, �������������������� ������
��������������������"
+
+#, python-format
+msgid "Package %(name)s is not marked to be updated."
+msgstr "���������� %(name)s ���� �������������� ������ ��������������������."
+
+#, python-format
+msgid "Error while getting packages marked to be updated. Details: %(err)s"
+msgstr "������������ ������������������ ��������������, �������������������� ������
��������������������. ����������������: %(err)s"
+
+msgid "There is no compatible package manager for this system."
+msgstr "������ ������������������������ ���������������������������� ��������������
������ �������� ��������������."
+
+#, python-format
+msgid "Invalid URI %(uri)s"
+msgstr "������������������������ URI %(uri)s"
+
+msgid "Unable to choose a virtual machine name"
+msgstr ""
+
+msgid "Invalid storage type. Types supported: 'cdrom', 'disk'"
+msgstr "������������������������ ������ ������������. ����������������������������
��������: cdrom"
+
+#, python-format
+msgid "The path '%(value)s' is not a valid local/remote path for the
device"
+msgstr ""
+
+msgid "Only CDROM path can be update."
+msgstr ""
+
+#, python-format
+msgid ""
+"The storage device %(dev_name)s does not exist in the virtual machine %"
+"(vm_name)s"
+msgstr ""
+
+#, python-format
+msgid "Error while creating new storage device: %(error)s"
+msgstr "������������ ���������������� �������������������� ����������������:
%(error)s"
+
+#, python-format
+msgid "Error while updating storage device: %(error)s"
+msgstr "������������ �������������������� �������������������� ����������������:
%(error)s"
+
+#, python-format
+msgid "Error while removing storage device: %(error)s"
+msgstr "������������ ���������������� �������������������� ����������������:
%(error)s"
+
+msgid "Do not support IDE device hot plug"
+msgstr ""
+
+msgid ""
+"Specify type and path or type and pool/volume to add a new virtual machine "
+"disk"
+msgstr "�������������� ������ �� �������� ������ �������������������� ������������
���������� ���������������������� ������������"
+
+msgid "Specify path to update virtual machine disk"
+msgstr "�������������� �������� ������ �������������������� ����������
���������������������� ������������"
+
+#, python-format
+msgid "Controller type %(type)s limitation of %(limit)s devices reached"
+msgstr ""
+
+#, python-format
+msgid "Cannot retrieve disk path information for given pool/volume: %(error)s"
+msgstr ""
+
+msgid "Volume already in use by other virtual machine."
+msgstr ""
+
+msgid ""
+"Only one of path or pool/volume can be specified to add a new virtual "
+"machine disk"
+msgstr "�������������� ������ �� �������� ������ �������������������� ������������
���������� ���������������������� ������������"
+
+#, python-format
+msgid ""
+"Volume chosen with format %(format)s does not fit in the storage type
%(type)"
+"s"
+msgstr ""
+
+msgid "YUM Repository ID must be one word only string."
+msgstr ""
+"���� ������������������ YUM ������������ �������� ��������������,
������������������ ������������ ���� ������������ ����������."
+
+msgid "Repository URL must be an http://, ftp:// or file:// URL."
+msgstr "URL ������������������ ������������ �������� http://, ftp:// ������ file://
."
+
+msgid ""
+"Repository configuration is a dictionary with specific values according to "
+"repository type."
+msgstr ""
+"������������������������ ������������������ ������������������������ ����������
�������������� ����������������, ������������������������ "
+"���������� ������������������."
+
+msgid "Distribution to DEB repository must be a string"
+msgstr "�������������� ������ ������������������ DEB ������������ ��������
��������������"
+
+msgid "Components to DEB repository must be listed in a array"
+msgstr "�������������������� ������ ������������������ DEB ������������ ��������
���������������������� �� ��������������"
+
+msgid "Components to DEB repository must be a string"
+msgstr "�������������������� ������ ������������������ DEB ������������ ��������
��������������"
+
+msgid "Mirror list to repository must be a string"
+msgstr ""
+
+msgid "YUM Repository name must be string."
+msgstr "������ ������������������ YUM ������������ �������� ��������������."
+
+msgid "GPG check must be a boolean value."
+msgstr "���������������� GPG ������������ �������� ������������������
������������������."
+
+msgid "GPG key must be a URL pointing to the ASCII-armored file."
+msgstr ""
+"�������� GPG ������������ �������� URL, ���������������������� ����
�������������������� �������� �� ������������������������ "
+"ASCII."
+
+#, python-format
+msgid "Could not update repository %(repo_id)s."
+msgstr "���� �������������� ���������������� ������������������ %(repo_id)s."
+
+#, python-format
+msgid "Repository %(repo_id)s does not exist."
+msgstr "������������������ %(repo_id)s ���� ��������������������."
+
+msgid ""
+"Specify repository base URL, mirror list or metalink in order to create or "
+"update a YUM repository."
+msgstr ""
+
+msgid "Repository management tool was not recognized for your system."
+msgstr "���� ������������������ �������������������� ��������������������
�������������������� ������ ��������������."
+
+#, python-format
+msgid "Repository %(repo_id)s is already enabled."
+msgstr "������������������ %(repo_id)s ������ ����������������."
+
+#, python-format
+msgid "Repository %(repo_id)s is already disabled."
+msgstr "������������������ %(repo_id)s ������ ������������������."
+
+#, python-format
+msgid "Could not remove repository %(repo_id)s."
+msgstr "���� �������������� �������������� ������������������ %(repo_id)s."
+
+#, python-format
+msgid "Could not write repository configuration file %(repo_file)s"
+msgstr "���� �������������� ���������������� �� �������� ������������������������
������������������ %(repo_file)s"
+
+msgid "Specify repository distribution in order to create a DEB repository."
+msgstr "�������������� �������������� ������������������ ������ ����������������
������������������ DEB."
+
+#, python-format
+msgid "Could not enable repository %(repo_id)s."
+msgstr "���� �������������� ���������������� ������������������ %(repo_id)s."
+
+#, python-format
+msgid "Could not disable repository %(repo_id)s."
+msgstr "���� �������������� ������������������ ������������������
%(repo_id)s."
+
+msgid "YUM Repository ID already exists"
+msgstr "���� ������������������ YUM ������ ��������������������"
+
+msgid "YUM Repository name must be a string"
+msgstr "������ ������������������ YUM ������������ �������� ��������������"
+
+#, python-format
+msgid "Unable to list repositories. Details: '%(err)s'"
+msgstr "���� �������������� �������������� ������������ ����������������.
����������������: %(err)s"
+
+#, python-format
+msgid "Unable to retrieve repository information. Details: '%(err)s'"
+msgstr "���� �������������� ���������������� �������������������� ��
������������������. ����������������: %(err)s"
+
+#, python-format
+msgid "Unable to add repository. Details: '%(err)s'"
+msgstr "���� �������������� ���������������� ������������������. ����������������:
%(err)s"
+
+#, python-format
+msgid "Unable to remove repository. Details: '%(err)s'"
+msgstr "���� �������������� �������������� ������������������. ����������������:
%(err)s"
+
+#, python-format
+msgid ""
+"Configuration items: '%(items)s' are not supported by repository
manager"
+msgstr ""
+
+msgid "Repository metalink must be an http://, ftp:// or file:// URL."
+msgstr ""
+
+msgid "Cannot specify mirrorlist and metalink at the same time."
+msgstr ""
+
+#, python-format
+msgid ""
+"Virtual machine '%(vm)s' must be stopped before creating a snapshot of
it."
+msgstr ""
+
+#, python-format
+msgid ""
+"Unable to create snapshot '%(name)s' on virtual machine '%(vm)s'.
Details: %"
+"(err)s"
+msgstr ""
+
+#, python-format
+msgid "Snapshot '%(name)s' does not exist on virtual machine
'%(vm)s'."
+msgstr ""
+
+#, python-format
+msgid ""
+"Unable to retrieve snapshot '%(name)s' on virtual machine '%(vm)s'.
Details: "
+"%(err)s"
+msgstr ""
+
+#, python-format
+msgid "Unable to list snapshots on virtual machine '%(vm)s'. Details:
%(err)s"
+msgstr ""
+
+#, python-format
+msgid ""
+"Unable to delete snapshot '%(name)s' on virtual machine '%(vm)s'.
Details: %"
+"(err)s"
+msgstr ""
+
+#, python-format
+msgid ""
+"Unable to retrieve current snapshot of virtual machine '%(vm)s'. Details:
%"
+"(err)s"
+msgstr ""
+
+#, python-format
+msgid ""
+"Unable to revert virtual machine '%(vm)s' to snapshot '%(name)s'.
Details: %"
+"(err)s"
+msgstr ""
+
+#, python-format
+msgid ""
+"Unable to create snapshot of virtual machine '%(vm)s' because it contains a
"
+"disk with format '%(format)s'; only 'qcow2' is supported."
+msgstr ""
+
+msgid "The number of vCPUs is too large for this system."
+msgstr ""
+
+msgid "Invalid vCPU/topology combination."
+msgstr ""
+
+msgid "This host (or current configuration) does not allow CPU topology."
+msgstr ""
+
+msgid "ERROR CODE"
+msgstr "������ ������������"
+
+msgid "REASON"
+msgstr "��������������"
+
+msgid "STACK"
+msgstr "��������"
+
+msgid "Go to Homepage"
+msgstr "�������������� ���� �������������� ����������������"
+
+msgid "Create a New Virtual Machine"
+msgstr "�������������� ���������� ���������������������� ������������"
+
+msgid "Virtual Machine Name"
+msgstr "������ ���������������������� ������������"
+
+msgid ""
+"The name used to identify the virtual machine. If omitted, a name will be "
+"chosen based on the template used."
+msgstr ""
+"������ ������ �������������������������� ���������������������� ������������.
�������� ���� ��������������, ������ ���������� �������������� "
+"�� ���������������������� ���� �������������������������� ��������������."
+
+msgid "Template"
+msgstr "������������"
+
+msgid "Please create a template first."
+msgstr "��������������������, ���������������� ������������ �� ������������
��������������."
+
+msgid "Create a Template"
+msgstr "�������������� ������������"
+
+msgid "Please choose a template."
+msgstr "��������������������, ���������������� ������������."
+
+msgid "OS"
+msgstr "����"
+
+msgid "OS Version"
+msgstr "������������ ����"
+
+msgid "CPUS"
+msgstr "��������������������"
+
+msgid "Memory"
+msgstr "������������"
+
+msgid "Create"
+msgstr "��������������"
+
+msgid "Creating..."
+msgstr ""
+
+msgid "Cancel"
+msgstr "������������"
+
+msgid "Edit Guest"
+msgstr "���������������� ���������������� ��������������"
+
+msgid "General"
+msgstr "����������"
+
+msgid "Storage"
+msgstr "������������������"
+
+msgid "Interface"
+msgstr "������������������"
+
+msgid "Permission"
+msgstr "������������"
+
+msgid "Host PCI Device"
+msgstr ""
+
+msgid "Snapshot"
+msgstr ""
+
+msgid "Name"
+msgstr "������"
+
+msgid "CPUs"
+msgstr "��������������������"
+
+msgid "Memory (MB)"
+msgstr "������������ (����)"
+
+msgid "Icon"
+msgstr "������������"
+
+msgid "Device"
+msgstr "������ ��������������������"
+
+msgid "Path"
+msgstr "�������� NFS"
+
+msgid "Network"
+msgstr "��������"
+
+msgid "Type"
+msgstr "������"
+
+msgid "MAC Address"
+msgstr ""
+
+msgid "Available system users and groups"
+msgstr ""
+
+msgid "Selected system users and groups"
+msgstr ""
+
+msgid "User"
+msgstr ""
+
+msgid "All"
+msgstr "������"
+
+msgid "To Add"
+msgstr ""
+
+msgid "Added"
+msgstr ""
+
+msgid "filter"
+msgstr ""
+
+msgid "Product"
+msgstr ""
+
+msgid "Vendor"
+msgstr "������������"
+
+msgid "Created"
+msgstr ""
+
+msgid "Save"
+msgstr "������������������"
+
+msgid "Replace"
+msgstr "����������������"
+
+msgid "Detach"
+msgstr "������������������"
+
+msgid "revert"
+msgstr ""
+
+msgid "Start"
+msgstr "������������������"
+
+msgid "Reset"
+msgstr "����������������"
+
+msgid "Pause"
+msgstr ""
+
+msgid "Resume"
+msgstr ""
+
+msgid "Power Off"
+msgstr "������������������"
+
+msgid "Actions"
+msgstr "����������������"
+
+msgid "Connect"
+msgstr "��������������������"
+
+msgid "Clone"
+msgstr "����������������������"
+
+msgid "Edit"
+msgstr "��������������������������"
+
+msgid "Shut Down"
+msgstr "������������������ ������������"
+
+msgid "Delete"
+msgstr "��������������"
+
+msgid "CPU"
+msgstr "������������������"
+
+msgid "Disk I/O"
+msgstr "���������������� ��������-����������"
+
+msgid "Network I/O"
+msgstr "�������������� ��������-����������"
+
+msgid "Livetile"
+msgstr "Livetile"
+
+msgid "No guests found."
+msgstr "���� �������������� ���������������� ��������������."
+
+msgid "Add a Storage Device to VM"
+msgstr "���������������� �������������������� ���������������� �� VM"
+
+msgid "Device Type"
+msgstr "������ ��������������������"
+
+msgid "The device type. Currently, \"cdrom\" and \"disk\" are
supported."
+msgstr "������ ��������������������. �� ������������ ������������
���������������������������� ������������ \"cdrom\"."
+
+msgid "Storage Pool"
+msgstr "������ ������������"
+
+msgid "Storage pool which volume located in"
+msgstr "�������� �� �������� ������������ ������������ ��������
��������������"
+
+msgid "Storage Volume"
+msgstr "������ �������� ������������"
+
+msgid "Storage volume to be attached"
+msgstr "������ �������� ������������ �������� ��������������"
+
+msgid "File Path"
+msgstr "�������� �� ����������"
+
+msgid "The ISO file path in the server for CDROM."
+msgstr "�������� �� ���������� ISO ������ CDROM ���� ��������������."
+
+msgid "Attach"
+msgstr "��������������������"
+
+msgid "Shut down"
+msgstr "����������������"
+
+msgid "Restart"
+msgstr "��������������������"
+
+msgid "Basic Information"
+msgstr "�������������� ��������������������"
+
+msgid "OS Distro"
+msgstr "�������������� ����"
+
+msgid "OS Code Name"
+msgstr "�������������� ������ ����"
+
+msgid "Processor"
+msgstr "������������������"
+
+msgid "CPU(s)"
+msgstr ""
+
+msgid "System Statistics"
+msgstr "������������������ ��������������������"
+
+msgid "Software Updates"
+msgstr "�������������������� ������������������������ ����������������������"
+
+msgid "Update Progress"
+msgstr "������ ��������������������"
+
+msgid "Repositories"
+msgstr "������������������"
+
+msgid "Debug Reports"
+msgstr "�������������������� ������������"
+
+msgid "The username or password you entered is incorrect. Please try again."
+msgstr "�������������� ���������������� ������ ������������������������ ������
������������. �������������� ������ ������."
+
+msgid "This field is required."
+msgstr "������ ������������������������ ��������."
+
+msgid "Log in"
+msgstr "����������"
+
+msgid "Logging in..."
+msgstr "��������..."
+
+msgid "Host"
+msgstr "��������"
+
+msgid "Guests"
+msgstr "���������������� ��������������"
+
+msgid "Templates"
+msgstr "��������������"
+
+msgid "Failed to get application configuration"
+msgstr "���� �������������� ���������������� ������������������������
��������������������"
+
+msgid "This is not a valid Linux path"
+msgstr "�������� ������������������������ �������� �� Linux"
+
+msgid "This is not a valid URL."
+msgstr "������ ������������������������ URL."
+
+msgid "No such data available."
+msgstr "������ ���������� ������������."
+
+msgid ""
+"Can not contact the host system. Verify the host system is up and that you "
+"have network connectivity to it. HTTP request response %1. "
+msgstr ""
+"������ ���������� �� ���������������� ����������. ������������������, ������
�������������� ���������� ���������������� �� ���������������� "
+"������ ����������������������. ���������� ���� ������������ HTTP: %1. "
+
+msgid "Unable to read file."
+msgstr ""
+
+msgid "Error while uploading file."
+msgstr ""
+
+msgid "Delete Confirmation"
+msgstr "�������������������������� ����������������"
+
+msgid "OK"
+msgstr "OK"
+
+msgid "Confirm"
+msgstr "����������������������"
+
+msgid "Warning"
+msgstr "����������������������������"
+
+msgid "Cloning..."
+msgstr ""
+
+msgid "Loading..."
+msgstr "����������������������..."
+
+msgid "An error occurred while retrieving system information."
+msgstr ""
+
+msgid "Retry"
+msgstr "������������������"
+
+msgid "Detailed message:"
+msgstr "������������������ ������������������:"
+
+msgid "No ISO found"
+msgstr ""
+
+msgid "This is not a valid ISO file."
+msgstr "�������� �������� ���� ���������������� �������������������� ��������������
ISO."
+
+msgid "This may take a long time. Do you want to continue?"
+msgstr "������ ������������ ���������� ��������������. ��������������������?"
+
+msgid "This will permanently delete the template. Would you like to continue?"
+msgstr "������������ ���������� ������������������������ ������������.
��������������������?"
+
+msgid "Unable to shut down system as there are some virtual machines running!"
+msgstr ""
+"�������������������� ������������������ ������������ ��������������,
������������������ �� ������ ���������������� ���������������������� "
+"������������!"
+
+msgid "Max:"
+msgstr "��������.:"
+
+msgid "Utilization"
+msgstr "��������������������������"
+
+msgid "Available"
+msgstr "����������������"
+
+msgid "Read Rate"
+msgstr "���������������� ������������"
+
+msgid "Write Rate"
+msgstr "���������������� ������������"
+
+msgid "Received"
+msgstr "����������������"
+
+msgid "Sent"
+msgstr "��������������������"
+
+msgid ""
+"Shutting down or restarting host will cause unsaved work lost. Continue to "
+"shut down/restarting?"
+msgstr ""
+"�������������������� ������������ �� �������������������� ����������
���������������� �� ������������ �������������������������� ������������. "
+"�������������������� �������������������� ������������/��������������������?"
+
+msgid ""
+"Repository will be removed permanently and can't be recovered. Do you want
"
+"to continue?"
+msgstr "������������������ ���������� �������������� ������ ����������������������
����������������������������. ��������������������?"
+
+msgid "ID"
+msgstr "����"
+
+msgid "Base URL"
+msgstr "�������������� URL"
+
+msgid "Is Mirror"
+msgstr "�������������������� ����������"
+
+msgid "URL Args"
+msgstr "������������������ URL"
+
+msgid "Enabled"
+msgstr "����������������"
+
+msgid "GPG Check"
+msgstr "���������������� GPG"
+
+msgid "GPG Key"
+msgstr "�������� GPG"
+
+msgid "Add"
+msgstr "����������������"
+
+msgid "Remove"
+msgstr "��������������"
+
+msgid "Enable"
+msgstr "����������������"
+
+msgid "Disable"
+msgstr "������������������"
+
+msgid "Package Name"
+msgstr "������ ������������"
+
+msgid "Version"
+msgstr "������������"
+
+msgid "Architecture"
+msgstr "����������������������"
+
+msgid "Repository"
+msgstr "������������������"
+
+msgid "Update All"
+msgstr "���������������� ������"
+
+msgid "Updating..."
+msgstr "��������������������..."
+
+msgid "Failed to retrieve packages update information."
+msgstr ""
+
+msgid "Failed to update package(s)."
+msgstr "���� �������������� ���������������� ������������."
+
+msgid ""
+"Debug report will be removed permanently and can't be recovered. Do you want
"
+"to continue?"
+msgstr ""
+"�������������������� ���������� ���������� ������������ ������
���������������������� ����������������������������. ��������������������?"
+
+msgid "Generated Time"
+msgstr "���������� ����������������"
+
+msgid "Generate"
+msgstr "��������������"
+
+msgid "Generating..."
+msgstr "����������������..."
+
+msgid "Rename"
+msgstr "��������������������������"
+
+msgid "Download"
+msgstr "������������������"
+
+msgid ""
+"Report name should contain only letters, digits, underscore ('_') and/or
"
+"hyphen ('-')."
+msgstr "������ ������������ ������������ ������������������ ������������ ����������,
���������� �� ������������ ('-')."
+
+msgid "Pending..."
+msgstr "����������������������..."
+
+msgid "Report name is the same as the original one."
+msgstr ""
+
+msgid ""
+"This will delete the virtual machine and its virtual disks. This operation "
+"cannot be undone. Would you like to continue?"
+msgstr ""
+"���������� �������������� ���������������������� ������������ ������������ ����
������������ ������������������������ ��������������. ������ "
+"���������������������� ����������������. ��������������������?"
+
+msgid "Power off Confirmation"
+msgstr "�������������������������� ����������������"
+
+msgid ""
+"This action may produce undesirable results, for example unflushed disk "
+"cache in the guest. Would you like to continue?"
+msgstr ""
+
+msgid "Reset Confirmation"
+msgstr "�������������������������� ����������������"
+
+msgid ""
+"There is a risk of data loss caused by reset without the guest OS shutdown. "
+"Would you like to continue?"
+msgstr ""
+
+msgid "Shut Down Confirmation"
+msgstr "�������������������������� ����������������"
+
+msgid "Note the guest OS may ignore this request. Would you like to continue?"
+msgstr "������������ ���������� ������������������������ ������������.
��������������������?"
+
+msgid "Virtual Machine delete Confirmation"
+msgstr ""
+
+msgid ""
+"This virtual machine is not persistent. Power Off will delete it. Continue?"
+msgstr ""
+
+msgid ""
+"When the target guest has SCSI or iSCSI volumes, they will be cloned on "
+"default storage pool. The same will happen when the target pool does not "
+"have enough space to clone the volumes. Do you want to continue?"
+msgstr ""
+
+msgid ""
+"This CDROM will be detached permanently and you can re-attach it. Continue "
+"to detach it?"
+msgstr ""
+"�������� CDROM ���������� ����������������. ������ ���������� ���������� ����������
��������������������. ������������������?"
+
+msgid "Attaching..."
+msgstr "����������������������..."
+
+msgid "Replacing..."
+msgstr "������������..."
+
+msgid "Successfully attached!"
+msgstr "�������������� ������������������!"
+
+msgid "Successfully replaced!"
+msgstr "�������������� ��������������!"
+
+msgid "Successfully detached!"
+msgstr "�������������� ����������������!"
+
+msgid ""
+"This disk will be detached permanently and you can re-attach it. Continue to
"
+"detach it?"
+msgstr ""
+
+msgid "interface:"
+msgstr ""
+
+msgid "address:"
+msgstr ""
+
+msgid "link_type:"
+msgstr ""
+
+msgid "block:"
+msgstr ""
+
+msgid "drive_type:"
+msgstr ""
+
+msgid "model:"
+msgstr ""
+
+msgid "Affected devices:"
+msgstr ""
+
+msgid "The VLAN id must be between 1 and 4094."
+msgstr "���� VLAN ������������ �������� ���� 1 ���� 4094."
+
+msgid "unavailable"
+msgstr "��������������������"
+
+msgid ""
+"This action will interrupt network connectivity for any virtual machine that
"
+"depend on this network."
+msgstr ""
+"������ ���������������� �������������� �������������� �������������������� ��
�������� ���������������������� ����������, �������������� "
+"�������������� ���� �������� ��������."
+
+msgid "Create a network"
+msgstr "�������������� ��������"
+
+msgid ""
+"This network is not persistent. Instead of stop, this action will "
+"permanently delete it. Would you like to continue?"
+msgstr ""
+"�������� ������ ������������ ���� ��������������������. ������������
����������������������, ������ ���������������� ������������������������ "
+"������ ������������. ��������������������?"
+
+msgid ""
+"The bridged VLAN tag may not work well with NetworkManager enabled. You "
+"should consider disabling it."
+msgstr ""
+
+msgid ""
+"This will permanently delete the storage pool. Would you like to continue?"
+msgstr "������ ������������ ���������� ������������������������ ������������.
��������������������?"
+
+msgid "This storage pool is empty."
+msgstr "�������� ������ ������������ ������������."
+
+msgid ""
+"It will format your disk and you will loose any data in there, are you sure "
+"to continue? "
+msgstr ""
+"�������� ���������� ����������������������������, �� ������ ������������ ����
������ ���������� ����������������. ���� "
+"�������������������������� ������������ ��������������������? "
+
+msgid "SCSI Fibre Channel"
+msgstr "SCSI Fibre Channel"
+
+msgid "No SCSI adapters found."
+msgstr "���� �������������� ���������������� SCSI."
+
+msgid "Loading iSCSI targets..."
+msgstr ""
+
+msgid "No iSCSI found. Please input one."
+msgstr ""
+
+msgid "Failed to load iSCSI targets."
+msgstr ""
+
+msgid "The storage pool name can not be blank."
+msgstr "���� �������������� ������ �������� ������������."
+
+msgid "The storage pool path can not be blank."
+msgstr "���� ������������ �������� �� �������� ������������."
+
+msgid "NFS server mount path can not be blank."
+msgstr "���� ������������ �������� ������������������������ ��������������
NFS."
+
+msgid "Invalid NFS mount path."
+msgstr "������������������������ �������� ������������������������ NFS."
+
+msgid "No logical device selected."
+msgstr "���� �������������� �������������������� ��������������������."
+
+msgid "The iSCSI target can not be blank."
+msgstr "���� ������������ �������������� ������������ iSCSI."
+
+msgid "Server name can not be blank."
+msgstr "���� �������������� ������ ��������������."
+
+msgid "This is not a valid Server Name or IP. Please, modify it."
+msgstr ""
+
+msgid "Looking for available partitions ..."
+msgstr "���������� ������������������ ����������������..."
+
+msgid "No available partitions found."
+msgstr "���� �������������� ������������������ ��������������."
+
+msgid ""
+"This storage pool is not persistent. Instead of deactivate, this action will
"
+"permanently delete it. Would you like to continue?"
+msgstr ""
+"�������� ������ ������������ ���� ��������������������. ������������
����������������������, ������ ���������������� ������������������������ "
+"������ ������������. ��������������������?"
+
+msgid "Unable to retrieve partitions information."
+msgstr "���� �������������� ���������������� �������������������� ��
������������������. ����������������: %(err)s"
+
+msgid "In progress..."
+msgstr ""
+
+msgid "Failed!"
+msgstr ""
+
+msgid "CDROM path needs to be a valid local/remote path and cannot be blank."
+msgstr ""
+
+msgid "Disk pool or volume cannot be blank."
+msgstr "���� �������������� ������ �������� ������������."
+
+msgid "Filter"
+msgstr ""
+
+msgid "Network Name"
+msgstr "������ ��������"
+
+msgid "State"
+msgstr "������������������"
+
+msgid "Network Type"
+msgstr "������ ��������"
+
+msgid "Address Space"
+msgstr "���������������� ������������������������"
+
+msgid "Name should not contain '/' and '\"'."
+msgstr "������������������������ ������ �������� ������������. �� ���������� ����
������������ �������� ���������������� '/'."
+
+msgid "Isolated: no external network connection"
+msgstr "�������������������������� (������ �������������������� ��������������
��������������������)"
+
+msgid "NAT: outbound physical network connection only"
+msgstr "NAT (������������ ������������������ �������������������� ��������������
��������������������)"
+
+msgid "Bridged: Virtual machines are connected to physical network directly"
+msgstr "���������� �������� (������������ ����������������������
���������������������� ���������� �� �������������������� ��������)"
+
+msgid "(No interfaces found)"
+msgstr ""
+
+msgid "Destination"
+msgstr "�������������� ������������������������:"
+
+msgid "Enable VLAN"
+msgstr "���������������� VLAN:"
+
+msgid "VLAN ID"
+msgstr ""
+
+msgid "Stop"
+msgstr "������������������"
+
+msgid "Generate a New Debug Report"
+msgstr "�������������� ���������� �������������������� ����������"
+
+msgid "Report Name"
+msgstr "������ ������������"
+
+msgid ""
+"The name used to identify the report. If omitted, a name will be chosen "
+"based on current time. Name can contain: letters, digits, underscore
(\"_\") "
+"and hyphen (\"-\")."
+msgstr ""
+"������ ������ �������������������������� ������������. �������� ����
��������������, ������ ���������� ������������������������ ���� "
+"������������ ���������������� ��������������. ������ ���������� ������������������:
����������, ���������� �� ������������ (\"-\")."
+
+msgid "Rename a Debug Report"
+msgstr "�������������� ���������� �������������������� ����������"
+
+msgid ""
+"The name used to identify the report. Name can contain: letters, digits and "
+"hyphen (\"-\")."
+msgstr ""
+"������ ������ �������������������������� ������������. �������� ����
��������������, ������ ���������� ������������������������ ���� "
+"������������ ���������������� ��������������. ������ ���������� ������������������:
����������, ���������� �� ������������ (\"-\")."
+
+msgid "Submit"
+msgstr "����������������������"
+
+msgid "Add a Repository"
+msgstr "���������������� ������������������"
+
+msgid "Identifier"
+msgstr "��������������������������"
+
+msgid "Single word, unique identifier for the repository."
+msgstr "������������������ ���������� - ��������������������
�������������������������� ������������������."
+
+msgid "Textual name for the repository."
+msgstr "������������������ ������ ������������������."
+
+msgid "URL"
+msgstr "URL"
+
+msgid "Required Field"
+msgstr "������������������������ ��������"
+
+msgid "URL to the repository. Supported protocols are http, ftp, and file."
+msgstr "URL ������������������. ���������������������������� ������������������:
http, ftp, file."
+
+msgid "Repository is a mirror"
+msgstr "������������������ ���������������� ��������������������
������������."
+
+msgid "Distribution"
+msgstr "��������������"
+
+msgid "Distribution of the DEB repository."
+msgstr "�������������� ������������������ DEB."
+
+msgid "Components"
+msgstr "��������������������"
+
+msgid "List of components in DEB repository."
+msgstr "������������ ���������������������� �� ������������������ DEB."
+
+msgid "Edit Repository"
+msgstr "���������������� ������������������"
+
+msgid "Mirror List URL"
+msgstr "URL ������������ �������������������� ����������"
+
+msgid "Yes"
+msgstr "����"
+
+msgid "No"
+msgstr "������"
+
+msgid "Capacity"
+msgstr "��������������"
+
+msgid "Allocated"
+msgstr "����������������"
+
+msgid "Location"
+msgstr "������������������������"
+
+msgid "Device path"
+msgstr "�������� �� ��������������������"
+
+msgid "active"
+msgstr "��������������"
+
+msgid "inactive"
+msgstr "������������������"
+
+msgid "Deactivate"
+msgstr "������������������"
+
+msgid "Activate"
+msgstr "������������������������"
+
+msgid "Add Volume"
+msgstr ""
+
+msgid "Extend"
+msgstr ""
+
+msgid "Undefine"
+msgstr "��������������"
+
+msgid "Format"
+msgstr "������������:"
+
+msgid "Allocation"
+msgstr "������������������ ����������������:"
+
+msgid "Define a New Storage Pool"
+msgstr "�������������� ������ ������������"
+
+msgid "Storage Pool Name"
+msgstr "������ �������� ������������"
+
+msgid ""
+"The name used to identify the storage pools, and it should not be empty."
+msgstr "������ ������ �������������������������� ���������� ������������. ����
���������� �������� ������������."
+
+msgid "Storage Pool Type"
+msgstr "������ �������� ������������"
+
+msgid "Storage Path"
+msgstr "�������� �� ����������"
+
+msgid ""
+"The path of the Storage Pool. Each Storage Pool must have a unique path."
+msgstr "�������� �� �������� ������������. ������������ ������ ������������
������������ ���������� �������������������� ��������."
+
+msgid ""
+"Kimchi will try to create the directory when it does not already exist in "
+"your system."
+msgstr "Kimchi �������������������� �������������� ��������������, �������� ����
���� �������������������� �� ��������������."
+
+msgid "NFS Server IP"
+msgstr "IP-���������� �������������� NFS"
+
+msgid "NFS server IP or hostname. It can be input or chosen from history."
+msgstr ""
+"IP-���������� ������ ������ ���������� �������������� NFS. ������ ����������
������������ ������ �������������� �� "
+"��������������������."
+
+msgid "NFS Path"
+msgstr "�������� NFS"
+
+msgid "The NFS exported path on NFS server."
+msgstr "�������������������������������� �������� NFS ���� ��������������
NFS."
+
+msgid "iSCSI Server"
+msgstr "������������ iSCSI"
+
+msgid "Server"
+msgstr "������������"
+
+msgid "Port"
+msgstr "��������"
+
+msgid "iSCSI server IP or hostname. It should not be empty."
+msgstr "IP-���������� ������ ������ ���������� �������������� iSCSI. ���� ����������
�������� ������������."
+
+msgid "Target"
+msgstr "�������������� ������������"
+
+msgid "The iSCSI target on iSCSI server"
+msgstr "�������������� ������������ iSCSI ���� �������������� iSCSI"
+
+msgid "Add iSCSI Authentication"
+msgstr "���������������� �������������������������� iSCSI"
+
+msgid "iSCSI Authentication"
+msgstr "�������������������������� iSCSI"
+
+msgid "User Name"
+msgstr "������ ������������������������"
+
+msgid "Password"
+msgstr "������������"
+
+msgid "SCSI Adapter"
+msgstr "�������������� SCSI"
+
+msgid "Please, wait..."
+msgstr "������������������..."
+
+msgid "Add a Volume to Storage Pool"
+msgstr ""
+
+msgid "Fetch from remote URL"
+msgstr ""
+
+msgid "Enter the remote URL here."
+msgstr ""
+
+msgid "Upload a file"
+msgstr ""
+
+msgid "Choose the file you want to upload."
+msgstr ""
+
+msgid "Add Template"
+msgstr "���������������� ������������"
+
+msgid "Where is the source media for this template? "
+msgstr "������ ������������������ ���������������� ���������������� ������
���������� ��������������?"
+
+msgid "Local ISO Image"
+msgstr "������������������ ���������� ISO"
+
+msgid "Local Image File"
+msgstr ""
+
+msgid "Remote ISO Image"
+msgstr "������������������ ���������� ISO"
+
+msgid "Search ISOs"
+msgstr "���������� �������������� ISO"
+
+msgid "The following ISOs are available:"
+msgstr "������������������ ������������ ISO:"
+
+msgid "OS: "
+msgstr "����: "
+
+msgid "Version: "
+msgstr "������������: "
+
+msgid "Size: "
+msgstr "������������: "
+
+msgid "Search more ISOs"
+msgstr "���������� ���������������������������� �������������� ISO"
+
+msgid "Create Templates from Selected ISO"
+msgstr "�������������� �������������� ���� ������������������ ��������������
ISO"
+
+msgid "I want to use a specific ISO file"
+msgstr "������������������������ �������������������� �������� ISO"
+
+msgid "Loading default remote ISOs ..."
+msgstr "���������������� ������������������ ISO ���� ������������������..."
+
+msgid "Arch: "
+msgstr "����������������������: "
+
+msgid "I want to use a custom URL"
+msgstr "������������������������ ������������ URL"
+
+msgid "Edit Template"
+msgstr "���������������� ������������"
+
+msgid "CDROM"
+msgstr "CDROM"
+
+msgid "Image File"
+msgstr ""
+
+msgid "Graphics"
+msgstr "��������������"
+
+msgid "Disk(GB)"
+msgstr ""
+
+msgid "Disk Format"
+msgstr ""
+
+msgid "CPU Number"
+msgstr "�������������������� ����������������������"
+
+msgid "Manually set CPU topology"
+msgstr ""
+
+msgid "Cores"
+msgstr ""
+
+msgid "Threads"
+msgstr ""
+
+msgid "No templates found."
+msgstr "���� �������������� ��������������."
+
+#~ msgid "Delete is not allowed for %(resource)s"
+#~ msgstr "���������������� ������������������ ������ %(resource)s"
+
+#~ msgid "%(resource)s does not implement update method"
+#~ msgstr "%(resource)s ���� ������������������ ����������
��������������������"
+
+#~ msgid "Create is not allowed for %(resource)s"
+#~ msgstr "���������������� ������������������ ������ %(resource)s"
+
+#~ msgid "Unable to parse JSON request"
+#~ msgstr "������������ �������������� �������������� JSON"
+
+#~ msgid "This API only supports JSON"
+#~ msgstr "������ �������������� API ������������������������ ������������
JSON"
+
+#~ msgid "Datastore is not initiated in the model object."
+#~ msgstr "������������������ ������������ �� �������������� ������������ ����
��������������������������������."
+
+#~ msgid "Unable to start task due error: %(err)s"
+#~ msgstr "���� �������������� ������������������ ������������ ����-����
������������ %(err)s"
+
+#~ msgid ""
+#~ "Authentication failed for user '%(username)s'. [Error code:
%(code)s]"
+#~ msgstr ""
+#~ "�������� �������������������������� ������������������������ %(username)s.
[������ ������������: %(code)s]"
+
+#~ msgid "You are not authorized to access Kimchi"
+#~ msgstr "������ �������� �������������� �� Kimchi"
+
+#~ msgid "Specify %(item)s to login into Kimchi"
+#~ msgstr "�������������� %(item)s ������ ���������� �� Kimchi"
+
+#~ msgid "Unable to find %(item)s in datastore"
+#~ msgstr "���� ������������ %(item)s �� ������������������ ������������"
+
+#~ msgid "Timeout while running command '%(cmd)s' after %(seconds)s
seconds"
+#~ msgstr "���������� ��������-������ �������������������� �������������� %(cmd)s
(%(seconds)s ��)"
+
+#~ msgid "Help"
+#~ msgstr "������������"
+
+#~ msgid "About"
+#~ msgstr "�� ������������������"
+
+#~ msgid "Log out"
+#~ msgstr "����������"
+
+#~ msgid "Version:"
+#~ msgstr "������������:"
diff --git a/src/wok/plugins/kimchi/po/zh_CN.po b/src/wok/plugins/kimchi/po/zh_CN.po
new file mode 100644
index 0000000..fc6dd84
--- /dev/null
+++ b/src/wok/plugins/kimchi/po/zh_CN.po
@@ -0,0 +1,2186 @@
+# i18n portable object for kimchi.
+# Copyright (C) IBM, Corp. 2013-2014
+# ShaoHe Feng <shaohef(a)linux.vnet.ibm.com>, 2013-04-18.
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: kimchi 0.1\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2015-07-01 16:11-0300\n"
+"PO-Revision-Date: 2013-06-27 10:48+0000\n"
+"Last-Translator: ShaoHe Feng <shaohef(a)linux.vnet.ibm.com>\n"
+"Language-Team: ShaoHe Feng <shaohef(a)linux.vnet.ibm.com>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Language: zh_CN\n"
+"Generated-By: pygettext.py 1.5\n"
+"X-Poedit-Country: CHINA\n"
+"X-Poedit-Language: Chinese\n"
+"X-Poedit-SourceCharset: utf-8\n"
+
+#, python-format
+msgid "Unknown parameter %(value)s"
+msgstr "������������ %(value)s"
+
+#, python-format
+msgid "Timeout of %(seconds)s seconds expired while running task
'%(task)s."
+msgstr "������'%(task)s������%(seconds)s������"
+
+#, python-format
+msgid "User %(user_id)s not found with given LDAP settings."
+msgstr "���������������LDAP���������������%(user_id)s������"
+
+msgid "Unknown \"_cap\" specified"
+msgstr "������������\"_cap\""
+
+msgid "\"_passthrough\" should be \"true\" or
\"false\""
+msgstr
"\"_passthrough\"���������\"true\"������\"false\""
+
+msgid "\"_passthrough_affected_by\" should be a device name string"
+msgstr
"\"_passthrough_affected_by\"���������������������������������"
+
+#, python-format
+msgid "Error while getting block devices. Details: %(err)s"
+msgstr "������������������������������������%(err)s"
+
+#, python-format
+msgid "Error while getting block device information for %(device)s."
+msgstr "��������������� %(device)s ������������������"
+
+#, python-format
+msgid "Unable to find distro file: %(filename)s"
+msgstr "���������������������������%(filename)s"
+
+#, python-format
+msgid ""
+"Unable to parse distro file: %(filename)s. Make sure, it is a JSON file."
+msgstr
"������������������������������%(filename)s������������������������JSON������������������"
+
+#, python-format
+msgid "Unable to login to iSCSI host target %(portal)s. Details: %(err)s"
+msgstr "������������ %(portal)s ������iSCSI���������������������������%(err)s"
+
+#, python-format
+msgid "Unable to login to iSCSI host %(host)s target %(target)s"
+msgstr "������������iSCSI������%(host)s������������%(target)s���"
+
+#, python-format
+msgid "Unable to find ISO file %(filename)s"
+msgstr "������������ISO������ %(filename)s"
+
+#, python-format
+msgid "The ISO file %(filename)s is not bootable"
+msgstr "ISO������%(filename)s���������������"
+
+#, python-format
+msgid "The ISO file %(filename)s does not have a valid El Torito boot record"
+msgstr "ISO������%(filename)s���������������El Torito���������������"
+
+#, python-format
+msgid "Invalid El Torito validation entry in ISO %(filename)s"
+msgstr "���ISO������%(filename)s������������������El Torito������������������"
+
+#, python-format
+msgid "Invalid El Torito boot indicator in ISO %(filename)s"
+msgstr "ISO������%(filename)s���El Torito������������������������"
+
+#, python-format
+msgid "Unexpected volume type for primary volume in ISO %(filename)s"
+msgstr "������������ISO������%(filename)s���������������"
+
+#, python-format
+msgid "Bad format while reading volume descriptor in ISO %(filename)s"
+msgstr "ISO������%(filename)s���������������������������"
+
+#, python-format
+msgid ""
+"The hypervisor doesn't have permission to use this ISO %(filename)s. "
+"Consider moving it under /var/lib/libvirt, or set the search permission to "
+"file access control lists for '%(user)s' user if possible, or add the
'%"
+"(user)s' to the ISO path group, or (not recommended) 'chmod -R o+x "
+"'path_to_iso'.Details: %(err)s"
+msgstr ""
+"hypervisor������������ISO������%(filename)s���������������������ISO������/var/lib/libvirt���"
+"���������������'%(user)s'���������������������������������'%(user)s'���������������ISO������������������"
+"������������������������������������������ 'chmod -R o+x
'���������������������������%(err)s"
+
+msgid "An error occurred when probing image OS information."
+msgstr "������������������������������������������������"
+
+msgid "No OS information found in given image."
+msgstr "���������������������������������������������������������"
+
+#, python-format
+msgid "Unable to read image file %(filename)s"
+msgstr "������������������������ %(filename)s"
+
+#, python-format
+msgid ""
+"Image file must be an existing file on system. %(filename)s is not a valid "
+"input."
+msgstr
"���������������������������������������%(filename)s���������������������"
+
+#, python-format
+msgid "Virtual machine %(name)s already exists"
+msgstr "���������%(name)s������������"
+
+#, python-format
+msgid "Virtual machine %(name)s does not exist"
+msgstr "���������%(name)s���������"
+
+#, python-format
+msgid ""
+"Unable to rename virtual machine %(name)s. The name %(new_name)s is already "
+"in use or the virtual machine is not powered off."
+msgstr ""
+"��������������������� %(name)s ������������������ %(new_name)s
������������������������������������"
+"������"
+
+#, python-format
+msgid "Unable to retrieve screenshot for stopped virtual machine %(name)s"
+msgstr "������������������������������������%(name)s���������"
+
+msgid "Remote ISO image is not supported by this server."
+msgstr "���������������������������ISO���������"
+
+#, python-format
+msgid "Screenshot is not supported on virtual machine %(name)s"
+msgstr "��������� %(name)s ���������������"
+
+#, python-format
+msgid "Unable to create virtual machine %(name)s. Details: %(err)s"
+msgstr "���������������������%(name)s������������%(err)s"
+
+#, python-format
+msgid "Unable to update virtual machine %(name)s. Details: %(err)s"
+msgstr "���������������������%(name)s������������%(err)s"
+
+#, python-format
+msgid "Unable to retrieve virtual machine %(name)s. Details: %(err)s"
+msgstr "���������������������%(name)s������������%(err)s"
+
+#, python-format
+msgid "Unable to connect to powered off virtual machine %(name)s."
+msgstr "���������%(name)s���������������������������"
+
+msgid "Virtual machine name must be a string without slashes (/)"
+msgstr ""
+
+#, python-format
+msgid "Invalid template URI %(value)s specified for virtual machine"
+msgstr "������������������������URI %(value)s"
+
+#, python-format
+msgid "Invalid storage pool URI %(value)s specified for virtual machine"
+msgstr "���������������������������URI %(value)s"
+
+msgid "Supported virtual machine graphics are Spice or VNC"
+msgstr "������������������������������Spice������VNC"
+
+msgid "Graphics address to listen on must be IPv4 or IPv6"
+msgstr "������������������������������������������IPv4���IPv6���������"
+
+msgid "Specify a template to create a virtual machine from"
+msgstr "������������������������������������"
+
+#, python-format
+msgid "Unable to start virtual machine %(name)s. Details: %(err)s"
+msgstr "��������������������� %(name)s. ���������%(err)s"
+
+#, python-format
+msgid "Unable to power off virtual machine %(name)s. Details: %(err)s"
+msgstr "���������������������%(name)s������������%(err)s"
+
+#, python-format
+msgid "Unable to delete virtual machine %(name)s. Details: %(err)s"
+msgstr "��������������������� %(name)s������������%(err)s"
+
+#, python-format
+msgid "Unable to reset virtual machine %(name)s. Details: %(err)s"
+msgstr "���������������������%(name)s������������%(err)s"
+
+msgid "User name list must be an array"
+msgstr "������������������������������������"
+
+msgid "User name must be a string"
+msgstr "���������������������������������"
+
+msgid "Group name list must be an array"
+msgstr "������������������������������������"
+
+msgid "Group name must be a string"
+msgstr "���������������������������������������"
+
+#, python-format
+msgid "User(s) '%(users)s' do not exist"
+msgstr "������'%(users)s'���������"
+
+#, python-format
+msgid "Group(s) '%(groups)s' do not exist"
+msgstr "���������'%(groups)s'���������"
+
+#, python-format
+msgid "Unable to shutdown virtual machine %(name)s. Details: %(err)s"
+msgstr "���������������������%(name)s������������%(err)s"
+
+#, python-format
+msgid ""
+"Unable to get access metadata of virtual machine %(name)s. Details: %(err)s"
+msgstr "��������������������� %(name)s������������������������%(err)s"
+
+msgid "The guest console password must be a string."
+msgstr "���������������������������������������������������"
+
+msgid "The life time for the guest console password must be a number."
+msgstr "������������������������������������������������������������"
+
+#, python-format
+msgid "Virtual machine '%(name)s' must be stopped before cloning it."
+msgstr "���������'%(name)s'���������������������������������"
+
+#, python-format
+msgid "Insufficient disk space to clone virtual machine '%(name)s'"
+msgstr "���������������'%(name)s'���������������������������������"
+
+#, python-format
+msgid "Unable to clone VM '%(name)s'. Details: %(err)s"
+msgstr
"���������������������������'%(name)s'������������������%(err)s"
+
+#, python-format
+msgid "Invalid operation for non-persistent virtual machine %(name)s"
+msgstr ""
+
+#, python-format
+msgid "Cannot suspend VM '%(name)s' because it is not running."
+msgstr ""
+
+#, python-format
+msgid "Unable to suspend VM '%(name)s'. Details: %(err)s"
+msgstr ""
+
+#, python-format
+msgid "Cannot resume VM '%(name)s' because it is not paused."
+msgstr ""
+
+#, python-format
+msgid "Unable to resume VM '%(name)s'. Details: %(err)s"
+msgstr ""
+
+msgid "Memory assigned is higher then the maximum allowed in the host."
+msgstr ""
+
+#, python-format
+msgid ""
+"VM '%(name)s' does not support live memory update. Update the memory with
"
+"the machine offline to enable this feature."
+msgstr ""
+
+msgid "Only increase memory is allowed in active VMs"
+msgstr ""
+
+msgid ""
+"For live memory update, new memory value must be equal old memory value plus
"
+"multiples of 1024 Mib"
+msgstr ""
+
+msgid "There are not enough free slots of 1024 Mib in the guest."
+msgstr ""
+
+msgid ""
+"Host's libvirt version does not support memory devices. Libvirt must be >=
"
+"1.2.14"
+msgstr ""
+
+#, python-format
+msgid "Error attaching memory device. Details: %(error)s"
+msgstr ""
+
+#, python-format
+msgid ""
+"VM %(vmid)s does not contain directly assigned host device %(dev_name)s."
+msgstr "���������%(vmid)s���������������������������������%(dev_name)s���"
+
+#, python-format
+msgid "The host device %(dev_name)s is not allowed to directly assign to VM."
+msgstr "������������%(dev_name)s������������������������������������"
+
+msgid ""
+"No IOMMU groups found. Host PCI pass through needs IOMMU group to function "
+"correctly. Please enable Intel VT-d or AMD IOMMU in your BIOS, then verify "
+"the Kernel is compiled with IOMMU support. For Intel CPU, add intel_iommu=on
"
+"to your Kernel parameter in /boot/grub2/grub.conf. For AMD CPU, add iommu=pt
"
+"iommu=1."
+msgstr ""
+"���������IOMMU groups���������PCI pass through������IOMMU
group������������������������������"
+"BIOS������������Intel VT-d ������ AMD IOMMU
���������������������������������������IOMMU���������"
+"Intel
CPU������������/boot/grub2/grub.conf���������������������intel_iommu=on���������AMD
"
+"CPU������������iommu=pt iommu=1���"
+
+msgid "\"name\" should be a device name string"
+msgstr "\"name\"���������������������������������������"
+
+#, python-format
+msgid ""
+"The device %(name)s is probably in use by the host. Unable to attach it to "
+"the guest."
+msgstr ""
+
+#, python-format
+msgid "Interface %(iface)s does not exist in virtual machine %(name)s"
+msgstr "��������� %(name)s ��������������� %(iface)s"
+
+#, python-format
+msgid ""
+"Network %(network)s specified for virtual machine %(name)s does not exist"
+msgstr "������������%(name)s���������������%(network)s���������"
+
+msgid "Supported virtual machine interfaces type is only network"
+msgstr "���������������������������������������"
+
+msgid "Network name for virtual machine interface must be a string"
+msgstr "������������������������������������������������"
+
+msgid "Invalid network model card specified for virtual machine interface"
+msgstr "���������������������������������������������"
+
+msgid "Specify type and network to add a new virtual machine interface"
+msgstr "���������������������������������������������"
+
+msgid "MAC Address must respect this format FF:FF:FF:FF:FF:FF"
+msgstr ""
+
+#, python-format
+msgid "MAC Address %(mac)s already exists in virtual machine %(name)s"
+msgstr ""
+
+msgid "Invalid MAC Address"
+msgstr ""
+
+msgid "Cannot change MAC address of a running virtual machine"
+msgstr ""
+
+#, python-format
+msgid "Template %(name)s already exists"
+msgstr "������ %(name)s ������������"
+
+#, python-format
+msgid ""
+"Network '%(network)s' specified for template %(template)s does not
exist"
+msgstr "��������� %(template)s ��������������� '%(network)s'
���������"
+
+#, python-format
+msgid ""
+"Storage pool %(pool)s specified for template %(template)s does not exist"
+msgstr "��������� %(template)s ������������������ '%(pool)s'
���������"
+
+#, python-format
+msgid "Storage pool %(pool)s specified for template %(template)s is not
active"
+msgstr "��������� %(template)s ������������������ '%(pool)s'
������������"
+
+#, python-format
+msgid "Invalid parameter '%(param)s' specified for CDROM."
+msgstr "���CDROM��������������� '%(param)s' ������"
+
+#, python-format
+msgid "Network %(network)s specified for template %(template)s is not active"
+msgstr "��������� %(template)s ��������������� '%(network)s'
������������"
+
+msgid "Template name must be a string"
+msgstr "���������������������������������������"
+
+msgid "Template icon must be a path to the image"
+msgstr "���������������������������������������������������"
+
+msgid "Template distribution must be a string"
+msgstr "������������������������������������������"
+
+msgid "Template distribution version must be a string"
+msgstr "���������������������������������������������������"
+
+msgid "The number of CPUs must be an integer greater than 0"
+msgstr "CPU���������������������������0���������"
+
+msgid "Amount of memory (MB) must be an integer greater than 512"
+msgstr "���������������MB���������������������������������512���������"
+
+msgid "Template CDROM must be a local or remote ISO file"
+msgstr "���������CDROM������������������������������������ISO������"
+
+#, python-format
+msgid "Invalid storage pool URI %(value)s specified for template"
+msgstr "������������������������������������URI %(value)s"
+
+msgid "Specify an ISO image as CDROM or a base image to create a template"
+msgstr "������������ISO���������������������������CDROM������������������"
+
+msgid "All networks for the template must be specified in a list."
+msgstr "������������������������������������������������"
+
+msgid "Specify a volume to a template when storage pool is iSCSI or SCSI"
+msgstr
"���������������������iSCSI������SCSI������������������������������������"
+
+#, python-format
+msgid "The volume %(volume)s is not in storage pool %(pool)s"
+msgstr "���%(volume)s���������������%(pool)s���"
+
+#, python-format
+msgid "Unable to create template due error: %(err)s"
+msgstr "������������������������������%(err)s"
+
+#, python-format
+msgid "Unable to delete template due error: %(err)s"
+msgstr "���������������%(err)s���������������������"
+
+msgid "Disk size must be an integer greater than 1GB."
+msgstr "������������������������1GB���"
+
+msgid "Template base image must be a valid local image file"
+msgstr "������������������������������������������������������������"
+
+#, python-format
+msgid "Cannot identify base image %(path)s format"
+msgstr "������������������������%(path)s������"
+
+msgid ""
+"When specifying CPU topology, VCPUs must be a product of sockets, cores, and
"
+"threads."
+msgstr "CPU������������VCPUs������������sockets, cores ������threads���"
+
+msgid ""
+"When specifying CPU topology, each element must be an integer greater than "
+"zero."
+msgstr "CPU���������������������������������������������������������"
+
+msgid ""
+"Invalid disk image format. Valid formats: bochs, cloop, cow, dmg, qcow, "
+"qcow2, qed, raw, vmdk, vpc."
+msgstr ""
+"���������������������������������������������������bochs, cloop, cow, dmg, qcow,
qcow2, qed, "
+"raw, vmdk, vpc���"
+
+#, python-format
+msgid "Storage pool %(name)s already exists"
+msgstr "���������%(name)s������������"
+
+#, python-format
+msgid "Storage pool %(name)s does not exist"
+msgstr "���������%(name)s���������"
+
+#, python-format
+msgid "Specify %(item)s in order to create the storage pool %(name)s"
+msgstr "���������������%(name)s������%(item)s"
+
+#, python-format
+msgid "Unable to delete active storage pool %(name)s"
+msgstr "������������������������������ %(name)s"
+
+#, python-format
+msgid "Unable to list storage pools. Details: %(err)s"
+msgstr "������������������������ ��������� %(err)s"
+
+#, python-format
+msgid "Unable to create storage pool %(name)s. Details: %(err)s"
+msgstr "��������������������� %(name)s������������ %(err)s"
+
+#, python-format
+msgid ""
+"Unable to get number of storage volumes in storage pool %(name)s. Details: %"
+"(err)s"
+msgstr "���������������������%(name)s��������������������������� %(err)s"
+
+#, python-format
+msgid "Unable to activate storage pool %(name)s. Details: %(err)s"
+msgstr "���������������������%(name)s������������ %(err)s"
+
+#, python-format
+msgid "Unable to deactivate storage pool %(name)s. Details: %(err)s"
+msgstr "���������������������%(name)s������������ %(err)s"
+
+#, python-format
+msgid "Unable to delete storage pool %(name)s. Details: %(err)s"
+msgstr "���������������������%(name)s������������ %(err)s"
+
+#, python-format
+msgid ""
+"Unable to create NFS Pool as export path %(path)s may block during mount"
+msgstr
"������������NFS������������������������������%(path)s������������������������"
+
+#, python-format
+msgid "Unable to create NFS Pool as export path %(path)s mount failed"
+msgstr "������������NFS������������������������������%(path)s������"
+
+#, python-format
+msgid "Unsupported storage pool type: %(type)s"
+msgstr "������������������������������%(type)s"
+
+#, python-format
+msgid "Error while retrieving storage pool XML to %(pool)s"
+msgstr "���������������XML���%(pool)s���������������"
+
+msgid "Storage pool name must be a string without slashes (/)"
+msgstr ""
+
+msgid ""
+"Supported storage pool types are dir, netfs, logical, iscsi, isci and
kimchi-"
+"iso"
+msgstr
"������������������������dir���netfs���logical���iscsi���isci������kimchi-iso"
+
+msgid "Storage pool path must be a string"
+msgstr "���������������������������������"
+
+msgid "Storage pool host must be a IP or hostname"
+msgstr "������������������������������IP���������������"
+
+msgid "Storage pool device must be the absolute path to the block device"
+msgstr "������������������������������������������������������"
+
+msgid "Storage pool devices parameter must be a list"
+msgstr "������������������������������������������"
+
+msgid "Target IQN of an iSCSI pool must be a string"
+msgstr "iSCSI������������������IQN������������������"
+
+msgid "Port of a remote storage server must be an integer between 1 and 65535"
+msgstr "���������������������������������������1���65535���������������"
+
+msgid "iSCSI target username must be a string"
+msgstr "iSCSI���������������������������������������"
+
+msgid "iSCSI target password must be a string"
+msgstr "iSCSI������������������������������������"
+
+msgid "Specify name and type to create a storage pool"
+msgstr "������������������������������������"
+
+#, python-format
+msgid ""
+"%(disk)s is not a valid disk/partition. Could not add it to the pool %(pool)"
+"s."
+msgstr "%(disk)s
���������������������/������������������������������������%(pool)s���"
+
+#, python-format
+msgid "Unable to extend logical pool %(pool)s. Details: %(err)s"
+msgstr "���������������������%(pool)s���������������������%(err)s"
+
+msgid "The parameter disks only can be updated for logical storage pool."
+msgstr "������������������������������������������������"
+
+msgid "The SCSI host adapter name must be a string."
+msgstr "SCSI���������������������������������������"
+
+msgid "The storage pool kimchi_isos is reserved for internal use"
+msgstr "���������kimchi_isos������������������"
+
+#, python-format
+msgid ""
+"Unable to activate NFS storage pool %(name)s. NFS server %(server)s is "
+"unreachable."
+msgstr
"������������NFS���������%(name)s���NFS���������%(server)s���������������"
+
+#, python-format
+msgid ""
+"Unable to deactivate NFS storage pool %(name)s. NFS server %(server)s is "
+"unreachable."
+msgstr
"������������NFS���������%(name)s���NFS���������%(server)s���������������"
+
+#, python-format
+msgid ""
+"Unable to deactivate pool %(name)s as it is associated with some templates"
+msgstr "���������������������%(name)s������������������������������������"
+
+#, python-format
+msgid "Unable to delete pool %(name)s as it is associated with some templates"
+msgstr "���������������������%(name)s������������������������������������"
+
+#, python-format
+msgid ""
+"A volume group named '%(name)s' already exists. Please, choose another name
"
+"to create the logical pool."
+msgstr
"������'%(name)s'������������������������������������������������������������������"
+
+#, python-format
+msgid "Unable to update database with deep scan information due error:
%(err)s"
+msgstr "������������������������������������������%(err)s���"
+
+#, python-format
+msgid "Storage volume %(name)s already exists"
+msgstr "���������%(name)s������������"
+
+#, python-format
+msgid "Storage volume %(name)s does not exist in storage pool %(pool)s"
+msgstr "���������%(pool)s������������������%(name)s"
+
+#, python-format
+msgid ""
+"Unable to create storage volume %(volume)s because storage pool %(pool)s is "
+"not active"
+msgstr "���������������������%(volume)s������������������%(pool)s
������������"
+
+#, python-format
+msgid "Specify %(item)s in order to create storage volume %(volume)s"
+msgstr "���������������%(volume)s������������%(item)s"
+
+#, python-format
+msgid ""
+"Unable to list storage volumes because storage pool %(pool)s is not active"
+msgstr "���������������������������������������%(pool)s������������"
+
+#, python-format
+msgid ""
+"Unable to create storage volume %(name)s in storage pool %(pool)s. Details:
%"
+"(err)s"
+msgstr
"������������������%(pool)s������������������%(name)s������������%(err)s"
+
+#, python-format
+msgid ""
+"Unable to list storage volumes in storage pool %(pool)s. Details: %(err)s"
+msgstr "������������������%(pool)s������������������������������%(err)s"
+
+#, python-format
+msgid "Unable to wipe storage volumes %(name)s. Details: %(err)s"
+msgstr "���������������������%(name)s������������%(err)s"
+
+#, python-format
+msgid "Unable to delete storage volume %(name)s. Details: %(err)s"
+msgstr "���������������������%(name)s������������%(err)s"
+
+#, python-format
+msgid "Unable to resize storage volume %(name)s. Details: %(err)s"
+msgstr "���������������������%(name)s���������������������%(err)s"
+
+#, python-format
+msgid "Storage type %(type)s does not support volume create and delete"
+msgstr "������������%(type)s������������������������������"
+
+msgid "Storage volume name must be a string"
+msgstr "������������������������������������"
+
+msgid "Storage volume allocation must be an integer number"
+msgstr "���������������������������������"
+
+msgid ""
+"Storage volume format not supported. Valid formats: bochs, cloop, cow, dmg, "
+"qcow, qcow2, qed, raw, vmdk, vpc."
+msgstr ""
+"������������������������������������������������bochs, cloop, cow, dmg, qcow,
qcow2, qed, "
+"raw, vmdk, vpc���"
+
+msgid "Storage volume requires a volume name"
+msgstr "���������������������"
+
+#, python-format
+msgid ""
+"Unable to update database with storage volume information due error: %(err)s"
+msgstr "���������������������������������������%(err)s"
+
+#, python-format
+msgid "Only one of parameter %(param)s can be specified"
+msgstr "���������������%(param)s������������������������"
+
+#, python-format
+msgid "Create volume from %(param)s is not supported"
+msgstr "������������%(param)s���������������"
+
+msgid "Storage volume capacity must be an integer number."
+msgstr "������������������������������������"
+
+msgid "Storage volume URL must be http://, https://, ftp:// or ftps://."
+msgstr "���������URL���������http://���https://���ftp://���ftps://"
+
+#, python-format
+msgid "Unable to access file %(url)s. Please, check it."
+msgstr "������������������%(url)s������������������������������������"
+
+#, python-format
+msgid ""
+"Unable to clone storage volume '%(name)s' in pool '%(pool)s'.
Details: %(err)"
+"s"
+msgstr
"������������������'%(pool)s'���������������'%(name)s'���������������������%(err)s"
+
+msgid "Specify chunk data and its size to upload a file."
+msgstr ""
+
+msgid "In order to upload a storage volume, specify the 'upload'
parameter."
+msgstr ""
+
+msgid ""
+"Unable to upload chunk data as it does not match with requested chunk size."
+msgstr ""
+
+#, python-format
+msgid "The storage volume %(vol)s is not under an upload process."
+msgstr ""
+
+msgid "The upload chunk data will exceed the storage volume size."
+msgstr ""
+
+#, python-format
+msgid "Unable to upload chunk data to storage volume. Details: %(err)s."
+msgstr ""
+
+#, python-format
+msgid "Interface %(name)s does not exist"
+msgstr "������%(name)s���������"
+
+#, python-format
+msgid "Network %(name)s already exists"
+msgstr "������%(name)s������������"
+
+#, python-format
+msgid "Network %(name)s does not exist"
+msgstr "������%(name)s���������"
+
+#, python-format
+msgid "Subnet %(subnet)s specified for network %(network)s is not valid."
+msgstr "���������%(network)s���������������%(subnet)s������"
+
+#, python-format
+msgid "Specify a network interface to create bridged network %(name)s"
+msgstr "������������������������������������������������������%(name)s"
+
+#, python-format
+msgid "Unable to delete active network %(name)s"
+msgstr "���������������������������%(name)s"
+
+#, python-format
+msgid "Interface %(iface)s specified for network %(network)s is already in
use"
+msgstr "���������%(network)s���������������%(iface)s������������"
+
+msgid "Interface should be bare NIC, bonding or bridge device."
+msgstr
"���������������������������������������������bonding���������������������"
+
+#, python-format
+msgid "Unable to create network %(name)s. Details: %(err)s"
+msgstr "������������������%(name)s������������%(err)s"
+
+#, python-format
+msgid "Unable to find a free IP address for network '%(name)s'"
+msgstr
"���������������'%(name)s'������������������������IP���������������"
+
+#, python-format
+msgid "The interface %(iface)s already exists."
+msgstr ""
+
+msgid "Network name must be a string without slashes (/) or quotes (\")"
+msgstr ""
+
+msgid "Supported network types are isolated, NAT and bridge"
+msgstr "���������������������������������NAT���������"
+
+msgid "Network subnet must be a string with IP address and prefix or netmask"
+msgstr
"���������������������������IP������������������������������������������������"
+
+msgid "Network interface must be a string"
+msgstr "������������������������������������"
+
+msgid "Network VLAN ID must be an integer between 1 and 4094"
+msgstr "������VLAN������������1���4094���������������"
+
+msgid "Specify name and type to create a Network"
+msgstr "���������������������������������"
+
+#, python-format
+msgid ""
+"Unable to delete network %(name)s. There are some virtual machines %(vms)s "
+"and/or templates linked to this network."
+msgstr ""
+
+#, python-format
+msgid ""
+"Unable to deactivate network %(name)s. There are some virtual machines
%(vms)"
+"s and/or templates linked to this network."
+msgstr ""
+
+#, python-format
+msgid "Bridge device %(name)s can not be the trunk device of a VLAN."
+msgstr "������������������%(name)s������VLAN���trunk���������"
+
+#, python-format
+msgid "Failed to activate interface %(iface)s: %(err)s."
+msgstr "������������������������ %(iface)s���%(err)s���"
+
+#, python-format
+msgid ""
+"Failed to activate interface %(iface)s. Please check the physical link "
+"status."
+msgstr "������������%(iface)s���������������������������������������������"
+
+#, python-format
+msgid "Failed to start network %(name)s. Details: %(err)s"
+msgstr "������������%(name)s������������������%(err)s"
+
+#, python-format
+msgid "Debug report %(name)s does not exist"
+msgstr "������������%(name)s���������"
+
+msgid "Debug report tool not found in system"
+msgstr "���������������������������������"
+
+#, python-format
+msgid "Unable to create debug report %(name)s. Details: %(err)s."
+msgstr "������������������������%(name)s������������%(err)s"
+
+#, python-format
+msgid "Can not find any debug report with the given name %(name)s"
+msgstr "������������������������%(name)s���������������"
+
+#, python-format
+msgid "Unable to generate debug report %(name)s. Details: %(err)s"
+msgstr "������������������������%(name)s������������%(err)s"
+
+msgid "You should give a name for the debug report file."
+msgstr "������������������������%(name)s������������%(err)s"
+
+msgid ""
+"Debug report name must be a string. Only letters, digits, underscore ('_')
"
+"and hyphen ('-') are allowed."
+msgstr ""
+"������������������������������������������������������������������������������������('_')���������������('-')"
+"������������������"
+
+#, python-format
+msgid ""
+"The debug report with specified name \"%(name)s\" already exists. Please
use "
+"another one."
+msgstr
"���������\"'%(name)s\"���������������������������������������������������������"
+
+#, python-format
+msgid "Storage server %(server)s was not used by Kimchi"
+msgstr "���������������%(server)s������Kimchi������"
+
+#, python-format
+msgid "Distro '%(name)s' does not exist"
+msgstr "������������'%(name)s'���������"
+
+#, python-format
+msgid "Partition %(name)s does not exist in the host"
+msgstr "������������������������%(name)s"
+
+msgid "Unable to shutdown host machine as there are running virtual machines"
+msgstr "������������������������������������������"
+
+msgid "Unable to reboot host machine as there are running virtual machines"
+msgstr "������������������������������������������"
+
+#, python-format
+msgid "Node device '%(name)s' not found"
+msgstr "������������������������'%(name)s'"
+
+msgid "Conflicting flag filters specified."
+msgstr "flag filters���������"
+
+msgid "No packages marked for update"
+msgstr "������������������������������"
+
+#, python-format
+msgid "Package %(name)s is not marked to be updated."
+msgstr "���������%(name)s������������������������"
+
+#, python-format
+msgid "Error while getting packages marked to be updated. Details: %(err)s"
+msgstr "���������������������������������������������������������%(err)s"
+
+msgid "There is no compatible package manager for this system."
+msgstr "������������������������������������������"
+
+#, python-format
+msgid "Invalid URI %(uri)s"
+msgstr "���������URI %(uri)s"
+
+msgid "Unable to choose a virtual machine name"
+msgstr "���������������������������������"
+
+msgid "Invalid storage type. Types supported: 'cdrom', 'disk'"
+msgstr
"������������������������������������������'cdrom'���'disk'"
+
+#, python-format
+msgid "The path '%(value)s' is not a valid local/remote path for the
device"
+msgstr "������'%(value)s'���������������������������/������������"
+
+msgid "Only CDROM path can be update."
+msgstr "���������CDROM���������������"
+
+#, python-format
+msgid ""
+"The storage device %(dev_name)s does not exist in the virtual machine %"
+"(vm_name)s"
+msgstr "������������%(dev_name)s������������%(vm_name)s������������"
+
+#, python-format
+msgid "Error while creating new storage device: %(error)s"
+msgstr "������������������������������������%(error)s"
+
+#, python-format
+msgid "Error while updating storage device: %(error)s"
+msgstr "������������������������������%(error)s"
+
+#, python-format
+msgid "Error while removing storage device: %(error)s"
+msgstr "������������������������������%(error)s"
+
+msgid "Do not support IDE device hot plug"
+msgstr "���������IDE������������������"
+
+msgid ""
+"Specify type and path or type and pool/volume to add a new virtual machine "
+"disk"
+msgstr
"���������������������������������������������������������������������������/���������"
+
+msgid "Specify path to update virtual machine disk"
+msgstr "������������������������������������"
+
+#, python-format
+msgid "Controller type %(type)s limitation of %(limit)s devices reached"
+msgstr "������������������%(type)s���������������������%(limit)s"
+
+#, python-format
+msgid "Cannot retrieve disk path information for given pool/volume: %(error)s"
+msgstr
"���������������������������/������������������������������������������%(error)s"
+
+msgid "Volume already in use by other virtual machine."
+msgstr "���������������������������������������"
+
+msgid ""
+"Only one of path or pool/volume can be specified to add a new virtual "
+"machine disk"
+msgstr
"���������������������������������������������������������/���������������������"
+
+#, python-format
+msgid ""
+"Volume chosen with format %(format)s does not fit in the storage type
%(type)"
+"s"
+msgstr "���������%(format)s���������������������������%(type)s"
+
+msgid "YUM Repository ID must be one word only string."
+msgstr "YUM������������ID������������������������������������������"
+
+msgid "Repository URL must be an http://, ftp:// or file:// URL."
+msgstr "������������URL���������http://��� ftp:// ��� file://"
+
+msgid ""
+"Repository configuration is a dictionary with specific values according to "
+"repository type."
+msgstr "������������������������������������������������������������������"
+
+msgid "Distribution to DEB repository must be a string"
+msgstr "DEB���������������������������������������������"
+
+msgid "Components to DEB repository must be listed in a array"
+msgstr "DEB������������������������������������������"
+
+msgid "Components to DEB repository must be a string"
+msgstr "DEB���������������������������������������"
+
+msgid "Mirror list to repository must be a string"
+msgstr ""
+
+msgid "YUM Repository name must be string."
+msgstr "YUM���������������������������������������"
+
+msgid "GPG check must be a boolean value."
+msgstr "GPG������������������������������"
+
+msgid "GPG key must be a URL pointing to the ASCII-armored file."
+msgstr "GPG������������������������ASCII���������������.asc������������URL"
+
+#, python-format
+msgid "Could not update repository %(repo_id)s."
+msgstr "������������������������%(repo_id)s"
+
+#, python-format
+msgid "Repository %(repo_id)s does not exist."
+msgstr "������������%(repo_id)s������������"
+
+msgid ""
+"Specify repository base URL, mirror list or metalink in order to create or "
+"update a YUM repository."
+msgstr ""
+
+msgid "Repository management tool was not recognized for your system."
+msgstr "������������������������������������������"
+
+#, python-format
+msgid "Repository %(repo_id)s is already enabled."
+msgstr "������������%(repo_id)s���������������"
+
+#, python-format
+msgid "Repository %(repo_id)s is already disabled."
+msgstr "������������%(repo_id)s���������������"
+
+#, python-format
+msgid "Could not remove repository %(repo_id)s."
+msgstr "������������������������%(repo_id)s"
+
+#, python-format
+msgid "Could not write repository configuration file %(repo_file)s"
+msgstr "������������������������������������%(repo_file)s"
+
+msgid "Specify repository distribution in order to create a DEB repository."
+msgstr "���������������������������������������������DEB���������"
+
+#, python-format
+msgid "Could not enable repository %(repo_id)s."
+msgstr "������������������������%(repo_id)s"
+
+#, python-format
+msgid "Could not disable repository %(repo_id)s."
+msgstr "������������������������%(repo_id)s"
+
+msgid "YUM Repository ID already exists"
+msgstr "YUM������ID������������"
+
+msgid "YUM Repository name must be a string"
+msgstr "YUM������������������������������������"
+
+#, python-format
+msgid "Unable to list repositories. Details: '%(err)s'"
+msgstr "������������������������������������'%(err)s'"
+
+#, python-format
+msgid "Unable to retrieve repository information. Details: '%(err)s'"
+msgstr "���������������������������������������������'%(err)s'"
+
+#, python-format
+msgid "Unable to add repository. Details: '%(err)s'"
+msgstr "������������������������������������'%(err)s'"
+
+#, python-format
+msgid "Unable to remove repository. Details: '%(err)s'"
+msgstr "������������������������������������'%(err)s'"
+
+#, python-format
+msgid ""
+"Configuration items: '%(items)s' are not supported by repository
manager"
+msgstr "���������������������������������: %(items)s"
+
+msgid "Repository metalink must be an http://, ftp:// or file:// URL."
+msgstr ""
+
+msgid "Cannot specify mirrorlist and metalink at the same time."
+msgstr ""
+
+#, python-format
+msgid ""
+"Virtual machine '%(vm)s' must be stopped before creating a snapshot of
it."
+msgstr "���������'%(vm)s'���������������������������������"
+
+#, python-format
+msgid ""
+"Unable to create snapshot '%(name)s' on virtual machine '%(vm)s'.
Details: %"
+"(err)s"
+msgstr
"������������������'%(vm)s'������������'%(name)s'������������%(err)s"
+
+#, python-format
+msgid "Snapshot '%(name)s' does not exist on virtual machine
'%(vm)s'."
+msgstr "������'%(name)s'������������������'%(vm)s'������"
+
+#, python-format
+msgid ""
+"Unable to retrieve snapshot '%(name)s' on virtual machine '%(vm)s'.
Details: "
+"%(err)s"
+msgstr
"������������������'%(vm)s'������������'%(name)s'������������%(err)s"
+
+#, python-format
+msgid "Unable to list snapshots on virtual machine '%(vm)s'. Details:
%(err)s"
+msgstr "���������������������'%(vm)s'���������������������%(err)s"
+
+#, python-format
+msgid ""
+"Unable to delete snapshot '%(name)s' on virtual machine '%(vm)s'.
Details: %"
+"(err)s"
+msgstr
"���������������������'%(vm)s'������'%(name)s'������������%(err)s"
+
+#, python-format
+msgid ""
+"Unable to retrieve current snapshot of virtual machine '%(vm)s'. Details:
%"
+"(err)s"
+msgstr "���������������������'%(vm)s'������������������������%(err)s"
+
+#, python-format
+msgid ""
+"Unable to revert virtual machine '%(vm)s' to snapshot '%(name)s'.
Details: %"
+"(err)s"
+msgstr
"���������������������'%(vm)s'���������'%(name)s'������������%(err)s"
+
+#, python-format
+msgid ""
+"Unable to create snapshot of virtual machine '%(vm)s' because it contains a
"
+"disk with format '%(format)s'; only 'qcow2' is supported."
+msgstr ""
+"������������������'%(vm)s'���������������������������������������'%(format)s'������������������������"
+"���'qcow2'���������"
+
+msgid "The number of vCPUs is too large for this system."
+msgstr "vCPUs������������������������������������"
+
+msgid "Invalid vCPU/topology combination."
+msgstr "���������vCPU/topology���������"
+
+msgid "This host (or current configuration) does not allow CPU topology."
+msgstr "������������������������������������������CPU���������"
+
+msgid "ERROR CODE"
+msgstr "���������"
+
+msgid "REASON"
+msgstr "������"
+
+msgid "STACK"
+msgstr "���������"
+
+msgid "Go to Homepage"
+msgstr "������������"
+
+msgid "Create a New Virtual Machine"
+msgstr "���������������������������"
+
+msgid "Virtual Machine Name"
+msgstr "���������������"
+
+msgid ""
+"The name used to identify the virtual machine. If omitted, a name will be "
+"chosen based on the template used."
+msgstr
"���������������������������������������������������������������������������������������������"
+
+msgid "Template"
+msgstr "������"
+
+msgid "Please create a template first."
+msgstr "������������������������"
+
+msgid "Create a Template"
+msgstr "������������������"
+
+msgid "Please choose a template."
+msgstr "������������������"
+
+msgid "OS"
+msgstr "������������"
+
+msgid "OS Version"
+msgstr "������������������"
+
+msgid "CPUS"
+msgstr "���������������"
+
+msgid "Memory"
+msgstr "������"
+
+msgid "Create"
+msgstr "������"
+
+msgid "Creating..."
+msgstr "������������..."
+
+msgid "Cancel"
+msgstr "������"
+
+msgid "Edit Guest"
+msgstr "���������������"
+
+msgid "General"
+msgstr "������"
+
+msgid "Storage"
+msgstr "������"
+
+msgid "Interface"
+msgstr "������������"
+
+msgid "Permission"
+msgstr "������"
+
+msgid "Host PCI Device"
+msgstr "������PCI������"
+
+msgid "Snapshot"
+msgstr "������"
+
+msgid "Name"
+msgstr "������"
+
+msgid "CPUs"
+msgstr "���������������"
+
+msgid "Memory (MB)"
+msgstr "������(MB)"
+
+msgid "Icon"
+msgstr "������"
+
+msgid "Device"
+msgstr "������������"
+
+msgid "Path"
+msgstr "������"
+
+msgid "Network"
+msgstr "������"
+
+msgid "Type"
+msgstr "������"
+
+msgid "MAC Address"
+msgstr ""
+
+msgid "Available system users and groups"
+msgstr "���������������������������������"
+
+msgid "Selected system users and groups"
+msgstr "���������������������������������"
+
+msgid "User"
+msgstr "������"
+
+msgid "All"
+msgstr "������"
+
+msgid "To Add"
+msgstr "���������"
+
+msgid "Added"
+msgstr "���������"
+
+msgid "filter"
+msgstr "���������"
+
+msgid "Product"
+msgstr "������"
+
+msgid "Vendor"
+msgstr "������"
+
+msgid "Created"
+msgstr "���������"
+
+msgid "Save"
+msgstr "������"
+
+msgid "Replace"
+msgstr "������"
+
+msgid "Detach"
+msgstr "������"
+
+msgid "revert"
+msgstr "������"
+
+msgid "Start"
+msgstr "������"
+
+msgid "Reset"
+msgstr "������"
+
+msgid "Pause"
+msgstr ""
+
+msgid "Resume"
+msgstr ""
+
+msgid "Power Off"
+msgstr "������������"
+
+msgid "Actions"
+msgstr "������"
+
+msgid "Connect"
+msgstr "���������"
+
+msgid "Clone"
+msgstr "������������"
+
+msgid "Edit"
+msgstr "������"
+
+msgid "Shut Down"
+msgstr "������"
+
+msgid "Delete"
+msgstr "������"
+
+msgid "CPU"
+msgstr "���������"
+
+msgid "Disk I/O"
+msgstr "������I/O"
+
+msgid "Network I/O"
+msgstr "������I/O"
+
+msgid "Livetile"
+msgstr "������"
+
+msgid "No guests found."
+msgstr "���������������������"
+
+msgid "Add a Storage Device to VM"
+msgstr "������������������������������������"
+
+msgid "Device Type"
+msgstr "������������"
+
+msgid "The device type. Currently, \"cdrom\" and \"disk\" are
supported."
+msgstr
"������������������������������������������\"cdrom\"���\"disk\"���
"
+
+msgid "Storage Pool"
+msgstr "���������"
+
+msgid "Storage pool which volume located in"
+msgstr "���������������������������"
+
+msgid "Storage Volume"
+msgstr "���������"
+
+msgid "Storage volume to be attached"
+msgstr "���������������������"
+
+msgid "File Path"
+msgstr "������������"
+
+msgid "The ISO file path in the server for CDROM."
+msgstr "������������CDROM������������ISO������������"
+
+msgid "Attach"
+msgstr "������"
+
+msgid "Shut down"
+msgstr "������"
+
+msgid "Restart"
+msgstr "������"
+
+msgid "Basic Information"
+msgstr "������������"
+
+msgid "OS Distro"
+msgstr "���������������������"
+
+msgid "OS Code Name"
+msgstr "������������������"
+
+msgid "Processor"
+msgstr "���������"
+
+msgid "CPU(s)"
+msgstr "CPU(s)"
+
+msgid "System Statistics"
+msgstr "������������������"
+
+msgid "Software Updates"
+msgstr "������������"
+
+msgid "Update Progress"
+msgstr "������������"
+
+msgid "Repositories"
+msgstr "������������"
+
+msgid "Debug Reports"
+msgstr "������������������"
+
+msgid "The username or password you entered is incorrect. Please try again."
+msgstr "���������������������������������������������"
+
+msgid "This field is required."
+msgstr "������������������"
+
+msgid "Log in"
+msgstr "������"
+
+msgid "Logging in..."
+msgstr "���������..."
+
+msgid "Host"
+msgstr "������"
+
+msgid "Guests"
+msgstr "���������"
+
+msgid "Templates"
+msgstr "������"
+
+msgid "Failed to get application configuration"
+msgstr "������������������������"
+
+msgid "This is not a valid Linux path"
+msgstr "������������������������Linux������"
+
+msgid "This is not a valid URL."
+msgstr "������������������������URL"
+
+msgid "No such data available."
+msgstr "���������������������"
+
+msgid ""
+"Can not contact the host system. Verify the host system is up and that you "
+"have network connectivity to it. HTTP request response %1. "
+msgstr ""
+"������������������������������������������������������������������������������������������HTTP���������������%1"
+
+msgid "Unable to read file."
+msgstr ""
+
+msgid "Error while uploading file."
+msgstr ""
+
+msgid "Delete Confirmation"
+msgstr "������������"
+
+msgid "OK"
+msgstr "������"
+
+msgid "Confirm"
+msgstr "������"
+
+msgid "Warning"
+msgstr "������"
+
+msgid "Cloning..."
+msgstr ""
+
+msgid "Loading..."
+msgstr "������������..."
+
+msgid "An error occurred while retrieving system information."
+msgstr ""
+
+msgid "Retry"
+msgstr "������"
+
+msgid "Detailed message:"
+msgstr "���������������"
+
+msgid "No ISO found"
+msgstr "������������ISO������"
+
+msgid "This is not a valid ISO file."
+msgstr "������������������������ISO������"
+
+msgid "This may take a long time. Do you want to continue?"
+msgstr "���������������������������������������"
+
+msgid "This will permanently delete the template. Would you like to continue?"
+msgstr "������������������������������������������"
+
+msgid "Unable to shut down system as there are some virtual machines running!"
+msgstr "���������������������������������������������"
+
+msgid "Max:"
+msgstr "���������"
+
+msgid "Utilization"
+msgstr "���������"
+
+msgid "Available"
+msgstr "������������"
+
+msgid "Read Rate"
+msgstr "���������"
+
+msgid "Write Rate"
+msgstr "���������"
+
+msgid "Received"
+msgstr "������"
+
+msgid "Sent"
+msgstr "������"
+
+msgid ""
+"Shutting down or restarting host will cause unsaved work lost. Continue to "
+"shut down/restarting?"
+msgstr
"���������������������������������������������������������������������������/���������"
+
+msgid ""
+"Repository will be removed permanently and can't be recovered. Do you want
"
+"to continue?"
+msgstr "���������������������������������������������������������������"
+
+msgid "ID"
+msgstr "���������"
+
+msgid "Base URL"
+msgstr "������URL"
+
+msgid "Is Mirror"
+msgstr "���������������"
+
+msgid "URL Args"
+msgstr "URL������"
+
+msgid "Enabled"
+msgstr "���������"
+
+msgid "GPG Check"
+msgstr "GPG������"
+
+msgid "GPG Key"
+msgstr "GPG���"
+
+msgid "Add"
+msgstr "������"
+
+msgid "Remove"
+msgstr "������"
+
+msgid "Enable"
+msgstr "������"
+
+msgid "Disable"
+msgstr "������"
+
+msgid "Package Name"
+msgstr "���������������"
+
+msgid "Version"
+msgstr "������"
+
+msgid "Architecture"
+msgstr "������������"
+
+msgid "Repository"
+msgstr "������������"
+
+msgid "Update All"
+msgstr "������������"
+
+msgid "Updating..."
+msgstr "������������..."
+
+msgid "Failed to retrieve packages update information."
+msgstr "������������������������������������"
+
+msgid "Failed to update package(s)."
+msgstr "���������������������"
+
+msgid ""
+"Debug report will be removed permanently and can't be recovered. Do you want
"
+"to continue?"
+msgstr "���������������������������������������������������������������������"
+
+msgid "Generated Time"
+msgstr "������������"
+
+msgid "Generate"
+msgstr "������"
+
+msgid "Generating..."
+msgstr "������������..."
+
+msgid "Rename"
+msgstr "���������"
+
+msgid "Download"
+msgstr "������"
+
+msgid ""
+"Report name should contain only letters, digits, underscore ('_') and/or
"
+"hyphen ('-')."
+msgstr
"������������������������������������������������������('_')������������('-')"
+
+msgid "Pending..."
+msgstr "������������..."
+
+msgid "Report name is the same as the original one."
+msgstr "������������������������������������"
+
+msgid ""
+"This will delete the virtual machine and its virtual disks. This operation "
+"cannot be undone. Would you like to continue?"
+msgstr
"���������������������������������������������������������������������������������"
+
+msgid "Power off Confirmation"
+msgstr "������������������"
+
+msgid ""
+"This action may produce undesirable results, for example unflushed disk "
+"cache in the guest. Would you like to continue?"
+msgstr
"������������������������������������������������������������������������������������������������"
+
+msgid "Reset Confirmation"
+msgstr "������������"
+
+msgid ""
+"There is a risk of data loss caused by reset without the guest OS shutdown. "
+"Would you like to continue?"
+msgstr
"������������������������������������������������������������������������������������������������������"
+
+msgid "Shut Down Confirmation"
+msgstr "������������"
+
+msgid "Note the guest OS may ignore this request. Would you like to continue?"
+msgstr
"���������������������������������������������������������������������������������"
+
+msgid "Virtual Machine delete Confirmation"
+msgstr "���������������������"
+
+msgid ""
+"This virtual machine is not persistent. Power Off will delete it. Continue?"
+msgstr
"������������������������������������������������������������������������������������"
+
+msgid ""
+"When the target guest has SCSI or iSCSI volumes, they will be cloned on "
+"default storage pool. The same will happen when the target pool does not "
+"have enough space to clone the volumes. Do you want to continue?"
+msgstr ""
+"������������������������SCSI������iSCSI���������������������������������������������������������������������"
+"������������������������������������������������������������������������������������������������������"
+
+msgid ""
+"This CDROM will be detached permanently and you can re-attach it. Continue "
+"to detach it?"
+msgstr "CDROM���������������������������������������������������������������"
+
+msgid "Attaching..."
+msgstr "������������"
+
+msgid "Replacing..."
+msgstr "������������..."
+
+msgid "Successfully attached!"
+msgstr "������������"
+
+msgid "Successfully replaced!"
+msgstr "������������"
+
+msgid "Successfully detached!"
+msgstr "������������"
+
+msgid ""
+"This disk will be detached permanently and you can re-attach it. Continue to
"
+"detach it?"
+msgstr
"���������������������������������������������������������������������������������������?"
+
+msgid "interface:"
+msgstr "���������"
+
+msgid "address:"
+msgstr "���������"
+
+msgid "link_type:"
+msgstr "���������������"
+
+msgid "block:"
+msgstr "������"
+
+msgid "drive_type:"
+msgstr "���������������"
+
+msgid "model:"
+msgstr "���������"
+
+msgid "Affected devices:"
+msgstr "���������������������"
+
+msgid "The VLAN id must be between 1 and 4094."
+msgstr "VLAN ������������������1���4094������"
+
+msgid "unavailable"
+msgstr "������������"
+
+msgid ""
+"This action will interrupt network connectivity for any virtual machine that
"
+"depend on this network."
+msgstr "������������������������������������������������������������������"
+
+msgid "Create a network"
+msgstr "������������������"
+
+msgid ""
+"This network is not persistent. Instead of stop, this action will "
+"permanently delete it. Would you like to continue?"
+msgstr ""
+"������������������������������������������������������������������������������������������������������������������"
+"���������"
+
+msgid ""
+"The bridged VLAN tag may not work well with NetworkManager enabled. You "
+"should consider disabling it."
+msgstr ""
+
+msgid ""
+"This will permanently delete the storage pool. Would you like to continue?"
+msgstr "���������������������������������������������"
+
+msgid "This storage pool is empty."
+msgstr "���������������������"
+
+msgid ""
+"It will format your disk and you will loose any data in there, are you sure "
+"to continue? "
+msgstr
"������������������������������������������������������������������������������������"
+
+msgid "SCSI Fibre Channel"
+msgstr "SCSI������������"
+
+msgid "No SCSI adapters found."
+msgstr "������������SCSI���������"
+
+msgid "Loading iSCSI targets..."
+msgstr "������iSCSI������..."
+
+msgid "No iSCSI found. Please input one."
+msgstr "������������iSCSI,������������������"
+
+msgid "Failed to load iSCSI targets."
+msgstr "������iSCSI���������������"
+
+msgid "The storage pool name can not be blank."
+msgstr "���������������������������������"
+
+msgid "The storage pool path can not be blank."
+msgstr "���������������������������������"
+
+msgid "NFS server mount path can not be blank."
+msgstr "NFS������������������������������������"
+
+msgid "Invalid NFS mount path."
+msgstr "���������NFS���������������"
+
+msgid "No logical device selected."
+msgstr "���������������������������"
+
+msgid "The iSCSI target can not be blank."
+msgstr "iSCSI���������������������"
+
+msgid "Server name can not be blank."
+msgstr "������������������������"
+
+msgid "This is not a valid Server Name or IP. Please, modify it."
+msgstr
"������������������������������������������IP���������������������������������"
+
+msgid "Looking for available partitions ..."
+msgstr "��������������������� ..."
+
+msgid "No available partitions found."
+msgstr "���������������������"
+
+msgid ""
+"This storage pool is not persistent. Instead of deactivate, this action will
"
+"permanently delete it. Would you like to continue?"
+msgstr
"���������������������������������������������������������������������������������������������������"
+
+msgid "Unable to retrieve partitions information."
+msgstr "���������������������������"
+
+msgid "In progress..."
+msgstr "������������..."
+
+msgid "Failed!"
+msgstr "���������"
+
+msgid "CDROM path needs to be a valid local/remote path and cannot be blank."
+msgstr "CDROM���������������������������������/������������������������������"
+
+msgid "Disk pool or volume cannot be blank."
+msgstr "���������������������������"
+
+#, fuzzy
+msgid "Filter"
+msgstr "���������"
+
+msgid "Network Name"
+msgstr "������������"
+
+msgid "State"
+msgstr "������"
+
+msgid "Network Type"
+msgstr "������������"
+
+msgid "Address Space"
+msgstr "������������"
+
+msgid "Name should not contain '/' and '\"'."
+msgstr "������������������������/������'\"'���"
+
+msgid "Isolated: no external network connection"
+msgstr "������: ������������������������"
+
+msgid "NAT: outbound physical network connection only"
+msgstr "NAT: ���������������������������������������"
+
+msgid "Bridged: Virtual machines are connected to physical network directly"
+msgstr "���������������������������������������������������������"
+
+msgid "(No interfaces found)"
+msgstr "(������������������������)"
+
+msgid "Destination"
+msgstr "������������"
+
+msgid "Enable VLAN"
+msgstr "������VLAN"
+
+msgid "VLAN ID"
+msgstr "VLAN���"
+
+msgid "Stop"
+msgstr "������"
+
+msgid "Generate a New Debug Report"
+msgstr "������������������������������"
+
+msgid "Report Name"
+msgstr "���������������"
+
+msgid ""
+"The name used to identify the report. If omitted, a name will be chosen "
+"based on current time. Name can contain: letters, digits, underscore
(\"_\") "
+"and hyphen (\"-\")."
+msgstr ""
+"������������������������������������������������������������������������������������������������������������������"
+"������������������������������ ('_') ���������������'-'���"
+
+msgid "Rename a Debug Report"
+msgstr "���������������������������"
+
+msgid ""
+"The name used to identify the report. Name can contain: letters, digits and "
+"hyphen (\"-\")."
+msgstr
"������������������������������������������������������������������������������������(\"-\")���"
+
+msgid "Submit"
+msgstr "������"
+
+msgid "Add a Repository"
+msgstr "������������������������"
+
+msgid "Identifier"
+msgstr "���������"
+
+msgid "Single word, unique identifier for the repository."
+msgstr "���������������������������������������"
+
+msgid "Textual name for the repository."
+msgstr "���������������������������"
+
+msgid "URL"
+msgstr "URL"
+
+msgid "Required Field"
+msgstr "���������������"
+
+msgid "URL to the repository. Supported protocols are http, ftp, and file."
+msgstr "���������������URL���������������������http���ftp������file"
+
+msgid "Repository is a mirror"
+msgstr "���������������������������"
+
+msgid "Distribution"
+msgstr "���������"
+
+msgid "Distribution of the DEB repository."
+msgstr "DEB������������������"
+
+msgid "Components"
+msgstr "������"
+
+msgid "List of components in DEB repository."
+msgstr "DEB������������������������"
+
+msgid "Edit Repository"
+msgstr "������������������"
+
+msgid "Mirror List URL"
+msgstr "������������URL"
+
+msgid "Yes"
+msgstr "���"
+
+msgid "No"
+msgstr "���"
+
+msgid "Capacity"
+msgstr "������"
+
+msgid "Allocated"
+msgstr "���������"
+
+msgid "Location"
+msgstr "������"
+
+msgid "Device path"
+msgstr "������������"
+
+msgid "active"
+msgstr "���������"
+
+msgid "inactive"
+msgstr "���������"
+
+msgid "Deactivate"
+msgstr "������"
+
+msgid "Activate"
+msgstr "������"
+
+msgid "Add Volume"
+msgstr "���������"
+
+msgid "Extend"
+msgstr "������"
+
+msgid "Undefine"
+msgstr "������������"
+
+msgid "Format"
+msgstr "������"
+
+msgid "Allocation"
+msgstr "������"
+
+msgid "Define a New Storage Pool"
+msgstr "���������������������������"
+
+msgid "Storage Pool Name"
+msgstr "���������������"
+
+msgid ""
+"The name used to identify the storage pools, and it should not be empty."
+msgstr "���������������������������������������������������������������"
+
+msgid "Storage Pool Type"
+msgstr "���������������"
+
+msgid "Storage Path"
+msgstr "������������"
+
+msgid ""
+"The path of the Storage Pool. Each Storage Pool must have a unique path."
+msgstr "������������������.���������������������������������������"
+
+msgid ""
+"Kimchi will try to create the directory when it does not already exist in "
+"your system."
+msgstr
"������������������������KIMCHI���������������������������������������������"
+
+msgid "NFS Server IP"
+msgstr "NFS���������IP"
+
+msgid "NFS server IP or hostname. It can be input or chosen from history."
+msgstr
"NFS���������IP���������������������������������������������������������������������"
+
+msgid "NFS Path"
+msgstr "NFS ������"
+
+msgid "The NFS exported path on NFS server."
+msgstr "NFS���������������������NFS������"
+
+msgid "iSCSI Server"
+msgstr "iSCSI���������"
+
+msgid "Server"
+msgstr "���������"
+
+msgid "Port"
+msgstr "������"
+
+msgid "iSCSI server IP or hostname. It should not be empty."
+msgstr "iSCSI���������IP������������������ ���������������"
+
+msgid "Target"
+msgstr "������"
+
+msgid "The iSCSI target on iSCSI server"
+msgstr "iSCSI������"
+
+msgid "Add iSCSI Authentication"
+msgstr "������ISCSI������"
+
+msgid "iSCSI Authentication"
+msgstr "iSCSI������"
+
+msgid "User Name"
+msgstr "���������"
+
+msgid "Password"
+msgstr "������"
+
+msgid "SCSI Adapter"
+msgstr "SCSI���������"
+
+msgid "Please, wait..."
+msgstr "���������..."
+
+msgid "Add a Volume to Storage Pool"
+msgstr "���������������������������"
+
+msgid "Fetch from remote URL"
+msgstr "���������URL������"
+
+msgid "Enter the remote URL here."
+msgstr "���������������������URL���"
+
+msgid "Upload a file"
+msgstr "������������������"
+
+msgid "Choose the file you want to upload."
+msgstr "������������������������������"
+
+msgid "Add Template"
+msgstr "������������"
+
+msgid "Where is the source media for this template? "
+msgstr "������������������������������"
+
+msgid "Local ISO Image"
+msgstr "������ISO������"
+
+msgid "Local Image File"
+msgstr "������������������"
+
+msgid "Remote ISO Image"
+msgstr "������ISO������"
+
+msgid "Search ISOs"
+msgstr "������ISO"
+
+msgid "The following ISOs are available:"
+msgstr "������ISO������������"
+
+msgid "OS: "
+msgstr "��������������� "
+
+msgid "Version: "
+msgstr "��������� "
+
+msgid "Size: "
+msgstr "���������"
+
+msgid "Search more ISOs"
+msgstr "������������ISO"
+
+msgid "Create Templates from Selected ISO"
+msgstr "������������ISO���������������"
+
+msgid "I want to use a specific ISO file"
+msgstr "������������ISO������"
+
+msgid "Loading default remote ISOs ..."
+msgstr "���������������������ISOs ..."
+
+msgid "Arch: "
+msgstr "���������������"
+
+msgid "I want to use a custom URL"
+msgstr "���������������������������URL"
+
+msgid "Edit Template"
+msgstr "������������"
+
+msgid "CDROM"
+msgstr "������"
+
+msgid "Image File"
+msgstr "������������"
+
+msgid "Graphics"
+msgstr "������"
+
+msgid "Disk(GB)"
+msgstr "������(GB)"
+
+msgid "Disk Format"
+msgstr ""
+
+msgid "CPU Number"
+msgstr "CPU������"
+
+msgid "Manually set CPU topology"
+msgstr "������������CPU������"
+
+msgid "Cores"
+msgstr "���������"
+
+msgid "Threads"
+msgstr "������"
+
+msgid "No templates found."
+msgstr "������������������"
+
+#~ msgid "Delete is not allowed for %(resource)s"
+#~ msgstr "���������������%(resource)s"
+
+#~ msgid "%(resource)s does not implement update method"
+#~ msgstr "���������������%(resource)s"
+
+#~ msgid "Create is not allowed for %(resource)s"
+#~ msgstr "���������������%(resource)s"
+
+#~ msgid "Unable to parse JSON request"
+#~ msgstr "������������JSON������"
+
+#~ msgid "This API only supports JSON"
+#~ msgstr "������API���������JSON"
+
+#~ msgid "Parameters does not match requirement in schema: %(err)s"
+#~ msgstr "���������������������������������%(err)s"
+
+#~ msgid "You don't have permission to perform this operation."
+#~ msgstr "������������������������������������"
+
+#~ msgid "Datastore is not initiated in the model object."
+#~ msgstr "���������model������������������������������"
+
+#~ msgid "Unable to start task due error: %(err)s"
+#~ msgstr "������������%(err)s������������������"
+
+#~ msgid ""
+#~ "Authentication failed for user '%(username)s'. [Error code:
%(code)s]"
+#~ msgstr
"������'%(username)s'������������������.[���������������%(code)s]"
+
+#~ msgid "You are not authorized to access Kimchi"
+#~ msgstr "������������������������Kimchi"
+
+#~ msgid "Specify %(item)s to login into Kimchi"
+#~ msgstr "������������Kimchi���%(item)s"
+
+#~ msgid "Invalid LDAP configuration: %(item)s : %(value)s"
+#~ msgstr "���������LDAP���������%(item)s : %(value)s"
+
+#~ msgid "Unable to find %(item)s in datastore"
+#~ msgstr "���������������������������%(item)s"
+
+#~ msgid "Timeout while running command '%(cmd)s' after %(seconds)s
seconds"
+#~ msgstr "������'%(cmd)s'������%(seconds)s���������������"
+
+#~ msgid "Peers"
+#~ msgstr "���������"
+
+#~ msgid "Searching"
+#~ msgstr "������������"
+
+#~ msgid "No peers found."
+#~ msgstr "������������������������"
+
+#~ msgid "Help"
+#~ msgstr "������"
+
+#~ msgid "About"
+#~ msgstr "������"
+
+#~ msgid "Log out"
+#~ msgstr "������"
+
+#~ msgid "Version:"
+#~ msgstr "���������"
+
+#~ msgid "Session timeout, please re-login."
+#~ msgstr "���������������������������������"
diff --git a/src/wok/plugins/kimchi/po/zh_TW.po b/src/wok/plugins/kimchi/po/zh_TW.po
new file mode 100644
index 0000000..90045b5
--- /dev/null
+++ b/src/wok/plugins/kimchi/po/zh_TW.po
@@ -0,0 +1,2138 @@
+# English translations for kimchi package.
+# Copyright (C) 2013 ORGANIZATION
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: kimchi 0.1\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2015-07-01 16:11-0300\n"
+"PO-Revision-Date: 2013-07-11 17:32-0400\n"
+"Last-Translator: Cr��stian Viana <vianac(a)linux.vnet.ibm.com>\n"
+"Language-Team: English\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Language: zh_TW\n"
+"Generated-By: pygettext.py 1.5\n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+
+#, python-format
+msgid "Unknown parameter %(value)s"
+msgstr ""
+
+#, python-format
+msgid "Timeout of %(seconds)s seconds expired while running task
'%(task)s."
+msgstr ""
+
+#, python-format
+msgid "User %(user_id)s not found with given LDAP settings."
+msgstr ""
+
+msgid "Unknown \"_cap\" specified"
+msgstr ""
+
+msgid "\"_passthrough\" should be \"true\" or
\"false\""
+msgstr ""
+
+msgid "\"_passthrough_affected_by\" should be a device name string"
+msgstr ""
+
+#, python-format
+msgid "Error while getting block devices. Details: %(err)s"
+msgstr "���������������������������������������������������%(err)s"
+
+#, python-format
+msgid "Error while getting block device information for %(device)s."
+msgstr "������ %(device)s ���������������������������������������"
+
+#, python-format
+msgid "Unable to find distro file: %(filename)s"
+msgstr "��������� distro ���������%(filename)s"
+
+#, python-format
+msgid ""
+"Unable to parse distro file: %(filename)s. Make sure, it is a JSON file."
+msgstr "������������ distro ���������%(filename)s������������������ JSON
���������"
+
+#, python-format
+msgid "Unable to login to iSCSI host target %(portal)s. Details: %(err)s"
+msgstr "������������ iSCSI ������������ %(portal)s������������������%(err)s"
+
+#, python-format
+msgid "Unable to login to iSCSI host %(host)s target %(target)s"
+msgstr "������������ iSCSI ������ %(host)s ������ %(target)s"
+
+#, python-format
+msgid "Unable to find ISO file %(filename)s"
+msgstr ""
+
+#, python-format
+msgid "The ISO file %(filename)s is not bootable"
+msgstr "ISO ������ %(filename)s ������������"
+
+#, python-format
+msgid "The ISO file %(filename)s does not have a valid El Torito boot record"
+msgstr "ISO ������ %(filename)s ��������������� El Torito ������������"
+
+#, python-format
+msgid "Invalid El Torito validation entry in ISO %(filename)s"
+msgstr "ISO %(filename)s ��������������� El Torito ������������"
+
+#, python-format
+msgid "Invalid El Torito boot indicator in ISO %(filename)s"
+msgstr "ISO %(filename)s ��������������� El Torito ���������������"
+
+#, python-format
+msgid "Unexpected volume type for primary volume in ISO %(filename)s"
+msgstr "ISO %(filename)s ���������������������������������������������"
+
+#, python-format
+msgid "Bad format while reading volume descriptor in ISO %(filename)s"
+msgstr "������ ISO %(filename)s ���������������������������������������������"
+
+#, python-format
+msgid ""
+"The hypervisor doesn't have permission to use this ISO %(filename)s. "
+"Consider moving it under /var/lib/libvirt, or set the search permission to "
+"file access control lists for '%(user)s' user if possible, or add the
'%"
+"(user)s' to the ISO path group, or (not recommended) 'chmod -R o+x "
+"'path_to_iso'.Details: %(err)s"
+msgstr ""
+"Hypervisor ��������������� ISO %(filename)s ���������������������������������������
/var/lib/"
+"libvirt ������������������������������'%(user)s'
���������������������������������������������������������"
+"��� '%(user)s' ��������� ISO
������������������������������������������������������ 'chmod -R o+x "
+"'path_to_iso'������������������%(err)s"
+
+msgid "An error occurred when probing image OS information."
+msgstr ""
+
+msgid "No OS information found in given image."
+msgstr ""
+
+#, python-format
+msgid "Unable to read image file %(filename)s"
+msgstr ""
+
+#, python-format
+msgid ""
+"Image file must be an existing file on system. %(filename)s is not a valid "
+"input."
+msgstr ""
+
+#, python-format
+msgid "Virtual machine %(name)s already exists"
+msgstr "������������ %(name)s ���������"
+
+#, python-format
+msgid "Virtual machine %(name)s does not exist"
+msgstr "������������ %(name)s ���������"
+
+#, python-format
+msgid ""
+"Unable to rename virtual machine %(name)s. The name %(new_name)s is already "
+"in use or the virtual machine is not powered off."
+msgstr ""
+
+#, python-format
+msgid "Unable to retrieve screenshot for stopped virtual machine %(name)s"
+msgstr "��������������������������������� %(name)s ���������"
+
+msgid "Remote ISO image is not supported by this server."
+msgstr "��������������������������� ISO ������������"
+
+#, python-format
+msgid "Screenshot is not supported on virtual machine %(name)s"
+msgstr ""
+
+#, python-format
+msgid "Unable to create virtual machine %(name)s. Details: %(err)s"
+msgstr "������������������������ %(name)s������������������%(err)s"
+
+#, python-format
+msgid "Unable to update virtual machine %(name)s. Details: %(err)s"
+msgstr "������������������������ %(name)s������������������%(err)s"
+
+#, python-format
+msgid "Unable to retrieve virtual machine %(name)s. Details: %(err)s"
+msgstr "������������������������ %(name)s������������������%(err)s"
+
+#, python-format
+msgid "Unable to connect to powered off virtual machine %(name)s."
+msgstr ""
+
+msgid "Virtual machine name must be a string without slashes (/)"
+msgstr ""
+
+#, python-format
+msgid "Invalid template URI %(value)s specified for virtual machine"
+msgstr ""
+
+#, python-format
+msgid "Invalid storage pool URI %(value)s specified for virtual machine"
+msgstr ""
+
+msgid "Supported virtual machine graphics are Spice or VNC"
+msgstr ""
+
+msgid "Graphics address to listen on must be IPv4 or IPv6"
+msgstr "������������������������������������ IPv4 ��� IPv6"
+
+msgid "Specify a template to create a virtual machine from"
+msgstr "���������������������������������������"
+
+#, python-format
+msgid "Unable to start virtual machine %(name)s. Details: %(err)s"
+msgstr "������������������������ %(name)s������������������%(err)s"
+
+#, python-format
+msgid "Unable to power off virtual machine %(name)s. Details: %(err)s"
+msgstr "������������������������ %(name)s������������������%(err)s"
+
+#, python-format
+msgid "Unable to delete virtual machine %(name)s. Details: %(err)s"
+msgstr "������������������������ %(name)s������������������%(err)s"
+
+#, python-format
+msgid "Unable to reset virtual machine %(name)s. Details: %(err)s"
+msgstr "������������������������������ %(name)s������������������%(err)s"
+
+msgid "User name list must be an array"
+msgstr ""
+
+msgid "User name must be a string"
+msgstr "���������������������������"
+
+msgid "Group name list must be an array"
+msgstr ""
+
+msgid "Group name must be a string"
+msgstr "���������������������������"
+
+#, python-format
+msgid "User(s) '%(users)s' do not exist"
+msgstr "��������� '%(users)s' ������������"
+
+#, python-format
+msgid "Group(s) '%(groups)s' do not exist"
+msgstr "��������� '%(groups)s' ������������"
+
+#, python-format
+msgid "Unable to shutdown virtual machine %(name)s. Details: %(err)s"
+msgstr "������������������������ %(name)s������������������%(err)s"
+
+#, python-format
+msgid ""
+"Unable to get access metadata of virtual machine %(name)s. Details: %(err)s"
+msgstr "������������������������ %(name)s������������������%(err)s"
+
+msgid "The guest console password must be a string."
+msgstr ""
+
+msgid "The life time for the guest console password must be a number."
+msgstr ""
+
+#, python-format
+msgid "Virtual machine '%(name)s' must be stopped before cloning it."
+msgstr ""
+
+#, python-format
+msgid "Insufficient disk space to clone virtual machine '%(name)s'"
+msgstr ""
+
+#, python-format
+msgid "Unable to clone VM '%(name)s'. Details: %(err)s"
+msgstr ""
+
+#, python-format
+msgid "Invalid operation for non-persistent virtual machine %(name)s"
+msgstr ""
+
+#, python-format
+msgid "Cannot suspend VM '%(name)s' because it is not running."
+msgstr ""
+
+#, python-format
+msgid "Unable to suspend VM '%(name)s'. Details: %(err)s"
+msgstr ""
+
+#, python-format
+msgid "Cannot resume VM '%(name)s' because it is not paused."
+msgstr ""
+
+#, python-format
+msgid "Unable to resume VM '%(name)s'. Details: %(err)s"
+msgstr ""
+
+msgid "Memory assigned is higher then the maximum allowed in the host."
+msgstr ""
+
+#, python-format
+msgid ""
+"VM '%(name)s' does not support live memory update. Update the memory with
"
+"the machine offline to enable this feature."
+msgstr ""
+
+msgid "Only increase memory is allowed in active VMs"
+msgstr ""
+
+msgid ""
+"For live memory update, new memory value must be equal old memory value plus
"
+"multiples of 1024 Mib"
+msgstr ""
+
+msgid "There are not enough free slots of 1024 Mib in the guest."
+msgstr ""
+
+msgid ""
+"Host's libvirt version does not support memory devices. Libvirt must be >=
"
+"1.2.14"
+msgstr ""
+
+#, python-format
+msgid "Error attaching memory device. Details: %(error)s"
+msgstr ""
+
+#, python-format
+msgid ""
+"VM %(vmid)s does not contain directly assigned host device %(dev_name)s."
+msgstr ""
+
+#, python-format
+msgid "The host device %(dev_name)s is not allowed to directly assign to VM."
+msgstr ""
+
+msgid ""
+"No IOMMU groups found. Host PCI pass through needs IOMMU group to function "
+"correctly. Please enable Intel VT-d or AMD IOMMU in your BIOS, then verify "
+"the Kernel is compiled with IOMMU support. For Intel CPU, add intel_iommu=on
"
+"to your Kernel parameter in /boot/grub2/grub.conf. For AMD CPU, add iommu=pt
"
+"iommu=1."
+msgstr ""
+
+msgid "\"name\" should be a device name string"
+msgstr ""
+
+#, python-format
+msgid ""
+"The device %(name)s is probably in use by the host. Unable to attach it to "
+"the guest."
+msgstr ""
+
+#, python-format
+msgid "Interface %(iface)s does not exist in virtual machine %(name)s"
+msgstr "������ %(iface)s ������������������������ %(name)s ���"
+
+#, python-format
+msgid ""
+"Network %(network)s specified for virtual machine %(name)s does not exist"
+msgstr "��������������� %(name)s ��������������� %(network)s ���������"
+
+msgid "Supported virtual machine interfaces type is only network"
+msgstr "���������������������������������������������������"
+
+msgid "Network name for virtual machine interface must be a string"
+msgstr "������������������������������������������������"
+
+msgid "Invalid network model card specified for virtual machine interface"
+msgstr "���������������������������������������������������"
+
+msgid "Specify type and network to add a new virtual machine interface"
+msgstr "������������������������������������������������"
+
+msgid "MAC Address must respect this format FF:FF:FF:FF:FF:FF"
+msgstr ""
+
+#, python-format
+msgid "MAC Address %(mac)s already exists in virtual machine %(name)s"
+msgstr ""
+
+msgid "Invalid MAC Address"
+msgstr ""
+
+msgid "Cannot change MAC address of a running virtual machine"
+msgstr ""
+
+#, python-format
+msgid "Template %(name)s already exists"
+msgstr "������ %(name)s ���������"
+
+#, python-format
+msgid ""
+"Network '%(network)s' specified for template %(template)s does not
exist"
+msgstr "��������� %(template)s ��������������� '%(network)s'
���������"
+
+#, python-format
+msgid ""
+"Storage pool %(pool)s specified for template %(template)s does not exist"
+msgstr "��������� %(template)s ������������������ '%(pool)s'
���������"
+
+#, python-format
+msgid "Storage pool %(pool)s specified for template %(template)s is not
active"
+msgstr "��������� %(template)s ������������������ '%(pool)s'
������������������������"
+
+#, python-format
+msgid "Invalid parameter '%(param)s' specified for CDROM."
+msgstr "��� CDROM ��������������� '%(param)s' ���������"
+
+#, python-format
+msgid "Network %(network)s specified for template %(template)s is not active"
+msgstr "��������� %(template)s ��������������� %(network)s
������������������������"
+
+msgid "Template name must be a string"
+msgstr "���������������������������"
+
+msgid "Template icon must be a path to the image"
+msgstr "������������������������������������"
+
+msgid "Template distribution must be a string"
+msgstr "���������������������������������"
+
+msgid "Template distribution version must be a string"
+msgstr "���������������������������������"
+
+msgid "The number of CPUs must be an integer greater than 0"
+msgstr "CPU ���������������������"
+
+msgid "Amount of memory (MB) must be an integer greater than 512"
+msgstr "��������������� (MB) ��������������� 512 ���������"
+
+msgid "Template CDROM must be a local or remote ISO file"
+msgstr "������ CDROM ������������������������ ISO ������"
+
+#, python-format
+msgid "Invalid storage pool URI %(value)s specified for template"
+msgstr "��������������������������� URI %(value)s ������"
+
+msgid "Specify an ISO image as CDROM or a base image to create a template"
+msgstr "������ ISO ��������������� CDROM ���������������"
+
+msgid "All networks for the template must be specified in a list."
+msgstr "���������������������������������������������������"
+
+msgid "Specify a volume to a template when storage pool is iSCSI or SCSI"
+msgstr ""
+
+#, python-format
+msgid "The volume %(volume)s is not in storage pool %(pool)s"
+msgstr ""
+
+#, python-format
+msgid "Unable to create template due error: %(err)s"
+msgstr "������������������������������������������%(err)s"
+
+#, python-format
+msgid "Unable to delete template due error: %(err)s"
+msgstr "������������������������������������������%(err)s"
+
+msgid "Disk size must be an integer greater than 1GB."
+msgstr ""
+
+msgid "Template base image must be a valid local image file"
+msgstr "������ CDROM ������������������������ ISO ������"
+
+#, python-format
+msgid "Cannot identify base image %(path)s format"
+msgstr ""
+
+msgid ""
+"When specifying CPU topology, VCPUs must be a product of sockets, cores, and
"
+"threads."
+msgstr ""
+
+msgid ""
+"When specifying CPU topology, each element must be an integer greater than "
+"zero."
+msgstr ""
+
+msgid ""
+"Invalid disk image format. Valid formats: bochs, cloop, cow, dmg, qcow, "
+"qcow2, qed, raw, vmdk, vpc."
+msgstr ""
+
+#, python-format
+msgid "Storage pool %(name)s already exists"
+msgstr "��������� %(name)s ���������"
+
+#, python-format
+msgid "Storage pool %(name)s does not exist"
+msgstr "��������� %(name)s ���������"
+
+#, python-format
+msgid "Specify %(item)s in order to create the storage pool %(name)s"
+msgstr "������ %(item)s ������������������ %(name)s"
+
+#, python-format
+msgid "Unable to delete active storage pool %(name)s"
+msgstr "��������������������������������� %(name)s"
+
+#, python-format
+msgid "Unable to list storage pools. Details: %(err)s"
+msgstr "���������������������������������������%(err)s"
+
+#, python-format
+msgid "Unable to create storage pool %(name)s. Details: %(err)s"
+msgstr "��������������������� %(name)s������������������%(err)s"
+
+#, python-format
+msgid ""
+"Unable to get number of storage volumes in storage pool %(name)s. Details: %"
+"(err)s"
+msgstr "��������������������� %(name)s
������������������������������������������%(err)s"
+
+#, python-format
+msgid "Unable to activate storage pool %(name)s. Details: %(err)s"
+msgstr "��������������������� %(name)s������������������%(err)s"
+
+#, python-format
+msgid "Unable to deactivate storage pool %(name)s. Details: %(err)s"
+msgstr "��������������������������� %(name)s������������������%(err)s"
+
+#, python-format
+msgid "Unable to delete storage pool %(name)s. Details: %(err)s"
+msgstr "��������������������� %(name)s������������������%(err)s"
+
+#, python-format
+msgid ""
+"Unable to create NFS Pool as export path %(path)s may block during mount"
+msgstr "������������ NFS ������������������������������������������������ %(path)s
���������������"
+
+#, python-format
+msgid "Unable to create NFS Pool as export path %(path)s mount failed"
+msgstr "������������ NFS ������������������������������ %(path)s ������������"
+
+#, python-format
+msgid "Unsupported storage pool type: %(type)s"
+msgstr "���������������������������������%(type)s"
+
+#, python-format
+msgid "Error while retrieving storage pool XML to %(pool)s"
+msgstr ""
+
+msgid "Storage pool name must be a string without slashes (/)"
+msgstr ""
+
+msgid ""
+"Supported storage pool types are dir, netfs, logical, iscsi, isci and
kimchi-"
+"iso"
+msgstr ""
+
+msgid "Storage pool path must be a string"
+msgstr "������������������������������"
+
+msgid "Storage pool host must be a IP or hostname"
+msgstr "������������������������ IP ���������������"
+
+msgid "Storage pool device must be the absolute path to the block device"
+msgstr ""
+
+msgid "Storage pool devices parameter must be a list"
+msgstr "������������������������������������"
+
+msgid "Target IQN of an iSCSI pool must be a string"
+msgstr "iSCSI ������������������ IQN ���������������"
+
+msgid "Port of a remote storage server must be an integer between 1 and 65535"
+msgstr "��������������������������������������������� 1 ��� 65535
���������������"
+
+msgid "iSCSI target username must be a string"
+msgstr ""
+
+msgid "iSCSI target password must be a string"
+msgstr ""
+
+msgid "Specify name and type to create a storage pool"
+msgstr "���������������������������������������"
+
+#, python-format
+msgid ""
+"%(disk)s is not a valid disk/partition. Could not add it to the pool %(pool)"
+"s."
+msgstr "%(disk)s
���������������������/������������������������������������������%(pool)s���"
+
+#, python-format
+msgid "Unable to extend logical pool %(pool)s. Details: %(err)s"
+msgstr ""
+
+msgid "The parameter disks only can be updated for logical storage pool."
+msgstr "������������������������������������������������������������"
+
+msgid "The SCSI host adapter name must be a string."
+msgstr "SCSI ���������������������������������������"
+
+msgid "The storage pool kimchi_isos is reserved for internal use"
+msgstr "��������� kimchi_isos ���������������������"
+
+#, python-format
+msgid ""
+"Unable to activate NFS storage pool %(name)s. NFS server %(server)s is "
+"unreachable."
+msgstr "������������ NFS ��������� %(name)s���NFS ���������
%(server)s���������������"
+
+#, python-format
+msgid ""
+"Unable to deactivate NFS storage pool %(name)s. NFS server %(server)s is "
+"unreachable."
+msgstr "������������������ NFS ��������� %(name)s���NFS ���������
%(server)s���������������"
+
+#, python-format
+msgid ""
+"Unable to deactivate pool %(name)s as it is associated with some templates"
+msgstr "���������������������������
%(name)s������������������������������������"
+
+#, python-format
+msgid "Unable to delete pool %(name)s as it is associated with some templates"
+msgstr "��������������������� %(name)s������������������������������������"
+
+#, python-format
+msgid ""
+"A volume group named '%(name)s' already exists. Please, choose another name
"
+"to create the logical pool."
+msgstr "������ '%(name)s'
������������������������������������������������������������������������������"
+
+#, python-format
+msgid "Unable to update database with deep scan information due error:
%(err)s"
+msgstr
"������������������������������������������������������������������������%(err)s"
+
+#, python-format
+msgid "Storage volume %(name)s already exists"
+msgstr "������������ %(name)s ���������"
+
+#, python-format
+msgid "Storage volume %(name)s does not exist in storage pool %(pool)s"
+msgstr "������������ %(name)s ��������������������� %(pool)s ���"
+
+#, python-format
+msgid ""
+"Unable to create storage volume %(volume)s because storage pool %(pool)s is "
+"not active"
+msgstr ""
+
+#, python-format
+msgid "Specify %(item)s in order to create storage volume %(volume)s"
+msgstr "������ %(item)s ��������������������� %(volume)s"
+
+#, python-format
+msgid ""
+"Unable to list storage volumes because storage pool %(pool)s is not active"
+msgstr "������������������������������������������ %(pool)s
������������������������"
+
+#, python-format
+msgid ""
+"Unable to create storage volume %(name)s in storage pool %(pool)s. Details:
%"
+"(err)s"
+msgstr "������������������ %(pool)s ���������������������
%(name)s������������������%(err)s"
+
+#, python-format
+msgid ""
+"Unable to list storage volumes in storage pool %(pool)s. Details: %(err)s"
+msgstr "��������������������� %(pool)s
������������������������������������%(err)s"
+
+#, python-format
+msgid "Unable to wipe storage volumes %(name)s. Details: %(err)s"
+msgstr "������������������������ %(name)s������������������%(err)s"
+
+#, python-format
+msgid "Unable to delete storage volume %(name)s. Details: %(err)s"
+msgstr "������������������������ %(name)s������������������%(err)s"
+
+#, python-format
+msgid "Unable to resize storage volume %(name)s. Details: %(err)s"
+msgstr "������������������������ %(name)s ���������������������������%(err)s"
+
+#, python-format
+msgid "Storage type %(type)s does not support volume create and delete"
+msgstr "��������������� %(type)s ������������������������������"
+
+msgid "Storage volume name must be a string"
+msgstr "���������������������������������"
+
+msgid "Storage volume allocation must be an integer number"
+msgstr "���������������������������������"
+
+msgid ""
+"Storage volume format not supported. Valid formats: bochs, cloop, cow, dmg, "
+"qcow, qcow2, qed, raw, vmdk, vpc."
+msgstr ""
+
+msgid "Storage volume requires a volume name"
+msgstr "������������������������������"
+
+#, python-format
+msgid ""
+"Unable to update database with storage volume information due error: %(err)s"
+msgstr
"������������������������������������������������������������������������%(err)s"
+
+#, python-format
+msgid "Only one of parameter %(param)s can be specified"
+msgstr ""
+
+#, python-format
+msgid "Create volume from %(param)s is not supported"
+msgstr ""
+
+msgid "Storage volume capacity must be an integer number."
+msgstr ""
+
+msgid "Storage volume URL must be http://, https://, ftp:// or ftps://."
+msgstr ""
+
+#, python-format
+msgid "Unable to access file %(url)s. Please, check it."
+msgstr ""
+
+#, python-format
+msgid ""
+"Unable to clone storage volume '%(name)s' in pool '%(pool)s'.
Details: %(err)"
+"s"
+msgstr ""
+
+msgid "Specify chunk data and its size to upload a file."
+msgstr ""
+
+msgid "In order to upload a storage volume, specify the 'upload'
parameter."
+msgstr ""
+
+msgid ""
+"Unable to upload chunk data as it does not match with requested chunk size."
+msgstr ""
+
+#, python-format
+msgid "The storage volume %(vol)s is not under an upload process."
+msgstr ""
+
+msgid "The upload chunk data will exceed the storage volume size."
+msgstr ""
+
+#, python-format
+msgid "Unable to upload chunk data to storage volume. Details: %(err)s."
+msgstr ""
+
+#, python-format
+msgid "Interface %(name)s does not exist"
+msgstr "������ %(name)s ���������"
+
+#, python-format
+msgid "Network %(name)s already exists"
+msgstr "������ %(name)s ���������"
+
+#, python-format
+msgid "Network %(name)s does not exist"
+msgstr "������ %(name)s ���������"
+
+#, python-format
+msgid "Subnet %(subnet)s specified for network %(network)s is not valid."
+msgstr "��������� %(network)s ������������������ %(subnet)s ���������"
+
+#, python-format
+msgid "Specify a network interface to create bridged network %(name)s"
+msgstr "������������������������������������������ %(name)s"
+
+#, python-format
+msgid "Unable to delete active network %(name)s"
+msgstr "������������������������������ %(name)s"
+
+#, python-format
+msgid "Interface %(iface)s specified for network %(network)s is already in
use"
+msgstr "��������� %(network)s ��������������� %(iface)s ���������������"
+
+msgid "Interface should be bare NIC, bonding or bridge device."
+msgstr "��������������������� NIC������������������������������������"
+
+#, python-format
+msgid "Unable to create network %(name)s. Details: %(err)s"
+msgstr "������������������ %(name)s������������������%(err)s"
+
+#, python-format
+msgid "Unable to find a free IP address for network '%(name)s'"
+msgstr "��������������� '%(name)s' ��������� IP ������"
+
+#, python-format
+msgid "The interface %(iface)s already exists."
+msgstr ""
+
+msgid "Network name must be a string without slashes (/) or quotes (\")"
+msgstr ""
+
+msgid "Supported network types are isolated, NAT and bridge"
+msgstr "���������������������������������������NAT ������������"
+
+msgid "Network subnet must be a string with IP address and prefix or netmask"
+msgstr "��������������������������������� IP
���������������������������������������"
+
+msgid "Network interface must be a string"
+msgstr "���������������������������"
+
+msgid "Network VLAN ID must be an integer between 1 and 4094"
+msgstr "������ VLAN ID ��������������� 1 ��� 4094 ���������������"
+
+msgid "Specify name and type to create a Network"
+msgstr "������������������������������������"
+
+#, python-format
+msgid ""
+"Unable to delete network %(name)s. There are some virtual machines %(vms)s "
+"and/or templates linked to this network."
+msgstr ""
+
+#, python-format
+msgid ""
+"Unable to deactivate network %(name)s. There are some virtual machines
%(vms)"
+"s and/or templates linked to this network."
+msgstr ""
+
+#, python-format
+msgid "Bridge device %(name)s can not be the trunk device of a VLAN."
+msgstr "��������������� %(name)s ��������� VLAN ������������������"
+
+#, python-format
+msgid "Failed to activate interface %(iface)s: %(err)s."
+msgstr "������������������ %(iface)s���%(err)s���"
+
+#, python-format
+msgid ""
+"Failed to activate interface %(iface)s. Please check the physical link "
+"status."
+msgstr "������������������ %(iface)s���������������������������������"
+
+#, python-format
+msgid "Failed to start network %(name)s. Details: %(err)s"
+msgstr ""
+
+#, python-format
+msgid "Debug report %(name)s does not exist"
+msgstr "������������ %(name)s ���������"
+
+msgid "Debug report tool not found in system"
+msgstr "���������������������������������������"
+
+#, python-format
+msgid "Unable to create debug report %(name)s. Details: %(err)s."
+msgstr "������������������������ %(name)s������������������%(err)s���"
+
+#, python-format
+msgid "Can not find any debug report with the given name %(name)s"
+msgstr ""
+
+#, python-format
+msgid "Unable to generate debug report %(name)s. Details: %(err)s"
+msgstr "������������������������ %(name)s������������������%(err)s"
+
+msgid "You should give a name for the debug report file."
+msgstr ""
+
+msgid ""
+"Debug report name must be a string. Only letters, digits, underscore ('_')
"
+"and hyphen ('-') are allowed."
+msgstr ""
+
+#, python-format
+msgid ""
+"The debug report with specified name \"%(name)s\" already exists. Please
use "
+"another one."
+msgstr "������ '%(name)s'
������������������������������������������������������������������������������"
+
+#, python-format
+msgid "Storage server %(server)s was not used by Kimchi"
+msgstr "Kimchi ��������������������������� %(server)s"
+
+#, python-format
+msgid "Distro '%(name)s' does not exist"
+msgstr "Distro '%(name)s' ���������"
+
+#, python-format
+msgid "Partition %(name)s does not exist in the host"
+msgstr "��������� %(name)s ���������������������"
+
+msgid "Unable to shutdown host machine as there are running virtual machines"
+msgstr "���������������������������������������������������������������"
+
+msgid "Unable to reboot host machine as there are running virtual machines"
+msgstr
"������������������������������������������������������������������������"
+
+#, python-format
+msgid "Node device '%(name)s' not found"
+msgstr "��������������������� '%(name)s'"
+
+msgid "Conflicting flag filters specified."
+msgstr ""
+
+msgid "No packages marked for update"
+msgstr "������������������������������������"
+
+#, python-format
+msgid "Package %(name)s is not marked to be updated."
+msgstr "������ %(name)s ������������������������������"
+
+#, python-format
+msgid "Error while getting packages marked to be updated. Details: %(err)s"
+msgstr
"������������������������������������������������������������������������%(err)s"
+
+msgid "There is no compatible package manager for this system."
+msgstr "���������������������������������������������"
+
+#, python-format
+msgid "Invalid URI %(uri)s"
+msgstr "URI %(uri)s ������"
+
+msgid "Unable to choose a virtual machine name"
+msgstr ""
+
+msgid "Invalid storage type. Types supported: 'cdrom', 'disk'"
+msgstr "���������������������������������������������'cdrom'"
+
+#, python-format
+msgid "The path '%(value)s' is not a valid local/remote path for the
device"
+msgstr ""
+
+msgid "Only CDROM path can be update."
+msgstr ""
+
+#, python-format
+msgid ""
+"The storage device %(dev_name)s does not exist in the virtual machine %"
+"(vm_name)s"
+msgstr ""
+
+#, python-format
+msgid "Error while creating new storage device: %(error)s"
+msgstr "������������������������������������������%(error)s"
+
+#, python-format
+msgid "Error while updating storage device: %(error)s"
+msgstr "������������������������������������%(error)s"
+
+#, python-format
+msgid "Error while removing storage device: %(error)s"
+msgstr "������������������������������������%(error)s"
+
+msgid "Do not support IDE device hot plug"
+msgstr ""
+
+msgid ""
+"Specify type and path or type and pool/volume to add a new virtual machine "
+"disk"
+msgstr "������������������������������������������������"
+
+msgid "Specify path to update virtual machine disk"
+msgstr "���������������������������������������"
+
+#, python-format
+msgid "Controller type %(type)s limitation of %(limit)s devices reached"
+msgstr ""
+
+#, python-format
+msgid "Cannot retrieve disk path information for given pool/volume: %(error)s"
+msgstr ""
+
+msgid "Volume already in use by other virtual machine."
+msgstr ""
+
+msgid ""
+"Only one of path or pool/volume can be specified to add a new virtual "
+"machine disk"
+msgstr "������������������������������������������������"
+
+#, python-format
+msgid ""
+"Volume chosen with format %(format)s does not fit in the storage type
%(type)"
+"s"
+msgstr ""
+
+msgid "YUM Repository ID must be one word only string."
+msgstr "YUM ��������� ID ���������������������������������������"
+
+msgid "Repository URL must be an http://, ftp:// or file:// URL."
+msgstr "��������� URL ��������� http://���ftp:// ��� file:// URL���"
+
+msgid ""
+"Repository configuration is a dictionary with specific values according to "
+"repository type."
+msgstr
"������������������������������������������������������������������������������"
+
+msgid "Distribution to DEB repository must be a string"
+msgstr "DEB ���������������������������������������"
+
+msgid "Components to DEB repository must be listed in a array"
+msgstr "DEB ������������������������������������������������"
+
+msgid "Components to DEB repository must be a string"
+msgstr "DEB ���������������������������������"
+
+msgid "Mirror list to repository must be a string"
+msgstr ""
+
+msgid "YUM Repository name must be string."
+msgstr "YUM ���������������������������������"
+
+msgid "GPG check must be a boolean value."
+msgstr "GPG ���������������������������"
+
+msgid "GPG key must be a URL pointing to the ASCII-armored file."
+msgstr "GPG ��������������������� ASCII ��������������� URL���"
+
+#, python-format
+msgid "Could not update repository %(repo_id)s."
+msgstr "��������������������� %(repo_id)s���"
+
+#, python-format
+msgid "Repository %(repo_id)s does not exist."
+msgstr "��������� %(repo_id)s ������������"
+
+msgid ""
+"Specify repository base URL, mirror list or metalink in order to create or "
+"update a YUM repository."
+msgstr ""
+
+msgid "Repository management tool was not recognized for your system."
+msgstr "���������������������������������������������"
+
+#, python-format
+msgid "Repository %(repo_id)s is already enabled."
+msgstr "������������������ %(repo_id)s���"
+
+#, python-format
+msgid "Repository %(repo_id)s is already disabled."
+msgstr "������������������ %(repo_id)s���"
+
+#, python-format
+msgid "Could not remove repository %(repo_id)s."
+msgstr "��������������������� %(repo_id)s���"
+
+#, python-format
+msgid "Could not write repository configuration file %(repo_file)s"
+msgstr "������������������������������ %(repo_file)s"
+
+msgid "Specify repository distribution in order to create a DEB repository."
+msgstr "������������������������������������ DEB ������������"
+
+#, python-format
+msgid "Could not enable repository %(repo_id)s."
+msgstr "��������������������� %(repo_id)s���"
+
+#, python-format
+msgid "Could not disable repository %(repo_id)s."
+msgstr "��������������������� %(repo_id)s���"
+
+msgid "YUM Repository ID already exists"
+msgstr "YUM ��������� ID ���������"
+
+msgid "YUM Repository name must be a string"
+msgstr "YUM ������������������������������"
+
+#, python-format
+msgid "Unable to list repositories. Details: '%(err)s'"
+msgstr "���������������������������������������'%(err)s'"
+
+#, python-format
+msgid "Unable to retrieve repository information. Details: '%(err)s'"
+msgstr "���������������������������������������������'%(err)s'"
+
+#, python-format
+msgid "Unable to add repository. Details: '%(err)s'"
+msgstr "���������������������������������������'%(err)s'"
+
+#, python-format
+msgid "Unable to remove repository. Details: '%(err)s'"
+msgstr "���������������������������������������'%(err)s'"
+
+#, python-format
+msgid ""
+"Configuration items: '%(items)s' are not supported by repository
manager"
+msgstr ""
+
+msgid "Repository metalink must be an http://, ftp:// or file:// URL."
+msgstr ""
+
+msgid "Cannot specify mirrorlist and metalink at the same time."
+msgstr ""
+
+#, python-format
+msgid ""
+"Virtual machine '%(vm)s' must be stopped before creating a snapshot of
it."
+msgstr ""
+
+#, python-format
+msgid ""
+"Unable to create snapshot '%(name)s' on virtual machine '%(vm)s'.
Details: %"
+"(err)s"
+msgstr ""
+
+#, python-format
+msgid "Snapshot '%(name)s' does not exist on virtual machine
'%(vm)s'."
+msgstr ""
+
+#, python-format
+msgid ""
+"Unable to retrieve snapshot '%(name)s' on virtual machine '%(vm)s'.
Details: "
+"%(err)s"
+msgstr ""
+
+#, python-format
+msgid "Unable to list snapshots on virtual machine '%(vm)s'. Details:
%(err)s"
+msgstr ""
+
+#, python-format
+msgid ""
+"Unable to delete snapshot '%(name)s' on virtual machine '%(vm)s'.
Details: %"
+"(err)s"
+msgstr ""
+
+#, python-format
+msgid ""
+"Unable to retrieve current snapshot of virtual machine '%(vm)s'. Details:
%"
+"(err)s"
+msgstr ""
+
+#, python-format
+msgid ""
+"Unable to revert virtual machine '%(vm)s' to snapshot '%(name)s'.
Details: %"
+"(err)s"
+msgstr ""
+
+#, python-format
+msgid ""
+"Unable to create snapshot of virtual machine '%(vm)s' because it contains a
"
+"disk with format '%(format)s'; only 'qcow2' is supported."
+msgstr ""
+
+msgid "The number of vCPUs is too large for this system."
+msgstr ""
+
+msgid "Invalid vCPU/topology combination."
+msgstr ""
+
+msgid "This host (or current configuration) does not allow CPU topology."
+msgstr ""
+
+msgid "ERROR CODE"
+msgstr "���������"
+
+msgid "REASON"
+msgstr "������"
+
+msgid "STACK"
+msgstr "������"
+
+msgid "Go to Homepage"
+msgstr "������������"
+
+msgid "Create a New Virtual Machine"
+msgstr "������������������������"
+
+msgid "Virtual Machine Name"
+msgstr "������������������"
+
+msgid ""
+"The name used to identify the virtual machine. If omitted, a name will be "
+"chosen based on the template used."
+msgstr
"���������������������������������������������������������������������������������������������"
+
+msgid "Template"
+msgstr "������"
+
+msgid "Please create a template first."
+msgstr "���������������������"
+
+msgid "Create a Template"
+msgstr "������������"
+
+msgid "Please choose a template."
+msgstr "������������������"
+
+msgid "OS"
+msgstr "OS"
+
+msgid "OS Version"
+msgstr "OS ������"
+
+msgid "CPUS"
+msgstr "CPUS"
+
+msgid "Memory"
+msgstr "���������"
+
+msgid "Create"
+msgstr "������"
+
+msgid "Creating..."
+msgstr ""
+
+msgid "Cancel"
+msgstr "������ "
+
+msgid "Edit Guest"
+msgstr "������������"
+
+msgid "General"
+msgstr "������"
+
+msgid "Storage"
+msgstr "���������"
+
+msgid "Interface"
+msgstr "������"
+
+msgid "Permission"
+msgstr "������"
+
+msgid "Host PCI Device"
+msgstr ""
+
+msgid "Snapshot"
+msgstr ""
+
+msgid "Name"
+msgstr "������"
+
+msgid "CPUs"
+msgstr "CPU"
+
+msgid "Memory (MB)"
+msgstr "���������"
+
+msgid "Icon"
+msgstr "������"
+
+msgid "Device"
+msgstr "������������"
+
+msgid "Path"
+msgstr "NFS ������"
+
+msgid "Network"
+msgstr "������"
+
+msgid "Type"
+msgstr "������"
+
+msgid "MAC Address"
+msgstr ""
+
+msgid "Available system users and groups"
+msgstr ""
+
+msgid "Selected system users and groups"
+msgstr ""
+
+msgid "User"
+msgstr ""
+
+msgid "All"
+msgstr "������"
+
+msgid "To Add"
+msgstr ""
+
+msgid "Added"
+msgstr ""
+
+msgid "filter"
+msgstr ""
+
+msgid "Product"
+msgstr ""
+
+msgid "Vendor"
+msgstr "���������"
+
+msgid "Created"
+msgstr ""
+
+msgid "Save"
+msgstr "������"
+
+msgid "Replace"
+msgstr "������"
+
+msgid "Detach"
+msgstr "������"
+
+msgid "revert"
+msgstr ""
+
+msgid "Start"
+msgstr "������"
+
+msgid "Reset"
+msgstr "������"
+
+msgid "Pause"
+msgstr ""
+
+msgid "Resume"
+msgstr ""
+
+msgid "Power Off"
+msgstr ""
+
+msgid "Actions"
+msgstr "������"
+
+msgid "Connect"
+msgstr "������"
+
+msgid "Clone"
+msgstr ""
+
+msgid "Edit"
+msgstr "������"
+
+msgid "Shut Down"
+msgstr "������"
+
+msgid "Delete"
+msgstr "������"
+
+msgid "CPU"
+msgstr "CPU"
+
+msgid "Disk I/O"
+msgstr "������ I/O"
+
+msgid "Network I/O"
+msgstr "������ I/O"
+
+msgid "Livetile"
+msgstr "Livetile"
+
+msgid "No guests found."
+msgstr "������������������"
+
+msgid "Add a Storage Device to VM"
+msgstr "������������������������ VM"
+
+msgid "Device Type"
+msgstr "������������"
+
+msgid "The device type. Currently, \"cdrom\" and \"disk\" are
supported."
+msgstr "������������������������������ \"cdrom\"���"
+
+msgid "Storage Pool"
+msgstr "���������"
+
+msgid "Storage pool which volume located in"
+msgstr "������������������������������"
+
+msgid "Storage Volume"
+msgstr "���������������"
+
+msgid "Storage volume to be attached"
+msgstr "���������������������������������"
+
+msgid "File Path"
+msgstr "������������"
+
+msgid "The ISO file path in the server for CDROM."
+msgstr "CDROM ��� ISO ������������������������������"
+
+msgid "Attach"
+msgstr "������"
+
+msgid "Shut down"
+msgstr "������"
+
+msgid "Restart"
+msgstr "������������"
+
+msgid "Basic Information"
+msgstr "������������"
+
+msgid "OS Distro"
+msgstr "OS Distro"
+
+msgid "OS Code Name"
+msgstr "OS ���������������"
+
+msgid "Processor"
+msgstr "���������"
+
+msgid "CPU(s)"
+msgstr ""
+
+msgid "System Statistics"
+msgstr "������������������"
+
+msgid "Software Updates"
+msgstr "������������"
+
+msgid "Update Progress"
+msgstr "������������"
+
+msgid "Repositories"
+msgstr "���������"
+
+msgid "Debug Reports"
+msgstr "������������"
+
+msgid "The username or password you entered is incorrect. Please try again."
+msgstr "������������������������������������������������������������"
+
+msgid "This field is required."
+msgstr "������������������������"
+
+msgid "Log in"
+msgstr "������"
+
+msgid "Logging in..."
+msgstr "������������..."
+
+msgid "Host"
+msgstr "������"
+
+msgid "Guests"
+msgstr "������"
+
+msgid "Templates"
+msgstr "������"
+
+msgid "Failed to get application configuration"
+msgstr "������������������������������"
+
+msgid "This is not a valid Linux path"
+msgstr "��������������� Linux ������"
+
+msgid "This is not a valid URL."
+msgstr "��������������� URL���"
+
+msgid "No such data available."
+msgstr "���������������������������"
+
+msgid ""
+"Can not contact the host system. Verify the host system is up and that you "
+"have network connectivity to it. HTTP request response %1. "
+msgstr ""
+"������������������������������������������������������������������������������������������������������������HTTP
"
+"��������������� %1���"
+
+msgid "Unable to read file."
+msgstr ""
+
+msgid "Error while uploading file."
+msgstr ""
+
+msgid "Delete Confirmation"
+msgstr "������������"
+
+msgid "OK"
+msgstr "������"
+
+msgid "Confirm"
+msgstr "������"
+
+msgid "Warning"
+msgstr "������"
+
+msgid "Cloning..."
+msgstr ""
+
+msgid "Loading..."
+msgstr "������������..."
+
+msgid "An error occurred while retrieving system information."
+msgstr ""
+
+msgid "Retry"
+msgstr "������"
+
+msgid "Detailed message:"
+msgstr "������������������"
+
+msgid "No ISO found"
+msgstr ""
+
+msgid "This is not a valid ISO file."
+msgstr "��������������� ISO ���������"
+
+msgid "This may take a long time. Do you want to continue?"
+msgstr "������������������������������������������"
+
+msgid "This will permanently delete the template. Would you like to continue?"
+msgstr "���������������������������������������������������"
+
+msgid "Unable to shut down system as there are some virtual machines running!"
+msgstr "������������������������������������������������������������������"
+
+msgid "Max:"
+msgstr "���������"
+
+msgid "Utilization"
+msgstr "���������"
+
+msgid "Available"
+msgstr "������"
+
+msgid "Read Rate"
+msgstr "������������"
+
+msgid "Write Rate"
+msgstr "������������"
+
+msgid "Received"
+msgstr "���������"
+
+msgid "Sent"
+msgstr "���������"
+
+msgid ""
+"Shutting down or restarting host will cause unsaved work lost. Continue to "
+"shut down/restarting?"
+msgstr
"������������������������������������������������������������������������������/������������������"
+
+msgid ""
+"Repository will be removed permanently and can't be recovered. Do you want
"
+"to continue?"
+msgstr "������������������������������������������������������������������"
+
+msgid "ID"
+msgstr "ID"
+
+msgid "Base URL"
+msgstr "������ URL"
+
+msgid "Is Mirror"
+msgstr "���������"
+
+msgid "URL Args"
+msgstr "URL ������"
+
+msgid "Enabled"
+msgstr "���������"
+
+msgid "GPG Check"
+msgstr "GPG ������"
+
+msgid "GPG Key"
+msgstr "GPG ������"
+
+msgid "Add"
+msgstr "������"
+
+msgid "Remove"
+msgstr "������"
+
+msgid "Enable"
+msgstr "������"
+
+msgid "Disable"
+msgstr "������"
+
+msgid "Package Name"
+msgstr "������������"
+
+msgid "Version"
+msgstr "������"
+
+msgid "Architecture"
+msgstr "������"
+
+msgid "Repository"
+msgstr "���������"
+
+msgid "Update All"
+msgstr "������������"
+
+msgid "Updating..."
+msgstr "������������..."
+
+msgid "Failed to retrieve packages update information."
+msgstr ""
+
+msgid "Failed to update package(s)."
+msgstr "���������������������"
+
+msgid ""
+"Debug report will be removed permanently and can't be recovered. Do you want
"
+"to continue?"
+msgstr "���������������������������������������������������������������������"
+
+msgid "Generated Time"
+msgstr "������������"
+
+msgid "Generate"
+msgstr "������"
+
+msgid "Generating..."
+msgstr "������������..."
+
+msgid "Rename"
+msgstr "������������"
+
+msgid "Download"
+msgstr "������"
+
+msgid ""
+"Report name should contain only letters, digits, underscore ('_') and/or
"
+"hyphen ('-')."
+msgstr "���������������������������������������������/������������
('-')���"
+
+msgid "Pending..."
+msgstr "������������..."
+
+msgid "Report name is the same as the original one."
+msgstr ""
+
+msgid ""
+"This will delete the virtual machine and its virtual disks. This operation "
+"cannot be undone. Would you like to continue?"
+msgstr
"���������������������������������������������������������������������������������������������"
+
+msgid "Power off Confirmation"
+msgstr "������������"
+
+msgid ""
+"This action may produce undesirable results, for example unflushed disk "
+"cache in the guest. Would you like to continue?"
+msgstr ""
+
+msgid "Reset Confirmation"
+msgstr "������������"
+
+msgid ""
+"There is a risk of data loss caused by reset without the guest OS shutdown. "
+"Would you like to continue?"
+msgstr ""
+
+msgid "Shut Down Confirmation"
+msgstr "������������"
+
+msgid "Note the guest OS may ignore this request. Would you like to continue?"
+msgstr "���������������������������������������������������"
+
+msgid "Virtual Machine delete Confirmation"
+msgstr ""
+
+msgid ""
+"This virtual machine is not persistent. Power Off will delete it. Continue?"
+msgstr ""
+
+msgid ""
+"When the target guest has SCSI or iSCSI volumes, they will be cloned on "
+"default storage pool. The same will happen when the target pool does not "
+"have enough space to clone the volumes. Do you want to continue?"
+msgstr ""
+
+msgid ""
+"This CDROM will be detached permanently and you can re-attach it. Continue "
+"to detach it?"
+msgstr ""
+"������������������������
CDROM��������������������������������������������������������� CDROM ������"
+
+msgid "Attaching..."
+msgstr "������������..."
+
+msgid "Replacing..."
+msgstr "������������..."
+
+msgid "Successfully attached!"
+msgstr "������������������"
+
+msgid "Successfully replaced!"
+msgstr "������������������"
+
+msgid "Successfully detached!"
+msgstr "������������������"
+
+msgid ""
+"This disk will be detached permanently and you can re-attach it. Continue to
"
+"detach it?"
+msgstr ""
+
+msgid "interface:"
+msgstr ""
+
+msgid "address:"
+msgstr ""
+
+msgid "link_type:"
+msgstr ""
+
+msgid "block:"
+msgstr ""
+
+msgid "drive_type:"
+msgstr ""
+
+msgid "model:"
+msgstr ""
+
+msgid "Affected devices:"
+msgstr ""
+
+msgid "The VLAN id must be between 1 and 4094."
+msgstr "VLAN ID ������������ 1 ��� 4094 ���������"
+
+msgid "unavailable"
+msgstr "������������"
+
+msgid ""
+"This action will interrupt network connectivity for any virtual machine that
"
+"depend on this network."
+msgstr
"������������������������������������������������������������������������������������"
+
+msgid "Create a network"
+msgstr "������������"
+
+msgid ""
+"This network is not persistent. Instead of stop, this action will "
+"permanently delete it. Would you like to continue?"
+msgstr ""
+"������������������������������������������������������������������������������������������������������������������"
+"������"
+
+msgid ""
+"The bridged VLAN tag may not work well with NetworkManager enabled. You "
+"should consider disabling it."
+msgstr ""
+
+msgid ""
+"This will permanently delete the storage pool. Would you like to continue?"
+msgstr "������������������������������������������������������"
+
+msgid "This storage pool is empty."
+msgstr "������������������������"
+
+msgid ""
+"It will format your disk and you will loose any data in there, are you sure "
+"to continue? "
+msgstr
"������������������������������������������������������������������������������������������������������"
+
+msgid "SCSI Fibre Channel"
+msgstr "SCSI ������������"
+
+msgid "No SCSI adapters found."
+msgstr "��������� SCSI ������������"
+
+msgid "Loading iSCSI targets..."
+msgstr ""
+
+msgid "No iSCSI found. Please input one."
+msgstr ""
+
+msgid "Failed to load iSCSI targets."
+msgstr ""
+
+msgid "The storage pool name can not be blank."
+msgstr "������������������������������"
+
+msgid "The storage pool path can not be blank."
+msgstr "������������������������������"
+
+msgid "NFS server mount path can not be blank."
+msgstr "NFS ������������������������������������"
+
+msgid "Invalid NFS mount path."
+msgstr "NFS ���������������������"
+
+msgid "No logical device selected."
+msgstr "������������������������"
+
+msgid "The iSCSI target can not be blank."
+msgstr "iSCSI ���������������������"
+
+msgid "Server name can not be blank."
+msgstr "������������������������������"
+
+msgid "This is not a valid Server Name or IP. Please, modify it."
+msgstr ""
+
+msgid "Looking for available partitions ..."
+msgstr "������������������������������ ..."
+
+msgid "No available partitions found."
+msgstr "������������������������������"
+
+msgid ""
+"This storage pool is not persistent. Instead of deactivate, this action will
"
+"permanently delete it. Would you like to continue?"
+msgstr ""
+"������������������������������������������������������������������������������������������������������������������"
+"������"
+
+msgid "Unable to retrieve partitions information."
+msgstr "���������������������������������������������'%(err)s'"
+
+msgid "In progress..."
+msgstr ""
+
+msgid "Failed!"
+msgstr ""
+
+msgid "CDROM path needs to be a valid local/remote path and cannot be blank."
+msgstr ""
+
+msgid "Disk pool or volume cannot be blank."
+msgstr "������������������������������"
+
+msgid "Filter"
+msgstr ""
+
+msgid "Network Name"
+msgstr "������������"
+
+msgid "State"
+msgstr "������"
+
+msgid "Network Type"
+msgstr "������������"
+
+msgid "Address Space"
+msgstr "������������"
+
+msgid "Name should not contain '/' and '\"'."
+msgstr "������������������������������������������ '/'���"
+
+msgid "Isolated: no external network connection"
+msgstr "������������������������������������"
+
+msgid "NAT: outbound physical network connection only"
+msgstr "NAT���������������������������������"
+
+msgid "Bridged: Virtual machines are connected to physical network directly"
+msgstr "������������������������������������������������������"
+
+msgid "(No interfaces found)"
+msgstr ""
+
+msgid "Destination"
+msgstr "������������"
+
+msgid "Enable VLAN"
+msgstr "������ VLAN���"
+
+msgid "VLAN ID"
+msgstr "VLAN ID���"
+
+msgid "Stop"
+msgstr "������"
+
+msgid "Generate a New Debug Report"
+msgstr "������������������������"
+
+msgid "Report Name"
+msgstr "������������"
+
+msgid ""
+"The name used to identify the report. If omitted, a name will be chosen "
+"based on current time. Name can contain: letters, digits, underscore
(\"_\") "
+"and hyphen (\"-\")."
+msgstr ""
+"������������������������������������������������������������������������������������������������������������������"
+"������������������ (\"-\")���"
+
+msgid "Rename a Debug Report"
+msgstr "������������������������"
+
+msgid ""
+"The name used to identify the report. Name can contain: letters, digits and "
+"hyphen (\"-\")."
+msgstr ""
+"������������������������������������������������������������������������������������������������������������������"
+"������������������ (\"-\")���"
+
+msgid "Submit"
+msgstr ""
+
+msgid "Add a Repository"
+msgstr "���������������"
+
+msgid "Identifier"
+msgstr "ID"
+
+msgid "Single word, unique identifier for the repository."
+msgstr "��������������������������� ID���"
+
+msgid "Textual name for the repository."
+msgstr "���������������������������"
+
+msgid "URL"
+msgstr "URL"
+
+msgid "Required Field"
+msgstr "������������"
+
+msgid "URL to the repository. Supported protocols are http, ftp, and file."
+msgstr "������������ URL��������������������������������� http���ftp ���
file���"
+
+msgid "Repository is a mirror"
+msgstr "���������������������"
+
+msgid "Distribution"
+msgstr "������������"
+
+msgid "Distribution of the DEB repository."
+msgstr "DEB ���������������������������"
+
+msgid "Components"
+msgstr "������"
+
+msgid "List of components in DEB repository."
+msgstr "DEB ������������������������������"
+
+msgid "Edit Repository"
+msgstr "���������������"
+
+msgid "Mirror List URL"
+msgstr "������������ URL"
+
+msgid "Yes"
+msgstr "���"
+
+msgid "No"
+msgstr "���"
+
+msgid "Capacity"
+msgstr "������"
+
+msgid "Allocated"
+msgstr "���������"
+
+msgid "Location"
+msgstr "������"
+
+msgid "Device path"
+msgstr "������������"
+
+msgid "active"
+msgstr "���������"
+
+msgid "inactive"
+msgstr "������������"
+
+msgid "Deactivate"
+msgstr "������������"
+
+msgid "Activate"
+msgstr "������"
+
+msgid "Add Volume"
+msgstr ""
+
+msgid "Extend"
+msgstr ""
+
+msgid "Undefine"
+msgstr "������������"
+
+msgid "Format"
+msgstr "���������"
+
+msgid "Allocation"
+msgstr "���������"
+
+msgid "Define a New Storage Pool"
+msgstr "���������������������"
+
+msgid "Storage Pool Name"
+msgstr "���������������"
+
+msgid ""
+"The name used to identify the storage pools, and it should not be empty."
+msgstr "������������������������������������������������������"
+
+msgid "Storage Pool Type"
+msgstr "���������������"
+
+msgid "Storage Path"
+msgstr "���������������"
+
+msgid ""
+"The path of the Storage Pool. Each Storage Pool must have a unique path."
+msgstr
"���������������������������������������������������������������������������"
+
+msgid ""
+"Kimchi will try to create the directory when it does not already exist in "
+"your system."
+msgstr "Kimchi
������������������������������������������������������������������������"
+
+msgid "NFS Server IP"
+msgstr "NFS ��������� IP"
+
+msgid "NFS server IP or hostname. It can be input or chosen from history."
+msgstr "NFS ��������� IP
���������������������������������������������������������������������"
+
+msgid "NFS Path"
+msgstr "NFS ������"
+
+msgid "The NFS exported path on NFS server."
+msgstr "NFS ������������ NFS ������������������"
+
+msgid "iSCSI Server"
+msgstr "iSCSI ���������"
+
+msgid "Server"
+msgstr "���������"
+
+msgid "Port"
+msgstr "���"
+
+msgid "iSCSI server IP or hostname. It should not be empty."
+msgstr "iSCSI ��������� IP ������������������������������������������"
+
+msgid "Target"
+msgstr "������"
+
+msgid "The iSCSI target on iSCSI server"
+msgstr "iSCSI ��������������� iSCSI ������"
+
+msgid "Add iSCSI Authentication"
+msgstr "������ iSCSI ������"
+
+msgid "iSCSI Authentication"
+msgstr "iSCSI ������"
+
+msgid "User Name"
+msgstr "���������������"
+
+msgid "Password"
+msgstr "������"
+
+msgid "SCSI Adapter"
+msgstr "SCSI ���������"
+
+msgid "Please, wait..."
+msgstr "���������..."
+
+msgid "Add a Volume to Storage Pool"
+msgstr ""
+
+msgid "Fetch from remote URL"
+msgstr ""
+
+msgid "Enter the remote URL here."
+msgstr ""
+
+msgid "Upload a file"
+msgstr ""
+
+msgid "Choose the file you want to upload."
+msgstr ""
+
+msgid "Add Template"
+msgstr "������������"
+
+msgid "Where is the source media for this template? "
+msgstr "���������������������������������������"
+
+msgid "Local ISO Image"
+msgstr "������ ISO ���������"
+
+msgid "Local Image File"
+msgstr ""
+
+msgid "Remote ISO Image"
+msgstr "������ ISO ���������"
+
+msgid "Search ISOs"
+msgstr "������ ISO"
+
+msgid "The following ISOs are available:"
+msgstr "������ ISO ���������"
+
+msgid "OS: "
+msgstr "OS���"
+
+msgid "Version: "
+msgstr "���������"
+
+msgid "Size: "
+msgstr "���������"
+
+msgid "Search more ISOs"
+msgstr "������������ ISO"
+
+msgid "Create Templates from Selected ISO"
+msgstr "��������� ISO ������������"
+
+msgid "I want to use a specific ISO file"
+msgstr "��������������������� ISO ������"
+
+msgid "Loading default remote ISOs ..."
+msgstr "������������������������ ISO ..."
+
+msgid "Arch: "
+msgstr "���������"
+
+msgid "I want to use a custom URL"
+msgstr "������������������ URL"
+
+msgid "Edit Template"
+msgstr "������������"
+
+msgid "CDROM"
+msgstr "CDROM"
+
+msgid "Image File"
+msgstr ""
+
+msgid "Graphics"
+msgstr "���������"
+
+msgid "Disk(GB)"
+msgstr ""
+
+msgid "Disk Format"
+msgstr ""
+
+msgid "CPU Number"
+msgstr "CPU ������"
+
+msgid "Manually set CPU topology"
+msgstr ""
+
+msgid "Cores"
+msgstr ""
+
+msgid "Threads"
+msgstr ""
+
+msgid "No templates found."
+msgstr "������������������"
+
+#~ msgid "Delete is not allowed for %(resource)s"
+#~ msgstr "��������������� %(resource)s ������������"
+
+#~ msgid "%(resource)s does not implement update method"
+#~ msgstr "%(resource)s ���������������������"
+
+#~ msgid "Create is not allowed for %(resource)s"
+#~ msgstr "��������������� %(resource)s ������������"
+
+#~ msgid "Unable to parse JSON request"
+#~ msgstr "������������ JSON ������"
+
+#~ msgid "This API only supports JSON"
+#~ msgstr "��� API ��������� JSON"
+
+#~ msgid "Datastore is not initiated in the model object."
+#~ msgstr "���������������������������������������������"
+
+#~ msgid "Unable to start task due error: %(err)s"
+#~ msgstr "������������������������������������������%(err)s"
+
+#~ msgid ""
+#~ "Authentication failed for user '%(username)s'. [Error code:
%(code)s]"
+#~ msgstr "��������� '%(username)s'
������������������[������������%(code)s]"
+
+#~ msgid "You are not authorized to access Kimchi"
+#~ msgstr "������������������������ Kimchi"
+
+#~ msgid "Specify %(item)s to login into Kimchi"
+#~ msgstr "������ %(item)s ��������� Kimchi"
+
+#~ msgid "Unable to find %(item)s in datastore"
+#~ msgstr "������������������������������ %(item)s"
+
+#~ msgid "Timeout while running command '%(cmd)s' after %(seconds)s
seconds"
+#~ msgstr "������������ '%(cmd)s' %(seconds)s ���������������"
+
+#~ msgid "Help"
+#~ msgstr "������"
+
+#~ msgid "About"
+#~ msgstr "������"
+
+#~ msgid "Log out"
+#~ msgstr "������"
+
+#~ msgid "Version:"
+#~ msgstr "���������"
diff --git a/src/wok/plugins/kimchi/repositories.py
b/src/wok/plugins/kimchi/repositories.py
new file mode 100644
index 0000000..9caabc4
--- /dev/null
+++ b/src/wok/plugins/kimchi/repositories.py
@@ -0,0 +1,529 @@
+#
+# Project Kimchi
+#
+# Copyright IBM, Corp. 2014-2015
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+import copy
+import os
+import time
+import urlparse
+from ConfigParser import ConfigParser
+
+from wok.basemodel import Singleton
+from wok.exception import InvalidOperation, InvalidParameter
+from wok.exception import OperationFailed, NotFoundError, MissingParameter
+from wok.utils import validate_repo_url
+
+from config import kimchiLock
+from yumparser import get_yum_repositories, write_repo_to_file
+
+
+class Repositories(object):
+ __metaclass__ = Singleton
+
+ """
+ Class to represent and operate with repositories information.
+ """
+ def __init__(self):
+ try:
+ __import__('yum')
+ self._pkg_mnger = YumRepo()
+ except ImportError:
+ try:
+ __import__('apt_pkg')
+ self._pkg_mnger = AptRepo()
+ except ImportError:
+ raise InvalidOperation('KCHREPOS0014E')
+
+ def addRepository(self, params):
+ """
+ Add and enable a new repository
+ """
+ config = params.get('config', {})
+ extra_keys = list(
+ set(config.keys()).difference(set(self._pkg_mnger.CONFIG_ENTRY)))
+ if len(extra_keys) > 0:
+ raise InvalidParameter("KCHREPOS0028E",
+ {'items': ",".join(extra_keys)})
+
+ return self._pkg_mnger.addRepo(params)
+
+ def getRepositories(self):
+ """
+ Return a dictionary with all Kimchi's repositories. Each element uses
+ the format {<repo_id>: {repo}}, where repo is a dictionary in the
+ repositories.Repositories() format.
+ """
+ return self._pkg_mnger.getRepositoriesList()
+
+ def getRepository(self, repo_id):
+ """
+ Return a dictionary with all info from a given repository ID.
+ """
+ info = self._pkg_mnger.getRepo(repo_id)
+ info['repo_id'] = repo_id
+ return info
+
+ def enableRepository(self, repo_id):
+ """
+ Enable a repository.
+ """
+ return self._pkg_mnger.toggleRepo(repo_id, True)
+
+ def disableRepository(self, repo_id):
+ """
+ Disable a given repository.
+ """
+ return self._pkg_mnger.toggleRepo(repo_id, False)
+
+ def updateRepository(self, repo_id, params):
+ """
+ Update the information of a given repository.
+ The input is the repo_id of the repository to be updated and a dict
+ with the information to be updated.
+ """
+ return self._pkg_mnger.updateRepo(repo_id, params)
+
+ def removeRepository(self, repo_id):
+ """
+ Remove a given repository
+ """
+ return self._pkg_mnger.removeRepo(repo_id)
+
+
+class YumRepo(object):
+ """
+ Class to represent and operate with YUM repositories.
+ It's loaded only on those systems listed at YUM_DISTROS and loads necessary
+ modules in runtime.
+ """
+ TYPE = 'yum'
+ DEFAULT_CONF_DIR = "/etc/yum.repos.d"
+ CONFIG_ENTRY = ('repo_name', 'mirrorlist', 'metalink')
+
+ def __init__(self):
+ self._confdir = self.DEFAULT_CONF_DIR
+
+ def _get_repos(self, errcode):
+ try:
+ kimchiLock.acquire()
+ repos = get_yum_repositories()
+ except Exception, e:
+ kimchiLock.release()
+ raise OperationFailed(errcode, {'err': str(e)})
+ finally:
+ kimchiLock.release()
+
+ return repos
+
+ def getRepositoriesList(self):
+ """
+ Return a list of repositories IDs
+ """
+ repos = self._get_repos('KCHREPOS0024E')
+ return repos.keys()
+
+ def getRepo(self, repo_id):
+ """
+ Return a dictionary in the repositories.Repositories() of the given
+ repository ID format with the information of a YumRepository object.
+ """
+ repos = self._get_repos('KCHREPOS0025E')
+
+ if repo_id not in repos.keys():
+ raise NotFoundError("KCHREPOS0012E", {'repo_id': repo_id})
+
+ entry = repos.get(repo_id)
+
+ info = {}
+ info['enabled'] = entry.enabled
+ info['baseurl'] = entry.baseurl or ''
+ info['config'] = {}
+ info['config']['repo_name'] = entry.name or ''
+ info['config']['gpgcheck'] = entry.gpgcheck
+ info['config']['gpgkey'] = entry.gpgkey or ''
+ info['config']['mirrorlist'] = entry.mirrorlist or ''
+ info['config']['metalink'] = entry.metalink or ''
+ return info
+
+ def addRepo(self, params):
+ """
+ Add a given repository to YumBase
+ """
+ # At least one base url, or one mirror, must be given.
+ baseurl = params.get('baseurl', '')
+
+ config = params.get('config', {})
+ mirrorlist = config.get('mirrorlist', '')
+ metalink = config.get('metalink', '')
+ if not baseurl and not mirrorlist and not metalink:
+ raise MissingParameter("KCHREPOS0013E")
+
+ if baseurl:
+ validate_repo_url(baseurl)
+
+ if mirrorlist:
+ validate_repo_url(mirrorlist)
+
+ if metalink:
+ validate_repo_url(metalink)
+
+ if mirrorlist and metalink:
+ raise InvalidOperation('KCHREPOS0030E')
+
+ repo_id = params.get('repo_id', None)
+ if repo_id is None:
+ repo_id = "kimchi_repo_%s" % str(int(time.time() * 1000))
+
+ repos = self._get_repos('KCHREPOS0026E')
+ if repo_id in repos.keys():
+ raise InvalidOperation("KCHREPOS0022E", {'repo_id':
repo_id})
+
+ repo_name = config.get('repo_name', repo_id)
+ repo = {'baseurl': baseurl, 'mirrorlist': mirrorlist,
+ 'name': repo_name, 'gpgcheck': 1,
+ 'gpgkey': [], 'enabled': 1, 'metalink':
metalink}
+
+ # write a repo file in the system with repo{} information.
+ parser = ConfigParser()
+ parser.add_section(repo_id)
+
+ for key, value in repo.iteritems():
+ if value:
+ parser.set(repo_id, key, value)
+
+ repofile = os.path.join(self._confdir, repo_id + '.repo')
+ try:
+ with open(repofile, 'w') as fd:
+ parser.write(fd)
+ except:
+ raise OperationFailed("KCHREPOS0018E",
+ {'repo_file': repofile})
+
+ return repo_id
+
+ def toggleRepo(self, repo_id, enable):
+ repos = self._get_repos('KCHREPOS0011E')
+ if repo_id not in repos.keys():
+ raise NotFoundError("KCHREPOS0012E", {'repo_id': repo_id})
+
+ entry = repos.get(repo_id)
+ if enable and entry.enabled:
+ raise InvalidOperation("KCHREPOS0015E", {'repo_id':
repo_id})
+
+ if not enable and not entry.enabled:
+ raise InvalidOperation("KCHREPOS0016E", {'repo_id':
repo_id})
+
+ kimchiLock.acquire()
+ try:
+ if enable:
+ entry.enable()
+ else:
+ entry.disable()
+
+ write_repo_to_file(entry)
+ except:
+ if enable:
+ raise OperationFailed("KCHREPOS0020E", {'repo_id':
repo_id})
+
+ raise OperationFailed("KCHREPOS0021E", {'repo_id':
repo_id})
+ finally:
+ kimchiLock.release()
+
+ return repo_id
+
+ def updateRepo(self, repo_id, params):
+ """
+ Update a given repository in repositories.Repositories() format
+ """
+ repos = self._get_repos('KCHREPOS0011E')
+ if repo_id not in repos.keys():
+ raise NotFoundError("KCHREPOS0012E", {'repo_id': repo_id})
+
+ entry = repos.get(repo_id)
+
+ baseurl = params.get('baseurl', None)
+ config = params.get('config', {})
+ mirrorlist = config.get('mirrorlist', None)
+ metalink = config.get('metalink', None)
+
+ if baseurl is not None and len(baseurl.strip()) == 0:
+ baseurl = None
+
+ if mirrorlist is not None and len(mirrorlist.strip()) == 0:
+ mirrorlist = None
+
+ if metalink is not None and len(metalink.strip()) == 0:
+ metalink = None
+
+ if baseurl is None and mirrorlist is None and metalink is None:
+ raise MissingParameter("KCHREPOS0013E")
+
+ if baseurl is not None:
+ validate_repo_url(baseurl)
+ entry.baseurl = baseurl
+
+ if mirrorlist is not None:
+ validate_repo_url(mirrorlist)
+ entry.mirrorlist = mirrorlist
+
+ if metalink is not None:
+ validate_repo_url(metalink)
+ entry.metalink = metalink
+
+ if mirrorlist and metalink:
+ raise InvalidOperation('KCHREPOS0030E')
+
+ entry.id = params.get('repo_id', repo_id)
+ entry.name = config.get('repo_name', entry.name)
+ entry.gpgcheck = config.get('gpgcheck', entry.gpgcheck)
+ entry.gpgkey = config.get('gpgkey', entry.gpgkey)
+ kimchiLock.acquire()
+ write_repo_to_file(entry)
+ kimchiLock.release()
+ return repo_id
+
+ def removeRepo(self, repo_id):
+ """
+ Remove a given repository
+ """
+ repos = self._get_repos('KCHREPOS0027E')
+ if repo_id not in repos.keys():
+ raise NotFoundError("KCHREPOS0012E", {'repo_id': repo_id})
+
+ entry = repos.get(repo_id)
+ parser = ConfigParser()
+ with open(entry.repofile) as fd:
+ parser.readfp(fd)
+
+ if len(parser.sections()) == 1:
+ os.remove(entry.repofile)
+ return
+
+ parser.remove_section(repo_id)
+ with open(entry.repofile, "w") as fd:
+ parser.write(fd)
+
+
+class AptRepo(object):
+ """
+ Class to represent and operate with YUM repositories.
+ It's loaded only on those systems listed at YUM_DISTROS and loads necessary
+ modules in runtime.
+ """
+ TYPE = 'deb'
+ KIMCHI_LIST = "kimchi-source.list"
+ CONFIG_ENTRY = ('dist', 'comps')
+
+ def __init__(self):
+ getattr(__import__('apt_pkg'), 'init_config')()
+ getattr(__import__('apt_pkg'), 'init_system')()
+ config = getattr(__import__('apt_pkg'), 'config')
+ self.pkg_lock = getattr(__import__('apt_pkg'), 'SystemLock')
+ module = __import__('aptsources.sourceslist', globals(), locals(),
+ ['SourcesList'], -1)
+
+ self._sourceparts_path = '/%s%s' % (
+ config.get('Dir::Etc'), config.get('Dir::Etc::sourceparts'))
+ self._sourceslist = getattr(module, 'SourcesList')
+ self.filename = os.path.join(self._sourceparts_path, self.KIMCHI_LIST)
+ if not os.path.exists(self.filename):
+ with open(self.filename, 'w') as fd:
+ fd.write("# This file is managed by Kimchi and it must not "
+ "be modified manually\n")
+
+ def _get_repos(self):
+ try:
+ with self.pkg_lock():
+ repos = self._sourceslist()
+ repos.refresh()
+ except Exception, e:
+ kimchiLock.release()
+ raise OperationFailed('KCHREPOS0025E', {'err': e.message})
+
+ return repos
+
+ def _get_repo_id(self, repo):
+ data = urlparse.urlparse(repo.uri)
+ name = data.hostname or data.path
+ return '%s-%s-%s' % (name, repo.dist, "-".join(repo.comps))
+
+ def _get_source_entry(self, repo_id):
+ kimchiLock.acquire()
+ repos = self._get_repos()
+ kimchiLock.release()
+
+ for r in repos:
+ # Ignore deb-src repositories
+ if r.type != 'deb':
+ continue
+
+ if self._get_repo_id(r) != repo_id:
+ continue
+
+ return r
+
+ return None
+
+ def getRepositoriesList(self):
+ """
+ Return a list of repositories IDs
+
+ APT repositories there aren't the concept about repository ID, so for
+ internal control, the repository ID will be built as described in
+ _get_repo_id()
+ """
+ kimchiLock.acquire()
+ repos = self._get_repos()
+ kimchiLock.release()
+
+ res = []
+ for r in repos:
+ # Ignore deb-src repositories
+ if r.type != 'deb':
+ continue
+
+ res.append(self._get_repo_id(r))
+
+ return res
+
+ def getRepo(self, repo_id):
+ """
+ Return a dictionary in the repositories.Repositories() format of the
+ given repository ID with the information of a SourceEntry object.
+ """
+ r = self._get_source_entry(repo_id)
+ if r is None:
+ raise NotFoundError("KCHREPOS0012E", {'repo_id': repo_id})
+
+ info = {'enabled': not r.disabled,
+ 'baseurl': r.uri,
+ 'config': {'dist': r.dist,
+ 'comps': r.comps}}
+ return info
+
+ def addRepo(self, params):
+ """
+ Add a new APT repository based on <params>
+ """
+ # To create a APT repository the dist is a required parameter
+ # (in addition to baseurl, verified on controller through API.json)
+ config = params.get('config', None)
+ if config is None:
+ raise MissingParameter("KCHREPOS0019E")
+
+ if 'dist' not in config.keys():
+ raise MissingParameter("KCHREPOS0019E")
+
+ uri = params['baseurl']
+ dist = config['dist']
+ comps = config.get('comps', [])
+
+ validate_repo_url(uri)
+
+ kimchiLock.acquire()
+ try:
+ repos = self._get_repos()
+ source_entry = repos.add('deb', uri, dist, comps,
+ file=self.filename)
+ with self.pkg_lock():
+ repos.save()
+ except Exception as e:
+ kimchiLock.release()
+ raise OperationFailed("KCHREPOS0026E", {'err': e.message})
+ kimchiLock.release()
+ return self._get_repo_id(source_entry)
+
+ def toggleRepo(self, repo_id, enable):
+ """
+ Enable a given repository
+ """
+ r = self._get_source_entry(repo_id)
+ if r is None:
+ raise NotFoundError("KCHREPOS0012E", {'repo_id': repo_id})
+
+ if enable and not r.disabled:
+ raise InvalidOperation("KCHREPOS0015E", {'repo_id':
repo_id})
+
+ if not enable and r.disabled:
+ raise InvalidOperation("KCHREPOS0016E", {'repo_id':
repo_id})
+
+ if enable:
+ line = 'deb'
+ else:
+ line = '#deb'
+
+ kimchiLock.acquire()
+ try:
+ repos = self._get_repos()
+ with self.pkg_lock():
+ repos.remove(r)
+ repos.add(line, r.uri, r.dist, r.comps, file=self.filename)
+ repos.save()
+ except:
+ kimchiLock.release()
+ if enable:
+ raise OperationFailed("KCHREPOS0020E", {'repo_id':
repo_id})
+
+ raise OperationFailed("KCHREPOS0021E", {'repo_id':
repo_id})
+ finally:
+ kimchiLock.release()
+
+ return repo_id
+
+ def updateRepo(self, repo_id, params):
+ """
+ Update a given repository in repositories.Repositories() format
+ """
+ old_info = self.getRepo(repo_id)
+ updated_info = copy.deepcopy(old_info)
+ updated_info['baseurl'] = params.get(
+ 'baseurl', updated_info['baseurl'])
+
+ if 'config' in params.keys():
+ config = params['config']
+ updated_info['config']['dist'] = config.get(
+ 'dist', old_info['config']['dist'])
+ updated_info['config']['comps'] = config.get(
+ 'comps', old_info['config']['comps'])
+
+ self.removeRepo(repo_id)
+ try:
+ return self.addRepo(updated_info)
+ except:
+ self.addRepo(old_info)
+ raise
+
+ def removeRepo(self, repo_id):
+ """
+ Remove a given repository
+ """
+ r = self._get_source_entry(repo_id)
+ if r is None:
+ raise NotFoundError("KCHREPOS0012E", {'repo_id': repo_id})
+
+ kimchiLock.acquire()
+ try:
+ repos = self._get_repos()
+ with self.pkg_lock():
+ repos.remove(r)
+ repos.save()
+ except:
+ kimchiLock.release()
+ raise OperationFailed("KCHREPOS0017E", {'repo_id':
repo_id})
+ finally:
+ kimchiLock.release()
diff --git a/src/wok/plugins/kimchi/root.py b/src/wok/plugins/kimchi/root.py
new file mode 100644
index 0000000..1e2bfc7
--- /dev/null
+++ b/src/wok/plugins/kimchi/root.py
@@ -0,0 +1,69 @@
+#
+# Project Kimchi
+#
+# Copyright IBM, Corp. 2013-2015
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+import json
+import os
+import cherrypy
+
+from wok.i18n import messages
+from wok.root import WokRoot
+
+import config
+import mockmodel
+import vnc
+from control import sub_nodes
+from model import model as kimchiModel
+
+
+class KimchiRoot(WokRoot):
+ def __init__(self, wok_options):
+ if hasattr(wok_options, "model"):
+ self.model = wok_options.model
+ elif wok_options.test:
+ self.model = mockmodel.MockModel()
+ else:
+ self.model = kimchiModel.Model()
+
+ dev_env = wok_options.environment != 'production'
+ super(KimchiRoot, self).__init__(self.model, dev_env)
+
+ for ident, node in sub_nodes.items():
+ setattr(self, ident, node(self.model))
+
+ if isinstance(self.model, kimchiModel.Model):
+ vnc_ws_proxy = vnc.new_ws_proxy()
+ cherrypy.engine.subscribe('exit', vnc_ws_proxy.terminate)
+
+ self.api_schema = json.load(open(os.path.join(os.path.dirname(
+ os.path.abspath(__file__)), 'API.json')))
+ self.paths = config.kimchiPaths
+ self.domain = 'kimchi'
+ self.messages = messages
+
+ make_dirs = [
+ os.path.abspath(config.get_distros_store()),
+ os.path.abspath(config.get_debugreports_path()),
+ os.path.abspath(config.get_screenshot_path())
+ ]
+ for directory in make_dirs:
+ if not os.path.isdir(directory):
+ os.makedirs(directory)
+
+ def get_custom_conf(self):
+ return config.KimchiConfig()
diff --git a/src/wok/plugins/kimchi/scan.py b/src/wok/plugins/kimchi/scan.py
new file mode 100644
index 0000000..b475c46
--- /dev/null
+++ b/src/wok/plugins/kimchi/scan.py
@@ -0,0 +1,89 @@
+#
+# Project Kimchi
+#
+# Copyright IBM, Corp. 2013-2014
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+#
+
+import glob
+import hashlib
+import os.path
+import shutil
+import tempfile
+import time
+
+from wok.utils import wok_log
+
+from isoinfo import IsoImage, probe_iso
+
+
+SCAN_IGNORE = ['/tmp/kimchi-scan-*']
+
+
+class Scanner(object):
+ SCAN_TTL = 300
+
+ def __init__(self, record_clean_cb):
+ self.clean_cb = record_clean_cb
+
+ def delete(self):
+ self.clean_stale(-1)
+
+ def clean_stale(self, window=SCAN_TTL):
+ """
+ Clear scan pools generated before time window,
+ Clear all scan pools if window is -1.
+ """
+ try:
+ now = time.time()
+ clean_list = glob.glob("/tmp/kimchi-scan-*")
+ for d in clean_list:
+ transient_pool = \
+ os.path.basename(d).replace('kimchi-scan-', '')[0:
-6]
+ if now - os.path.getmtime(d) > window:
+ shutil.rmtree(d)
+ self.clean_cb(transient_pool)
+ except OSError as e:
+ msg = "Exception %s occured when cleaning stale pool, ignore"
+ wok_log.debug(msg % e.message)
+
+ def scan_dir_prepare(self, name):
+ # clean stale scan storage pools
+ self.clean_stale()
+ return tempfile.mkdtemp(prefix='kimchi-scan-' + name,
dir='/tmp')
+
+ def start_scan(self, cb, params):
+ def updater(iso_info):
+ iso_name = os.path.basename(iso_info['path'])[:-3]
+
+ duplicates = "%s/%s*" % (params['pool_path'], iso_name)
+ for f in glob.glob(duplicates):
+ iso_img = IsoImage(f)
+ if (iso_info['distro'], iso_info['version']) == \
+ iso_img.probe():
+ return
+
+ iso_path = iso_name + hashlib.md5(iso_info['path']).hexdigest() + \
+ '.iso'
+ link_name = os.path.join(params['pool_path'],
+ os.path.basename(iso_path))
+ os.symlink(iso_info['path'], link_name)
+
+ ignore_paths = params.get('ignore_list', [])
+ scan_params = dict(path=params['scan_path'], updater=updater,
+ ignore_list=ignore_paths + SCAN_IGNORE)
+ probe_iso(None, scan_params)
+ cb('', True)
diff --git a/src/wok/plugins/kimchi/screenshot.py b/src/wok/plugins/kimchi/screenshot.py
new file mode 100644
index 0000000..ffe5a1a
--- /dev/null
+++ b/src/wok/plugins/kimchi/screenshot.py
@@ -0,0 +1,184 @@
+#
+# Project Kimchi
+#
+# Copyright IBM, Corp. 2013-2014
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+#
+
+import glob
+import os
+import signal
+import tempfile
+import time
+import uuid
+
+try:
+ from PIL import Image
+except ImportError:
+ import Image
+
+
+from wok.utils import wok_log
+
+import config
+
+
+(fd, pipe) = tempfile.mkstemp()
+stream_test_result = None
+
+
+class VMScreenshot(object):
+ OUTDATED_SECS = 5
+ THUMBNAIL_SIZE = (256, 256)
+ LIVE_WINDOW = 60
+ MAX_STREAM_ATTEMPTS = 10
+
+ def __init__(self, args):
+ self.vm_uuid = args['uuid']
+ args.setdefault('thumbnail',
+ os.path.join(config.get_screenshot_path(),
+ '%s-%s.png' %
+ (self.vm_uuid, str(uuid.uuid4()))))
+ self.info = args
+
+ @staticmethod
+ def get_stream_test_result():
+ return stream_test_result
+
+ def lookup(self):
+ now = time.time()
+ try:
+ last_update = os.path.getmtime(self.info['thumbnail'])
+ except OSError:
+ last_update = 0
+
+ if now - last_update > self.OUTDATED_SECS:
+ self._clean_extra(self.LIVE_WINDOW)
+ self._generate_thumbnail()
+ return 'plugins/kimchi/data/screenshots/%s' %\
+ os.path.basename(self.info['thumbnail'])
+
+ def _clean_extra(self, window=-1):
+ """
+ Clear screenshots before time specified by window,
+ Clear all screenshots if window is -1.
+ """
+ try:
+ now = time.time()
+ clear_list = glob.glob("%s/%s-*.png" %
+ (config.get_screenshot_path(),
+ self.vm_uuid))
+ for f in clear_list:
+ if now - os.path.getmtime(f) > window:
+ os.unlink(f)
+ except OSError:
+ pass
+
+ def delete(self):
+ return self._clean_extra()
+
+ def _generate_scratch(self, thumbnail):
+ """
+ Generate screenshot of given vm.
+ Override me in child class.
+ """
+ pass
+
+ def _create_black_image(self, thumbnail):
+ image = Image.new("RGB", self.THUMBNAIL_SIZE, 'black')
+ image.save(thumbnail)
+
+ def _watch_stream_creation(self, thumbnail):
+ """
+ This is a verification test for libvirt stream functionality.
+
+ It is necessary to avoid the server hangs while creating the screenshot
+ image using libvirt stream API.
+
+ This problem was found in libvirt 0.9.6 for SLES11 SP2.
+
+ This test consists in running the screeshot creation with a timeout.
+ If timeout occurs, the libvirt is taking too much time to create the
+ screenshot image and the stream must be disabled it if happens
+ successively (to avoid blocking server requests).
+ """
+ pid = os.fork()
+ if pid == 0:
+ try:
+ self._generate_scratch(thumbnail)
+ os._exit(0)
+ except:
+ os._exit(1)
+ else:
+ counter = 0
+ ret = os.waitpid(pid, os.WNOHANG)
+ while ret == (0, 0) and counter < 3:
+ counter += 1
+ time.sleep(1)
+ ret = os.waitpid(pid, os.WNOHANG)
+
+ fd = open(pipe, "a")
+ if ret != (pid, 0):
+ fd.write("-")
+ if ret[0] != pid:
+ os.kill(int(pid), signal.SIGKILL)
+ os.waitpid(pid, 0)
+ else:
+ fd.write("+")
+ fd.close()
+
+ def _get_test_result(self):
+ if not os.path.exists(pipe):
+ return
+
+ fd = open(pipe, "r")
+ data = fd.read()
+ fd.close()
+
+ if len(data) >= self.MAX_STREAM_ATTEMPTS or bool('+' in data):
+ global stream_test_result
+ stream_test_result = bool('+' in data)
+ os.remove(pipe)
+
+ def _generate_thumbnail(self):
+ thumbnail = os.path.join(config.get_screenshot_path(), '%s-%s.png' %
+ (self.vm_uuid, str(uuid.uuid4())))
+
+ self._get_test_result()
+ if stream_test_result is None:
+ self._watch_stream_creation(thumbnail)
+ elif stream_test_result:
+ try:
+ self._generate_scratch(thumbnail)
+ except:
+ wok_log.error("screenshot_creation: Unable to create "
+ "screenshot image %s." % thumbnail)
+ else:
+ self._create_black_image(thumbnail)
+
+ if os.path.getsize(thumbnail) == 0:
+ self._create_black_image(thumbnail)
+ else:
+ im = Image.open(thumbnail)
+ try:
+ # Prevent Image lib from lazy load,
+ # work around pic truncate validation in thumbnail generation
+ im.thumbnail(self.THUMBNAIL_SIZE)
+ except Exception as e:
+ wok_log.warning("Image load with warning: %s." % e)
+ im.save(thumbnail, "PNG")
+
+ self.info['thumbnail'] = thumbnail
diff --git a/src/wok/plugins/kimchi/swupdate.py b/src/wok/plugins/kimchi/swupdate.py
new file mode 100644
index 0000000..84b927f
--- /dev/null
+++ b/src/wok/plugins/kimchi/swupdate.py
@@ -0,0 +1,263 @@
+#
+# Project Kimchi
+#
+# Copyright IBM, Corp. 2014-2015
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+import subprocess
+import time
+
+from wok.basemodel import Singleton
+from wok.exception import NotFoundError, OperationFailed
+from wok.utils import run_command, wok_log
+
+from config import kimchiLock
+from yumparser import get_yum_packages_list_update
+
+
+class SoftwareUpdate(object):
+ __metaclass__ = Singleton
+
+ """
+ Class to represent and operate with OS software update.
+ """
+ def __init__(self):
+ # This stores all packages to be updated for Kimchi perspective. It's a
+ # dictionary of dictionaries, in the format {'package_name': package},
+ # where:
+ # package = {'package_name': <string>, 'version':
<string>,
+ # 'arch': <string>, 'repository': <string>
+ # }
+ self._packages = {}
+
+ # This stores the number of packages to update
+ self._num2update = 0
+
+ # Get the distro of host machine and creates an object related to
+ # correct package management system
+ try:
+ __import__('yum')
+ wok_log.info("Loading YumUpdate features.")
+ self._pkg_mnger = YumUpdate()
+ except ImportError:
+ try:
+ __import__('apt')
+ wok_log.info("Loading AptUpdate features.")
+ self._pkg_mnger = AptUpdate()
+ except ImportError:
+ zypper_help = ["zypper", "--help"]
+ (stdout, stderr, returncode) = run_command(zypper_help)
+ if returncode == 0:
+ wok_log.info("Loading ZypperUpdate features.")
+ self._pkg_mnger = ZypperUpdate()
+ else:
+ raise Exception("There is no compatible package manager "
+ "for this system.")
+
+ def _scanUpdates(self):
+ """
+ Update self._packages with packages to be updated.
+ """
+ self._packages = {}
+ self._num2update = 0
+
+ # Call system pkg_mnger to get the packages as list of dictionaries.
+ for pkg in self._pkg_mnger.getPackagesList():
+
+ # Check if already exist a package in self._packages
+ pkg_id = pkg.get('package_name')
+ if pkg_id in self._packages.keys():
+ # package already listed to update. do nothing
+ continue
+
+ # Update the self._packages and self._num2update
+ self._packages[pkg_id] = pkg
+ self._num2update = self._num2update + 1
+
+ def getUpdates(self):
+ """
+ Return the self._packages.
+ """
+ self._scanUpdates()
+ return self._packages
+
+ def getUpdate(self, name):
+ """
+ Return a dictionary with all info from a given package name.
+ """
+ if name not in self._packages.keys():
+ raise NotFoundError('KCHPKGUPD0002E', {'name': name})
+
+ return self._packages[name]
+
+ def getNumOfUpdates(self):
+ """
+ Return the number of packages to be updated.
+ """
+ self._scanUpdates()
+ return self._num2update
+
+ def doUpdate(self, cb, params):
+ """
+ Execute the update
+ """
+ # reset messages
+ cb('')
+
+ cmd = self._pkg_mnger.update_cmd
+ proc = subprocess.Popen(cmd, stdout=subprocess.PIPE,
+ stderr=subprocess.PIPE)
+ msgs = []
+ while proc.poll() is None:
+ msgs.append(proc.stdout.readline())
+ cb(''.join(msgs))
+ time.sleep(0.5)
+
+ # read the final output lines
+ msgs.extend(proc.stdout.readlines())
+
+ retcode = proc.poll()
+ if retcode == 0:
+ return cb(''.join(msgs), True)
+
+ msgs.extend(proc.stderr.readlines())
+ return cb(''.join(msgs), False)
+
+
+class YumUpdate(object):
+ """
+ Class to represent and operate with YUM software update system.
+ It's loaded only on those systems listed at YUM_DISTROS and loads necessary
+ modules in runtime.
+ """
+ def __init__(self):
+ self._pkgs = {}
+ self.update_cmd = ["yum", "-y", "update"]
+
+ def _refreshUpdateList(self):
+ """
+ Update the list of packages to be updated in the system.
+ """
+ try:
+ kimchiLock.acquire()
+ self._pkgs = get_yum_packages_list_update()
+ except Exception, e:
+ raise OperationFailed('KCHPKGUPD0003E', {'err': str(e)})
+ finally:
+ kimchiLock.release()
+
+ def getPackagesList(self):
+ """
+ Return a list of package's dictionaries. Each dictionary contains the
+ information about a package, in the format:
+ package = {'package_name': <string>, 'version':
<string>,
+ 'arch': <string>, 'repository': <string>}
+ """
+ self._refreshUpdateList()
+ pkg_list = []
+ for pkg in self._pkgs:
+ package = {'package_name': pkg.name, 'version': pkg.version,
+ 'arch': pkg.arch, 'repository': pkg.ui_from_repo}
+ pkg_list.append(package)
+ return pkg_list
+
+
+class AptUpdate(object):
+ """
+ Class to represent and operate with APT software update system.
+ It's loaded only on those systems listed at APT_DISTROS and loads necessary
+ modules in runtime.
+ """
+ def __init__(self):
+ self._pkgs = {}
+ self.pkg_lock = getattr(__import__('apt_pkg'), 'SystemLock')
+ self.update_cmd = ['apt-get', 'upgrade', '-y']
+
+ def _refreshUpdateList(self):
+ """
+ Update the list of packages to be updated in the system.
+ """
+ apt_cache = getattr(__import__('apt'), 'Cache')()
+ try:
+ with self.pkg_lock():
+ apt_cache.update()
+ apt_cache.upgrade()
+ self._pkgs = apt_cache.get_changes()
+ except Exception, e:
+ kimchiLock.release()
+ raise OperationFailed('KCHPKGUPD0003E', {'err': e.message})
+
+ def getPackagesList(self):
+ """
+ Return a list of package's dictionaries. Each dictionary contains the
+ information about a package, in the format
+ package = {'package_name': <string>, 'version':
<string>,
+ 'arch': <string>, 'repository': <string>}
+ """
+ kimchiLock.acquire()
+ self._refreshUpdateList()
+ kimchiLock.release()
+ pkg_list = []
+ for pkg in self._pkgs:
+ package = {'package_name': pkg.shortname,
+ 'version': pkg.candidate.version,
+ 'arch': pkg._pkg.architecture,
+ 'repository': pkg.candidate.origins[0].label}
+ pkg_list.append(package)
+
+ return pkg_list
+
+
+class ZypperUpdate(object):
+ """
+ Class to represent and operate with Zypper software update system.
+ It's loaded only on those systems listed at ZYPPER_DISTROS and loads
+ necessary modules in runtime.
+ """
+ def __init__(self):
+ self._pkgs = {}
+ self.update_cmd = ["zypper", "--non-interactive",
"update",
+ "--auto-agree-with-licenses"]
+
+ def _refreshUpdateList(self):
+ """
+ Update the list of packages to be updated in the system.
+ """
+ self._pkgs = []
+ cmd = ["zypper", "list-updates"]
+ (stdout, stderr, returncode) = run_command(cmd)
+
+ if len(stderr) > 0:
+ raise OperationFailed('KCHPKGUPD0003E', {'err': stderr})
+
+ for line in stdout.split('\n'):
+ if line.find('v |') >= 0:
+ info = line.split(' | ')
+ package = {'package_name': info[2], 'version': info[4],
+ 'arch': info[5], 'repository': info[1]}
+ self._pkgs.append(package)
+
+ def getPackagesList(self):
+ """
+ Return a list of package's dictionaries. Each dictionary contains the
+ information about a package, in the format
+ package = {'package_name': <string>, 'version':
<string>,
+ 'arch': <string>, 'repository': <string>}
+ """
+ kimchiLock.acquire()
+ self._refreshUpdateList()
+ kimchiLock.release()
+ return self._pkgs
diff --git a/src/wok/plugins/kimchi/template.conf b/src/wok/plugins/kimchi/template.conf
new file mode 100644
index 0000000..f3615e6
--- /dev/null
+++ b/src/wok/plugins/kimchi/template.conf
@@ -0,0 +1,47 @@
+#
+# Configuration file for Kimchi Templates
+#
+
+[main]
+# Memory in MB
+#memory = 1024
+
+# List of networks separated by comma
+# Represents the virtual network interfaces to be assigned to guest
+#networks = default,
+
+[storage]
+# Storage pool used to handle the guest disk
+#pool = default
+
+# Specify multiple [[disk.X]] sub-sections to add multiples disks to guest
+# All the disk files will be created in the same storage pool as set above
+[[disk.0]]
+# Disk size in GB
+#size = 10
+
+# Disk format
+#format = qcow2
+
+[graphics]
+# Graphics type
+# Valid options: vnc | spice
+#type = vnc
+
+# The network which the vnc/spice server listens on
+#listen = 127.0.0.1
+
+[processor]
+# Number of vcpus
+# When specifying CPU topology, make sure cpus value is equal to the product
+# of sockets, cores, and threads.
+#cpus = 1
+
+# Number of sockets (not set by default)
+#sockets =
+
+# Number of cores per socket (not set by default)
+#cores =
+
+# Number of threads per core (not set by default)
+#threads =
diff --git a/src/wok/plugins/kimchi/tests/Makefile.am
b/src/wok/plugins/kimchi/tests/Makefile.am
new file mode 100644
index 0000000..c1f6784
--- /dev/null
+++ b/src/wok/plugins/kimchi/tests/Makefile.am
@@ -0,0 +1,50 @@
+#
+# Kimchi
+#
+# Copyright IBM Corp, 2013
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+EXTRA_DIST = \
+ Makefile.am \
+ run_tests.sh.in \
+ test_config.py.in \
+ $(filter-out test_config.py, $(wildcard *.py)) \
+ $(NULL)
+
+noinst_SCRIPTS = run_tests.sh
+
+do_substitution = \
+ sed -e 's,[@]HAVE_PYMOD_UNITTEST[@],$(HAVE_PYMOD_UNITTEST),g' \
+ -e 's,[@]prefix[@],$(prefix),g' \
+ -e 's,[@]datadir[@],$(datadir),g' \
+ -e 's,[@]PYTHON_VERSION[@],$(PYTHON_VERSION),g' \
+ -e 's,[@]wokdir[@],$(pythondir)/wok,g' \
+ -e 's,[@]pkgdatadir[@],$(pkgdatadir),g'
+
+
+run_tests.sh: run_tests.sh.in Makefile
+ $(do_substitution) < $(srcdir)/run_tests.sh.in > run_tests.sh
+ chmod +x run_tests.sh
+
+test_config.py: test_config.py.in Makefile
+ $(do_substitution) < $(srcdir)/test_config.py.in > test_config.py
+
+check-local:
+ $(MKDIR_P) $(top_srcdir)/data/screenshots
+ ./run_tests.sh
+
+BUILT_SOURCES = test_config.py
+CLEANFILES = run_tests.sh test_config.py
diff --git a/src/wok/plugins/kimchi/tests/iso_gen.py
b/src/wok/plugins/kimchi/tests/iso_gen.py
new file mode 100644
index 0000000..736c660
--- /dev/null
+++ b/src/wok/plugins/kimchi/tests/iso_gen.py
@@ -0,0 +1,212 @@
+#
+# Project Kimchi
+#
+# Copyright IBM, Corp. 2013-2015
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+import platform
+import struct
+
+from wok.plugins.kimchi.isoinfo import IsoImage
+
+
+iso_des = [
+ ('openbsd', lambda v: True,
+ lambda v: 'OpenBSD/i386 %s Install CD' % v),
+ ('centos', lambda v: True, lambda v: 'CentOS_%s_Final' % v),
+ ('windows', '2000', 'W2AFPP'),
+ ('windows', 'xp', 'WXPFPP'),
+ ('windows', '2003', 'ARMECHK'),
+ ('windows', '2003r2', 'CRMEFPP'),
+ ('windows', '2008', 'KRTMSVOL'),
+ ('windows', '2008r2', 'GRMSXVOL'),
+ ('windows', 'vista', 'FB1EVOL'),
+ ('windows', '7', 'GRMCULFRER'),
+ ('windows', '8', 'HB1_CCPA_X86FRE'),
+ ('sles', '10', 'SLES10'),
+ ('sles', '11', 'SUSE_SLES-11-0-0'),
+ ('opensuse', '11.1', 'SU1110.001'),
+ ('opensuse', '11.3', 'openSUSE-DVD-x86_64.0702..001'),
+ ('opensuse', '11.4', 'openSUSE-DVD-x86_640024'),
+ ('opensuse', '12.1', 'openSUSE-DVD-x86_640039'),
+ ('opensuse', '12.2', 'openSUSE-DVD-x86_640167'),
+ ('opensuse', lambda v: True, lambda v: 'openSUSE-%s' % v),
+ ('rhel', '4.8', 'RHEL/4-U8'),
+ ('rhel', lambda v: v.startswith('6.'), lambda v: 'RHEL_%s' %
v),
+ ('debian', lambda v: True, lambda v: 'Debian %s' % v),
+ ('ubuntu',
+ lambda v: v in ('7.10', '8.04', '8.10', '9.04',
'9.10', '10.04', '10.10',
+ '11.04', '11.10', '12.04', '12.10',
'13.04', '13.10',
+ '14.04'),
+ lambda v: 'Ubuntu %s' % v),
+ ('fedora',
+ lambda v: v in ('16', '17', '18', '19'),
+ lambda v: 'Fedora %s' % v)
+]
+
+
+class FakeIsoImage(object):
+ def _build_iso(self, fd, iso_volid, bootable):
+ if platform.machine().startswith('ppc'):
+ self._build_powerpc_bootable_iso(fd, iso_volid)
+ return
+ self._build_intel_iso(fd, iso_volid, bootable)
+
+ def _build_powerpc_bootable_iso(self, fd, iso_volid):
+ self._build_prim_vol(fd, iso_volid)
+ self._build_bootable_ppc_path_table(fd)
+
+ def _build_intel_iso(self, fd, iso_volid, bootable):
+ # Do not change the order of the method calls
+ self._build_el_boot(fd, bootable)
+ self._build_prim_vol(fd, iso_volid)
+ self._build_el_torito(fd)
+
+ def _build_prim_vol(self, fd, iso_volid):
+ fd.seek(16 * IsoImage.SECTOR_SIZE)
+ fmt = IsoImage.VOL_DESC
+ vd_type = 1
+ vd_ident = 'CD001'
+ vd_ver = 1
+ pad0 = 1
+ sys_id = 'fake os'
+ vol_id = iso_volid
+ data = (vd_type, vd_ident, vd_ver, pad0, sys_id, vol_id)
+ s = fmt.pack(*data)
+ fd.write(s)
+ self._add_sector_padding(fd, s)
+
+ def _add_sector_padding(self, fd, s):
+ padding_len = IsoImage.SECTOR_SIZE - len(s)
+ fmt = struct.Struct('=%ss' % padding_len)
+ s = fmt.pack('a' * padding_len)
+ fd.write(s)
+
+ def _build_el_torito(self, fd):
+ fmt = IsoImage.EL_TORITO_BOOT_RECORD
+ vd_type = 0
+ vd_ident = 'CD001'
+ vd_ver = 1
+ et_ident = "EL TORITO SPECIFICATION:"
+ pad0 = 'a' * 32
+ boot_cat = 0
+ data = (vd_type, vd_ident, vd_ver, et_ident, pad0, boot_cat)
+ s = fmt.pack(*data)
+ fd.write(s)
+ self._add_sector_padding(fd, s)
+
+ def _build_el_boot(self, fd, bootable):
+ fmt = IsoImage.EL_TORITO_VALIDATION_ENTRY
+ hdr_id = 0
+ platform_id = 0
+ pad0 = 1
+ ident = 'c' * 24
+ csum = 1
+ key55 = 0x55
+ keyAA = 0xaa
+ data = (hdr_id, platform_id, pad0, ident, csum, key55, keyAA)
+ s = fmt.pack(*data)
+ fd.write(s)
+
+ fmt = IsoImage.EL_TORITO_BOOT_ENTRY
+ if bootable:
+ boot = 0x88
+ else:
+ boot = 0
+ media_type = 1
+ load_seg = 1
+ sys_type = 1
+ pad0 = 1
+ sectors = 1
+ load_rba = 1
+ data = (boot, media_type, load_seg, sys_type, pad0, sectors, load_rba)
+ s = fmt.pack(*data)
+ fd.write(s)
+
+ s = 'a' * IsoImage.SECTOR_SIZE
+ fd.write(s)
+
+ def _build_bootable_ppc_path_table(self, fd):
+ # write path table locator
+ PATH_TABLE_LOC_OFFSET = 16 * IsoImage.SECTOR_SIZE + 132
+ PATH_TABLE_SIZE_LOC = struct.Struct("<I 4s I")
+ path_table_size = 64
+ path_table_loc = 18
+ fd.seek(PATH_TABLE_LOC_OFFSET)
+ fmt = PATH_TABLE_SIZE_LOC
+ data = (path_table_size, 4*'0', path_table_loc)
+ s = fmt.pack(*data)
+ fd.write(s)
+ # write path table entry
+ fd.seek(path_table_loc * IsoImage.SECTOR_SIZE)
+ DIR_NAMELEN_LOCATION_PARENT = struct.Struct("<B B I H 3s")
+ dir_namelen = 3
+ dir_loc = 19
+ dir_parent = 1
+ dir_name = 'ppc'
+ data = (dir_namelen, 0, dir_loc, dir_parent, dir_name)
+ fmt = DIR_NAMELEN_LOCATION_PARENT
+ s = fmt.pack(*data)
+ fd.write(s)
+ # write 'ppc' dir record
+ ppc_dir_offset = dir_loc * IsoImage.SECTOR_SIZE
+ fd.seek(ppc_dir_offset)
+ STATIC_DIR_RECORD_FMT = struct.Struct("<B 9s I 11s B 6s B 12s")
+ dir_rec_len = 1
+ unused1 = 9 * '0'
+ dir_size = 100
+ unused2 = 11 * '0'
+ file_flags = 0
+ unused3 = 6 * '0'
+ file_name_len = 12
+ boot_file_name = "bootinfo.txt"
+ data = (dir_rec_len, unused1, dir_size, unused2, file_flags,
+ unused3, file_name_len, boot_file_name)
+ fmt = STATIC_DIR_RECORD_FMT
+ s = fmt.pack(*data)
+ fd.write(s)
+
+
+def construct_fake_iso(path, bootable, version, distro):
+ iso = FakeIsoImage()
+
+ for d, v, gen_id in iso_des:
+ if d != distro:
+ continue
+ if hasattr(v, '__call__'):
+ supported = v(version)
+ else:
+ supported = version == v
+
+ if not supported:
+ continue
+
+ if hasattr(gen_id, '__call__'):
+ vol_id = gen_id(version)
+ else:
+ vol_id = gen_id
+ with open(path, 'w') as fd:
+ return iso._build_iso(fd, vol_id, bootable)
+
+ raise Exception("%s: %s not supported generation" % (distro, version))
+
+
+if __name__ == '__main__':
+ construct_fake_iso('centos.iso', True, '6.1', 'centos')
+ construct_fake_iso('ubuntu12.04.iso', True, '12.04',
'ubuntu')
+ construct_fake_iso('fedora17.iso', True, '17', 'fedora')
+ construct_fake_iso('sles10.iso', True, '10', 'sles')
+ construct_fake_iso('openbsd.iso', True, '5.0', 'openbsd')
diff --git a/src/wok/plugins/kimchi/tests/run_tests.sh.in
b/src/wok/plugins/kimchi/tests/run_tests.sh.in
new file mode 100644
index 0000000..beef75e
--- /dev/null
+++ b/src/wok/plugins/kimchi/tests/run_tests.sh.in
@@ -0,0 +1,55 @@
+#!/bin/bash
+#
+# Project Kimchi
+#
+# Copyright IBM, Corp. 2013-2015
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+HAVE_UNITTEST=@HAVE_PYMOD_UNITTEST@
+PYTHON_VER=@PYTHON_VERSION@
+
+if [ "$1" = "-v" ]; then
+ OPTS="-v"
+ shift
+else
+ OPTS=""
+fi
+
+if [ $# -ne 0 ]; then
+ ARGS="$@"
+else
+ ARGS=`find -name "test_*.py" | xargs -I @ basename @ .py`
+fi
+
+if [ "$HAVE_UNITTEST" != "yes" -o "$PYTHON_VER" ==
"2.6" ]; then
+ CMD="unit2"
+else
+ CMD="python -m unittest"
+fi
+
+LIST=($ARGS)
+MODEL_LIST=()
+MOCK_LIST=()
+for ((i=0;i<${#LIST[@]};i++)); do
+
+ if [[ ${LIST[$i]} == test_model* ]]; then
+ MODEL_LIST+=(${LIST[$i]})
+ else
+ MOCK_LIST+=(${LIST[$i]})
+ fi
+done
+
+PYTHONPATH=../plugins:../src:../ $CMD $OPTS ${MODEL_LIST[@]} ${MOCK_LIST[@]}
diff --git a/src/wok/plugins/kimchi/tests/test_authorization.py
b/src/wok/plugins/kimchi/tests/test_authorization.py
new file mode 100644
index 0000000..87d68ab
--- /dev/null
+++ b/src/wok/plugins/kimchi/tests/test_authorization.py
@@ -0,0 +1,178 @@
+#
+# Project Kimchi
+#
+# Copyright IBM, Corp. 2014-2015
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+import json
+import os
+import unittest
+from functools import partial
+
+from wok.plugins.kimchi import mockmodel
+
+from iso_gen import construct_fake_iso
+from utils import get_free_port, patch_auth, request
+from utils import run_server, wait_task
+
+
+test_server = None
+model = None
+host = None
+port = None
+ssl_port = None
+fake_iso = '/tmp/fake.iso'
+
+
+def setUpModule():
+ global test_server, model, host, port, ssl_port
+
+ patch_auth(sudo=False)
+ model = mockmodel.MockModel('/tmp/obj-store-test')
+ host = '127.0.0.1'
+ port = get_free_port('http')
+ ssl_port = get_free_port('https')
+ test_server = run_server(host, port, ssl_port, test_mode=True, model=model)
+
+ # Create fake ISO to do the tests
+ construct_fake_iso(fake_iso, True, '12.04', 'ubuntu')
+
+
+def tearDownModule():
+ test_server.stop()
+ os.unlink('/tmp/obj-store-test')
+ os.unlink(fake_iso)
+
+
+class AuthorizationTests(unittest.TestCase):
+ def setUp(self):
+ self.request = partial(request, host, ssl_port)
+ model.reset()
+
+ def test_nonroot_access(self):
+ # Non-root users can access static host information
+ resp = self.request('/plugins/kimchi/host', '{}', 'GET')
+ self.assertEquals(403, resp.status)
+
+ # Non-root users can access host stats
+ resp = self.request('/plugins/kimchi/host/stats', '{}',
'GET')
+ self.assertEquals(403, resp.status)
+
+ # Non-root users can not reboot/shutdown host system
+ resp = self.request('/plugins/kimchi/host/reboot', '{}',
'POST')
+ self.assertEquals(403, resp.status)
+ resp = self.request('/plugins/kimchi/host/shutdown', '{}',
'POST')
+ self.assertEquals(403, resp.status)
+
+ # Non-root users can not get or debug reports
+ resp = self.request('/plugins/kimchi/debugreports', '{}',
'GET')
+ self.assertEquals(403, resp.status)
+ resp = self.request('/plugins/kimchi/debugreports', '{}',
'POST')
+ self.assertEquals(403, resp.status)
+
+ # Non-root users can not create or delete network (only get)
+ resp = self.request('/plugins/kimchi/networks', '{}',
'GET')
+ self.assertEquals(200, resp.status)
+ resp = self.request('/plugins/kimchi/networks', '{}',
'POST')
+ self.assertEquals(403, resp.status)
+ resp = self.request('/plugins/kimchi/networks/default/activate',
'{}',
+ 'POST')
+ self.assertEquals(403, resp.status)
+ resp = self.request('/plugins/kimchi/networks/default', '{}',
'DELETE')
+ self.assertEquals(403, resp.status)
+
+ # Non-root users can not create or delete storage pool (only get)
+ resp = self.request('/plugins/kimchi/storagepools', '{}',
'GET')
+ self.assertEquals(200, resp.status)
+ resp = self.request('/plugins/kimchi/storagepools', '{}',
'POST')
+ self.assertEquals(403, resp.status)
+ resp = self.request('/plugins/kimchi/storagepools/default/activate',
+ '{}', 'POST')
+ self.assertEquals(403, resp.status)
+ resp = self.request('/plugins/kimchi/storagepools/default',
'{}',
+ 'DELETE')
+ self.assertEquals(403, resp.status)
+
+ # Non-root users can not update or delete a template
+ # but he can get and create a new one
+ resp = self.request('/plugins/kimchi/templates', '{}',
'GET')
+ self.assertEquals(403, resp.status)
+ req = json.dumps({'name': 'test', 'cdrom': fake_iso})
+ resp = self.request('/plugins/kimchi/templates', req, 'POST')
+ self.assertEquals(403, resp.status)
+ resp = self.request('/plugins/kimchi/templates/test', '{}',
'PUT')
+ self.assertEquals(403, resp.status)
+ resp = self.request('/plugins/kimchi/templates/test', '{}',
'DELETE')
+ self.assertEquals(403, resp.status)
+
+ # Non-root users can only get vms authorized to them
+ model.templates_create({'name': u'test', 'cdrom':
fake_iso})
+
+ task_info = model.vms_create({
+ 'name': u'test-me',
+ 'template': '/plugins/kimchi/templates/test'
+ })
+ wait_task(model.task_lookup, task_info['id'])
+
+ model.vm_update(u'test-me',
+ {'users': [mockmodel.fake_user.keys()[0]],
+ 'groups': []})
+
+ task_info = model.vms_create({
+ 'name': u'test-usera',
+ 'template': '/plugins/kimchi/templates/test'
+ })
+ wait_task(model.task_lookup, task_info['id'])
+
+ non_root = list(set(model.users_get_list()) - set(['root']))[0]
+ model.vm_update(u'test-usera', {'users': [non_root],
'groups': []})
+
+ task_info = model.vms_create({
+ 'name': u'test-groupa',
+ 'template': '/plugins/kimchi/templates/test'
+ })
+ wait_task(model.task_lookup, task_info['id'])
+ a_group = model.groups_get_list()[0]
+ model.vm_update(u'test-groupa', {'groups': [a_group]})
+
+ resp = self.request('/plugins/kimchi/vms', '{}', 'GET')
+ self.assertEquals(200, resp.status)
+ vms_data = json.loads(resp.read())
+ self.assertEquals([u'test-groupa', u'test-me'],
+ sorted([v['name'] for v in vms_data]))
+ resp = self.request('/plugins/kimchi/vms', req, 'POST')
+ self.assertEquals(403, resp.status)
+
+ # Create a vm using mockmodel directly to test Resource access
+ task_info = model.vms_create({
+ 'name': 'kimchi-test',
+ 'template': '/plugins/kimchi/templates/test'
+ })
+ wait_task(model.task_lookup, task_info['id'])
+ resp = self.request('/plugins/kimchi/vms/kimchi-test', '{}',
'PUT')
+ self.assertEquals(403, resp.status)
+ resp = self.request('/plugins/kimchi/vms/kimchi-test', '{}',
'DELETE')
+ self.assertEquals(403, resp.status)
+
+ # Non-root users can only update VMs authorized by them
+ resp = self.request('/plugins/kimchi/vms/test-me/start', '{}',
'POST')
+ self.assertEquals(200, resp.status)
+ resp = self.request('/plugins/kimchi/vms/test-usera/start',
'{}',
+ 'POST')
+ self.assertEquals(403, resp.status)
+
+ model.template_delete('test')
+ model.vm_delete('test-me')
diff --git a/src/wok/plugins/kimchi/tests/test_config.py.in
b/src/wok/plugins/kimchi/tests/test_config.py.in
new file mode 100644
index 0000000..4604eb1
--- /dev/null
+++ b/src/wok/plugins/kimchi/tests/test_config.py.in
@@ -0,0 +1,267 @@
+#
+# Project Kimchi
+#
+# Copyright IBM, Corp. 2014-2015
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+import unittest
+from cherrypy.lib.reprconf import Parser
+
+from wok.config import Paths, PluginPaths, WokConfig
+
+from wok.plugins.kimchi.config import get_debugreports_path
+from wok.plugins.kimchi.config import get_screenshot_path
+from wok.plugins.kimchi.config import KimchiConfig, KimchiPaths
+
+
+get_prefix = None
+
+
+def setUpModule():
+ global get_prefix
+ get_prefix = Paths.get_prefix
+
+
+def tearDownModule():
+ Paths.get_prefix = KimchiPaths.get_prefix = get_prefix
+
+
+class ConfigTests(unittest.TestCase):
+ def assertInstalledPath(self, actual, expected):
+ if '@pkgdatadir@' != '/usr/share/kimchi':
+ usr_local = '/usr/local'
+ if not expected.startswith('/usr'):
+ expected = usr_local + expected
+ self.assertEquals(actual, expected)
+
+ def test_installed_paths(self):
+ Paths.get_prefix = lambda self: '@datadir@/wok'
+ paths = Paths()
+ self.assertInstalledPath(paths.state_dir, '/var/lib/wok')
+ self.assertInstalledPath(paths.log_dir, '/var/log/wok')
+ self.assertInstalledPath(paths.conf_dir, '/etc/wok')
+ self.assertInstalledPath(paths.src_dir, '@wokdir@')
+ self.assertInstalledPath(paths.plugins_dir, '@wokdir@/plugins')
+ self.assertInstalledPath(paths.ui_dir, '@datadir@/wok/ui')
+ self.assertInstalledPath(paths.mo_dir, '@prefix@/share/locale')
+
+ def test_uninstalled_paths(self):
+ Paths.get_prefix = lambda self: '/home/user/wok'
+ paths = Paths()
+ self.assertEquals(paths.state_dir, '/home/user/wok/data')
+ self.assertEquals(paths.log_dir, '/home/user/wok/log')
+ self.assertEquals(paths.conf_dir, '/home/user/wok/src')
+ self.assertEquals(paths.src_dir, '/home/user/wok/src/wok')
+ self.assertEquals(paths.plugins_dir, '/home/user/wok/plugins')
+ self.assertEquals(paths.ui_dir, '/home/user/wok/ui')
+ self.assertEquals(paths.mo_dir, '/home/user/wok/mo')
+
+ def test_installed_plugin_paths(self):
+ KimchiPaths.get_prefix = lambda self: '@datadir@/wok'
+ paths = KimchiPaths()
+ self.assertInstalledPath(paths.conf_dir, '/etc/wok/plugins.d')
+ self.assertInstalledPath(paths.conf_file,
+ '/etc/wok/plugins.d/kimchi.conf')
+ self.assertInstalledPath(paths.src_dir, '@wokdir@/plugins/kimchi')
+ self.assertInstalledPath(paths.ui_dir,
+ '@datadir@/wok/plugins/kimchi/ui')
+ self.assertInstalledPath(paths.mo_dir, '@prefix@/share/locale')
+
+ def test_uninstalled_plugin_paths(self):
+ KimchiPaths.get_prefix = lambda self: '/home/user/wok'
+ paths = KimchiPaths()
+ self.assertEquals(paths.conf_dir, '/home/user/wok/plugins/kimchi')
+ self.assertEquals(
+ paths.conf_file, '/home/user/wok/plugins/kimchi/kimchi.conf')
+ self.assertEquals(paths.src_dir, '/home/user/wok/plugins/kimchi')
+ self.assertEquals(paths.ui_dir, '/home/user/wok/plugins/kimchi/ui')
+ self.assertEquals(paths.mo_dir, '/home/user/wok/plugins/kimchi/mo')
+
+ def test_wok_config(self):
+ Paths.get_prefix = PluginPaths.get_prefix = get_prefix
+ paths = Paths()
+ CACHEEXPIRES = 31536000
+ SESSIONSTIMEOUT = 10
+ configObj = {
+ '/': {
+ 'tools.trailing_slash.on': False,
+ 'request.methods_with_bodies': ('POST', 'PUT'),
+ 'tools.nocache.on': True,
+ 'tools.proxy.on': True,
+ 'tools.sessions.on': True,
+ 'tools.sessions.name': 'wok',
+ 'tools.sessions.secure': True,
+ 'tools.sessions.httponly': True,
+ 'tools.sessions.locking': 'explicit',
+ 'tools.sessions.storage_type': 'ram',
+ 'tools.sessions.timeout': SESSIONSTIMEOUT,
+ 'tools.wokauth.on': False
+ },
+ '/wok-ui.html': {
+ 'tools.wokauth.on': True
+ },
+ '/css': {
+ 'tools.staticdir.on': True,
+ 'tools.staticdir.dir': '%s/ui/css' % paths.prefix,
+ 'tools.expires.on': True,
+ 'tools.expires.secs': CACHEEXPIRES,
+ 'tools.nocache.on': False,
+ 'tools.wokauth.on': False
+ },
+ '/js': {
+ 'tools.staticdir.on': True,
+ 'tools.staticdir.dir': '%s/ui/js' % paths.prefix,
+ 'tools.expires.on': True,
+ 'tools.expires.secs': CACHEEXPIRES,
+ 'tools.nocache.on': False,
+ 'tools.wokauth.on': False
+ },
+ '/libs': {
+ 'tools.staticdir.on': True,
+ 'tools.staticdir.dir': '%s/ui/libs' % paths.prefix,
+ 'tools.expires.on': True,
+ 'tools.expires.secs': CACHEEXPIRES,
+ 'tools.nocache.on': False,
+ 'tools.wokauth.on': False
+ },
+ '/images': {
+ 'tools.staticdir.on': True,
+ 'tools.staticdir.dir': '%s/ui/images' % paths.prefix,
+ 'tools.nocache.on': False,
+ 'tools.wokauth.on': False
+ },
+ '/favicon.ico': {
+ 'tools.staticfile.on': True,
+ 'tools.staticfile.filename':
+ '%s/images/logo.ico' % paths.ui_dir
+ },
+ '/robots.txt': {
+ 'tools.staticfile.on': True,
+ 'tools.staticfile.filename': '%s/robots.txt' %
paths.ui_dir
+ },
+ }
+
+ wok_config = WokConfig()
+ self.assertEquals(wok_config, configObj)
+
+
+ def test_kimchi_config(self):
+ KimchiPaths.get_prefix = PluginPaths.get_prefix = get_prefix
+ paths = KimchiPaths()
+ pluginPrefix = paths.add_prefix(paths.plugin_dir)
+ CACHEEXPIRES = 31536000
+ SESSIONSTIMEOUT = 10
+ configObj = {
+ 'wok': {
+ 'enable': True,
+ 'plugin_class': "KimchiRoot",
+ 'uri': '/%s' % paths.plugin_dir,
+ 'extra_auth_api_class': "control.sub_nodes"
+ },
+ '/': {
+ 'tools.trailing_slash.on': False,
+ 'request.methods_with_bodies': ('POST', 'PUT'),
+ 'tools.nocache.on': True,
+ 'tools.proxy.on': True,
+ 'tools.sessions.on': True,
+ 'tools.sessions.name': 'wok',
+ 'tools.sessions.secure': True,
+ 'tools.sessions.httponly': True,
+ 'tools.sessions.locking': 'explicit',
+ 'tools.sessions.storage_type': 'ram',
+ 'tools.sessions.timeout': SESSIONSTIMEOUT,
+ 'tools.wokauth.on': True
+ },
+ '/novnc': {
+ 'tools.staticdir.on': True,
+ 'tools.staticdir.dir': paths.novnc_dir,
+ 'tools.nocache.on': True,
+ 'tools.wokauth.on': True
+ },
+ '/spice_auto.html': {
+ 'tools.staticfile.on': True,
+ 'tools.staticfile.filename': paths.spice_file,
+ 'tools.nocache.on': True,
+ 'tools.wokauth.on': True
+ },
+ '/spice-html5': {
+ 'tools.staticdir.on': True,
+ 'tools.staticdir.dir': paths.spice_dir,
+ 'tools.nocache.on': True
+ },
+ '/spice-html5/spice.css': {
+ 'tools.staticfile.on': True,
+ 'tools.staticfile.filename': paths.spice_css_file,
+ 'tools.nocache.on': True,
+ },
+ '/ui/config/tab-ext.xml': {
+ 'tools.staticfile.on': True,
+ 'tools.staticfile.filename': '%s/ui/config/tab-ext.xml'
%
+ pluginPrefix,
+ 'tools.nocache.on': True
+ },
+ '/css': {
+ 'tools.staticdir.on': True,
+ 'tools.staticdir.dir': '%s/ui/css' % pluginPrefix,
+ 'tools.expires.on': True,
+ 'tools.expires.secs': CACHEEXPIRES,
+ 'tools.nocache.on': False,
+ 'tools.wokauth.on': False
+ },
+ '/js': {
+ 'tools.staticdir.on': True,
+ 'tools.staticdir.dir': '%s/ui/js' % pluginPrefix,
+ 'tools.expires.on': True,
+ 'tools.expires.secs': CACHEEXPIRES,
+ 'tools.nocache.on': False,
+ 'tools.wokauth.on': False
+ },
+ '/libs': {
+ 'tools.staticdir.on': True,
+ 'tools.staticdir.dir': '%s/ui/libs' % pluginPrefix,
+ 'tools.expires.on': True,
+ 'tools.expires.secs': CACHEEXPIRES,
+ 'tools.nocache.on': False,
+ 'tools.wokauth.on': False,
+ },
+ '/images': {
+ 'tools.staticdir.on': True,
+ 'tools.staticdir.dir': '%s/ui/images' % pluginPrefix,
+ 'tools.nocache.on': False,
+ 'tools.wokauth.on': False
+ },
+ '/data/screenshots': {
+ 'tools.staticdir.on': True,
+ 'tools.staticdir.dir': get_screenshot_path(),
+ 'tools.nocache.on': False
+ },
+ '/data/debugreports': {
+ 'tools.staticdir.on': True,
+ 'tools.staticdir.dir': get_debugreports_path(),
+ 'tools.nocache.on': False,
+ 'tools.wokauth.on': True,
+ 'tools.staticdir.content_types': {'xz':
'application/x-xz'}
+ },
+ '/help': {
+ 'tools.staticdir.on': True,
+ 'tools.staticdir.dir': '%s/ui/pages/help' %
pluginPrefix,
+ 'tools.nocache.on': True
+ }
+ }
+
+ kimchi_config = Parser().dict_from_file(KimchiPaths().conf_file)
+ kimchi_config.update(KimchiConfig())
+ self.assertEquals(kimchi_config, configObj)
diff --git a/src/wok/plugins/kimchi/tests/test_exception.py
b/src/wok/plugins/kimchi/tests/test_exception.py
new file mode 100644
index 0000000..4459aa6
--- /dev/null
+++ b/src/wok/plugins/kimchi/tests/test_exception.py
@@ -0,0 +1,123 @@
+#
+# Kimchi
+#
+# Copyright IBM, Corp. 2013-2014
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+import json
+import os
+import unittest
+
+from wok.plugins.kimchi import mockmodel
+
+from utils import get_free_port, patch_auth, request, run_server
+
+
+test_server = None
+model = None
+host = None
+port = None
+ssl_port = None
+
+
+def setup_server(environment='development'):
+ global test_server, model, host, port, ssl_port
+
+ patch_auth()
+ model = mockmodel.MockModel('/tmp/obj-store-test')
+ host = '127.0.0.1'
+ port = get_free_port('http')
+ ssl_port = get_free_port('https')
+ test_server = run_server(host, port, ssl_port, test_mode=True, model=model,
+ environment=environment)
+
+
+class ExceptionTests(unittest.TestCase):
+ def tearDown(self):
+ test_server.stop()
+ os.unlink('/tmp/obj-store-test')
+
+ def test_production_env(self):
+ """
+ Test reasons sanitized in production env
+ """
+ setup_server('production')
+ # test 404
+ resp = json.loads(
+ request(host, ssl_port, '/plugins/kimchi/vms/blah').read()
+ )
+ self.assertEquals('404 Not Found', resp.get('code'))
+
+ # test 405 wrong method
+ resp = json.loads(request(host, ssl_port, '/', None,
'DELETE').read())
+ msg = u'WOKAPI0002E: Delete is not allowed for wokroot'
+ self.assertEquals('405 Method Not Allowed', resp.get('code'))
+ self.assertEquals(msg, resp.get('reason'))
+
+ # test 400 parse error
+ resp = json.loads(
+ request(host, ssl_port, '/plugins/kimchi/vms', '{',
'POST').read()
+ )
+ msg = u'WOKAPI0006E: Unable to parse JSON request'
+ self.assertEquals('400 Bad Request', resp.get('code'))
+ self.assertEquals(msg, resp.get('reason'))
+ self.assertNotIn('call_stack', resp)
+
+ # test 400 missing required parameter
+ req = json.dumps({})
+ resp = json.loads(
+ request(host, ssl_port, '/plugins/kimchi/vms', req,
'POST').read()
+ )
+ self.assertEquals('400 Bad Request', resp.get('code'))
+ m = u"KCHVM0016E: Specify a template to create a virtual machine from"
+ self.assertEquals(m, resp.get('reason'))
+ self.assertNotIn('call_stack', resp)
+
+ def test_development_env(self):
+ """
+ Test traceback thrown in development env
+ """
+ setup_server()
+ # test 404
+ resp = json.loads(
+ request(host, ssl_port, '/plugins/kimchi/vms/blah').read()
+ )
+ self.assertEquals('404 Not Found', resp.get('code'))
+
+ # test 405 wrong method
+ resp = json.loads(request(host, ssl_port, '/', None,
'DELETE').read())
+ msg = u'WOKAPI0002E: Delete is not allowed for wokroot'
+ self.assertEquals('405 Method Not Allowed', resp.get('code'))
+ self.assertEquals(msg, resp.get('reason'))
+
+ # test 400 parse error
+ resp = json.loads(
+ request(host, ssl_port, '/plugins/kimchi/vms', '{',
'POST').read()
+ )
+ msg = u'WOKAPI0006E: Unable to parse JSON request'
+ self.assertEquals('400 Bad Request', resp.get('code'))
+ self.assertEquals(msg, resp.get('reason'))
+ self.assertIn('call_stack', resp)
+
+ # test 400 missing required parameter
+ req = json.dumps({})
+ resp = json.loads(
+ request(host, ssl_port, '/plugins/kimchi/vms', req,
'POST').read()
+ )
+ m = u"KCHVM0016E: Specify a template to create a virtual machine from"
+ self.assertEquals('400 Bad Request', resp.get('code'))
+ self.assertEquals(m, resp.get('reason'))
+ self.assertIn('call_stack', resp)
diff --git a/src/wok/plugins/kimchi/tests/test_host.py
b/src/wok/plugins/kimchi/tests/test_host.py
new file mode 100644
index 0000000..6cd0833
--- /dev/null
+++ b/src/wok/plugins/kimchi/tests/test_host.py
@@ -0,0 +1,206 @@
+# -*- coding: utf-8 -*-
+#
+# Project Kimchi
+#
+# Copyright IBM, Corp. 2015
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+import json
+import os
+import platform
+import psutil
+import tempfile
+import time
+import unittest
+from functools import partial
+
+from wok.plugins.kimchi.mockmodel import MockModel
+
+from utils import get_free_port, patch_auth, request, run_server, wait_task
+
+
+test_server = None
+model = None
+host = None
+ssl_port = None
+tmpfile = None
+
+
+def setUpModule():
+ global test_server, model, host, ssl_port, tmpfile
+
+ patch_auth()
+ tmpfile = tempfile.mktemp()
+ model = MockModel(tmpfile)
+ host = '127.0.0.1'
+ port = get_free_port('http')
+ ssl_port = get_free_port('https')
+ cherrypy_port = get_free_port('cherrypy_port')
+ test_server = run_server(host, port, ssl_port, test_mode=True,
+ cherrypy_port=cherrypy_port, model=model)
+
+
+def tearDownModule():
+ test_server.stop()
+ os.unlink(tmpfile)
+
+
+class HostTests(unittest.TestCase):
+ def setUp(self):
+ self.request = partial(request, host, ssl_port)
+
+ def test_hostinfo(self):
+ resp = self.request('/plugins/kimchi/host').read()
+ info = json.loads(resp)
+ keys = ['os_distro', 'os_version', 'os_codename',
'cpu_model',
+ 'memory', 'cpus']
+ self.assertEquals(sorted(keys), sorted(info.keys()))
+
+ distro, version, codename = platform.linux_distribution()
+ self.assertEquals(distro, info['os_distro'])
+ self.assertEquals(version, info['os_version'])
+ self.assertEquals(unicode(codename, "utf-8"),
info['os_codename'])
+ self.assertEquals(psutil.TOTAL_PHYMEM, info['memory'])
+
+ def test_hoststats(self):
+ time.sleep(1)
+ stats_keys = ['cpu_utilization', 'memory',
'disk_read_rate',
+ 'disk_write_rate', 'net_recv_rate',
'net_sent_rate']
+ resp = self.request('/plugins/kimchi/host/stats').read()
+ stats = json.loads(resp)
+ self.assertEquals(sorted(stats_keys), sorted(stats.keys()))
+
+ cpu_utilization = stats['cpu_utilization']
+ self.assertIsInstance(cpu_utilization, float)
+ self.assertGreaterEqual(cpu_utilization, 0.0)
+ self.assertTrue(cpu_utilization <= 100.0)
+
+ memory_stats = stats['memory']
+ self.assertIn('total', memory_stats)
+ self.assertIn('free', memory_stats)
+ self.assertIn('cached', memory_stats)
+ self.assertIn('buffers', memory_stats)
+ self.assertIn('avail', memory_stats)
+
+ resp = self.request('/plugins/kimchi/host/stats/history').read()
+ history = json.loads(resp)
+ self.assertEquals(sorted(stats_keys), sorted(history.keys()))
+
+ def test_host_actions(self):
+ def _task_lookup(taskid):
+ return json.loads(
+ self.request('/plugins/kimchi/tasks/%s' % taskid).read()
+ )
+
+ resp = self.request('/plugins/kimchi/host/shutdown', '{}',
'POST')
+ self.assertEquals(200, resp.status)
+ resp = self.request('/plugins/kimchi/host/reboot', '{}',
'POST')
+ self.assertEquals(200, resp.status)
+
+ # Test system update
+ resp = self.request('/plugins/kimchi/host/packagesupdate', None,
'GET')
+ pkgs = json.loads(resp.read())
+ self.assertEquals(3, len(pkgs))
+
+ pkg_keys = ['package_name', 'repository', 'arch',
'version']
+ for p in pkgs:
+ name = p['package_name']
+ resp = self.request('/plugins/kimchi/host/packagesupdate/' + name,
+ None, 'GET')
+ info = json.loads(resp.read())
+ self.assertEquals(sorted(pkg_keys), sorted(info.keys()))
+
+ resp = self.request('/plugins/kimchi/host/swupdate', '{}',
'POST')
+ task = json.loads(resp.read())
+ task_params = [u'id', u'message', u'status',
u'target_uri']
+ self.assertEquals(sorted(task_params), sorted(task.keys()))
+
+ resp = self.request('/tasks/' + task[u'id'], None,
+ 'GET')
+ task_info = json.loads(resp.read())
+ self.assertEquals(task_info['status'], 'running')
+ wait_task(_task_lookup, task_info['id'])
+ resp = self.request('/tasks/' + task[u'id'], None,
+ 'GET')
+ task_info = json.loads(resp.read())
+ self.assertEquals(task_info['status'], 'finished')
+ self.assertIn(u'All packages updated', task_info['message'])
+ pkgs = model.packagesupdate_get_list()
+ self.assertEquals(0, len(pkgs))
+
+ def test_host_partitions(self):
+ resp = self.request('/plugins/kimchi/host/partitions')
+ self.assertEquals(200, resp.status)
+ partitions = json.loads(resp.read())
+
+ keys = ['name', 'path', 'type', 'fstype',
'size', 'mountpoint',
+ 'available']
+ for item in partitions:
+ resp = self.request('/plugins/kimchi/host/partitions/%s' %
+ item['name'])
+ info = json.loads(resp.read())
+ self.assertEquals(sorted(info.keys()), sorted(keys))
+
+ def test_host_devices(self):
+ def asset_devices_type(devices, dev_type):
+ for dev in devices:
+ self.assertEquals(dev['device_type'], dev_type)
+
+ resp = self.request('/plugins/kimchi/host/devices?_cap=scsi_host')
+ nodedevs = json.loads(resp.read())
+ # Mockmodel brings 3 preconfigured scsi fc_host
+ self.assertEquals(3, len(nodedevs))
+
+ nodedev = json.loads(
+ self.request('/plugins/kimchi/host/devices/scsi_host2').read()
+ )
+ # Mockmodel generates random wwpn and wwnn
+ self.assertEquals('scsi_host2', nodedev['name'])
+ self.assertEquals('fc_host', nodedev['adapter']['type'])
+ self.assertEquals(16, len(nodedev['adapter']['wwpn']))
+ self.assertEquals(16, len(nodedev['adapter']['wwnn']))
+
+ devs = json.loads(self.request('/plugins/kimchi/host/devices').read())
+ dev_names = [dev['name'] for dev in devs]
+ for dev_type in ('pci', 'usb_device', 'scsi'):
+ resp = self.request('/plugins/kimchi/host/devices?_cap=%s' %
+ dev_type)
+ devsByType = json.loads(resp.read())
+ names = [dev['name'] for dev in devsByType]
+ self.assertTrue(set(names) <= set(dev_names))
+ asset_devices_type(devsByType, dev_type)
+
+ resp = self.request('/plugins/kimchi/host/devices?_passthrough=true')
+ passthru_devs = [dev['name'] for dev in json.loads(resp.read())]
+ self.assertTrue(set(passthru_devs) <= set(dev_names))
+
+ for dev_type in ('pci', 'usb_device', 'scsi'):
+ resp = self.request(
+ '/plugins/kimchi/host/devices?_cap=%s&_passthrough=true' %
+ dev_type
+ )
+ filteredDevs = json.loads(resp.read())
+ filteredNames = [dev['name'] for dev in filteredDevs]
+ self.assertTrue(set(filteredNames) <= set(dev_names))
+ asset_devices_type(filteredDevs, dev_type)
+
+ for dev in passthru_devs:
+ resp = self.request(
+ '/plugins/kimchi/host/devices?_passthrough_affected_by=%s' %
+ dev
+ )
+ affected_devs = [dev['name'] for dev in json.loads(resp.read())]
+ self.assertTrue(set(affected_devs) <= set(dev_names))
diff --git a/src/wok/plugins/kimchi/tests/test_mock_network.py
b/src/wok/plugins/kimchi/tests/test_mock_network.py
new file mode 100644
index 0000000..4e2a939
--- /dev/null
+++ b/src/wok/plugins/kimchi/tests/test_mock_network.py
@@ -0,0 +1,73 @@
+# -*- coding: utf-8 -*-
+#
+# Project Kimchi
+#
+# Copyright IBM, Corp. 2015
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+import json
+import os
+import unittest
+from functools import partial
+
+from wok.plugins.kimchi.mockmodel import MockModel
+
+from test_model_network import _do_network_test
+from utils import get_free_port, patch_auth, request, run_server
+
+
+model = None
+test_server = None
+host = None
+port = None
+ssl_port = None
+cherrypy_port = None
+
+
+def setUpModule():
+ global test_server, model, host, port, ssl_port, cherrypy_port
+
+ patch_auth()
+ model = MockModel('/tmp/obj-store-test')
+ host = '127.0.0.1'
+ port = get_free_port('http')
+ ssl_port = get_free_port('https')
+ cherrypy_port = get_free_port('cherrypy_port')
+ test_server = run_server(host, port, ssl_port, test_mode=True,
+ cherrypy_port=cherrypy_port, model=model)
+
+
+def tearDownModule():
+ test_server.stop()
+ os.unlink('/tmp/obj-store-test')
+
+
+class MockNetworkTests(unittest.TestCase):
+ def setUp(self):
+ self.request = partial(request, host, ssl_port)
+ model.reset()
+
+ def test_vlan_tag_bridge(self):
+ # Verify the current system has at least one interface to create a
+ # bridged network
+ interfaces = json.loads(
+ self.request('/plugins/kimchi/interfaces?type=nic').read()
+ )
+ if len(interfaces) > 0:
+ iface = interfaces[0]['name']
+ _do_network_test(self, model, {'name': u'bridge-network',
+ 'connection': 'bridge',
+ 'interface': iface, 'vlan_id':
987})
diff --git a/src/wok/plugins/kimchi/tests/test_mock_storagepool.py
b/src/wok/plugins/kimchi/tests/test_mock_storagepool.py
new file mode 100644
index 0000000..5cf5b3e
--- /dev/null
+++ b/src/wok/plugins/kimchi/tests/test_mock_storagepool.py
@@ -0,0 +1,147 @@
+# -*- coding: utf-8 -*-
+#
+# Project Kimchi
+#
+# Copyright IBM, Corp. 2015
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+import json
+import os
+import unittest
+from functools import partial
+
+from wok.plugins.kimchi.mockmodel import MockModel
+
+from utils import get_free_port, patch_auth, request, run_server
+
+
+model = None
+test_server = None
+host = None
+port = None
+ssl_port = None
+cherrypy_port = None
+
+
+def setUpModule():
+ global test_server, model, host, port, ssl_port, cherrypy_port
+
+ patch_auth()
+ model = MockModel('/tmp/obj-store-test')
+ host = '127.0.0.1'
+ port = get_free_port('http')
+ ssl_port = get_free_port('https')
+ cherrypy_port = get_free_port('cherrypy_port')
+ test_server = run_server(host, port, ssl_port, test_mode=True,
+ cherrypy_port=cherrypy_port, model=model)
+
+
+def tearDownModule():
+ test_server.stop()
+ os.unlink('/tmp/obj-store-test')
+
+
+class MockStoragepoolTests(unittest.TestCase):
+ def setUp(self):
+ self.request = partial(request, host, ssl_port)
+ model.reset()
+
+ def _task_lookup(self, taskid):
+ return json.loads(
+ self.request('/tasks/%s' % taskid).read()
+ )
+
+ def test_storagepool(self):
+ # MockModel always returns 2 partitions (vdx, vdz)
+ partitions = json.loads(
+ self.request('/plugins/kimchi/host/partitions').read()
+ )
+ devs = [dev['path'] for dev in partitions]
+
+ # MockModel always returns 3 FC devices
+ fc_devs = json.loads(
+ self.request('/plugins/kimchi/host/devices?_cap=fc_host').read()
+ )
+ fc_devs = [dev['name'] for dev in fc_devs]
+
+ poolDefs = [
+ {'type': 'dir', 'name':
u'k������h��UnitTestDirPool',
+ 'path': '/tmp/kimchi-images'},
+ {'type': 'netfs', 'name':
u'k������h��UnitTestNSFPool',
+ 'source': {'host': 'localhost',
+ 'path': '/var/lib/kimchi/nfs-pool'}},
+ {'type': 'scsi', 'name':
u'k������h��UnitTestSCSIFCPool',
+ 'source': {'adapter_name': fc_devs[0]}},
+ {'type': 'iscsi', 'name':
u'k������h��UnitTestISCSIPool',
+ 'source': {'host': '127.0.0.1',
+ 'target':
'iqn.2015-01.localhost.kimchiUnitTest'}},
+ {'type': 'logical', 'name':
u'k������h��UnitTestLogicalPool',
+ 'source': {'devices': [devs[0]]}}]
+
+ def _do_test(params):
+ name = params['name']
+ uri = '/plugins/kimchi/storagepools/%s' %
name.encode('utf-8')
+
+ req = json.dumps(params)
+ resp = self.request('/plugins/kimchi/storagepools', req,
'POST')
+ self.assertEquals(201, resp.status)
+
+ # activate the storage pool
+ resp = self.request(uri + '/activate', '{}', 'POST')
+ storagepool = json.loads(self.request(uri).read())
+ self.assertEquals('active', storagepool['state'])
+
+ # Set autostart flag of an active storage pool
+ for autostart in [True, False]:
+ t = {'autostart': autostart}
+ req = json.dumps(t)
+ resp = self.request(uri, req, 'PUT')
+ storagepool = json.loads(self.request(uri).read())
+ self.assertEquals(autostart, storagepool['autostart'])
+
+ # Extend an active logical pool
+ if params['type'] == 'logical':
+ t = {'disks': [devs[1]]}
+ req = json.dumps(t)
+ resp = self.request(uri, req, 'PUT')
+ self.assertEquals(200, resp.status)
+
+ # Deactivate the storage pool
+ resp = self.request(uri + '/deactivate', '{}',
'POST')
+ storagepool = json.loads(self.request(uri).read())
+ self.assertEquals('inactive', storagepool['state'])
+
+ # Set autostart flag of an inactive storage pool
+ for autostart in [True, False]:
+ t = {'autostart': autostart}
+ req = json.dumps(t)
+ resp = self.request(uri, req, 'PUT')
+ storagepool = json.loads(self.request(uri).read())
+ self.assertEquals(autostart, storagepool['autostart'])
+
+ # Extend an inactive logical pool
+ if params['type'] == 'logical':
+ t = {'disks': [devs[1]]}
+ req = json.dumps(t)
+ resp = self.request(uri, req, 'PUT')
+ self.assertEquals(200, resp.status)
+
+ # Delete the storage pool
+ resp = self.request(uri, '{}', 'DELETE')
+ self.assertEquals(204, resp.status)
+
+ for pool in poolDefs:
+ _do_test(pool)
diff --git a/src/wok/plugins/kimchi/tests/test_mock_storagevolume.py
b/src/wok/plugins/kimchi/tests/test_mock_storagevolume.py
new file mode 100644
index 0000000..9d0a5ad
--- /dev/null
+++ b/src/wok/plugins/kimchi/tests/test_mock_storagevolume.py
@@ -0,0 +1,98 @@
+# -*- coding: utf-8 -*-
+#
+# Project Kimchi
+#
+# Copyright IBM, Corp. 2015
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+import json
+import os
+import unittest
+from functools import partial
+
+from wok.plugins.kimchi.mockmodel import MockModel
+
+from test_model_storagevolume import _do_volume_test
+from utils import get_free_port, patch_auth, request, run_server
+
+
+model = None
+test_server = None
+host = None
+port = None
+ssl_port = None
+cherrypy_port = None
+
+
+def setUpModule():
+ global test_server, model, host, port, ssl_port, cherrypy_port
+
+ patch_auth()
+ model = MockModel('/tmp/obj-store-test')
+ host = '127.0.0.1'
+ port = get_free_port('http')
+ ssl_port = get_free_port('https')
+ cherrypy_port = get_free_port('cherrypy_port')
+ test_server = run_server(host, port, ssl_port, test_mode=True,
+ cherrypy_port=cherrypy_port, model=model)
+
+
+def tearDownModule():
+ test_server.stop()
+ os.unlink('/tmp/obj-store-test')
+
+
+class MockStorageVolumeTests(unittest.TestCase):
+ def setUp(self):
+ self.request = partial(request, host, ssl_port)
+
+ def test_storagevolume(self):
+ # MockModel always returns 2 partitions (vdx, vdz)
+ partitions = json.loads(
+ self.request('/plugins/kimchi/host/partitions').read()
+ )
+ devs = [dev['path'] for dev in partitions]
+
+ # MockModel always returns 3 FC devices
+ fc_devs = json.loads(
+ self.request('/plugins/kimchi/host/devices?_cap=fc_host').read()
+ )
+ fc_devs = [dev['name'] for dev in fc_devs]
+
+ poolDefs = [
+ {'type': 'dir', 'name':
u'k������h��UnitTestDirPool',
+ 'path': '/tmp/kimchi-images'},
+ {'type': 'netfs', 'name':
u'k������h��UnitTestNSFPool',
+ 'source': {'host': 'localhost',
+ 'path': '/var/lib/kimchi/nfs-pool'}},
+ {'type': 'scsi', 'name':
u'k������h��UnitTestSCSIFCPool',
+ 'source': {'adapter_name': fc_devs[0]}},
+ {'type': 'iscsi', 'name':
u'k������h��UnitTestISCSIPool',
+ 'source': {'host': '127.0.0.1',
+ 'target':
'iqn.2015-01.localhost.kimchiUnitTest'}},
+ {'type': 'logical', 'name':
u'k������h��UnitTestLogicalPool',
+ 'source': {'devices': [devs[0]]}}]
+
+ for pool in poolDefs:
+ pool_name = pool['name']
+ uri = '/plugins/kimchi/storagepools/%s' %
pool_name.encode('utf-8')
+ req = json.dumps(pool)
+ resp = self.request('/plugins/kimchi/storagepools', req,
'POST')
+ self.assertEquals(201, resp.status)
+ # activate the storage pool
+ resp = self.request(uri + '/activate', '{}', 'POST')
+ self.assertEquals(200, resp.status)
+ _do_volume_test(self, model, host, ssl_port, pool_name)
diff --git a/src/wok/plugins/kimchi/tests/test_mockmodel.py
b/src/wok/plugins/kimchi/tests/test_mockmodel.py
new file mode 100644
index 0000000..ffbf8d5
--- /dev/null
+++ b/src/wok/plugins/kimchi/tests/test_mockmodel.py
@@ -0,0 +1,141 @@
+#
+# Project Kimchi
+#
+# Copyright IBM, Corp. 2013-2015
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+import cherrypy
+import json
+import os
+import time
+import unittest
+
+from wok.plugins.kimchi import mockmodel
+from wok.plugins.kimchi.osinfo import get_template_default
+
+from utils import get_free_port, patch_auth, request, run_server, wait_task
+
+
+test_server = None
+model = None
+host = None
+port = None
+ssl_port = None
+fake_iso = None
+
+
+def setUpModule():
+ global host, port, ssl_port, model, test_server, fake_iso
+ cherrypy.request.headers = {'Accept': 'application/json'}
+ model = mockmodel.MockModel('/tmp/obj-store-test')
+ patch_auth()
+ port = get_free_port('http')
+ ssl_port = get_free_port('https')
+ host = '127.0.0.1'
+ test_server = run_server(host, port, ssl_port, test_mode=True,
+ model=model)
+ fake_iso = '/tmp/fake.iso'
+ open(fake_iso, 'w').close()
+
+
+def tearDown():
+ test_server.stop()
+ os.unlink('/tmp/obj-store-test')
+ os.unlink(fake_iso)
+
+
+class MockModelTests(unittest.TestCase):
+ def setUp(self):
+ model.reset()
+
+ def test_screenshot_refresh(self):
+ # Create a VM
+ req = json.dumps({'name': 'test', 'cdrom': fake_iso})
+ request(host, ssl_port, '/plugins/kimchi/templates', req,
'POST')
+ req = json.dumps({'name': 'test-vm', 'template':
'/templates/test'})
+ resp = request(host, ssl_port, '/plugins/kimchi/vms', req,
'POST')
+ task = json.loads(resp.read())
+ wait_task(model.task_lookup, task['id'])
+
+ # Test screenshot refresh for running vm
+ request(host, ssl_port, '/plugins/kimchi/vms/test-vm/start',
'{}',
+ 'POST')
+ resp = request(host, ssl_port,
+ '/plugins/kimchi/vms/test-vm/screenshot')
+ self.assertEquals(200, resp.status)
+ self.assertEquals('image/png', resp.getheader('content-type'))
+ resp1 = request(host, ssl_port, '/plugins/kimchi/vms/test-vm')
+ rspBody = resp1.read()
+ testvm_Data = json.loads(rspBody)
+ screenshotURL = testvm_Data['screenshot']
+ time.sleep(5)
+ resp2 = request(host, ssl_port, screenshotURL)
+ self.assertEquals(200, resp2.status)
+ self.assertEquals(resp2.getheader('content-type'),
+ resp.getheader('content-type'))
+ self.assertEquals(resp2.getheader('content-length'),
+ resp.getheader('content-length'))
+ self.assertEquals(resp2.getheader('last-modified'),
+ resp.getheader('last-modified'))
+
+ def test_vm_list_sorted(self):
+ req = json.dumps({'name': 'test', 'cdrom': fake_iso})
+ request(host, ssl_port, '/plugins/kimchi/templates', req,
'POST')
+
+ def add_vm(name):
+ # Create a VM
+ req = json.dumps({'name': name,
+ 'template':
'/plugins/kimchi/templates/test'})
+ task = json.loads(request(host, ssl_port, '/plugins/kimchi/vms',
+ req, 'POST').read())
+ wait_task(model.task_lookup, task['id'])
+
+ vms = [u'abc', u'bca', u'cab', u'xba']
+ for vm in vms:
+ add_vm(vm)
+
+ vms.append(u'test')
+ self.assertEqual(model.vms_get_list(), sorted(vms))
+
+ def test_vm_info(self):
+ model.templates_create({'name': u'test',
+ 'cdrom': fake_iso})
+ task = model.vms_create({'name': u'test-vm',
+ 'template':
'/plugins/kimchi/templates/test'})
+ wait_task(model.task_lookup, task['id'])
+ vms = model.vms_get_list()
+ self.assertEquals(2, len(vms))
+ self.assertIn(u'test-vm', vms)
+
+ keys = set(('name', 'state', 'stats', 'uuid',
'memory', 'cpus',
+ 'screenshot', 'icon', 'graphics',
'users', 'groups',
+ 'access', 'persistent'))
+
+ stats_keys = set(('cpu_utilization',
+ 'net_throughput', 'net_throughput_peak',
+ 'io_throughput', 'io_throughput_peak'))
+
+ info = model.vm_lookup(u'test-vm')
+ self.assertEquals(keys, set(info.keys()))
+ self.assertEquals('shutoff', info['state'])
+ self.assertEquals('test-vm', info['name'])
+ self.assertEquals(get_template_default('old', 'memory'),
+ info['memory'])
+ self.assertEquals(1, info['cpus'])
+ self.assertEquals('images/icon-vm.png', info['icon'])
+ self.assertEquals(stats_keys, set(info['stats'].keys()))
+ self.assertEquals('vnc', info['graphics']['type'])
+ self.assertEquals('127.0.0.1',
info['graphics']['listen'])
diff --git a/src/wok/plugins/kimchi/tests/test_model.py
b/src/wok/plugins/kimchi/tests/test_model.py
new file mode 100644
index 0000000..7c89048
--- /dev/null
+++ b/src/wok/plugins/kimchi/tests/test_model.py
@@ -0,0 +1,1248 @@
+# -*- coding: utf-8 -*-
+#
+# Project Kimchi
+#
+# Copyright IBM, Corp. 2013-2015
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+import grp
+import os
+import pwd
+import re
+import shutil
+import time
+import unittest
+import uuid
+
+import wok.objectstore
+from wok.basemodel import Singleton
+from wok.config import config
+from wok.exception import InvalidOperation
+from wok.exception import InvalidParameter, NotFoundError, OperationFailed
+from wok.rollbackcontext import RollbackContext
+from wok.utils import add_task
+
+from wok.plugins.kimchi import netinfo
+from wok.plugins.kimchi.osinfo import get_template_default
+from wok.plugins.kimchi.model import model
+from wok.plugins.kimchi.model.libvirtconnection import LibvirtConnection
+
+import iso_gen
+import utils
+
+
+invalid_repository_urls = ['www.fedora.org', # missing protocol
+ '://www.fedora.org', # missing protocol
+ 'http://www.fedora', # invalid domain name
+ 'file:///home/foobar'] # invalid path
+
+TMP_DIR = '/var/lib/kimchi/tests/'
+UBUNTU_ISO = TMP_DIR + 'ubuntu14.04.iso'
+
+
+def setUpModule():
+ if not os.path.exists(TMP_DIR):
+ os.makedirs(TMP_DIR)
+
+ iso_gen.construct_fake_iso(UBUNTU_ISO, True, '14.04', 'ubuntu')
+
+ # Some FeatureTests functions depend on server to validate their result.
+ # As CapabilitiesModel is a Singleton class it will get the first result
+ # from FeatureTests which may be wrong when using the Model instance
+ # directly - the case of this test_model.py
+ # So clean Singleton instances to make sure to get the right result when
+ # running the following tests.
+ Singleton._instances = {}
+
+
+def tearDownModule():
+ shutil.rmtree(TMP_DIR)
+
+
+class ModelTests(unittest.TestCase):
+ def setUp(self):
+ self.tmp_store = '/tmp/kimchi-store-test'
+
+ def tearDown(self):
+ # FIXME: Tests using 'test:///default' URI should be moved to
+ # test_rest or test_mockmodel to avoid overriding problems
+ LibvirtConnection._connections['test:///default'] = {}
+
+ os.unlink(self.tmp_store)
+
+ def test_vm_info(self):
+ inst = model.Model('test:///default', self.tmp_store)
+ vms = inst.vms_get_list()
+ self.assertEquals(1, len(vms))
+ self.assertEquals('test', vms[0])
+
+ keys = set(('name', 'state', 'stats', 'uuid',
'memory', 'cpus',
+ 'screenshot', 'icon', 'graphics',
'users', 'groups',
+ 'access', 'persistent'))
+
+ stats_keys = set(('cpu_utilization',
+ 'net_throughput', 'net_throughput_peak',
+ 'io_throughput', 'io_throughput_peak'))
+ info = inst.vm_lookup('test')
+ self.assertEquals(keys, set(info.keys()))
+ self.assertEquals('running', info['state'])
+ self.assertEquals('test', info['name'])
+ self.assertEquals(2048, info['memory'])
+ self.assertEquals(2, info['cpus'])
+ self.assertEquals(None, info['icon'])
+ self.assertEquals(stats_keys, set(info['stats'].keys()))
+ self.assertRaises(NotFoundError, inst.vm_lookup, 'nosuchvm')
+ self.assertEquals([], info['users'])
+ self.assertEquals([], info['groups'])
+ self.assertTrue(info['persistent'])
+
+ @unittest.skipUnless(utils.running_as_root(), 'Must be run as root')
+ def test_vm_lifecycle(self):
+ inst = model.Model(objstore_loc=self.tmp_store)
+
+ with RollbackContext() as rollback:
+ vol_params = {'name': u'test-vol', 'capacity': 1024}
+ task = inst.storagevolumes_create(u'default', vol_params)
+ rollback.prependDefer(inst.storagevolume_delete, u'default',
+ vol_params['name'])
+ inst.task_wait(task['id'])
+ task = inst.task_lookup(task['id'])
+ self.assertEquals('finished', task['status'])
+ vol = inst.storagevolume_lookup(u'default',
vol_params['name'])
+
+ params = {'name': 'test', 'disks': [{'base':
vol['path'],
+ 'size': 1}],
+ 'cdrom': UBUNTU_ISO}
+ inst.templates_create(params)
+ rollback.prependDefer(inst.template_delete, 'test')
+
+ params = {'name': 'kimchi-vm',
+ 'template': '/plugins/kimchi/templates/test'}
+ task = inst.vms_create(params)
+ rollback.prependDefer(inst.vm_delete, 'kimchi-vm')
+ inst.task_wait(task['id'], 10)
+ task = inst.task_lookup(task['id'])
+ self.assertEquals('finished', task['status'])
+
+ vms = inst.vms_get_list()
+ self.assertTrue('kimchi-vm' in vms)
+
+ inst.vm_start('kimchi-vm')
+
+ info = inst.vm_lookup('kimchi-vm')
+ self.assertEquals('running', info['state'])
+
+ self.assertRaises(InvalidOperation, inst.vmsnapshots_create,
+ u'kimchi-vm')
+
+ inst.vm_poweroff(u'kimchi-vm')
+ vm = inst.vm_lookup(u'kimchi-vm')
+
+ empty_snap = inst.currentvmsnapshot_lookup(u'kimchi-vm')
+ self.assertEquals({}, empty_snap)
+
+ # this snapshot should be deleted when its VM is deleted
+ params = {'name': u'mysnap'}
+ task = inst.vmsnapshots_create(u'kimchi-vm', params)
+ inst.task_wait(task['id'])
+ task = inst.task_lookup(task['id'])
+ self.assertEquals('finished', task['status'])
+
+ self.assertRaises(NotFoundError, inst.vmsnapshot_lookup,
+ u'kimchi-vm', u'foobar')
+
+ snap = inst.vmsnapshot_lookup(u'kimchi-vm', params['name'])
+ self.assertTrue(int(time.time()) >= int(snap['created']))
+ self.assertEquals(vm['state'], snap['state'])
+ self.assertEquals(params['name'], snap['name'])
+ self.assertEquals(u'', snap['parent'])
+
+ snaps = inst.vmsnapshots_get_list(u'kimchi-vm')
+ self.assertEquals([params['name']], snaps)
+
+ current_snap = inst.currentvmsnapshot_lookup(u'kimchi-vm')
+ self.assertEquals(snap, current_snap)
+
+ task = inst.vmsnapshots_create(u'kimchi-vm')
+ snap_name = task['target_uri'].split('/')[-1]
+ rollback.prependDefer(inst.vmsnapshot_delete,
+ u'kimchi-vm', snap_name)
+ inst.task_wait(task['id'])
+ task = inst.task_lookup(task['id'])
+ self.assertEquals('finished', task['status'])
+
+ snaps = inst.vmsnapshots_get_list(u'kimchi-vm')
+ self.assertEquals(sorted([params['name'], snap_name],
+ key=unicode.lower), snaps)
+
+ snap = inst.vmsnapshot_lookup(u'kimchi-vm', snap_name)
+ current_snap = inst.currentvmsnapshot_lookup(u'kimchi-vm')
+ self.assertEquals(snap, current_snap)
+
+ # update vm name
+ inst.vm_update('kimchi-vm', {'name':
u'kimchi-vm-new'})
+
+ # Look up the first created snapshot from the renamed vm
+ snap = inst.vmsnapshot_lookup(u'kimchi-vm-new',
params['name'])
+
+ # snapshot revert to the first created vm
+ result = inst.vmsnapshot_revert(u'kimchi-vm-new',
params['name'])
+ self.assertEquals(result, [u'kimchi-vm', snap['name']])
+
+ vm = inst.vm_lookup(u'kimchi-vm')
+ self.assertEquals(vm['state'], snap['state'])
+
+ current_snap = inst.currentvmsnapshot_lookup(u'kimchi-vm')
+ self.assertEquals(params['name'], current_snap['name'])
+
+ self.assertRaises(NotFoundError, inst.vmsnapshot_delete,
+ u'kimchi-vm', u'foobar')
+
+ # suspend and resume the VM
+ info = inst.vm_lookup(u'kimchi-vm')
+ self.assertEquals(info['state'], 'shutoff')
+ self.assertRaises(InvalidOperation, inst.vm_suspend, u'kimchi-vm')
+ inst.vm_start(u'kimchi-vm')
+ info = inst.vm_lookup(u'kimchi-vm')
+ self.assertEquals(info['state'], 'running')
+ inst.vm_suspend(u'kimchi-vm')
+ info = inst.vm_lookup(u'kimchi-vm')
+ self.assertEquals(info['state'], 'paused')
+ self.assertRaises(InvalidParameter, inst.vm_update, u'kimchi-vm',
+ {'name': 'foo'})
+ inst.vm_resume(u'kimchi-vm')
+ info = inst.vm_lookup(u'kimchi-vm')
+ self.assertEquals(info['state'], 'running')
+ self.assertRaises(InvalidOperation, inst.vm_resume, u'kimchi-vm')
+ # leave the VM suspended to make sure a paused VM can be
+ # deleted correctly
+ inst.vm_suspend(u'kimchi-vm')
+
+ vms = inst.vms_get_list()
+ self.assertFalse('kimchi-vm' in vms)
+
+ @unittest.skipUnless(utils.running_as_root(), 'Must be run as root')
+ def test_image_based_template(self):
+ inst = model.Model(objstore_loc=self.tmp_store)
+
+ with RollbackContext() as rollback:
+ vol = 'base-vol.img'
+ params = {'name': vol,
+ 'capacity': 1073741824, # 1 GiB
+ 'allocation': 1048576, # 1 MiB
+ 'format': 'qcow2'}
+ task_id = inst.storagevolumes_create('default',
params)['id']
+ rollback.prependDefer(inst.storagevolume_delete, 'default', vol)
+ inst.task_wait(task_id)
+ self.assertEquals('finished',
inst.task_lookup(task_id)['status'])
+ vol_path = inst.storagevolume_lookup('default', vol)['path']
+
+ params = {'name': 'test', 'disks': [{'base':
vol_path}]}
+ self.assertRaises(OperationFailed, inst.templates_create, params)
+
+ # Hack the model objstore to add a new template
+ # It is needed as the image file must be a bootable image when
+ # using model
+ # As it is difficult to create one on test runtime, inject a
+ # template with an empty image file to the objstore to test the
+ # feature
+ tmpl_name = "img-tmpl"
+ tmpl_info = {"cpus": 1, "cdrom": "",
+ "graphics": {"type": "vnc",
"listen": "127.0.0.1"},
+ "networks": ["default"], "memory":
1024, "folder": [],
+ "icon": "images/icon-vm.png",
+ "os_distro": "unknown",
"os_version": "unknown",
+ "disks": [{"base": vol_path,
"size": 10}],
+ "storagepool":
"/plugins/kimchi/storagepools/default"}
+
+ with inst.objstore as session:
+ session.store('template', tmpl_name, tmpl_info)
+
+ params = {'name': 'kimchi-vm',
+ 'template': '/plugins/kimchi/templates/img-tmpl'}
+ task = inst.vms_create(params)
+ inst.task_wait(task['id'])
+ rollback.prependDefer(inst.vm_delete, 'kimchi-vm')
+
+ vms = inst.vms_get_list()
+ self.assertTrue('kimchi-vm' in vms)
+
+ inst.vm_start('kimchi-vm')
+ rollback.prependDefer(inst.vm_poweroff, 'kimchi-vm')
+
+ info = inst.vm_lookup('kimchi-vm')
+ self.assertEquals('running', info['state'])
+
+ @unittest.skipUnless(utils.running_as_root(), 'Must be run as root')
+ def test_vm_graphics(self):
+ inst = model.Model(objstore_loc=self.tmp_store)
+ params = {'name': 'test', 'disks': [], 'cdrom':
UBUNTU_ISO}
+ inst.templates_create(params)
+ with RollbackContext() as rollback:
+ params = {'name': 'kimchi-vnc',
+ 'template': '/plugins/kimchi/templates/test'}
+ task1 = inst.vms_create(params)
+ inst.task_wait(task1['id'])
+ rollback.prependDefer(inst.vm_delete, 'kimchi-vnc')
+
+ info = inst.vm_lookup('kimchi-vnc')
+ self.assertEquals('vnc', info['graphics']['type'])
+ self.assertEquals('127.0.0.1',
info['graphics']['listen'])
+
+ graphics = {'type': 'spice', 'listen':
'127.0.0.1'}
+ params = {'name': 'kimchi-spice',
+ 'template': '/plugins/kimchi/templates/test',
+ 'graphics': graphics}
+ task2 = inst.vms_create(params)
+ inst.task_wait(task2['id'])
+ rollback.prependDefer(inst.vm_delete, 'kimchi-spice')
+
+ info = inst.vm_lookup('kimchi-spice')
+ self.assertEquals('spice', info['graphics']['type'])
+ self.assertEquals('127.0.0.1',
info['graphics']['listen'])
+
+ inst.template_delete('test')
+
+ @unittest.skipUnless(utils.running_as_root(), 'Must be run as root')
+ def test_vm_ifaces(self):
+ inst = model.Model(objstore_loc=self.tmp_store)
+ with RollbackContext() as rollback:
+ params = {'name': 'test', 'disks': [],
'cdrom': UBUNTU_ISO}
+ inst.templates_create(params)
+ rollback.prependDefer(inst.template_delete, 'test')
+
+ # Create a network
+ net_name = 'test-network'
+ net_args = {'name': net_name,
+ 'connection': 'nat',
+ 'subnet': '127.0.100.0/24'}
+ inst.networks_create(net_args)
+ rollback.prependDefer(inst.network_delete, net_name)
+ inst.network_activate(net_name)
+ rollback.prependDefer(inst.network_deactivate, net_name)
+
+ for vm_name in ['kimchi-ifaces', 'kimchi-ifaces-running']:
+ params = {'name': vm_name,
+ 'template': '/plugins/kimchi/templates/test'}
+ task = inst.vms_create(params)
+ inst.task_wait(task['id'])
+ rollback.prependDefer(inst.vm_delete, vm_name)
+
+ ifaces = inst.vmifaces_get_list(vm_name)
+ self.assertEquals(1, len(ifaces))
+
+ iface = inst.vmiface_lookup(vm_name, ifaces[0])
+ self.assertEquals(17, len(iface['mac']))
+ self.assertEquals("default", iface['network'])
+ self.assertIn("model", iface)
+
+ # attach network interface to vm
+ iface_args = {"type": "network",
+ "network": "test-network",
+ "model": "virtio"}
+ mac = inst.vmifaces_create(vm_name, iface_args)
+ # detach network interface from vm
+ rollback.prependDefer(inst.vmiface_delete, vm_name, mac)
+ self.assertEquals(17, len(mac))
+
+ iface = inst.vmiface_lookup(vm_name, mac)
+ self.assertEquals("network", iface["type"])
+ self.assertEquals("test-network", iface['network'])
+ self.assertEquals("virtio", iface["model"])
+
+ # attach network interface to vm without providing model
+ iface_args = {"type": "network",
+ "network": "test-network"}
+ mac = inst.vmifaces_create(vm_name, iface_args)
+ rollback.prependDefer(inst.vmiface_delete, vm_name, mac)
+
+ iface = inst.vmiface_lookup(vm_name, mac)
+ self.assertEquals("network", iface["type"])
+ self.assertEquals("test-network", iface['network'])
+
+ # update vm interface
+ newMacAddr = '54:50:e3:44:8a:af'
+ iface_args = {"mac": newMacAddr}
+ inst.vmiface_update(vm_name, mac, iface_args)
+ iface = inst.vmiface_lookup(vm_name, newMacAddr)
+ self.assertEquals(newMacAddr, iface['mac'])
+
+ # undo mac address change
+ iface_args = {"mac": mac}
+ inst.vmiface_update(vm_name, newMacAddr, iface_args)
+ iface = inst.vmiface_lookup(vm_name, mac)
+ self.assertEquals(mac, iface['mac'])
+
+ @unittest.skipUnless(utils.running_as_root(), 'Must be run as root')
+ def test_vm_disk(self):
+ disk_path = os.path.join(TMP_DIR, 'existent2.iso')
+ open(disk_path, 'w').close()
+ modern_disk_bus = get_template_default('modern', 'disk_bus')
+
+ def _attach_disk(expect_bus=modern_disk_bus):
+ disk_args = {"type": "disk",
+ "pool": pool,
+ "vol": vol}
+ disk = inst.vmstorages_create(vm_name, disk_args)
+ storage_list = inst.vmstorages_get_list(vm_name)
+ self.assertEquals(prev_count + 1, len(storage_list))
+
+ # Check the bus type to be 'virtio'
+ disk_info = inst.vmstorage_lookup(vm_name, disk)
+ self.assertEquals(u'disk', disk_info['type'])
+ self.assertEquals(vol_path, disk_info['path'])
+ self.assertEquals(expect_bus, disk_info['bus'])
+ return disk
+
+ inst = model.Model(objstore_loc=self.tmp_store)
+ with RollbackContext() as rollback:
+ path = os.path.join(TMP_DIR, 'kimchi-images')
+ pool = 'test-pool'
+ vol = 'test-volume.img'
+ vol_path = "%s/%s" % (path, vol)
+ if not os.path.exists(path):
+ os.mkdir(path)
+ rollback.prependDefer(shutil.rmtree, path)
+
+ args = {'name': pool,
+ 'path': path,
+ 'type': 'dir'}
+ inst.storagepools_create(args)
+ rollback.prependDefer(inst.storagepool_delete, pool)
+
+ # Activate the pool before adding any volume
+ inst.storagepool_activate(pool)
+ rollback.prependDefer(inst.storagepool_deactivate, pool)
+
+ params = {'name': vol,
+ 'capacity': 1073741824, # 1 GiB
+ 'allocation': 536870912, # 512 MiB
+ 'format': 'qcow2'}
+ task_id = inst.storagevolumes_create(pool, params)['id']
+ rollback.prependDefer(inst.storagevolume_delete, pool, vol)
+ inst.task_wait(task_id)
+
+ vm_name = 'kimchi-cdrom'
+ params = {'name': 'test', 'disks': [],
'cdrom': UBUNTU_ISO}
+ inst.templates_create(params)
+ rollback.prependDefer(inst.template_delete, 'test')
+ params = {'name': vm_name,
+ 'template': '/plugins/kimchi/templates/test'}
+ task1 = inst.vms_create(params)
+ inst.task_wait(task1['id'])
+ rollback.prependDefer(inst.vm_delete, vm_name)
+
+ prev_count = len(inst.vmstorages_get_list(vm_name))
+ self.assertEquals(1, prev_count)
+
+ # Volume format with mismatched type raise error
+ cdrom_args = {"type": "cdrom", "pool": pool,
"vol": vol}
+ self.assertRaises(InvalidParameter, inst.vmstorages_create,
+ vm_name, cdrom_args)
+
+ # Cold plug and unplug a disk
+ disk = _attach_disk()
+ inst.vmstorage_delete(vm_name, disk)
+
+ # Hot plug a disk
+ inst.vm_start(vm_name)
+ disk = _attach_disk()
+
+ # VM disk still there after powered off
+ inst.vm_poweroff(vm_name)
+ disk_info = inst.vmstorage_lookup(vm_name, disk)
+ self.assertEquals(u'disk', disk_info['type'])
+ inst.vmstorage_delete(vm_name, disk)
+
+ # Specifying pool and path at same time will fail
+ disk_args = {"type": "disk",
+ "pool": pool,
+ "vol": vol,
+ "path": disk_path}
+ self.assertRaises(
+ InvalidParameter, inst.vmstorages_create, vm_name, disk_args)
+
+ old_distro_iso = TMP_DIR + 'rhel4_8.iso'
+ iso_gen.construct_fake_iso(old_distro_iso, True, '4.8',
'rhel')
+
+ vm_name = 'kimchi-ide-bus-vm'
+ params = {'name': 'old_distro_template', 'disks':
[],
+ 'cdrom': old_distro_iso}
+ inst.templates_create(params)
+ rollback.prependDefer(inst.template_delete, 'old_distro_template')
+ params = {
+ 'name': vm_name,
+ 'template':
'/plugins/kimchi/templates/old_distro_template'
+ }
+ task2 = inst.vms_create(params)
+ inst.task_wait(task2['id'])
+ rollback.prependDefer(inst.vm_delete, vm_name)
+
+ # Need to check the right disk_bus for old distro
+ disk = _attach_disk(get_template_default('old', 'disk_bus'))
+ inst.vmstorage_delete('kimchi-ide-bus-vm', disk)
+
+ # Hot plug IDE bus disk does not work
+ inst.vm_start(vm_name)
+ self.assertRaises(InvalidOperation, _attach_disk)
+ inst.vm_poweroff(vm_name)
+
+ @unittest.skipUnless(utils.running_as_root(), 'Must be run as root')
+ def test_vm_cdrom(self):
+ inst = model.Model(objstore_loc=self.tmp_store)
+ with RollbackContext() as rollback:
+ vm_name = 'kimchi-cdrom'
+ params = {'name': 'test', 'disks': [],
'cdrom': UBUNTU_ISO}
+ inst.templates_create(params)
+ rollback.prependDefer(inst.template_delete, 'test')
+ params = {'name': vm_name,
+ 'template': '/plugins/kimchi/templates/test'}
+ task = inst.vms_create(params)
+ inst.task_wait(task['id'])
+ rollback.prependDefer(inst.vm_delete, vm_name)
+
+ prev_count = len(inst.vmstorages_get_list(vm_name))
+ self.assertEquals(1, prev_count)
+
+ # dummy .iso files
+ iso_path = os.path.join(TMP_DIR, 'existent.iso')
+ iso_path2 = os.path.join(TMP_DIR, 'existent2.iso')
+ open(iso_path, 'w').close()
+ rollback.prependDefer(os.remove, iso_path)
+ open(iso_path2, 'w').close()
+ rollback.prependDefer(os.remove, iso_path2)
+ wrong_iso_path = '/nonexistent.iso'
+
+ # Create a cdrom
+ cdrom_args = {"type": "cdrom",
+ "path": iso_path}
+ cdrom_dev = inst.vmstorages_create(vm_name, cdrom_args)
+ storage_list = inst.vmstorages_get_list(vm_name)
+ self.assertEquals(prev_count + 1, len(storage_list))
+
+ # Get cdrom info
+ cd_info = inst.vmstorage_lookup(vm_name, cdrom_dev)
+ self.assertEquals(u'cdrom', cd_info['type'])
+ self.assertEquals(iso_path, cd_info['path'])
+
+ # update path of existing cd with
+ # non existent iso
+ self.assertRaises(InvalidParameter, inst.vmstorage_update,
+ vm_name, cdrom_dev, {'path': wrong_iso_path})
+
+ # Make sure CD ROM still exists after failure
+ cd_info = inst.vmstorage_lookup(vm_name, cdrom_dev)
+ self.assertEquals(u'cdrom', cd_info['type'])
+ self.assertEquals(iso_path, cd_info['path'])
+
+ # update path of existing cd with existent iso of shutoff vm
+ inst.vmstorage_update(vm_name, cdrom_dev, {'path': iso_path2})
+ cdrom_info = inst.vmstorage_lookup(vm_name, cdrom_dev)
+ self.assertEquals(iso_path2, cdrom_info['path'])
+
+ # update path of existing cd with existent iso of running vm
+ inst.vm_start(vm_name)
+ inst.vmstorage_update(vm_name, cdrom_dev, {'path': iso_path})
+ cdrom_info = inst.vmstorage_lookup(vm_name, cdrom_dev)
+ self.assertEquals(iso_path, cdrom_info['path'])
+
+ # eject cdrom
+ cdrom_dev = inst.vmstorage_update(vm_name, cdrom_dev, {'path':
''})
+ cdrom_info = inst.vmstorage_lookup(vm_name, cdrom_dev)
+ self.assertEquals('', cdrom_info['path'])
+ inst.vm_poweroff(vm_name)
+
+ # removing non existent cdrom
+ self.assertRaises(NotFoundError, inst.vmstorage_delete, vm_name,
+ "fakedev")
+
+ # removing valid cdrom
+ inst.vmstorage_delete(vm_name, cdrom_dev)
+ storage_list = inst.vmstorages_get_list(vm_name)
+ self.assertEquals(prev_count, len(storage_list))
+
+ # Create a new cdrom using a remote iso
+ valid_remote_iso_path = utils.get_remote_iso_path()
+ cdrom_args = {"type": "cdrom",
+ "path": valid_remote_iso_path}
+ cdrom_dev = inst.vmstorages_create(vm_name, cdrom_args)
+ storage_list = inst.vmstorages_get_list(vm_name)
+ self.assertEquals(prev_count + 1, len(storage_list))
+
+ # Update remote-backed cdrom with the same ISO
+ inst.vmstorage_update(vm_name, cdrom_dev,
+ {'path': valid_remote_iso_path})
+ cdrom_info = inst.vmstorage_lookup(vm_name, cdrom_dev)
+ cur_cdrom_path = re.sub(":80/", '/',
cdrom_info['path'])
+ self.assertEquals(valid_remote_iso_path, cur_cdrom_path)
+
+ @unittest.skipUnless(utils.running_as_root(), 'Must be run as root')
+ def test_vm_storage_provisioning(self):
+ inst = model.Model(objstore_loc=self.tmp_store)
+
+ with RollbackContext() as rollback:
+ params = {'name': 'test', 'disks': [{'size':
1}],
+ 'cdrom': UBUNTU_ISO}
+ inst.templates_create(params)
+ rollback.prependDefer(inst.template_delete, 'test')
+
+ params = {'name': 'test-vm-1',
+ 'template': '/plugins/kimchi/templates/test'}
+ task = inst.vms_create(params)
+ inst.task_wait(task['id'])
+ rollback.prependDefer(inst.vm_delete, 'test-vm-1')
+
+ vm_info = inst.vm_lookup(params['name'])
+ disk_path = '%s/%s-0.img' % (
+ inst.storagepool_lookup('default')['path'],
vm_info['uuid'])
+ self.assertTrue(os.access(disk_path, os.F_OK))
+ self.assertFalse(os.access(disk_path, os.F_OK))
+
+ def test_vm_memory_hotplug(self):
+ config.set("authentication", "method", "pam")
+ inst = model.Model(None, objstore_loc=self.tmp_store)
+ orig_params = {'name': 'test', 'memory': 1024,
'cdrom': UBUNTU_ISO}
+ inst.templates_create(orig_params)
+
+ with RollbackContext() as rollback:
+ params = {'name': 'kimchi-vm1',
+ 'template': '/plugins/kimchi/templates/test'}
+ task1 = inst.vms_create(params)
+ inst.task_wait(task1['id'])
+ rollback.prependDefer(utils.rollback_wrapper, inst.vm_delete,
+ 'kimchi-vm1')
+ # Start vm
+ inst.vm_start('kimchi-vm1')
+ rollback.prependDefer(utils.rollback_wrapper, inst.vm_poweroff,
+ 'kimchi-vm1')
+
+ # Hotplug memory, only available in Libvirt >= 1.2.14
+ params = {'memory': 2048}
+ if inst.capabilities_lookup()['mem_hotplug_support']:
+ inst.vm_update('kimchi-vm1', params)
+ rollback.prependDefer(utils.rollback_wrapper, inst.vm_delete,
+ 'kimchi-vm1')
+ self.assertEquals(params['memory'],
+
inst.vm_lookup('kimchi-vm1')['memory'])
+ else:
+ self.assertRaises(InvalidOperation, inst.vm_update,
+ 'kimchi-vm1', params)
+
+ def test_vm_edit(self):
+ config.set("authentication", "method", "pam")
+ inst = model.Model(None,
+ objstore_loc=self.tmp_store)
+
+ orig_params = {'name': 'test', 'memory': 1024,
'cpus': 1,
+ 'cdrom': UBUNTU_ISO}
+ inst.templates_create(orig_params)
+
+ with RollbackContext() as rollback:
+ params_1 = {'name': 'kimchi-vm1',
+ 'template': '/plugins/kimchi/templates/test'}
+ params_2 = {'name': 'kimchi-vm2',
+ 'template': '/plugins/kimchi/templates/test'}
+ task1 = inst.vms_create(params_1)
+ inst.task_wait(task1['id'])
+ rollback.prependDefer(utils.rollback_wrapper, inst.vm_delete,
+ 'kimchi-vm1')
+ task2 = inst.vms_create(params_2)
+ inst.task_wait(task2['id'])
+ rollback.prependDefer(utils.rollback_wrapper, inst.vm_delete,
+ 'kimchi-vm2')
+
+ vms = inst.vms_get_list()
+ self.assertTrue('kimchi-vm1' in vms)
+
+ # make sure "vm_update" works when the domain has a snapshot
+ inst.vmsnapshots_create(u'kimchi-vm1')
+
+ # update vm graphics when vm is not running
+ inst.vm_update(u'kimchi-vm1',
+ {"graphics": {"passwd":
"123456"}})
+
+ inst.vm_start('kimchi-vm1')
+ rollback.prependDefer(utils.rollback_wrapper, inst.vm_poweroff,
+ 'kimchi-vm1')
+
+ vm_info = inst.vm_lookup(u'kimchi-vm1')
+ self.assertEquals('123456',
vm_info['graphics']["passwd"])
+ self.assertEquals(None,
vm_info['graphics']["passwdValidTo"])
+
+ # update vm graphics when vm is running
+ inst.vm_update(u'kimchi-vm1',
+ {"graphics": {"passwd":
"abcdef",
+ "passwdValidTo": 20}})
+ vm_info = inst.vm_lookup(u'kimchi-vm1')
+ self.assertEquals('abcdef',
vm_info['graphics']["passwd"])
+ self.assertGreaterEqual(20,
vm_info['graphics']['passwdValidTo'])
+
+ info = inst.vm_lookup('kimchi-vm1')
+ self.assertEquals('running', info['state'])
+
+ params = {'name': 'new-vm'}
+ self.assertRaises(InvalidParameter, inst.vm_update,
+ 'kimchi-vm1', params)
+
+ # change VM users and groups, when wm is running.
+ inst.vm_update(u'kimchi-vm1',
+ {'users': ['root'], 'groups':
['root']})
+ vm_info = inst.vm_lookup(u'kimchi-vm1')
+ self.assertEquals(['root'], vm_info['users'])
+ self.assertEquals(['root'], vm_info['groups'])
+ # change VM users and groups by removing all elements,
+ # when wm is running.
+ inst.vm_update(u'kimchi-vm1', {'users': [], 'groups':
[]})
+ vm_info = inst.vm_lookup(u'kimchi-vm1')
+ self.assertEquals([], vm_info['users'])
+ self.assertEquals([], vm_info['groups'])
+
+ inst.vm_poweroff('kimchi-vm1')
+ self.assertRaises(OperationFailed, inst.vm_update,
+ 'kimchi-vm1', {'name':
'kimchi-vm2'})
+
+ params = {'name': u'��e��-�����', 'cpus': 4,
'memory': 2048}
+ inst.vm_update('kimchi-vm1', params)
+ rollback.prependDefer(utils.rollback_wrapper, inst.vm_delete,
+ u'��e��-�����')
+ self.assertEquals(info['uuid'],
inst.vm_lookup(u'��e��-�����')['uuid'])
+ info = inst.vm_lookup(u'��e��-�����')
+ for key in params.keys():
+ self.assertEquals(params[key], info[key])
+
+ # change only VM users - groups are not changed (default is empty)
+ users = inst.users_get_list()[:3]
+ inst.vm_update(u'��e��-�����', {'users': users})
+ self.assertEquals(users,
inst.vm_lookup(u'��e��-�����')['users'])
+ self.assertEquals([],
inst.vm_lookup(u'��e��-�����')['groups'])
+
+ # change only VM groups - users are not changed (default is empty)
+ groups = inst.groups_get_list()[:2]
+ inst.vm_update(u'��e��-�����', {'groups': groups})
+ self.assertEquals(users,
inst.vm_lookup(u'��e��-�����')['users'])
+ self.assertEquals(groups,
inst.vm_lookup(u'��e��-�����')['groups'])
+
+ # change VM users and groups by adding a new element to each one
+ users.append(pwd.getpwuid(os.getuid()).pw_name)
+ groups.append(grp.getgrgid(os.getgid()).gr_name)
+ inst.vm_update(u'��e��-�����', {'users': users,
'groups': groups})
+ self.assertEquals(users,
inst.vm_lookup(u'��e��-�����')['users'])
+ self.assertEquals(groups,
inst.vm_lookup(u'��e��-�����')['groups'])
+
+ # change VM users (wrong value) and groups
+ # when an error occurs, everything fails and nothing is changed
+ self.assertRaises(InvalidParameter, inst.vm_update, u'��e��-�����',
+ {'users': ['userdoesnotexist'],
'groups': []})
+ self.assertEquals(users,
inst.vm_lookup(u'��e��-�����')['users'])
+ self.assertEquals(groups,
inst.vm_lookup(u'��e��-�����')['groups'])
+
+ # change VM users and groups (wrong value)
+ # when an error occurs, everything fails and nothing is changed
+ self.assertRaises(InvalidParameter, inst.vm_update, u'��e��-�����',
+ {'users': [], 'groups':
['groupdoesnotexist']})
+ self.assertEquals(users,
inst.vm_lookup(u'��e��-�����')['users'])
+ self.assertEquals(groups,
inst.vm_lookup(u'��e��-�����')['groups'])
+
+ # change VM users and groups by removing all elements
+ inst.vm_update(u'��e��-�����', {'users': [],
'groups': []})
+ self.assertEquals([],
inst.vm_lookup(u'��e��-�����')['users'])
+ self.assertEquals([],
inst.vm_lookup(u'��e��-�����')['groups'])
+
+ def test_get_interfaces(self):
+ inst = model.Model('test:///default',
+ objstore_loc=self.tmp_store)
+ expected_ifaces = netinfo.all_favored_interfaces()
+ ifaces = inst.interfaces_get_list()
+ self.assertEquals(len(expected_ifaces), len(ifaces))
+ for name in expected_ifaces:
+ iface = inst.interface_lookup(name)
+ self.assertEquals(iface['name'], name)
+ self.assertIn('type', iface)
+ self.assertIn('status', iface)
+ self.assertIn('ipaddr', iface)
+ self.assertIn('netmask', iface)
+
+ def test_async_tasks(self):
+ class task_except(Exception):
+ pass
+
+ def quick_op(cb, message):
+ cb(message, True)
+
+ def long_op(cb, params):
+ time.sleep(params.get('delay', 3))
+ cb(params.get('message', ''), params.get('result',
False))
+
+ def abnormal_op(cb, params):
+ try:
+ raise task_except
+ except:
+ cb("Exception raised", False)
+
+ def continuous_ops(cb, params):
+ cb("step 1 OK")
+ time.sleep(2)
+ cb("step 2 OK")
+ time.sleep(2)
+ cb("step 3 OK", params.get('result', True))
+
+ inst = model.Model('test:///default',
+ objstore_loc=self.tmp_store)
+ taskid = add_task('', quick_op, inst.objstore, 'Hello')
+ inst.task_wait(taskid)
+ self.assertEquals(1, taskid)
+ self.assertEquals('finished',
inst.task_lookup(taskid)['status'])
+ self.assertEquals('Hello', inst.task_lookup(taskid)['message'])
+
+ taskid = add_task('', long_op, inst.objstore,
+ {'delay': 3, 'result': False,
+ 'message': 'It was not meant to be'})
+ self.assertEquals(2, taskid)
+ self.assertEquals('running', inst.task_lookup(taskid)['status'])
+ self.assertEquals('OK', inst.task_lookup(taskid)['message'])
+ inst.task_wait(taskid)
+ self.assertEquals('failed', inst.task_lookup(taskid)['status'])
+ self.assertEquals('It was not meant to be',
+ inst.task_lookup(taskid)['message'])
+ taskid = add_task('', abnormal_op, inst.objstore, {})
+ inst.task_wait(taskid)
+ self.assertEquals('Exception raised',
+ inst.task_lookup(taskid)['message'])
+ self.assertEquals('failed', inst.task_lookup(taskid)['status'])
+
+ taskid = add_task('', continuous_ops, inst.objstore,
+ {'result': True})
+ self.assertEquals('running', inst.task_lookup(taskid)['status'])
+ inst.task_wait(taskid, timeout=10)
+ self.assertEquals('finished',
inst.task_lookup(taskid)['status'])
+
+ @unittest.skipUnless(utils.running_as_root(), 'Must be run as root')
+ def test_delete_running_vm(self):
+ inst = model.Model(objstore_loc=self.tmp_store)
+
+ with RollbackContext() as rollback:
+ params = {'name': u'test', 'disks': [],
'cdrom': UBUNTU_ISO}
+ inst.templates_create(params)
+ rollback.prependDefer(inst.template_delete, 'test')
+
+ params = {'name': u'k������h��-�����',
+ 'template': u'/plugins/kimchi/templates/test'}
+ task = inst.vms_create(params)
+ inst.task_wait(task['id'])
+ rollback.prependDefer(utils.rollback_wrapper, inst.vm_delete,
+ u'k������h��-�����')
+
+ inst.vm_start(u'k������h��-�����')
+
self.assertEquals(inst.vm_lookup(u'k������h��-�����')['state'],
'running')
+ rollback.prependDefer(utils.rollback_wrapper, inst.vm_poweroff,
+ u'k������h��-�����')
+
+ inst.vm_delete(u'k������h��-�����')
+
+ vms = inst.vms_get_list()
+ self.assertFalse(u'k������h��-�����' in vms)
+
+ @unittest.skipUnless(utils.running_as_root(), 'Must be run as root')
+ def test_vm_list_sorted(self):
+ inst = model.Model(objstore_loc=self.tmp_store)
+
+ with RollbackContext() as rollback:
+ params = {'name': 'test', 'disks': [],
'cdrom': UBUNTU_ISO}
+ inst.templates_create(params)
+ rollback.prependDefer(inst.template_delete, 'test')
+
+ params = {'name': 'kimchi-vm',
+ 'template': '/plugins/kimchi/templates/test'}
+ task = inst.vms_create(params)
+ inst.task_wait(task['id'])
+ rollback.prependDefer(inst.vm_delete, 'kimchi-vm')
+
+ vms = inst.vms_get_list()
+
+ self.assertEquals(vms, sorted(vms, key=unicode.lower))
+
+ def test_vm_clone(self):
+ inst = model.Model('test:///default', objstore_loc=self.tmp_store)
+
+ all_vm_names = inst.vms_get_list()
+ name = all_vm_names[0]
+
+ original_vm = inst.vm_lookup(name)
+ if original_vm['state'] == u'shutoff':
+ inst.vm_start(name)
+
+ # the VM 'test' should be running by now, so we can't clone it yet
+ self.assertRaises(InvalidParameter, inst.vm_clone, name)
+
+ with RollbackContext() as rollback:
+ inst.vm_poweroff(name)
+ rollback.prependDefer(inst.vm_start, name)
+
+ # create two simultaneous clones of the same VM
+ # and make sure both of them complete successfully
+ task1 = inst.vm_clone(name)
+ task2 = inst.vm_clone(name)
+ clone1_name = task1['target_uri'].split('/')[-2]
+ rollback.prependDefer(inst.vm_delete, clone1_name)
+ clone2_name = task2['target_uri'].split('/')[-2]
+ rollback.prependDefer(inst.vm_delete, clone2_name)
+ inst.task_wait(task1['id'])
+ task1 = inst.task_lookup(task1['id'])
+ self.assertEquals('finished', task1['status'])
+ inst.task_wait(task2['id'])
+ task2 = inst.task_lookup(task2['id'])
+ self.assertEquals('finished', task2['status'])
+
+ # update the original VM info because its state has changed
+ original_vm = inst.vm_lookup(name)
+ clone_vm = inst.vm_lookup(clone1_name)
+
+ self.assertNotEqual(original_vm['name'], clone_vm['name'])
+ self.assertTrue(re.match(u'%s-clone-\d+' %
original_vm['name'],
+ clone_vm['name']))
+ del original_vm['name']
+ del clone_vm['name']
+
+ self.assertNotEqual(original_vm['uuid'], clone_vm['uuid'])
+ del original_vm['uuid']
+ del clone_vm['uuid']
+
+ # compare all VM settings except the ones already compared
+ # (and removed) above (i.e. 'name' and 'uuid')
+ self.assertEquals(original_vm, clone_vm)
+
+ def test_use_test_host(self):
+ inst = model.Model('test:///default',
+ objstore_loc=self.tmp_store)
+
+ with RollbackContext() as rollback:
+ params = {
+ 'name': 'test',
+ 'disks': [],
+ 'cdrom': UBUNTU_ISO,
+ 'storagepool':
'/plugins/kimchi/storagepools/default-pool',
+ 'domain': 'test',
+ 'arch': 'i686'
+ }
+
+ inst.templates_create(params)
+ rollback.prependDefer(inst.template_delete, 'test')
+
+ params = {'name': 'kimchi-vm',
+ 'template': '/plugins/kimchi/templates/test'}
+ task = inst.vms_create(params)
+ inst.task_wait(task['id'])
+ rollback.prependDefer(inst.vm_delete, 'kimchi-vm')
+
+ vms = inst.vms_get_list()
+
+ self.assertTrue('kimchi-vm' in vms)
+
+ @unittest.skipUnless(utils.running_as_root(), 'Must be run as root')
+ def test_debug_reports(self):
+ inst = model.Model('test:///default',
+ objstore_loc=self.tmp_store)
+
+ if not inst.capabilities_lookup()['system_report_tool']:
+ raise unittest.SkipTest("Without debug report tool")
+
+ try:
+ timeout = int(os.environ['TEST_REPORT_TIMEOUT'])
+ except (ValueError, KeyError):
+ timeout = 120
+
+ namePrefix = 'unitTestReport'
+ # sosreport always deletes unsual letters like '-' and '_' in
the
+ # generated report file name.
+ uuidstr = str(uuid.uuid4()).translate(None, "-_")
+ reportName = namePrefix + uuidstr
+ try:
+ inst.debugreport_delete(namePrefix + '*')
+ except NotFoundError:
+ pass
+ with RollbackContext() as rollback:
+ report_list = inst.debugreports_get_list()
+ self.assertFalse(reportName in report_list)
+ try:
+ tmp_name = reportName + "_1"
+ task = inst.debugreports_create({'name': reportName})
+ rollback.prependDefer(inst.debugreport_delete, tmp_name)
+ taskid = task['id']
+ inst.task_wait(taskid, timeout)
+ self.assertEquals('finished',
+ inst.task_lookup(taskid)['status'],
+ "It is not necessary an error. "
+ "You may need to increase the "
+ "timeout number by "
+ "TEST_REPORT_TIMEOUT=200 "
+ "./run_tests.sh test_model")
+ report_list = inst.debugreports_get_list()
+ self.assertTrue(reportName in report_list)
+ name = inst.debugreport_update(reportName, {'name': tmp_name})
+ self.assertEquals(name, tmp_name)
+ report_list = inst.debugreports_get_list()
+ self.assertTrue(tmp_name in report_list)
+ except OperationFailed, e:
+ if 'debugreport tool not found' not in e.message:
+ raise e
+
+ def test_get_distros(self):
+ inst = model.Model('test:///default',
+ objstore_loc=self.tmp_store)
+ distros = inst.distros_get_list()
+ for d in distros:
+ distro = inst.distro_lookup(d)
+ self.assertIn('name', distro)
+ self.assertIn('os_distro', distro)
+ self.assertIn('os_version', distro)
+ self.assertIn('os_arch', distro)
+ self.assertIn('path', distro)
+
+ @unittest.skipUnless(utils.running_as_root(), 'Must be run as root')
+ def test_deep_scan(self):
+ inst = model.Model(None,
+ objstore_loc=self.tmp_store)
+ with RollbackContext() as rollback:
+ deep_path = os.path.join(TMP_DIR, 'deep-scan')
+ subdir_path = os.path.join(deep_path, 'isos')
+ if not os.path.exists(subdir_path):
+ os.makedirs(subdir_path)
+ ubuntu_iso = os.path.join(deep_path, 'ubuntu12.04.iso')
+ sles_iso = os.path.join(subdir_path, 'sles10.iso')
+ iso_gen.construct_fake_iso(ubuntu_iso, True, '12.04',
'ubuntu')
+ iso_gen.construct_fake_iso(sles_iso, True, '10', 'sles')
+
+ args = {'name': 'kimchi-scanning-pool',
+ 'path': deep_path,
+ 'type': 'kimchi-iso'}
+ inst.storagepools_create(args)
+ rollback.prependDefer(shutil.rmtree, deep_path)
+ rollback.prependDefer(shutil.rmtree, args['path'])
+ rollback.prependDefer(inst.storagepool_deactivate, args['name'])
+
+ time.sleep(1)
+ volumes = inst.storagevolumes_get_list(args['name'])
+ self.assertEquals(len(volumes), 2)
+
+ def test_repository_create(self):
+ inst = model.Model('test:///default',
+ objstore_loc=self.tmp_store)
+
+ yum_repos = [{'repo_id': 'fedora-fake',
+ 'baseurl': 'http://www.fedora.org'},
+ {'repo_id': 'fedora-updates-fake',
+ 'config':
+ {'mirrorlist': 'http://www.fedoraproject.org'}}]
+
+ deb_repos = [{'baseurl': 'http://archive.ubuntu.com/ubuntu/',
+ 'config': {'dist': 'quantal'}},
+ {'baseurl': 'http://archive.ubuntu.com/ubuntu/',
+ 'config': {'dist': 'quantal',
'comps': ['main']}}]
+
+ yum_invalid_repos = []
+ deb_invalid_repos = []
+
+ for url in invalid_repository_urls:
+ wrong_baseurl = {'repo_id': 'wrong-id', 'baseurl':
url}
+ wrong_mirrorlist = {'repo_id': 'wrong-id',
+ 'baseurl': 'www.example.com',
+ 'config': {'mirrorlist': url}}
+ wrong_config_item = {
+ 'repo_id': 'wrong-id',
+ 'baseurl': 'www.example.com',
+ 'config': {
+ 'gpgkey': 'file:///tmp/KEY-fedora-updates-fake-19'}}
+
+ yum_invalid_repos.append(wrong_baseurl)
+ yum_invalid_repos.append(wrong_mirrorlist)
+ yum_invalid_repos.append(wrong_config_item)
+
+ wrong_baseurl['config'] = {'dist': 'tasty'}
+ wrong_config = {'baseurl': deb_repos[0]['baseurl'],
+ 'config': {
+ 'unsupported_item':
"a_unsupported_item"}}
+ deb_invalid_repos.append(wrong_baseurl)
+ deb_invalid_repos.append(wrong_config)
+
+ repo_type = inst.capabilities_lookup()['repo_mngt_tool']
+ if repo_type == 'yum':
+ test_repos = yum_repos
+ invalid_repos = yum_invalid_repos
+ elif repo_type == 'deb':
+ test_repos = deb_repos
+ invalid_repos = deb_invalid_repos
+ else:
+ # repository management tool was not recognized by Kimchi
+ # skip test case
+ return
+
+ # create repositories with invalid data
+ for repo in invalid_repos:
+ self.assertRaises(InvalidParameter, inst.repositories_create, repo)
+
+ for repo in test_repos:
+ system_host_repos = len(inst.repositories_get_list())
+ repo_id = inst.repositories_create(repo)
+ host_repos = inst.repositories_get_list()
+ self.assertEquals(system_host_repos + 1, len(host_repos))
+
+ repo_info = inst.repository_lookup(repo_id)
+ self.assertEquals(repo_id, repo_info['repo_id'])
+ self.assertEquals(True, repo_info.get('enabled'))
+ self.assertEquals(repo.get('baseurl', ''),
+ repo_info.get('baseurl'))
+
+ original_config = repo.get('config', {})
+ config_info = repo_info.get('config', {})
+
+ if repo_type == 'yum':
+ self.assertEquals(original_config.get('mirrorlist', ''),
+ config_info.get('mirrorlist', ''))
+ self.assertEquals(True, config_info['gpgcheck'])
+ else:
+ self.assertEquals(original_config['dist'],
config_info['dist'])
+ self.assertEquals(original_config.get('comps', []),
+ config_info.get('comps', []))
+
+ inst.repository_delete(repo_id)
+ self.assertRaises(NotFoundError, inst.repository_lookup, repo_id)
+
+ self.assertRaises(NotFoundError, inst.repository_lookup, 'google')
+
+ def test_repository_update(self):
+ inst = model.Model('test:///default',
+ objstore_loc=self.tmp_store)
+
+ yum_repo = {'repo_id': 'fedora-fake',
+ 'baseurl': 'http://www.fedora.org'}
+ yum_new_repo = {'baseurl': 'http://www.fedoraproject.org'}
+
+ deb_repo = {'baseurl': 'http://archive.ubuntu.com/ubuntu/',
+ 'config': {'dist': 'quantal'}}
+ deb_new_repo = {'baseurl':
'http://br.archive.canonical.com/ubuntu/',
+ 'config': {'dist': 'utopic'}}
+
+ yum_invalid_repos = []
+ deb_invalid_repos = []
+
+ for url in invalid_repository_urls:
+ wrong_baseurl = {'baseurl': url}
+ wrong_mirrorlist = {'baseurl': 'www.example.com',
+ 'config': {'mirrorlist': url}}
+
+ yum_invalid_repos.append(wrong_baseurl)
+ yum_invalid_repos.append(wrong_mirrorlist)
+
+ wrong_baseurl['config'] = {'dist': 'tasty'}
+ deb_invalid_repos.append(wrong_baseurl)
+
+ repo_type = inst.capabilities_lookup()['repo_mngt_tool']
+ if repo_type == 'yum':
+ repo = yum_repo
+ new_repo = yum_new_repo
+ invalid_repos = yum_invalid_repos
+ elif repo_type == 'deb':
+ repo = deb_repo
+ new_repo = deb_new_repo
+ invalid_repos = deb_invalid_repos
+ else:
+ # repository management tool was not recognized by Kimchi
+ # skip test case
+ return
+
+ system_host_repos = len(inst.repositories_get_list())
+
+ with RollbackContext() as rollback:
+ repo_id = inst.repositories_create(repo)
+ rollback.prependDefer(inst.repository_delete, repo_id)
+
+ host_repos = inst.repositories_get_list()
+ self.assertEquals(system_host_repos + 1, len(host_repos))
+
+ # update repositories with invalid data
+ for tmp_repo in invalid_repos:
+ self.assertRaises(InvalidParameter, inst.repository_update,
+ repo_id, tmp_repo)
+
+ new_repo_id = inst.repository_update(repo_id, new_repo)
+ repo_info = inst.repository_lookup(new_repo_id)
+
+ self.assertEquals(new_repo_id, repo_info['repo_id'])
+ self.assertEquals(new_repo['baseurl'], repo_info['baseurl'])
+ self.assertEquals(True, repo_info['enabled'])
+ inst.repository_update(new_repo_id, repo)
+
+ def test_repository_disable_enable(self):
+ inst = model.Model('test:///default',
+ objstore_loc=self.tmp_store)
+
+ yum_repo = {'repo_id': 'fedora-fake',
+ 'baseurl': 'http://www.fedora.org'}
+ deb_repo = {'baseurl': 'http://archive.ubuntu.com/ubuntu/',
+ 'config': {'dist': 'quantal'}}
+
+ repo_type = inst.capabilities_lookup()['repo_mngt_tool']
+ if repo_type == 'yum':
+ repo = yum_repo
+ elif repo_type == 'deb':
+ repo = deb_repo
+ else:
+ # repository management tool was not recognized by Kimchi
+ # skip test case
+ return
+
+ system_host_repos = len(inst.repositories_get_list())
+
+ repo_id = inst.repositories_create(repo)
+
+ host_repos = inst.repositories_get_list()
+ self.assertEquals(system_host_repos + 1, len(host_repos))
+
+ repo_info = inst.repository_lookup(repo_id)
+ self.assertEquals(True, repo_info['enabled'])
+
+ inst.repository_disable(repo_id)
+ repo_info = inst.repository_lookup(repo_id)
+ self.assertEquals(False, repo_info['enabled'])
+
+ inst.repository_enable(repo_id)
+ repo_info = inst.repository_lookup(repo_id)
+ self.assertEquals(True, repo_info['enabled'])
+
+ # remove files creates
+ inst.repository_delete(repo_id)
+
+
+class BaseModelTests(unittest.TestCase):
+ class FoosModel(object):
+ def __init__(self):
+ self.data = {}
+
+ def create(self, params):
+ self.data.update(params)
+
+ def get_list(self):
+ return list(self.data)
+
+ class TestModel(wok.basemodel.BaseModel):
+ def __init__(self):
+ foo = BaseModelTests.FoosModel()
+ super(BaseModelTests.TestModel, self).__init__([foo])
+
+ def test_root_model(self):
+ t = BaseModelTests.TestModel()
+ t.foos_create({'item1': 10})
+ self.assertEquals(t.foos_get_list(), ['item1'])
diff --git a/src/wok/plugins/kimchi/tests/test_model_network.py
b/src/wok/plugins/kimchi/tests/test_model_network.py
new file mode 100644
index 0000000..e4cf5ef
--- /dev/null
+++ b/src/wok/plugins/kimchi/tests/test_model_network.py
@@ -0,0 +1,149 @@
+# -*- coding: utf-8 -*-
+#
+# Project Kimchi
+#
+# Copyright IBM, Corp. 2015
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+import json
+import os
+import unittest
+from functools import partial
+
+from wok.rollbackcontext import RollbackContext
+
+from wok.plugins.kimchi.model.model import Model
+
+from utils import get_free_port, patch_auth, request, rollback_wrapper
+from utils import run_server
+
+
+model = None
+test_server = None
+host = None
+port = None
+ssl_port = None
+cherrypy_port = None
+
+
+def setUpModule():
+ global test_server, model, host, port, ssl_port, cherrypy_port
+
+ patch_auth()
+ model = Model(None, '/tmp/obj-store-test')
+ host = '127.0.0.1'
+ port = get_free_port('http')
+ ssl_port = get_free_port('https')
+ cherrypy_port = get_free_port('cherrypy_port')
+ test_server = run_server(host, port, ssl_port, test_mode=True,
+ cherrypy_port=cherrypy_port, model=model)
+
+
+def tearDownModule():
+ test_server.stop()
+ os.unlink('/tmp/obj-store-test')
+
+
+def _do_network_test(self, model, params):
+ with RollbackContext() as rollback:
+ net_name = params['name']
+ uri = '/plugins/kimchi/networks/%s' % net_name.encode('utf-8')
+
+ # Create a network
+ req = json.dumps(params)
+ resp = self.request('/plugins/kimchi/networks', req, 'POST')
+ rollback.prependDefer(rollback_wrapper, model.network_delete,
+ net_name)
+ self.assertEquals(201, resp.status)
+
+ # Verify the network
+ resp = self.request(uri)
+ network = json.loads(resp.read())
+ self.assertEquals('inactive', network['state'])
+ self.assertTrue(network['persistent'])
+
+ # activate the network
+ resp = self.request(uri + '/activate', '{}', 'POST')
+ rollback.prependDefer(rollback_wrapper,
+ model.network_deactivate, net_name)
+ self.assertEquals(200, resp.status)
+ resp = self.request(uri)
+ network = json.loads(resp.read())
+ self.assertEquals('active', network['state'])
+
+ # Deactivate the network
+ resp = self.request(uri + '/deactivate', '{}', 'POST')
+ self.assertEquals(200, resp.status)
+ resp = self.request(uri)
+ network = json.loads(resp.read())
+ self.assertEquals('inactive', network['state'])
+
+ # Delete the network
+ resp = self.request(uri, '{}', 'DELETE')
+ self.assertEquals(204, resp.status)
+
+
+class NetworkTests(unittest.TestCase):
+ def setUp(self):
+ self.request = partial(request, host, ssl_port)
+
+ def test_get_networks(self):
+ networks = json.loads(self.request('/plugins/kimchi/networks').read())
+ self.assertIn('default', [net['name'] for net in networks])
+
+ with RollbackContext() as rollback:
+ # Now add a couple of Networks to the mock model
+ for i in xrange(5):
+ name = 'network-%i' % i
+ req = json.dumps({'name': name,
+ 'connection': 'nat',
+ 'subnet': '127.0.10%i.0/24' % i})
+
+ resp = self.request('/plugins/kimchi/networks', req,
'POST')
+ rollback.prependDefer(model.network_delete, name)
+ self.assertEquals(201, resp.status)
+ network = json.loads(resp.read())
+ self.assertEquals([], network["vms"])
+
+ nets = json.loads(self.request('/plugins/kimchi/networks').read())
+ self.assertEquals(len(networks) + 5, len(nets))
+
+ network = json.loads(
+ self.request('/plugins/kimchi/networks/network-1').read()
+ )
+ keys = [u'name', u'connection', u'interface',
u'subnet', u'dhcp',
+ u'vms', u'in_use', u'autostart',
u'state', u'persistent']
+ self.assertEquals(sorted(keys), sorted(network.keys()))
+
+ def test_network_lifecycle(self):
+ # Verify all the supported network type
+ networks = [{'name': u'k������h��-��et', 'connection':
'isolated'},
+ {'name': u'nat-network', 'connection':
'nat'},
+ {'name': u'subnet-network', 'connection':
'nat',
+ 'subnet': '127.0.100.0/24'}]
+
+ # Verify the current system has at least one interface to create a
+ # bridged network
+ interfaces = json.loads(
+ self.request('/plugins/kimchi/interfaces?type=nic').read()
+ )
+ if len(interfaces) > 0:
+ iface = interfaces[0]['name']
+ networks.append({'name': u'bridge-network',
'connection': 'bridge',
+ 'interface': iface})
+
+ for net in networks:
+ _do_network_test(self, model, net)
diff --git a/src/wok/plugins/kimchi/tests/test_model_storagepool.py
b/src/wok/plugins/kimchi/tests/test_model_storagepool.py
new file mode 100644
index 0000000..5f9b966
--- /dev/null
+++ b/src/wok/plugins/kimchi/tests/test_model_storagepool.py
@@ -0,0 +1,123 @@
+# -*- coding: utf-8 -*-
+#
+# Project Kimchi
+#
+# Copyright IBM, Corp. 2015
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+import json
+import os
+import tempfile
+import unittest
+from functools import partial
+
+from wok.rollbackcontext import RollbackContext
+
+from wok.plugins.kimchi.model.model import Model
+
+from utils import get_free_port, patch_auth, request
+from utils import run_server
+
+
+model = None
+test_server = None
+host = None
+port = None
+ssl_port = None
+cherrypy_port = None
+
+
+def setUpModule():
+ global test_server, model, host, port, ssl_port, cherrypy_port
+
+ patch_auth()
+ model = Model(None, '/tmp/obj-store-test')
+ host = '127.0.0.1'
+ port = get_free_port('http')
+ ssl_port = get_free_port('https')
+ cherrypy_port = get_free_port('cherrypy_port')
+ test_server = run_server(host, port, ssl_port, test_mode=True,
+ cherrypy_port=cherrypy_port, model=model)
+
+
+def tearDownModule():
+ test_server.stop()
+ os.unlink('/tmp/obj-store-test')
+
+
+class StoragepoolTests(unittest.TestCase):
+ def setUp(self):
+ self.request = partial(request, host, ssl_port)
+
+ def test_get_storagepools(self):
+ storagepools = json.loads(
+ self.request('/plugins/kimchi/storagepools').read()
+ )
+ self.assertIn('default', [pool['name'] for pool in
storagepools])
+
+ with RollbackContext() as rollback:
+ # Now add a couple of storage pools
+ for i in xrange(3):
+ name = u'k������h��-storagepool-%i' % i
+ req = json.dumps({'name': name, 'type': 'dir',
+ 'path': '/var/lib/libvirt/images/%i' %
i})
+ resp = self.request('/plugins/kimchi/storagepools', req,
+ 'POST')
+ rollback.prependDefer(model.storagepool_delete, name)
+
+ self.assertEquals(201, resp.status)
+
+ # Pool name must be unique
+ req = json.dumps({'name': name, 'type': 'dir',
+ 'path': '/var/lib/libvirt/images/%i' %
i})
+ resp = self.request('/plugins/kimchi/storagepools', req,
+ 'POST')
+ self.assertEquals(400, resp.status)
+
+ # Verify pool information
+ resp = self.request('/plugins/kimchi/storagepools/%s' %
+ name.encode("utf-8"))
+ p = json.loads(resp.read())
+ keys = [u'name', u'state', u'capacity',
u'allocated',
+ u'available', u'path', u'source',
u'type',
+ u'nr_volumes', u'autostart',
u'persistent']
+ self.assertEquals(sorted(keys), sorted(p.keys()))
+ self.assertEquals(name, p['name'])
+ self.assertEquals('inactive', p['state'])
+ self.assertEquals(True, p['persistent'])
+ self.assertEquals(True, p['autostart'])
+ self.assertEquals(0, p['nr_volumes'])
+
+ pools = json.loads(
+ self.request('/plugins/kimchi/storagepools').read()
+ )
+ self.assertEquals(len(storagepools) + 3, len(pools))
+
+ # Create a pool with an existing path
+ tmp_path = tempfile.mkdtemp(dir='/var/lib/kimchi')
+ rollback.prependDefer(os.rmdir, tmp_path)
+ req = json.dumps({'name': 'existing_path', 'type':
'dir',
+ 'path': tmp_path})
+ resp = self.request('/plugins/kimchi/storagepools', req,
'POST')
+ rollback.prependDefer(model.storagepool_delete, 'existing_path')
+ self.assertEquals(201, resp.status)
+
+ # Reserved pool return 400
+ req = json.dumps({'name': 'kimchi_isos', 'type':
'dir',
+ 'path': '/var/lib/libvirt/images/%i' % i})
+ resp = request(host, ssl_port, '/plugins/kimchi/storagepools', req,
+ 'POST')
+ self.assertEquals(400, resp.status)
diff --git a/src/wok/plugins/kimchi/tests/test_model_storagevolume.py
b/src/wok/plugins/kimchi/tests/test_model_storagevolume.py
new file mode 100644
index 0000000..46c07bd
--- /dev/null
+++ b/src/wok/plugins/kimchi/tests/test_model_storagevolume.py
@@ -0,0 +1,280 @@
+# -*- coding: utf-8 -*-
+#
+# Project Kimchi
+#
+# Copyright IBM, Corp. 2015
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+import json
+import os
+import requests
+import unittest
+from functools import partial
+
+from wok.config import paths
+from wok.rollbackcontext import RollbackContext
+
+from wok.plugins.kimchi.config import READONLY_POOL_TYPE
+from wok.plugins.kimchi.mockmodel import MockModel
+from wok.plugins.kimchi.model.model import Model
+
+from utils import fake_auth_header, get_free_port, patch_auth, request
+from utils import rollback_wrapper, run_server, wait_task
+
+
+model = None
+test_server = None
+host = None
+port = None
+ssl_port = None
+cherrypy_port = None
+
+
+def setUpModule():
+ global test_server, model, host, port, ssl_port, cherrypy_port
+
+ patch_auth()
+ model = Model(None, '/tmp/obj-store-test')
+ host = '127.0.0.1'
+ port = get_free_port('http')
+ ssl_port = get_free_port('https')
+ cherrypy_port = get_free_port('cherrypy_port')
+ test_server = run_server(host, port, ssl_port, test_mode=True,
+ cherrypy_port=cherrypy_port, model=model)
+
+
+def tearDownModule():
+ test_server.stop()
+ os.unlink('/tmp/obj-store-test')
+
+
+def _do_volume_test(self, model, host, ssl_port, pool_name):
+ def _task_lookup(taskid):
+ return json.loads(
+ self.request('/tasks/%s' % taskid).read()
+ )
+
+ uri = '/plugins/kimchi/storagepools/%s/storagevolumes' \
+ % pool_name.encode('utf-8')
+ resp = self.request(uri)
+ self.assertEquals(200, resp.status)
+
+ resp = self.request('/plugins/kimchi/storagepools/%s' %
+ pool_name.encode('utf-8'))
+ pool_info = json.loads(resp.read())
+ with RollbackContext() as rollback:
+ # Create storage volume with 'capacity'
+ vol = 'test-volume'
+ vol_uri = uri + '/' + vol
+ req = json.dumps({'name': vol, 'format': 'raw',
+ 'capacity': 1073741824}) # 1 GiB
+ resp = self.request(uri, req, 'POST')
+ if pool_info['type'] in READONLY_POOL_TYPE:
+ self.assertEquals(400, resp.status)
+ else:
+ rollback.prependDefer(rollback_wrapper, model.storagevolume_delete,
+ pool_name, vol)
+ self.assertEquals(202, resp.status)
+ task_id = json.loads(resp.read())['id']
+ wait_task(_task_lookup, task_id)
+ status = json.loads(
+ self.request('/tasks/%s' % task_id).read()
+ )
+ self.assertEquals('finished', status['status'])
+ vol_info = json.loads(self.request(vol_uri).read())
+ vol_info['name'] = vol
+ vol_info['format'] = 'raw'
+ vol_info['capacity'] = 1073741824
+
+ # Resize the storage volume: increase its capacity to 2 GiB
+ req = json.dumps({'size': 2147483648}) # 2 GiB
+ resp = self.request(vol_uri + '/resize', req, 'POST')
+ self.assertEquals(200, resp.status)
+ storagevolume = json.loads(self.request(vol_uri).read())
+ self.assertEquals(2147483648, storagevolume['capacity'])
+
+ # Resize the storage volume: decrease its capacity to 512 MiB
+ # FIXME: Due a libvirt bug it is not possible to decrease the
+ # volume capacity
+ # For reference:
+ # -
https://bugzilla.redhat.com/show_bug.cgi?id=1021802
+ req = json.dumps({'size': 536870912}) # 512 MiB
+ resp = self.request(vol_uri + '/resize', req, 'POST')
+ # It is only possible when using MockModel
+ if isinstance(model, MockModel):
+ self.assertEquals(200, resp.status)
+ storagevolume = json.loads(self.request(vol_uri).read())
+ self.assertEquals(536870912, storagevolume['capacity'])
+ else:
+ self.assertEquals(500, resp.status)
+
+ # Wipe the storage volume
+ resp = self.request(vol_uri + '/wipe', '{}', 'POST')
+ self.assertEquals(200, resp.status)
+ storagevolume = json.loads(self.request(vol_uri).read())
+ self.assertEquals(0, storagevolume['allocation'])
+
+ # Clone the storage volume
+ vol_info = json.loads(self.request(vol_uri).read())
+ resp = self.request(vol_uri + '/clone', '{}',
'POST')
+ self.assertEquals(202, resp.status)
+ task = json.loads(resp.read())
+ cloned_vol_name = task['target_uri'].split('/')[-1]
+ rollback.prependDefer(model.storagevolume_delete, pool_name,
+ cloned_vol_name)
+ wait_task(_task_lookup, task['id'])
+ task = json.loads(
+ self.request('/tasks/%s' % task['id']).read()
+ )
+ self.assertEquals('finished', task['status'])
+ resp = self.request(uri + '/' +
cloned_vol_name.encode('utf-8'))
+
+ self.assertEquals(200, resp.status)
+ cloned_vol = json.loads(resp.read())
+
+ self.assertNotEquals(vol_info['name'], cloned_vol['name'])
+ self.assertNotEquals(vol_info['path'], cloned_vol['path'])
+ for key in ['name', 'path', 'allocation']:
+ del vol_info[key]
+ del cloned_vol[key]
+
+ self.assertEquals(vol_info, cloned_vol)
+
+ # Delete the storage volume
+ resp = self.request(vol_uri, '{}', 'DELETE')
+ self.assertEquals(204, resp.status)
+ resp = self.request(vol_uri)
+ self.assertEquals(404, resp.status)
+
+ # Storage volume upload
+ # It is done through a sequence of POST and several PUT requests
+ filename = 'COPYING.LGPL'
+ filepath = os.path.join(paths.get_prefix(), filename)
+ filesize = os.stat(filepath).st_size
+
+ # Create storage volume for upload
+ req = json.dumps({'name': filename, 'format': 'raw',
+ 'capacity': filesize, 'upload': True})
+ resp = self.request(uri, req, 'POST')
+ if pool_info['type'] in READONLY_POOL_TYPE:
+ self.assertEquals(400, resp.status)
+ else:
+ rollback.prependDefer(rollback_wrapper, model.storagevolume_delete,
+ pool_name, filename)
+ self.assertEquals(202, resp.status)
+ task_id = json.loads(resp.read())['id']
+ wait_task(_task_lookup, task_id)
+ status = json.loads(self.request('/tasks/%s' %
+ task_id).read())
+ self.assertEquals('ready for upload', status['message'])
+
+ # Upload volume content
+ url = 'https://%s:%s' % (host, ssl_port) + uri + '/' +
filename
+
+ # Create a file with 5M to upload
+ # Max body size is set to 4M so the upload will fail with 413
+ newfile = '/tmp/5m-file'
+ with open(newfile, 'wb') as fd:
+ fd.seek(5*1024*1024-1)
+ fd.write("\0")
+ rollback.prependDefer(os.remove, newfile)
+
+ with open(newfile, 'rb') as fd:
+ with open(newfile + '.tmp', 'wb') as tmp_fd:
+ data = fd.read()
+ tmp_fd.write(data)
+
+ with open(newfile + '.tmp', 'rb') as tmp_fd:
+ r = requests.put(url, data={'chunk_size': len(data)},
+ files={'chunk': tmp_fd},
+ verify=False,
+ headers=fake_auth_header())
+ self.assertEquals(r.status_code, 413)
+
+ # Do upload
+ index = 0
+ chunk_size = 2 * 1024
+ content = ''
+
+ with open(filepath, 'rb') as fd:
+ while True:
+ with open(filepath + '.tmp', 'wb') as tmp_fd:
+ fd.seek(index*chunk_size)
+ data = fd.read(chunk_size)
+ tmp_fd.write(data)
+
+ with open(filepath + '.tmp', 'rb') as tmp_fd:
+ r = requests.put(url, data={'chunk_size': len(data)},
+ files={'chunk': tmp_fd},
+ verify=False,
+ headers=fake_auth_header())
+ self.assertEquals(r.status_code, 200)
+ content += data
+ index = index + 1
+
+ if len(data) < chunk_size:
+ break
+
+ rollback.prependDefer(os.remove, filepath + '.tmp')
+ resp = self.request(uri + '/' + filename)
+ self.assertEquals(200, resp.status)
+ uploaded_path = json.loads(resp.read())['path']
+ with open(uploaded_path) as fd:
+ uploaded_content = fd.read()
+
+ self.assertEquals(content, uploaded_content)
+
+ # Create storage volume with 'url'
+ url = 'https://github.com/kimchi-project/kimchi/raw/master/COPYING'
+ req = json.dumps({'url': url})
+ resp = self.request(uri, req, 'POST')
+
+ if pool_info['type'] in READONLY_POOL_TYPE:
+ self.assertEquals(400, resp.status)
+ else:
+ rollback.prependDefer(model.storagevolume_delete, pool_name,
+ 'COPYING')
+ self.assertEquals(202, resp.status)
+ task = json.loads(resp.read())
+ wait_task(_task_lookup, task['id'])
+ resp = self.request(uri + '/COPYING')
+ self.assertEquals(200, resp.status)
+
+
+class StorageVolumeTests(unittest.TestCase):
+ def setUp(self):
+ self.request = partial(request, host, ssl_port)
+
+ def test_get_storagevolume(self):
+ uri = '/plugins/kimchi/storagepools/default/storagevolumes'
+ resp = self.request(uri)
+ self.assertEquals(200, resp.status)
+
+ keys = [u'name', u'type', u'capacity',
u'allocation', u'path',
+ u'used_by', u'format']
+ for vol in json.loads(resp.read()):
+ resp = self.request(uri + '/' + vol['name'])
+ self.assertEquals(200, resp.status)
+
+ all_keys = keys[:]
+ vol_info = json.loads(resp.read())
+ if vol_info['format'] == 'iso':
+ all_keys.extend([u'os_distro', u'os_version',
u'bootable'])
+
+ self.assertEquals(sorted(all_keys), sorted(vol_info.keys()))
+
+ def test_storagevolume_action(self):
+ _do_volume_test(self, model, host, ssl_port, 'default')
diff --git a/src/wok/plugins/kimchi/tests/test_networkxml.py
b/src/wok/plugins/kimchi/tests/test_networkxml.py
new file mode 100644
index 0000000..a64b6c2
--- /dev/null
+++ b/src/wok/plugins/kimchi/tests/test_networkxml.py
@@ -0,0 +1,172 @@
+#
+# Kimchi
+#
+# Copyright IBM, Corp. 2013-2014
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+import ipaddr
+import lxml.etree as ET
+import unittest
+
+from wok.xmlutils.utils import xpath_get_text
+
+from wok.plugins.kimchi.xmlutils import network as nxml
+
+import utils
+
+
+class NetworkXmlTests(unittest.TestCase):
+ def test_dhcp_xml(self):
+ """
+ Test network dhcp xml
+ """
+ dhcp_range = {"start": "192.168.122.100", "end":
"192.168.122.254"}
+ host1 = {"mac": "00:16:3e:77:e2:ed",
+ "name": "foo.example.com",
+ "ip": "192.168.122.10"}
+ host2 = {"mac": "00:16:3e:3e:a9:1a",
+ "name": "bar.example.com",
+ "ip": "192.168.122.11"}
+ params = {}
+
+ dhcp = nxml._get_dhcp_elem(**params)
+ self.assertEquals(None, dhcp)
+
+ params["range"] = dhcp_range
+ xml = ET.tostring(nxml._get_dhcp_elem(**params))
+ start = xpath_get_text(xml, "/dhcp/range/@start")
+ end = xpath_get_text(xml, "/dhcp/range/@end")
+ self.assertEquals(dhcp_range['start'], start[0])
+ self.assertEquals(dhcp_range['end'], end[0])
+
+ params["hosts"] = [host1, host2]
+ xml = ET.tostring(nxml._get_dhcp_elem(**params))
+ ip = xpath_get_text(xml, "/dhcp/host/@ip")
+ self.assertEquals(ip, [host1['ip'], host2['ip']])
+
+ def test_ip_xml(self):
+ """
+ Test network ip xml
+ """
+ dhcp_range = {"start": "192.168.122.100", "end":
"192.168.122.254"}
+ params = {}
+
+ dhcp = nxml._get_dhcp_elem(**params)
+ self.assertEquals(None, dhcp)
+
+ params["net"] = "192.168.122.0/255.255.255.0"
+ params["dhcp"] = {'range': dhcp_range}
+ xml = ET.tostring(nxml._get_ip_elem(**params))
+ start = xpath_get_text(xml, "/ip/dhcp/range/@start")[0]
+ end = xpath_get_text(xml, "/ip/dhcp/range/@end")[0]
+ self.assertEquals(dhcp_range['start'], start)
+ self.assertEquals(dhcp_range['end'], end)
+
+ address = xpath_get_text(xml, "/ip/@address")[0]
+ netmask = xpath_get_text(xml, "/ip/@netmask")[0]
+ self.assertEquals(address, params["net"].split("/")[0])
+ self.assertEquals(netmask, params["net"].split("/")[1])
+
+ # test _get_ip_xml can accepts strings: '192.168.122.0/24',
+ # which is same as "192.168.122.0/255.255.255.0"
+ params["net"] = "192.168.122.0/24"
+ xml = ET.tostring(nxml._get_ip_elem(**params))
+ netmask = xpath_get_text(xml, "/ip/@netmask")[0]
+ self.assertEquals(netmask,
+ str(ipaddr.IPNetwork(params["net"]).netmask))
+
+ def test_forward_xml(self):
+ """
+ Test network forward xml
+ """
+ params = {"mode": None}
+
+ forward = nxml._get_forward_elem(**params)
+ self.assertEquals(None, forward)
+
+ params["mode"] = 'nat'
+ params["dev"] = 'eth0'
+ xml = ET.tostring(nxml._get_forward_elem(**params))
+ mode = xpath_get_text(xml, "/forward/@mode")[0]
+ dev = xpath_get_text(xml, "/forward/@dev")[0]
+ self.assertEquals(params['mode'], mode)
+ self.assertEquals(params['dev'], dev)
+
+ def test_network_xml(self):
+ """
+ Test network xml
+ """
+ params = {"name": "test",
+ "forward": {"mode": "nat",
"dev": ""},
+ "net": "192.168.0.0/255.255.255.0"}
+ xml = nxml.to_network_xml(**params)
+ name = xpath_get_text(xml, "/network/name")[0]
+ self.assertEquals(name, params['name'])
+
+ forward_mode = xpath_get_text(xml, "/network/forward/@mode")[0]
+ self.assertEquals(forward_mode, params['forward']['mode'])
+ forward_dev = xpath_get_text(xml, "/network/forward/@dev")[0]
+ self.assertEquals(forward_dev, '')
+
+ address = xpath_get_text(xml, "/network/ip/@address")[0]
+ self.assertEquals(address, params["net"].split("/")[0])
+ netmask = xpath_get_text(xml, "/network/ip/@netmask")[0]
+ self.assertEquals(netmask, params["net"].split("/")[1])
+
+ dhcp_start = xpath_get_text(xml, "/network/ip/dhcp/range/@start")
+ self.assertEquals(dhcp_start, [])
+ dhcp_end = xpath_get_text(xml, "/network/ip/dhcp/range/@end")
+ self.assertEquals(dhcp_end, [])
+
+ # test optional params
+ params['forward']['dev'] = "eth0"
+ params['dhcp'] = {"range": {'start':
'192.168.0.1',
+ 'end': '192.168.0.254'}}
+ xml = nxml.to_network_xml(**params)
+ forward_dev = xpath_get_text(xml, "/network/forward/@dev")[0]
+ self.assertEquals(forward_dev, params['forward']['dev'])
+
+ dhcp_start = xpath_get_text(xml, "/network/ip/dhcp/range/@start")[0]
+ self.assertEquals(dhcp_start,
params['dhcp']['range']['start'])
+ dhcp_end = xpath_get_text(xml, "/network/ip/dhcp/range/@end")[0]
+ self.assertEquals(dhcp_end,
params['dhcp']['range']['end'])
+
+ # test _get_ip_xml can accepts strings: '192.168.122.0/24',
+ # which is same as "192.168.122.0/255.255.255.0"
+ params["net"] = "192.168.0.0/24"
+ xml = nxml.to_network_xml(**params)
+ netmask = xpath_get_text(xml, "/network/ip/@netmask")[0]
+ self.assertEquals(netmask,
+ str(ipaddr.IPNetwork(params["net"]).netmask))
+
+
+class InterfaceXmlTests(unittest.TestCase):
+
+ def test_vlan_tagged_bridge_no_ip(self):
+ expected_xml = """
+ <interface type='bridge' name='br10'>
+ <start mode='onboot'/>
+ <bridge>
+ <interface type='vlan' name='em1.10'>
+ <vlan tag='10'>
+ <interface name='em1'/>
+ </vlan>
+ </interface>
+ </bridge>
+ </interface>
+ """
+ actual_xml = nxml.create_vlan_tagged_bridge_xml('br10', 'em1',
'10')
+ self.assertEquals(actual_xml, utils.normalize_xml(expected_xml))
diff --git a/src/wok/plugins/kimchi/tests/test_objectstore.py
b/src/wok/plugins/kimchi/tests/test_objectstore.py
new file mode 100644
index 0000000..632786f
--- /dev/null
+++ b/src/wok/plugins/kimchi/tests/test_objectstore.py
@@ -0,0 +1,97 @@
+# -*- coding: utf-8 -*-
+#
+# Project Kimchi
+#
+# Copyright IBM, Corp. 2015
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+import os
+import tempfile
+import threading
+import unittest
+
+from wok import objectstore
+from wok.exception import NotFoundError
+
+
+tmpfile = None
+
+
+def setUpModule():
+ global tmpfile
+ tmpfile = tempfile.mktemp()
+
+
+def tearDownModule():
+ os.unlink(tmpfile)
+
+
+class ObjectStoreTests(unittest.TestCase):
+ def test_objectstore(self):
+ store = objectstore.ObjectStore(tmpfile)
+
+ with store as session:
+ # Test create
+ session.store('f����', 't��st1', {'��': 1})
+ session.store('f����', 't��st2', {'��': 2})
+
+ # Test list
+ items = session.get_list('f����')
+ self.assertTrue(u't��st1' in items)
+ self.assertTrue(u't��st2' in items)
+
+ # Test get
+ item = session.get('f����', 't��st1')
+ self.assertEquals(1, item[u'��'])
+
+ # Test delete
+ session.delete('f����', 't��st2')
+ self.assertEquals(1, len(session.get_list('f����')))
+
+ # Test get non-existent item
+
+ self.assertRaises(NotFoundError, session.get,
+ '��', '��')
+
+ # Test delete non-existent item
+ self.assertRaises(NotFoundError, session.delete,
+ 'f����', 't��st2')
+
+ # Test refresh existing item
+ session.store('f����', 't��st1', {'��': 2})
+ item = session.get('f����', 't��st1')
+ self.assertEquals(2, item[u'��'])
+
+ def test_object_store_threaded(self):
+ def worker(ident):
+ with store as session:
+ session.store('foo', ident, {})
+
+ store = objectstore.ObjectStore(tmpfile)
+
+ threads = []
+ for i in xrange(50):
+ t = threading.Thread(target=worker, args=(i,))
+ t.setDaemon(True)
+ t.start()
+ threads.append(t)
+
+ for t in threads:
+ t.join()
+
+ with store as session:
+ self.assertEquals(50, len(session.get_list('foo')))
+ self.assertEquals(10, len(store._connections.keys()))
diff --git a/src/wok/plugins/kimchi/tests/test_osinfo.py
b/src/wok/plugins/kimchi/tests/test_osinfo.py
new file mode 100644
index 0000000..bd2af58
--- /dev/null
+++ b/src/wok/plugins/kimchi/tests/test_osinfo.py
@@ -0,0 +1,69 @@
+#
+# Project Kimchi
+#
+# Copyright IBM, Corp. 2013-2015
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+import unittest
+
+from wok.plugins.kimchi.osinfo import _get_arch, get_template_default, lookup
+from wok.plugins.kimchi.osinfo import modern_version_bases
+
+
+class OSInfoTests(unittest.TestCase):
+ def test_default_lookup(self):
+ entry = lookup(None, None)
+ self.assertEquals('unknown', entry['os_distro'])
+ self.assertEquals('unknown', entry['os_version'])
+ self.assertEquals(['default'], entry['networks'])
+
+ def test_old_distros(self):
+ old_versions = {'debian': '5.0', 'ubuntu':
'7.04', 'opensuse': '10.1',
+ 'centos': '5.1', 'rhel': '5.1',
'fedora': '15'}
+ for distro, version in old_versions.iteritems():
+ entry = lookup(distro, version)
+ self.assertEquals(entry['disk_bus'],
+ get_template_default('old', 'disk_bus'))
+ self.assertEquals(entry['nic_model'],
+ get_template_default('old', 'nic_model'))
+
+ def test_modern_bases(self):
+ for distro, version in modern_version_bases[_get_arch()].iteritems():
+ entry = lookup(distro, version)
+ self.assertEquals(entry['disk_bus'],
+ get_template_default('modern',
'disk_bus'))
+ self.assertEquals(entry['nic_model'],
+ get_template_default('modern',
'nic_model'))
+
+ def test_modern_distros(self):
+ # versions based on ppc64 modern distros
+ modern_versions = {'ubuntu': '14.04', 'opensuse':
'13.1',
+ 'rhel': '6.5', 'fedora': '19',
'sles': '11sp3'}
+ for distro, version in modern_versions.iteritems():
+ entry = lookup(distro, version)
+ self.assertEquals(entry['disk_bus'],
+ get_template_default('modern',
'disk_bus'))
+ self.assertEquals(entry['nic_model'],
+ get_template_default('modern',
'nic_model'))
+
+ def test_lookup_unknown_distro_version_returns_old_distro(self):
+ distro = 'unknown_distro'
+ version = 'unknown_version'
+ entry = lookup(distro, version)
+ self.assertEquals(entry['disk_bus'],
+ get_template_default('old', 'disk_bus'))
+ self.assertEquals(entry['nic_model'],
+ get_template_default('old', 'nic_model'))
diff --git a/src/wok/plugins/kimchi/tests/test_plugin.py
b/src/wok/plugins/kimchi/tests/test_plugin.py
new file mode 100644
index 0000000..fc8e277
--- /dev/null
+++ b/src/wok/plugins/kimchi/tests/test_plugin.py
@@ -0,0 +1,126 @@
+#
+# Project Kimchi
+#
+# Copyright IBM, Corp. 2013-2014
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+import json
+import os
+import unittest
+from functools import partial
+
+from wok.utils import get_enabled_plugins
+
+from wok.plugins.kimchi import mockmodel
+
+import utils
+
+
+test_server = None
+model = None
+host = None
+port = None
+ssl_port = None
+
+
+def setUpModule():
+ global test_server, model, host, port, ssl_port
+
+ utils.patch_auth()
+ model = mockmodel.MockModel('/tmp/obj-store-test')
+ host = '127.0.0.1'
+ port = utils.get_free_port('http')
+ ssl_port = utils.get_free_port('https')
+ test_server = utils.run_server(host, port, ssl_port, test_mode=True,
+ model=model)
+
+
+def tearDownModule():
+ test_server.stop()
+ os.unlink('/tmp/obj-store-test')
+
+
+(a)unittest.skipUnless(
+ 'sample' in [plugin for plugin, _config in get_enabled_plugins()],
+ 'sample plugin is not enabled, skip this test!')
+class PluginTests(unittest.TestCase):
+
+ def setUp(self):
+ self.request = partial(utils.request, host, ssl_port)
+
+ def _create_rectangle(self, name, length, width):
+ req = json.dumps({'name': name, 'length': length,
'width': width})
+ resp = self.request('/plugins/sample/rectangles', req, 'POST')
+ return resp
+
+ def _get_rectangle(self, name):
+ resp = self.request('/plugins/sample/rectangles/%s' % name)
+ return json.loads(resp.read())
+
+ def _create_rectangle_and_assert(self, name, length, width):
+ resp = self._create_rectangle(name, length, width)
+ self.assertEquals(201, resp.status)
+
+ rectangle = self._get_rectangle(name)
+ self.assertEquals(rectangle['name'], name)
+ self.assertEquals(rectangle['length'], length)
+ self.assertEquals(rectangle['width'], width)
+
+ def _get_rectangles_list(self):
+ resp = self.request('/plugins/sample/rectangles')
+ rectangles = json.loads(resp.read())
+ name_list = [rectangle['name'] for rectangle in rectangles]
+ return name_list
+
+ def test_rectangles(self):
+ # Create two new rectangles
+ self._create_rectangle_and_assert('small', 10, 8)
+ self._create_rectangle_and_assert('big', 20, 16)
+
+ # Verify they're in the list
+ name_list = self._get_rectangles_list()
+ self.assertIn('small', name_list)
+ self.assertIn('big', name_list)
+
+ # Update the big rectangle.
+ req = json.dumps({'length': 40, 'width': 30})
+ resp = self.request('/plugins/sample/rectangles/big', req,
'PUT')
+ self.assertEquals(200, resp.status)
+ big = self._get_rectangle('big')
+ self.assertEquals(big['length'], 40)
+ self.assertEquals(big['width'], 30)
+
+ # Delete two rectangles
+ resp = self.request('/plugins/sample/rectangles/big', '{}',
'DELETE')
+ self.assertEquals(204, resp.status)
+ resp = self.request('/plugins/sample/rectangles/small', '{}',
'DELETE')
+ self.assertEquals(204, resp.status)
+ name_list = self._get_rectangles_list()
+ self.assertEquals([], name_list)
+
+ def test_bad_params(self):
+ # Bad name
+ resp = self._create_rectangle(1.0, 30, 40)
+ self.assertEquals(400, resp.status)
+
+ # Bad length value
+ resp = self._create_rectangle('test', -10.0, 40)
+ self.assertEquals(400, resp.status)
+
+ # Missing param for width
+ req = json.dumps({'name': 'nowidth', 'length': 40})
+ resp = self.request('/plugins/sample/rectangles', req, 'POST')
+ self.assertEquals(400, resp.status)
diff --git a/src/wok/plugins/kimchi/tests/test_rest.py
b/src/wok/plugins/kimchi/tests/test_rest.py
new file mode 100644
index 0000000..243074e
--- /dev/null
+++ b/src/wok/plugins/kimchi/tests/test_rest.py
@@ -0,0 +1,1327 @@
+# -*- coding: utf-8 -*-
+#
+# Project Kimchi
+#
+# Copyright IBM, Corp. 2013-2015
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+import json
+import os
+import re
+import time
+import unittest
+import urllib2
+import urlparse
+from functools import partial
+
+from wok.rollbackcontext import RollbackContext
+from wok.utils import add_task
+
+from wok.plugins.kimchi import mockmodel
+from wok.plugins.kimchi.osinfo import get_template_default
+
+import iso_gen
+from utils import get_free_port, patch_auth, request
+from utils import run_server, wait_task
+
+
+test_server = None
+model = None
+host = None
+port = None
+ssl_port = None
+cherrypy_port = None
+fake_iso = '/tmp/fake.iso'
+
+
+def setUpModule():
+ global test_server, model, host, port, ssl_port, cherrypy_port
+
+ patch_auth()
+ model = mockmodel.MockModel('/tmp/obj-store-test')
+ host = '127.0.0.1'
+ port = get_free_port('http')
+ ssl_port = get_free_port('https')
+ cherrypy_port = get_free_port('cherrypy_port')
+ test_server = run_server(host, port, ssl_port, test_mode=True,
+ cherrypy_port=cherrypy_port, model=model)
+
+ # Create fake ISO to do the tests
+ iso_gen.construct_fake_iso(fake_iso, True, '12.04', 'ubuntu')
+ iso_gen.construct_fake_iso("/var/lib/libvirt/images/fedora.iso", True,
+ "17", "fedora")
+
+
+def tearDownModule():
+ test_server.stop()
+ os.unlink('/tmp/obj-store-test')
+ os.unlink(fake_iso)
+ os.unlink("/var/lib/libvirt/images/fedora.iso")
+
+
+class RestTests(unittest.TestCase):
+ def _async_op(self, cb, opaque):
+ time.sleep(1)
+ cb('success', True)
+
+ def _except_op(self, cb, opaque):
+ time.sleep(1)
+ raise Exception("Oops, this is an exception handle test."
+ " You can ignore it safely")
+ cb('success', True)
+
+ def _intermid_op(self, cb, opaque):
+ time.sleep(1)
+ cb('in progress')
+
+ def setUp(self):
+ self.request = partial(request, host, ssl_port)
+ model.reset()
+
+ def assertHTTPStatus(self, code, *args):
+ resp = self.request(*args)
+ self.assertEquals(code, resp.status)
+
+ def test_get_vms(self):
+ vms = json.loads(self.request('/plugins/kimchi/vms').read())
+ # test_rest.py uses MockModel() which connects to libvirt URI
+ # test:///default. By default this driver already has one VM created
+ self.assertEquals(1, len(vms))
+
+ # Create a template as a base for our VMs
+ req = json.dumps({'name': 'test', 'cdrom': fake_iso})
+ resp = self.request('/plugins/kimchi/templates', req, 'POST')
+ self.assertEquals(201, resp.status)
+
+ test_users = ['root']
+ test_groups = ['wheel']
+ # Now add a couple of VMs to the mock model
+ for i in xrange(10):
+ name = 'vm-%i' % i
+ req = json.dumps({'name': name,
+ 'template':
'/plugins/kimchi/templates/test',
+ 'users': test_users, 'groups':
test_groups})
+ resp = self.request('/plugins/kimchi/vms', req, 'POST')
+ self.assertEquals(202, resp.status)
+ task = json.loads(resp.read())
+ wait_task(self._task_lookup, task['id'])
+
+ vms = json.loads(self.request('/plugins/kimchi/vms').read())
+ self.assertEquals(11, len(vms))
+
+ vm = json.loads(self.request('/plugins/kimchi/vms/vm-1').read())
+ self.assertEquals('vm-1', vm['name'])
+ self.assertEquals('shutoff', vm['state'])
+ self.assertEquals([], vm['users'])
+ self.assertEquals([], vm['groups'])
+
+ def test_edit_vm(self):
+ req = json.dumps({'name': 'test', 'cdrom': fake_iso})
+ resp = self.request('/plugins/kimchi/templates', req, 'POST')
+ self.assertEquals(201, resp.status)
+
+ req = json.dumps({'name': 'vm-1',
+ 'template': '/plugins/kimchi/templates/test'})
+ resp = self.request('/plugins/kimchi/vms', req, 'POST')
+ self.assertEquals(202, resp.status)
+ task = json.loads(resp.read())
+ wait_task(self._task_lookup, task['id'])
+
+ vm = json.loads(self.request('/plugins/kimchi/vms/vm-1').read())
+ self.assertEquals('vm-1', vm['name'])
+
+ resp = self.request('/plugins/kimchi/vms/vm-1/start', '{}',
'POST')
+ self.assertEquals(200, resp.status)
+
+ req = json.dumps({'unsupported-attr': 'attr'})
+ resp = self.request('/plugins/kimchi/vms/vm-1', req, 'PUT')
+ self.assertEquals(400, resp.status)
+
+ req = json.dumps({'name': 'new-vm'})
+ resp = self.request('/plugins/kimchi/vms/vm-1', req, 'PUT')
+ self.assertEquals(400, resp.status)
+
+ req = json.dumps({'cpus': 3})
+ resp = self.request('/plugins/kimchi/vms/vm-1', req, 'PUT')
+ self.assertEquals(200, resp.status)
+
+ # Check if there is support to memory hotplug, once vm is running
+ resp = self.request('/plugins/kimchi/config/capabilities').read()
+ conf = json.loads(resp)
+ req = json.dumps({'memory': 2048})
+ resp = self.request('/plugins/kimchi/vms/vm-1', req, 'PUT')
+ if conf['mem_hotplug_support']:
+ self.assertEquals(200, resp.status)
+ else:
+ self.assertEquals(400, resp.status)
+
+ req = json.dumps({"graphics": {'passwd': "abcdef"}})
+ resp = self.request('/plugins/kimchi/vms/vm-1', req, 'PUT')
+ info = json.loads(resp.read())
+ self.assertEquals('abcdef',
info["graphics"]["passwd"])
+ self.assertEquals(None, info["graphics"]["passwdValidTo"])
+
+ resp = self.request('/plugins/kimchi/vms/vm-1/poweroff', '{}',
'POST')
+ self.assertEquals(200, resp.status)
+
+ req = json.dumps({"graphics": {'passwd': "123456",
+ 'passwdValidTo': 20}})
+ resp = self.request('/plugins/kimchi/vms/vm-1', req, 'PUT')
+ info = json.loads(resp.read())
+ self.assertEquals('123456',
info["graphics"]["passwd"])
+ self.assertGreaterEqual(20,
info["graphics"]["passwdValidTo"])
+
+ req = json.dumps({'name': 12})
+ resp = self.request('/plugins/kimchi/vms/vm-1', req, 'PUT')
+ self.assertEquals(400, resp.status)
+
+ req = json.dumps({'name': ''})
+ resp = self.request('/plugins/kimchi/vms/vm-1', req, 'PUT')
+ self.assertEquals(400, resp.status)
+
+ req = json.dumps({'cpus': -2})
+ resp = self.request('/plugins/kimchi/vms/vm-1', req, 'PUT')
+ self.assertEquals(400, resp.status)
+
+ req = json.dumps({'cpus': 'four'})
+ resp = self.request('/plugins/kimchi/vms/vm-1', req, 'PUT')
+ self.assertEquals(400, resp.status)
+
+ req = json.dumps({'memory': 100})
+ resp = self.request('/plugins/kimchi/vms/vm-1', req, 'PUT')
+ self.assertEquals(400, resp.status)
+
+ req = json.dumps({'memory': 'ten gigas'})
+ resp = self.request('/plugins/kimchi/vms/vm-1', req, 'PUT')
+ self.assertEquals(400, resp.status)
+
+ req = json.dumps({'name': 'new-name', 'cpus': 5,
'UUID': 'notallowed'})
+ resp = self.request('/plugins/kimchi/vms/vm-1', req, 'PUT')
+ self.assertEquals(400, resp.status)
+
+ params = {'name': u'�����-����d��t��d', 'cpus': 5,
'memory': 3072}
+ req = json.dumps(params)
+ resp = self.request('/plugins/kimchi/vms/vm-1', req, 'PUT')
+ self.assertEquals(303, resp.status)
+ vm = json.loads(
+ self.request('/plugins/kimchi/vms/�����-����d��t��d', req).read()
+ )
+ for key in params.keys():
+ self.assertEquals(params[key], vm[key])
+
+ # change only VM users - groups are not changed (default is empty)
+ resp = self.request('/plugins/kimchi/users', '{}',
'GET')
+ users = json.loads(resp.read())
+ req = json.dumps({'users': users})
+ resp = self.request('/plugins/kimchi/vms/�����-����d��t��d', req,
'PUT')
+ self.assertEquals(200, resp.status)
+ info = json.loads(
+ self.request('/plugins/kimchi/vms/�����-����d��t��d',
'{}').read()
+ )
+ self.assertEquals(users, info['users'])
+
+ # change only VM groups - users are not changed (default is empty)
+ resp = self.request('/plugins/kimchi/groups', '{}',
'GET')
+ groups = json.loads(resp.read())
+ req = json.dumps({'groups': groups})
+ resp = self.request('/plugins/kimchi/vms/�����-����d��t��d', req,
'PUT')
+ self.assertEquals(200, resp.status)
+ info = json.loads(
+ self.request('/plugins/kimchi/vms/�����-����d��t��d',
'{}').read()
+ )
+ self.assertEquals(groups, info['groups'])
+
+ # change VM users (wrong value) and groups
+ # when an error occurs, everything fails and nothing is changed
+ req = json.dumps({'users': ['userdoesnotexist'],
'groups': []})
+ resp = self.request('/plugins/kimchi/vms/�����-����d��t��d', req,
'PUT')
+ self.assertEquals(400, resp.status)
+
+ # change VM users and groups (wrong value)
+ # when an error occurs, everything fails and nothing is changed
+ req = json.dumps({'users': [], 'groups':
['groupdoesnotexist']})
+ resp = self.request('/plugins/kimchi/vms/�����-����d��t��d', req,
'PUT')
+ self.assertEquals(400, resp.status)
+
+ def test_vm_lifecycle(self):
+ # Create a Template
+ req = json.dumps({'name': 'test', 'disks':
[{'size': 1}],
+ 'icon': 'images/icon-debian.png',
+ 'cdrom': fake_iso})
+ resp = self.request('/plugins/kimchi/templates', req, 'POST')
+ self.assertEquals(201, resp.status)
+
+ # Create a VM
+ req = json.dumps({'name': 'test-vm',
+ 'template': '/plugins/kimchi/templates/test'})
+ resp = self.request('/plugins/kimchi/vms', req, 'POST')
+ task = json.loads(resp.read())
+ wait_task(self._task_lookup, task['id'])
+ self.assertEquals(202, resp.status)
+
+ # Verify the VM
+ vm = json.loads(self.request('/plugins/kimchi/vms/test-vm').read())
+ self.assertEquals('shutoff', vm['state'])
+ self.assertEquals('images/icon-debian.png', vm['icon'])
+
+ # Verify the volume was created
+ vol_uri = '/plugins/kimchi/storagepools/default-pool/storagevolumes/' \
+ + '%s-0.img'
+ resp = self.request(vol_uri % vm['uuid'])
+ vol = json.loads(resp.read())
+ self.assertEquals(1 << 30, vol['capacity'])
+ self.assertEquals(['test-vm'], vol['used_by'])
+
+ # Start the VM
+ resp = self.request('/plugins/kimchi/vms/test-vm/start', '{}',
'POST')
+ vm = json.loads(self.request('/plugins/kimchi/vms/test-vm').read())
+ self.assertEquals('running', vm['state'])
+
+ # Test screenshot
+ resp = self.request(vm['screenshot'], method='HEAD')
+ self.assertEquals(200, resp.status)
+
self.assertTrue(resp.getheader('Content-type').startswith('image'))
+
+ # Clone a running VM
+ resp = self.request('/plugins/kimchi/vms/test-vm/clone', '{}',
'POST')
+ self.assertEquals(400, resp.status)
+
+ # Force poweroff the VM
+ resp = self.request('/plugins/kimchi/vms/test-vm/poweroff',
'{}',
+ 'POST')
+ vm = json.loads(self.request('/plugins/kimchi/vms/test-vm').read())
+ self.assertEquals('shutoff', vm['state'])
+
+ # Test create VM with same name fails with 400
+ req = json.dumps({'name': 'test-vm',
+ 'template': '/plugins/kimchi/templates/test'})
+ resp = self.request('/plugins/kimchi/vms', req, 'POST')
+ self.assertEquals(400, resp.status)
+
+ # Clone a VM
+ resp = self.request('/plugins/kimchi/vms/test-vm/clone', '{}',
'POST')
+ self.assertEquals(202, resp.status)
+ task = json.loads(resp.read())
+ wait_task(self._task_lookup, task['id'])
+ task = json.loads(
+ self.request('/tasks/%s' % task['id'], '{}').read()
+ )
+ self.assertEquals('finished', task['status'])
+ clone_vm_name = task['target_uri'].split('/')[-2]
+ self.assertTrue(re.match(u'test-vm-clone-\d+', clone_vm_name))
+
+ resp = self.request('/plugins/kimchi/vms/test-vm', '{}')
+ original_vm_info = json.loads(resp.read())
+ resp = self.request('/plugins/kimchi/vms/%s' % clone_vm_name,
'{}')
+ self.assertEquals(200, resp.status)
+ clone_vm_info = json.loads(resp.read())
+
+ self.assertNotEqual(original_vm_info['name'],
clone_vm_info['name'])
+ del original_vm_info['name']
+ del clone_vm_info['name']
+
+ self.assertNotEqual(original_vm_info['uuid'],
clone_vm_info['uuid'])
+ del original_vm_info['uuid']
+ del clone_vm_info['uuid']
+
+ self.assertEquals(original_vm_info, clone_vm_info)
+
+ # Create a snapshot on a stopped VM
+ params = {'name': 'test-snap'}
+ resp = self.request('/plugins/kimchi/vms/test-vm/snapshots',
+ json.dumps(params),
+ 'POST')
+ self.assertEquals(202, resp.status)
+ task = json.loads(resp.read())
+ wait_task(self._task_lookup, task['id'])
+ task = json.loads(
+ self.request('/tasks/%s' % task['id']).read()
+ )
+ self.assertEquals('finished', task['status'])
+
+ # Look up a non-existing snapshot
+ resp = self.request('/plugins/kimchi/vms/test-vm/snapshots/snap404',
+ '{}', 'GET')
+ self.assertEquals(404, resp.status)
+
+ # Look up a snapshot
+ resp = self.request('/plugins/kimchi/vms/test-vm/snapshots/%s' %
+ params['name'], '{}', 'GET')
+ self.assertEquals(200, resp.status)
+ snap = json.loads(resp.read())
+ self.assertTrue(int(time.time()) >= int(snap['created']))
+ self.assertEquals(params['name'], snap['name'])
+ self.assertEquals(u'', snap['parent'])
+ self.assertEquals(u'shutoff', snap['state'])
+
+ resp = self.request('/plugins/kimchi/vms/test-vm/snapshots',
'{}',
+ 'GET')
+ self.assertEquals(200, resp.status)
+ snaps = json.loads(resp.read())
+ self.assertEquals(1, len(snaps))
+
+ # Look up current snapshot (the one created above)
+ resp = self.request('/plugins/kimchi/vms/test-vm/snapshots/current',
+ '{}', 'GET')
+ self.assertEquals(200, resp.status)
+ snap = json.loads(resp.read())
+ self.assertEquals(params['name'], snap['name'])
+
+ resp = self.request('/plugins/kimchi/vms/test-vm/snapshots',
'{}',
+ 'POST')
+ self.assertEquals(202, resp.status)
+ task = json.loads(resp.read())
+ snap_name = task['target_uri'].split('/')[-1]
+ wait_task(self._task_lookup, task['id'])
+ resp = self.request('/tasks/%s' % task['id'], '{}',
+ 'GET')
+ task = json.loads(resp.read())
+ self.assertEquals('finished', task['status'])
+
+ resp = self.request('/plugins/kimchi/vms/test-vm/snapshots',
'{}',
+ 'GET')
+ self.assertEquals(200, resp.status)
+ snaps = json.loads(resp.read())
+ self.assertEquals(2, len(snaps))
+
+ # Look up current snapshot (the one created above)
+ resp = self.request('/plugins/kimchi/vms/test-vm/snapshots/current',
+ '{}', 'GET')
+ self.assertEquals(200, resp.status)
+ snap = json.loads(resp.read())
+ self.assertEquals(snap_name, snap['name'])
+
+ # Revert to snapshot
+ resp = self.request('/plugins/kimchi/vms/test-vm/snapshots/%s/revert' %
+ params['name'], '{}', 'POST')
+ self.assertEquals(200, resp.status)
+ snap = json.loads(resp.read())
+ resp = self.request('/plugins/kimchi/vms/test-vm', '{}',
'GET')
+ self.assertEquals(200, resp.status)
+ vm = json.loads(resp.read())
+ self.assertEquals(vm['state'], snap['state'])
+ resp = self.request('/plugins/kimchi/vms/test-vm/snapshots/current',
+ '{}', 'GET')
+ self.assertEquals(200, resp.status)
+ current_snap = json.loads(resp.read())
+ self.assertEquals(snap, current_snap)
+
+ # Delete a snapshot
+ resp = self.request('/plugins/kimchi/vms/test-vm/snapshots/%s' %
+ params['name'], '{}', 'DELETE')
+ self.assertEquals(204, resp.status)
+
+ # Suspend the VM
+ resp = self.request('/plugins/kimchi/vms/test-vm', '{}',
'GET')
+ self.assertEquals(200, resp.status)
+ vm = json.loads(resp.read())
+ self.assertEquals(vm['state'], 'shutoff')
+ resp = self.request('/plugins/kimchi/vms/test-vm/suspend', '{}',
+ 'POST')
+ self.assertEquals(400, resp.status)
+ resp = self.request('/plugins/kimchi/vms/test-vm/start', '{}',
'POST')
+ self.assertEquals(200, resp.status)
+ resp = self.request('/plugins/kimchi/vms/test-vm', '{}',
'GET')
+ self.assertEquals(200, resp.status)
+ vm = json.loads(resp.read())
+ self.assertEquals(vm['state'], 'running')
+ resp = self.request('/plugins/kimchi/vms/test-vm/suspend', '{}',
+ 'POST')
+ self.assertEquals(200, resp.status)
+ resp = self.request('/plugins/kimchi/vms/test-vm', '{}',
'GET')
+ self.assertEquals(200, resp.status)
+ vm = json.loads(resp.read())
+ self.assertEquals(vm['state'], 'paused')
+
+ # Resume the VM
+ resp = self.request('/plugins/kimchi/vms/test-vm/resume', '{}',
'POST')
+ self.assertEquals(200, resp.status)
+ resp = self.request('/plugins/kimchi/vms/test-vm', '{}',
'GET')
+ self.assertEquals(200, resp.status)
+ vm = json.loads(resp.read())
+ self.assertEquals(vm['state'], 'running')
+
+ # Delete the VM
+ resp = self.request('/plugins/kimchi/vms/test-vm', '{}',
'DELETE')
+ self.assertEquals(204, resp.status)
+
+ # Delete the Template
+ resp = self.request('/plugins/kimchi/templates/test', '{}',
'DELETE')
+ self.assertEquals(204, resp.status)
+
+ # Verify the volume was deleted
+ self.assertHTTPStatus(404, vol_uri % vm['uuid'])
+
+ def test_vm_graphics(self):
+ # Create a Template
+ req = json.dumps({'name': 'test', 'cdrom': fake_iso})
+ resp = self.request('/plugins/kimchi/templates', req, 'POST')
+ self.assertEquals(201, resp.status)
+
+ # Create a VM with default args
+ req = json.dumps({'name': 'test-vm',
+ 'template': '/plugins/kimchi/templates/test'})
+ resp = self.request('/plugins/kimchi/vms', req, 'POST')
+ self.assertEquals(202, resp.status)
+ task = json.loads(resp.read())
+ wait_task(self._task_lookup, task['id'])
+ # Verify the VM
+ vm = json.loads(self.request('/plugins/kimchi/vms/test-vm').read())
+ self.assertEquals('127.0.0.1', vm['graphics']['listen'])
+ self.assertEquals('vnc', vm['graphics']['type'])
+ # Delete the VM
+ resp = self.request('/plugins/kimchi/vms/test-vm', '{}',
'DELETE')
+ self.assertEquals(204, resp.status)
+
+ # Create a VM with specified graphics type and listen
+ graphics = {'type': 'vnc', 'listen':
'127.0.0.1'}
+ req = json.dumps({'name': 'test-vm',
+ 'template': '/plugins/kimchi/templates/test',
+ 'graphics': graphics})
+ resp = self.request('/plugins/kimchi/vms', req, 'POST')
+ self.assertEquals(202, resp.status)
+ task = json.loads(resp.read())
+ wait_task(self._task_lookup, task['id'])
+ # Verify the VM
+ vm = json.loads(self.request('/plugins/kimchi/vms/test-vm').read())
+ self.assertEquals('127.0.0.1', vm['graphics']['listen'])
+ self.assertEquals('vnc', vm['graphics']['type'])
+ # Delete the VM
+ resp = self.request('/plugins/kimchi/vms/test-vm', '{}',
'DELETE')
+ self.assertEquals(204, resp.status)
+
+ # Create a VM with listen as ipv6 address
+ graphics = {'type': 'spice', 'listen':
'fe00::0'}
+ req = json.dumps({'name': 'test-vm',
+ 'template': '/plugins/kimchi/templates/test',
+ 'graphics': graphics})
+ resp = self.request('/plugins/kimchi/vms', req, 'POST')
+ self.assertEquals(202, resp.status)
+ task = json.loads(resp.read())
+ wait_task(self._task_lookup, task['id'])
+ # Verify the VM
+ vm = json.loads(self.request('/plugins/kimchi/vms/test-vm').read())
+ self.assertEquals('fe00::0', vm['graphics']['listen'])
+ self.assertEquals('spice', vm['graphics']['type'])
+ # Delete the VM
+ resp = self.request('/plugins/kimchi/vms/test-vm', '{}',
'DELETE')
+ self.assertEquals(204, resp.status)
+
+ # Create a VM with specified graphics type and default listen
+ graphics = {'type': 'spice'}
+ req = json.dumps({'name': 'test-vm',
+ 'template': '/plugins/kimchi/templates/test',
+ 'graphics': graphics})
+ resp = self.request('/plugins/kimchi/vms', req, 'POST')
+ self.assertEquals(202, resp.status)
+ task = json.loads(resp.read())
+ wait_task(self._task_lookup, task['id'])
+ # Verify the VM
+ vm = json.loads(self.request('/plugins/kimchi/vms/test-vm').read())
+ self.assertEquals('127.0.0.1', vm['graphics']['listen'])
+ self.assertEquals('spice', vm['graphics']['type'])
+ # Delete the VM
+ resp = self.request('/plugins/kimchi/vms/test-vm', '{}',
'DELETE')
+ self.assertEquals(204, resp.status)
+
+ # Try to create a VM with invalid graphics type
+ graphics = {'type': 'invalid'}
+ req = json.dumps({'name': 'test-vm',
+ 'template': '/plugins/kimchi/templates/test',
+ 'graphics': graphics})
+ resp = self.request('/plugins/kimchi/vms', req, 'POST')
+ self.assertEquals(400, resp.status)
+
+ # Try to create a VM with invalid graphics listen
+ graphics = {'type': 'spice', 'listen':
'invalid'}
+ req = json.dumps({'name': 'test-vm',
+ 'template': '/plugins/kimchi/templates/test',
+ 'graphics': graphics})
+ resp = self.request('/plugins/kimchi/vms', req, 'POST')
+ self.assertEquals(400, resp.status)
+
+ # Delete the Template
+ resp = self.request('/plugins/kimchi/templates/test', '{}',
'DELETE')
+ self.assertEquals(204, resp.status)
+
+ def test_vm_storage_devices(self):
+
+ with RollbackContext() as rollback:
+ # Create a template as a base for our VMs
+ req = json.dumps({'name': 'test', 'cdrom':
fake_iso})
+ resp = self.request('/plugins/kimchi/templates', req,
'POST')
+ self.assertEquals(201, resp.status)
+ # Delete the template
+ rollback.prependDefer(self.request,
+ '/plugins/kimchi/templates/test',
'{}',
+ 'DELETE')
+
+ # Create a VM with default args
+ req = json.dumps({'name': 'test-vm',
+ 'template':
'/plugins/kimchi/templates/test'})
+ resp = self.request('/plugins/kimchi/vms', req, 'POST')
+ self.assertEquals(202, resp.status)
+ task = json.loads(resp.read())
+ wait_task(self._task_lookup, task['id'])
+ # Delete the VM
+ rollback.prependDefer(self.request, '/plugins/kimchi/vms/test-vm',
+ '{}', 'DELETE')
+
+ # Check storage devices
+ resp = self.request('/plugins/kimchi/vms/test-vm/storages',
'{}',
+ 'GET')
+ devices = json.loads(resp.read())
+ self.assertEquals(2, len(devices))
+ dev_types = []
+ for d in devices:
+ self.assertIn(u'type', d.keys())
+ self.assertIn(u'dev', d.keys())
+ self.assertIn(u'path', d.keys())
+ dev_types.append(d['type'])
+
+ self.assertEquals(['cdrom', 'disk'], sorted(dev_types))
+
+ # Attach cdrom with nonexistent iso
+ req = json.dumps({'dev': 'hdx',
+ 'type': 'cdrom',
+ 'path': '/tmp/nonexistent.iso'})
+ resp = self.request('/plugins/kimchi/vms/test-vm/storages', req,
+ 'POST')
+ self.assertEquals(400, resp.status)
+
+ # Create temp storage pool
+ req = json.dumps({'name': 'tmp',
+ 'capacity': 1024,
+ 'allocated': 512,
+ 'path': '/tmp',
+ 'type': 'dir'})
+ resp = self.request('/plugins/kimchi/storagepools', req,
'POST')
+ self.assertEquals(201, resp.status)
+ resp = self.request('/plugins/kimchi/storagepools/tmp/activate',
+ req, 'POST')
+ self.assertEquals(200, resp.status)
+
+ # 'name' is required for this type of volume
+ req = json.dumps({'capacity': 1024,
+ 'allocation': 512,
+ 'type': 'disk',
+ 'format': 'raw'})
+ resp = self.request(
+ '/plugins/kimchi/storagepools/tmp/storagevolumes', req,
'POST'
+ )
+ self.assertEquals(400, resp.status)
+ req = json.dumps({'name': "attach-volume",
+ 'capacity': 1024,
+ 'allocation': 512,
+ 'type': 'disk',
+ 'format': 'raw'})
+ resp = self.request(
+ '/plugins/kimchi/storagepools/tmp/storagevolumes', req,
'POST'
+ )
+ self.assertEquals(202, resp.status)
+ time.sleep(1)
+
+ # Attach cdrom with both path and volume specified
+ open('/tmp/existent.iso', 'w').close()
+ req = json.dumps({'dev': 'hdx',
+ 'type': 'cdrom',
+ 'pool': 'tmp',
+ 'vol': 'attach-volume',
+ 'path': '/tmp/existent.iso'})
+ resp = self.request(
+ '/plugins/kimchi/vms/test-vm/storages', req, 'POST'
+ )
+ self.assertEquals(400, resp.status)
+
+ # Attach disk with both path and volume specified
+ req = json.dumps({'dev': 'hdx',
+ 'type': 'disk',
+ 'pool': 'tmp',
+ 'vol': 'attach-volume',
+ 'path': '/tmp/existent.iso'})
+ resp = self.request(
+ '/plugins/kimchi/vms/test-vm/storages', req, 'POST'
+ )
+ self.assertEquals(400, resp.status)
+
+ # Attach disk with only pool specified
+ req = json.dumps({'dev': 'hdx',
+ 'type': 'cdrom',
+ 'pool': 'tmp'})
+ resp = self.request(
+ '/plugins/kimchi/vms/test-vm/storages', req, 'POST'
+ )
+ self.assertEquals(400, resp.status)
+
+ # Attach disk with pool and vol specified
+ req = json.dumps({'type': 'disk',
+ 'pool': 'tmp',
+ 'vol': 'attach-volume'})
+ resp = self.request(
+ '/plugins/kimchi/vms/test-vm/storages', req, 'POST'
+ )
+ self.assertEquals(201, resp.status)
+ cd_info = json.loads(resp.read())
+ self.assertEquals('disk', cd_info['type'])
+
+ # Attach a cdrom with existent dev name
+ req = json.dumps({'type': 'cdrom',
+ 'path': '/tmp/existent.iso'})
+ resp = self.request(
+ '/plugins/kimchi/vms/test-vm/storages', req, 'POST'
+ )
+ self.assertEquals(201, resp.status)
+ cd_info = json.loads(resp.read())
+ cd_dev = cd_info['dev']
+ self.assertEquals('cdrom', cd_info['type'])
+ self.assertEquals('/tmp/existent.iso', cd_info['path'])
+ # Delete the file and cdrom
+ rollback.prependDefer(self.request,
+ '/plugins/kimchi/vms/test-vm/storages/hdx',
+ '{}', 'DELETE')
+ os.remove('/tmp/existent.iso')
+
+ # Change path of storage cdrom
+ cdrom =
u'http://fedora.mirrors.tds.net/pub/fedora/releases/20/'\
+ 'Live/x86_64/Fedora-Live-Desktop-x86_64-20-1.iso'
+ req = json.dumps({'path': cdrom})
+ resp = self.request('/plugins/kimchi/vms/test-vm/storages/' +
+ cd_dev, req, 'PUT')
+ self.assertEquals(200, resp.status)
+ cd_info = json.loads(resp.read())
+ self.assertEquals(urlparse.urlparse(cdrom).path,
+ urlparse.urlparse(cd_info['path']).path)
+
+ # Test GET
+ devs = json.loads(
+ self.request('/plugins/kimchi/vms/test-vm/storages').read()
+ )
+ self.assertEquals(4, len(devs))
+
+ # Detach storage cdrom
+ resp = self.request('/plugins/kimchi/vms/test-vm/storages/' +
+ cd_dev, '{}', 'DELETE')
+ self.assertEquals(204, resp.status)
+
+ # Test GET
+ devs = json.loads(
+ self.request('/plugins/kimchi/vms/test-vm/storages').read()
+ )
+ self.assertEquals(3, len(devs))
+ resp = self.request('/plugins/kimchi/storagepools/tmp/deactivate',
+ {}, 'POST')
+ self.assertEquals(200, resp.status)
+ resp = self.request('/plugins/kimchi/storagepools/tmp', {},
+ 'DELETE')
+ self.assertEquals(204, resp.status)
+
+ def test_vm_iface(self):
+
+ with RollbackContext() as rollback:
+ # Create a template as a base for our VMs
+ req = json.dumps({'name': 'test', 'cdrom':
fake_iso})
+ resp = self.request('/plugins/kimchi/templates', req,
'POST')
+ self.assertEquals(201, resp.status)
+ # Delete the template
+ rollback.prependDefer(self.request,
+ '/plugins/kimchi/templates/test',
'{}',
+ 'DELETE')
+
+ # Create a VM with default args
+ req = json.dumps({'name': 'test-vm',
+ 'template':
'/plugins/kimchi/templates/test'})
+ resp = self.request('/plugins/kimchi/vms', req, 'POST')
+ self.assertEquals(202, resp.status)
+ task = json.loads(resp.read())
+ wait_task(self._task_lookup, task['id'])
+ # Delete the VM
+ rollback.prependDefer(self.request,
+ '/plugins/kimchi/vms/test-vm', '{}',
+ 'DELETE')
+
+ # Create a network
+ req = json.dumps({'name': 'test-network',
+ 'connection': 'nat',
+ 'net': '127.0.1.0/24'})
+ resp = self.request('/plugins/kimchi/networks', req, 'POST')
+ self.assertEquals(201, resp.status)
+ # Delete the network
+ rollback.prependDefer(self.request,
+ '/plugins/kimchi/networks/test-network',
+ '{}', 'DELETE')
+
+ ifaces = json.loads(
+ self.request('/plugins/kimchi/vms/test-vm/ifaces').read()
+ )
+ self.assertEquals(1, len(ifaces))
+
+ for iface in ifaces:
+ res = json.loads(
+ self.request('/plugins/kimchi/vms/test-vm/ifaces/%s' %
+ iface['mac']).read()
+ )
+ self.assertEquals('default', res['network'])
+ self.assertEquals(17, len(res['mac']))
+ self.assertEquals(get_template_default('old',
'nic_model'),
+ res['model'])
+
+ # try to attach an interface without specifying 'model'
+ req = json.dumps({'type': 'network'})
+ resp = self.request('/plugins/kimchi/vms/test-vm/ifaces', req,
+ 'POST')
+ self.assertEquals(400, resp.status)
+
+ # attach network interface to vm
+ req = json.dumps({"type": "network",
+ "network": "test-network",
+ "model": "virtio"})
+ resp = self.request('/plugins/kimchi/vms/test-vm/ifaces', req,
+ 'POST')
+ self.assertEquals(201, resp.status)
+ iface = json.loads(resp.read())
+
+ self.assertEquals('test-network', iface['network'])
+ self.assertEquals(17, len(iface['mac']))
+ self.assertEquals('virtio', iface['model'])
+ self.assertEquals('network', iface['type'])
+
+ # update vm interface
+ newMacAddr = '54:50:e3:44:8a:af'
+ req = json.dumps({"network": "default",
"model": "virtio",
+ "type": "network", "mac":
newMacAddr})
+ resp = self.request('/plugins/kimchi/vms/test-vm/ifaces/%s' %
+ iface['mac'], req, 'PUT')
+ self.assertEquals(303, resp.status)
+ iface = json.loads(
+ self.request('/plugins/kimchi/vms/test-vm/ifaces/%s' %
+ newMacAddr).read()
+ )
+ self.assertEquals(newMacAddr, iface['mac'])
+
+ # detach network interface from vm
+ resp = self.request('/plugins/kimchi/vms/test-vm/ifaces/%s' %
+ iface['mac'], '{}', 'DELETE')
+ self.assertEquals(204, resp.status)
+
+ def test_vm_customise_storage(self):
+ # Create a Template
+ req = json.dumps({'name': 'test', 'cdrom': fake_iso,
+ 'disks': [{'size': 1}]})
+ resp = self.request('/plugins/kimchi/templates', req, 'POST')
+ self.assertEquals(201, resp.status)
+
+ # Create alternate storage
+ req = json.dumps({'name': 'alt',
+ 'capacity': 1024,
+ 'allocated': 512,
+ 'path': '/tmp',
+ 'type': 'dir'})
+ resp = self.request('/plugins/kimchi/storagepools', req, 'POST')
+ self.assertEquals(201, resp.status)
+ resp = self.request('/plugins/kimchi/storagepools/alt/activate', req,
+ 'POST')
+ self.assertEquals(200, resp.status)
+
+ # Create a VM
+ req = json.dumps({'name': 'test-vm',
+ 'template': '/plugins/kimchi/templates/test',
+ 'storagepool':
'/plugins/kimchi/storagepools/alt'})
+ resp = self.request('/plugins/kimchi/vms', req, 'POST')
+ self.assertEquals(202, resp.status)
+ task = json.loads(resp.read())
+ wait_task(self._task_lookup, task['id'])
+ resp = self.request('/plugins/kimchi/vms/test-vm', {}, 'GET')
+ vm_info = json.loads(resp.read())
+
+ # Test template not changed after vm customise its pool
+ t = json.loads(self.request('/plugins/kimchi/templates/test').read())
+ self.assertEquals(t['storagepool'],
+ '/plugins/kimchi/storagepools/default-pool')
+
+ # Verify the volume was created
+ vol_uri = '/plugins/kimchi/storagepools/alt/storagevolumes/%s-0.img' \
+ % vm_info['uuid']
+ resp = self.request(vol_uri)
+ vol = json.loads(resp.read())
+ self.assertEquals(1 << 30, vol['capacity'])
+
+ # Delete the VM
+ resp = self.request('/plugins/kimchi/vms/test-vm', '{}',
'DELETE')
+ self.assertEquals(204, resp.status)
+
+ # Verify the volume was deleted
+ self.assertHTTPStatus(404, vol_uri)
+
+ def test_scsi_fc_storage(self):
+ # Create scsi fc pool
+ req = json.dumps({'name': 'scsi_fc_pool',
+ 'type': 'scsi',
+ 'source': {'adapter_name':
'scsi_host2'}})
+ resp = self.request('/plugins/kimchi/storagepools', req, 'POST')
+ self.assertEquals(201, resp.status)
+
+ # Test create vms using lun of this pool
+ # activate the storage pool
+ resp = self.request(
+ '/plugins/kimchi/storagepools/scsi_fc_pool/activate', '{}',
'POST'
+ )
+
+ # Create template fails because SCSI volume is missing
+ tmpl_params = {
+ 'name': 'test_fc_pool', 'cdrom': fake_iso,
+ 'storagepool': '/plugins/kimchi/storagepools/scsi_fc_pool'
+ }
+ req = json.dumps(tmpl_params)
+ resp = self.request('/plugins/kimchi/templates', req, 'POST')
+ self.assertEquals(400, resp.status)
+
+ # Choose SCSI volume to create template
+ resp = self.request(
+ '/plugins/kimchi/storagepools/scsi_fc_pool/storagevolumes'
+ )
+ lun_name = json.loads(resp.read())[0]['name']
+
+ tmpl_params['disks'] = [{'index': 0, 'volume':
lun_name}]
+ req = json.dumps(tmpl_params)
+ resp = self.request('/plugins/kimchi/templates', req, 'POST')
+ self.assertEquals(201, resp.status)
+
+ # Create vm in scsi pool
+ req = json.dumps({'name': 'test-vm',
+ 'template':
'/plugins/kimchi/templates/test_fc_pool'})
+ resp = self.request('/plugins/kimchi/vms', req, 'POST')
+ self.assertEquals(202, resp.status)
+ task = json.loads(resp.read())
+ wait_task(self._task_lookup, task['id'])
+
+ # Start the VM
+ resp = self.request('/plugins/kimchi/vms/test-vm/start', '{}',
'POST')
+ vm = json.loads(self.request('/plugins/kimchi/vms/test-vm').read())
+ self.assertEquals('running', vm['state'])
+
+ # Force poweroff the VM
+ resp = self.request('/plugins/kimchi/vms/test-vm/poweroff',
'{}',
+ 'POST')
+ vm = json.loads(self.request('/plugins/kimchi/vms/test-vm').read())
+ self.assertEquals('shutoff', vm['state'])
+
+ # Delete the VM
+ resp = self.request('/plugins/kimchi/vms/test-vm', '{}',
'DELETE')
+ self.assertEquals(204, resp.status)
+
+ def test_unnamed_vms(self):
+ # Create a Template
+ req = json.dumps({'name': 'test', 'cdrom': fake_iso})
+ resp = self.request('/plugins/kimchi/templates', req, 'POST')
+ self.assertEquals(201, resp.status)
+
+ # Create 5 unnamed vms from this template
+ for i in xrange(1, 6):
+ req = json.dumps({'template':
'/plugins/kimchi/templates/test'})
+ task = json.loads(self.request('/plugins/kimchi/vms',
+ req, 'POST').read())
+ wait_task(self._task_lookup, task['id'])
+ resp = self.request('/plugins/kimchi/vms/test-vm-%i' % i, {},
+ 'GET')
+ self.assertEquals(resp.status, 200)
+ count = len(json.loads(self.request('/plugins/kimchi/vms').read()))
+ self.assertEquals(6, count)
+
+ def test_create_vm_without_template(self):
+ req = json.dumps({'name': 'vm-without-template'})
+ resp = self.request('/plugins/kimchi/vms', req, 'POST')
+ self.assertEquals(400, resp.status)
+ resp = json.loads(resp.read())
+ self.assertIn(u"KCHVM0016E:", resp['reason'])
+
+ def test_create_vm_with_bad_template_uri(self):
+ req = json.dumps({'name': 'vm-bad-template',
+ 'template': '/mytemplate'})
+ resp = self.request('/plugins/kimchi/vms', req, 'POST')
+ self.assertEquals(400, resp.status)
+ resp = json.loads(resp.read())
+ self.assertIn(u"KCHVM0012E", resp['reason'])
+
+ def test_create_vm_with_img_based_template(self):
+ resp = json.loads(
+ self.request(
+ '/plugins/kimchi/storagepools/default-pool/storagevolumes'
+ ).read()
+ )
+ self.assertEquals(0, len(resp))
+
+ # Create a Template
+ mock_base = '/tmp/mock.img'
+ open(mock_base, 'w').close()
+ req = json.dumps({'name': 'test', 'disks':
[{'base': mock_base}]})
+ resp = self.request('/plugins/kimchi/templates', req, 'POST')
+ self.assertEquals(201, resp.status)
+
+ req = json.dumps({'template': '/plugins/kimchi/templates/test'})
+ resp = self.request('/plugins/kimchi/vms', req, 'POST')
+ self.assertEquals(202, resp.status)
+ task = json.loads(resp.read())
+ wait_task(self._task_lookup, task['id'])
+
+ # Test storage volume created with backing store of base file
+ resp = json.loads(
+ self.request(
+ '/plugins/kimchi/storagepools/default-pool/storagevolumes'
+ ).read()
+ )
+ self.assertEquals(1, len(resp))
+
+ def _create_pool(self, name):
+ req = json.dumps({'name': name,
+ 'capacity': 10240,
+ 'allocated': 5120,
+ 'path': '/var/lib/libvirt/images/',
+ 'type': 'dir'})
+ resp = self.request('/plugins/kimchi/storagepools', req, 'POST')
+ self.assertEquals(201, resp.status)
+
+ # Verify the storage pool
+ storagepool = json.loads(self.request('/plugins/kimchi/storagepools/%s'
+ % name).read())
+ self.assertEquals('inactive', storagepool['state'])
+ return name
+
+ def _delete_pool(self, name):
+ # Delete the storage pool
+ resp = self.request('/plugins/kimchi/storagepools/%s' % name,
'{}',
+ 'DELETE')
+ self.assertEquals(204, resp.status)
+
+ def test_iso_scan_shallow(self):
+ # fake environment preparation
+ self._create_pool('pool-3')
+ self.request('/plugins/kimchi/storagepools/pool-3/activate',
'{}',
+ 'POST')
+ params = {'name': 'fedora.iso',
+ 'capacity': 1073741824, # 1 GiB
+ 'type': 'file',
+ 'format': 'iso'}
+ task_info = model.storagevolumes_create('pool-3', params)
+ wait_task(self._task_lookup, task_info['id'])
+
+ storagevolume = json.loads(
+ self.request(
+ '/plugins/kimchi/storagepools/kimchi_isos/storagevolumes/'
+ ).read()
+ )[0]
+ self.assertEquals('fedora.iso', storagevolume['name'])
+ self.assertEquals('iso', storagevolume['format'])
+ self.assertEquals('/var/lib/libvirt/images/fedora.iso',
+ storagevolume['path'])
+ self.assertEquals(1073741824, storagevolume['capacity']) # 1 GiB
+ self.assertEquals(0, storagevolume['allocation'])
+ self.assertEquals('17', storagevolume['os_version'])
+ self.assertEquals('fedora', storagevolume['os_distro'])
+ self.assertEquals(True, storagevolume['bootable'])
+
+ # Create a template
+ # In real model os distro/version can be omitted
+ # as we will scan the iso
+ req = json.dumps({'name': 'test',
+ 'cdrom': storagevolume['path'],
+ 'os_distro': storagevolume['os_distro'],
+ 'os_version': storagevolume['os_version']})
+ resp = self.request('/plugins/kimchi/templates', req, 'POST')
+ self.assertEquals(201, resp.status)
+
+ # Verify the template
+ t = json.loads(self.request('/plugins/kimchi/templates/test').read())
+ self.assertEquals('test', t['name'])
+ self.assertEquals('fedora', t['os_distro'])
+ self.assertEquals('17', t['os_version'])
+ self.assertEquals(get_template_default('old', 'memory'),
t['memory'])
+
+ # Deactivate or destroy scan pool return 405
+ resp = self.request(
+ '/plugins/kimchi/storagepools/kimchi_isos/storagevolumes'
+ '/deactivate', '{}', 'POST'
+ )
+ self.assertEquals(405, resp.status)
+
+ resp = self.request(
+ '/plugins/kimchi/storagepools/kimchi_isos/storagevolumes',
+ '{}', 'DELETE'
+ )
+ self.assertEquals(405, resp.status)
+
+ # Delete the template
+ resp = self.request('/plugins/kimchi/templates/%s' % t['name'],
'{}',
+ 'DELETE')
+ self.assertEquals(204, resp.status)
+
+ resp = self.request('/plugins/kimchi/storagepools/pool-3/deactivate',
+ '{}', 'POST')
+ self.assertEquals(200, resp.status)
+ self._delete_pool('pool-3')
+
+ def test_screenshot_refresh(self):
+ # Create a VM
+ req = json.dumps({'name': 'test', 'cdrom': fake_iso})
+ resp = self.request('/plugins/kimchi/templates', req, 'POST')
+ req = json.dumps({'name': 'test-vm',
+ 'template': '/plugins/kimchi/templates/test'})
+ resp = self.request('/plugins/kimchi/vms', req, 'POST')
+ task = json.loads(resp.read())
+ wait_task(self._task_lookup, task['id'])
+
+ # Test screenshot for shut-off state vm
+ resp = self.request('/plugins/kimchi/vms/test-vm/screenshot')
+ self.assertEquals(404, resp.status)
+
+ # Test screenshot for running vm
+ resp = self.request('/plugins/kimchi/vms/test-vm/start', '{}',
'POST')
+ vm = json.loads(self.request('/plugins/kimchi/vms/test-vm').read())
+
+ resp = self.request(vm['screenshot'], method='HEAD')
+ self.assertEquals(200, resp.status)
+
self.assertTrue(resp.getheader('Content-type').startswith('image'))
+
+ # Test screenshot sub-resource redirect
+ resp = self.request('/plugins/kimchi/vms/test-vm/screenshot')
+ self.assertEquals(200, resp.status)
+ self.assertEquals('image/png', resp.getheader('content-type'))
+ lastMod1 = resp.getheader('last-modified')
+
+ # Take another screenshot instantly and compare the last Modified date
+ resp = self.request('/plugins/kimchi/vms/test-vm/screenshot')
+ lastMod2 = resp.getheader('last-modified')
+ self.assertEquals(lastMod2, lastMod1)
+
+ resp = self.request('/plugins/kimchi/vms/test-vm/screenshot',
'{}',
+ 'DELETE')
+ self.assertEquals(405, resp.status)
+
+ # No screenshot after stopped the VM
+ self.request('/plugins/kimchi/vms/test-vm/poweroff', '{}',
'POST')
+ resp = self.request('/plugins/kimchi/vms/test-vm/screenshot')
+ self.assertEquals(404, resp.status)
+
+ # Picture link not available after VM deleted
+ self.request('/plugins/kimchi/vms/test-vm/start', '{}',
'POST')
+ vm = json.loads(self.request('/plugins/kimchi/vms/test-vm').read())
+ img_lnk = vm['screenshot']
+ self.request('/plugins/kimchi/vms/test-vm', '{}',
'DELETE')
+ resp = self.request(img_lnk)
+ self.assertEquals(404, resp.status)
+
+ def test_interfaces(self):
+ resp = self.request('/plugins/kimchi/interfaces').read()
+ self.assertIn('name', resp)
+ interfaces = json.loads(resp)
+ keys = ['name', 'type', 'ipaddr', 'netmask',
'status']
+ for interface in interfaces:
+ self.assertEquals(sorted(keys), sorted(interface.keys()))
+
+ def _task_lookup(self, taskid):
+ return json.loads(
+ self.request('/tasks/%s' % taskid).read()
+ )
+
+ def test_tasks(self):
+ id1 = add_task('/tasks/1', self._async_op,
+ model.objstore)
+ id2 = add_task('/tasks/2', self._except_op,
+ model.objstore)
+ id3 = add_task('/tasks/3', self._intermid_op,
+ model.objstore)
+
+ target_uri = urllib2.quote('^/tasks/*', safe="")
+ filter_data = 'status=running&target_uri=%s' % target_uri
+ tasks = json.loads(
+ self.request('/tasks?%s' % filter_data).read()
+ )
+ self.assertEquals(3, len(tasks))
+
+ tasks = json.loads(self.request('/tasks').read())
+ tasks_ids = [int(t['id']) for t in tasks]
+ self.assertEquals(set([id1, id2, id3]) - set(tasks_ids), set([]))
+ wait_task(self._task_lookup, id2)
+ foo2 = json.loads(
+ self.request('/tasks/%s' % id2).read()
+ )
+ keys = ['id', 'status', 'message', 'target_uri']
+ self.assertEquals(sorted(keys), sorted(foo2.keys()))
+ self.assertEquals('failed', foo2['status'])
+ wait_task(self._task_lookup, id3)
+ foo3 = json.loads(
+ self.request('/tasks/%s' % id3).read()
+ )
+ self.assertEquals('in progress', foo3['message'])
+ self.assertEquals('running', foo3['status'])
+
+ def test_config(self):
+ resp = self.request('/plugins/kimchi/config').read()
+ conf = json.loads(resp)
+ keys = ["display_proxy_port", "version"]
+ self.assertEquals(keys, sorted(conf.keys()))
+
+ def test_capabilities(self):
+ resp = self.request('/plugins/kimchi/config/capabilities').read()
+ conf = json.loads(resp)
+
+ keys = [u'libvirt_stream_protocols', u'qemu_stream',
u'qemu_spice',
+ u'screenshot', u'system_report_tool',
u'update_tool',
+ u'repo_mngt_tool', u'federation', u'kernel_vfio',
u'auth',
+ u'nm_running', u'mem_hotplug_support']
+ self.assertEquals(sorted(keys), sorted(conf.keys()))
+
+ def test_peers(self):
+ resp = self.request('/plugins/kimchi/peers').read()
+ self.assertEquals([], json.loads(resp))
+
+ def test_distros(self):
+ resp = self.request('/plugins/kimchi/config/distros').read()
+ distros = json.loads(resp)
+ for distro in distros:
+ self.assertIn('name', distro)
+ self.assertIn('os_distro', distro)
+ self.assertIn('os_version', distro)
+ self.assertIn('path', distro)
+
+ # Test in X86
+ ident = "Fedora 20"
+ resp = self.request('/plugins/kimchi/config/distros/%s' %
+ urllib2.quote(ident)).read()
+ distro = json.loads(resp)
+ if os.uname()[4] in ['x86_64', 'amd64']:
+ self.assertEquals(distro['name'], ident)
+ self.assertEquals(distro['os_distro'], "fedora")
+ self.assertEquals(distro['os_version'], "20")
+ self.assertEquals(distro['os_arch'], "x86_64")
+ self.assertIn('path', distro)
+ else:
+ # Distro not found error
+ self.assertIn('KCHDISTRO0001E', distro.get('reason'))
+
+ # Test in PPC
+ ident = "Fedora 20 (PPC64)"
+ resp = self.request('/plugins/kimchi/config/distros/%s' %
+ urllib2.quote(ident)).read()
+ distro = json.loads(resp)
+ if os.uname()[4] == 'ppc64':
+ self.assertEquals(distro['name'], ident)
+ self.assertEquals(distro['os_distro'], "fedora")
+ self.assertEquals(distro['os_version'], "20")
+ self.assertEquals(distro['os_arch'], "ppc64")
+ self.assertIn('path', distro)
+ else:
+ # Distro not found error
+ self.assertIn('KCHDISTRO0001E', distro.get('reason'))
+
+ def test_debugreports(self):
+ resp = request(host, ssl_port, '/plugins/kimchi/debugreports')
+ self.assertEquals(200, resp.status)
+
+ def _report_delete(self, name):
+ request(host, ssl_port, '/plugins/kimchi/debugreports/%s' % name,
'{}',
+ 'DELETE')
+
+ def test_create_debugreport(self):
+ req = json.dumps({'name': 'report1'})
+ with RollbackContext() as rollback:
+ resp = request(host, ssl_port, '/plugins/kimchi/debugreports', req,
+ 'POST')
+ self.assertEquals(202, resp.status)
+ task = json.loads(resp.read())
+ # make sure the debugreport doesn't exist until the
+ # the task is finished
+ wait_task(self._task_lookup, task['id'])
+ rollback.prependDefer(self._report_delete, 'report2')
+ resp = request(host, ssl_port,
+ '/plugins/kimchi/debugreports/report1')
+ debugreport = json.loads(resp.read())
+ self.assertEquals("report1", debugreport['name'])
+ self.assertEquals(200, resp.status)
+ req = json.dumps({'name': 'report2'})
+ resp = request(host, ssl_port,
+ '/plugins/kimchi/debugreports/report1', req,
'PUT')
+ self.assertEquals(303, resp.status)
+
+ def test_debugreport_download(self):
+ req = json.dumps({'name': 'report1'})
+ with RollbackContext() as rollback:
+ resp = request(host, ssl_port, '/plugins/kimchi/debugreports', req,
+ 'POST')
+ self.assertEquals(202, resp.status)
+ task = json.loads(resp.read())
+ # make sure the debugreport doesn't exist until the
+ # the task is finished
+ wait_task(self._task_lookup, task['id'], 20)
+ rollback.prependDefer(self._report_delete, 'report1')
+ resp = request(host, ssl_port,
+ '/plugins/kimchi/debugreports/report1')
+ debugreport = json.loads(resp.read())
+ self.assertEquals("report1", debugreport['name'])
+ self.assertEquals(200, resp.status)
+ resp = request(host, ssl_port,
+ '/plugins/kimchi/debugreports/report1/content')
+ self.assertEquals(200, resp.status)
+ resp = request(host, ssl_port,
+ '/plugins/kimchi/debugreports/report1')
+ debugre = json.loads(resp.read())
+ resp = request(host, ssl_port, debugre['uri'])
+ self.assertEquals(200, resp.status)
+
+ def test_repositories(self):
+ def verify_repo(t, res):
+ for field in ('repo_id', 'enabled', 'baseurl',
'config'):
+ if field in t.keys():
+ self.assertEquals(t[field], res[field])
+
+ base_uri = '/plugins/kimchi/host/repositories'
+ resp = self.request(base_uri)
+ self.assertEquals(200, resp.status)
+ # Already have one repo in Kimchi's system
+ self.assertEquals(1, len(json.loads(resp.read())))
+
+ # Create a repository
+ repo = {'repo_id': 'fedora-fake',
+ 'baseurl': 'http://www.fedora.org'}
+ req = json.dumps(repo)
+ resp = self.request(base_uri, req, 'POST')
+ self.assertEquals(201, resp.status)
+
+ # Verify the repository
+ res = json.loads(self.request('%s/fedora-fake' % base_uri).read())
+ verify_repo(repo, res)
+
+ # Update the repository
+ params = {}
+ params['baseurl'] = repo['baseurl'] =
'http://www.fedoraproject.org'
+ resp = self.request('%s/fedora-fake' % base_uri, json.dumps(params),
+ 'PUT')
+
+ # Verify the repository
+ res = json.loads(self.request('%s/fedora-fake' % base_uri).read())
+ verify_repo(repo, res)
+
+ # Delete the repository
+ resp = self.request('%s/fedora-fake' % base_uri, '{}',
'DELETE')
+ self.assertEquals(204, resp.status)
+
+
+class HttpsRestTests(RestTests):
+ """
+ Run all of the same tests as above, but use https instead
+ """
+ def setUp(self):
+ self.request = partial(request, host, ssl_port)
+ model.reset()
diff --git a/src/wok/plugins/kimchi/tests/test_rollbackcontext.py
b/src/wok/plugins/kimchi/tests/test_rollbackcontext.py
new file mode 100644
index 0000000..6eac6d0
--- /dev/null
+++ b/src/wok/plugins/kimchi/tests/test_rollbackcontext.py
@@ -0,0 +1,99 @@
+#
+# Project Kimchi
+#
+# Copyright IBM, Corp. 2014
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+import unittest
+
+from wok.rollbackcontext import RollbackContext
+
+
+class FirstError(Exception):
+ '''A hypothetical exception to be raise in the test
firstly.'''
+ pass
+
+
+class SecondError(Exception):
+ '''A hypothetical exception to be raise in the test
secondly.'''
+ pass
+
+
+class RollbackContextTests(unittest.TestCase):
+
+ def setUp(self):
+ self._counter = 0
+
+ def _inc_counter(self):
+ self._counter += 1
+
+ def _raise(self, exception=FirstError):
+ raise exception()
+
+ def test_rollback(self):
+ with RollbackContext() as rollback:
+ rollback.prependDefer(self._inc_counter)
+ rollback.prependDefer(self._inc_counter)
+ self.assertEquals(self._counter, 2)
+
+ def test_raise(self):
+ try:
+ with RollbackContext() as rollback:
+ rollback.prependDefer(self._inc_counter)
+ rollback.prependDefer(self._inc_counter)
+ raise FirstError()
+ rollback.prependDefer(self._inc_counter)
+ except FirstError:
+ # All undo before the FirstError should be run
+ self.assertEquals(self._counter, 2)
+ else:
+ self.fail('Should have raised FirstError')
+
+ def test_raise_undo(self):
+ try:
+ with RollbackContext() as rollback:
+ rollback.prependDefer(self._inc_counter)
+ rollback.prependDefer(self._raise)
+ rollback.prependDefer(self._inc_counter)
+ except FirstError:
+ # All undo should be run
+ self.assertEquals(self._counter, 2)
+ else:
+ self.fail('Should have raised FirstError')
+
+ def test_raise_prefer_original(self):
+ try:
+ with RollbackContext() as rollback:
+ rollback.prependDefer(self._raise, SecondError)
+ raise FirstError()
+ except FirstError:
+ pass
+ except SecondError:
+ self.fail('Should have preferred FirstError to SecondError')
+ else:
+ self.fail('Should have raised FirstError')
+
+ def test_raise_prefer_first_undo(self):
+ try:
+ with RollbackContext() as rollback:
+ rollback.prependDefer(self._raise, SecondError)
+ rollback.prependDefer(self._raise, FirstError)
+ except FirstError:
+ pass
+ except SecondError:
+ self.fail('Should have preferred FirstError to SecondError')
+ else:
+ self.fail('Should have raised FirstError')
diff --git a/src/wok/plugins/kimchi/tests/test_server.py
b/src/wok/plugins/kimchi/tests/test_server.py
new file mode 100644
index 0000000..d5ef565
--- /dev/null
+++ b/src/wok/plugins/kimchi/tests/test_server.py
@@ -0,0 +1,289 @@
+#
+# Project Kimchi
+#
+# Copyright IBM, Corp. 2013-2015
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+import base64
+import cherrypy
+import json
+import os
+import tempfile
+import threading
+import unittest
+from functools import partial
+
+from wok.control.base import Collection, Resource
+
+from wok.plugins.kimchi import mockmodel
+
+import utils
+
+
+test_server = None
+model = None
+host = None
+port = None
+ssl_port = None
+cherrypy_port = None
+tmpfile = None
+
+
+def setUpModule():
+ global test_server, model, host, port, ssl_port, cherrypy_port, tmpfile
+
+ utils.patch_auth()
+ tmpfile = tempfile.mktemp()
+ model = mockmodel.MockModel(tmpfile)
+ host = '127.0.0.1'
+ port = utils.get_free_port('http')
+ ssl_port = utils.get_free_port('https')
+ cherrypy_port = utils.get_free_port('cherrypy_port')
+ test_server = utils.run_server(host, port, ssl_port, test_mode=True,
+ cherrypy_port=cherrypy_port, model=model)
+
+
+def tearDownModule():
+ test_server.stop()
+ os.unlink(tmpfile)
+
+
+class ServerTests(unittest.TestCase):
+ def setUp(self):
+ self.request = partial(utils.request, host, ssl_port)
+ model.reset()
+
+ def assertValidJSON(self, txt):
+ try:
+ json.loads(txt)
+ except ValueError:
+ self.fail("Invalid JSON: %s" % txt)
+
+ def test_server_start(self):
+ """
+ Test that we can start a server and receive HTTP:200.
+ """
+ resp = self.request('/')
+ self.assertEquals(200, resp.status)
+
+ def test_multithreaded_connection(self):
+ def worker():
+ for i in xrange(100):
+ ret = model.vms_get_list()
+ self.assertEquals('test', ret[0])
+
+ threads = []
+ for i in xrange(100):
+ t = threading.Thread(target=worker)
+ t.setDaemon(True)
+ t.start()
+ threads.append(t)
+ for t in threads:
+ t.join()
+
+ def test_collection(self):
+ c = Collection(model)
+
+ # The base Collection is always empty
+ cherrypy.request.method = 'GET'
+ cherrypy.request.headers['Accept'] = 'application/json'
+ self.assertEquals('[]', c.index())
+
+ # POST and DELETE raise HTTP:405 by default
+ for method in ('POST', 'DELETE'):
+ cherrypy.request.method = method
+ try:
+ c.index()
+ except cherrypy.HTTPError, e:
+ self.assertEquals(405, e.code)
+ else:
+ self.fail("Expected exception not raised")
+
+ def test_resource(self):
+ r = Resource(model)
+
+ # Test the base Resource representation
+ cherrypy.request.method = 'GET'
+ cherrypy.request.headers['Accept'] = 'application/json'
+ self.assertEquals('{}', r.index())
+
+ # POST and DELETE raise HTTP:405 by default
+ for method in ('POST', 'DELETE'):
+ cherrypy.request.method = method
+ try:
+ r.index()
+ except cherrypy.HTTPError, e:
+ self.assertEquals(405, e.code)
+ else:
+ self.fail("Expected exception not raised")
+
+ def test_404(self):
+ """
+ A non-existent path should return HTTP:404
+ """
+ url_list = ['/plugins/kimchi/doesnotexist',
'/plugins/kimchi/vms/blah']
+ for url in url_list:
+ resp = self.request(url)
+ self.assertEquals(404, resp.status)
+
+ # Verify it works for DELETE too
+ resp = self.request('/plugins/kimchi/templates/blah', '',
'DELETE')
+ self.assertEquals(404, resp.status)
+
+ def test_accepts(self):
+ """
+ Verify the following expectations regarding the client Accept header:
+ If omitted, default to html
+ If 'application/json', serve the rest api
+ If 'text/html', serve the UI
+ If both of the above (in any order), serve the rest api
+ If neither of the above, HTTP:406
+ """
+ resp = self.request("/", headers={})
+ location = resp.getheader('location')
+ self.assertTrue(location.endswith("login.html"))
+ resp = self.request("/login.html", headers={})
+ self.assertTrue('<!doctype html>' in resp.read().lower())
+
+ resp = self.request("/", headers={'Accept':
'application/json'})
+ self.assertValidJSON(resp.read())
+
+ resp = self.request("/", headers={'Accept':
'text/html'})
+ location = resp.getheader('location')
+ self.assertTrue(location.endswith("login.html"))
+
+ resp = self.request("/", headers={'Accept':
+ 'application/json, text/html'})
+ self.assertValidJSON(resp.read())
+
+ resp = self.request("/", headers={'Accept':
+ 'text/html, application/json'})
+ self.assertValidJSON(resp.read())
+
+ h = {'Accept': 'text/plain'}
+ resp = self.request('/', None, 'GET', h)
+ self.assertEquals(406, resp.status)
+
+ def test_auth_unprotected(self):
+ hdrs = {'AUTHORIZATION': ''}
+ uris = ['/plugins/kimchi/js/kimchi.min.js',
+ '/plugins/kimchi/css/theme-default.min.css',
+ '/plugins/kimchi/images/icon-vm.png',
+ '/libs/jquery-1.10.0.min.js',
+ '/login.html',
+ '/logout']
+
+ for uri in uris:
+ resp = self.request(uri, None, 'HEAD', hdrs)
+ self.assertEquals(200, resp.status)
+
+ def test_auth_protected(self):
+ hdrs = {'AUTHORIZATION': ''}
+ uris = ['/plugins/kimchi/vms',
+ '/plugins/kimchi/vms/doesnotexist',
+ '/tasks']
+
+ for uri in uris:
+ resp = self.request(uri, None, 'GET', hdrs)
+ self.assertEquals(401, resp.status)
+
+ def test_auth_bad_creds(self):
+ # Test HTTPBA
+ hdrs = {'AUTHORIZATION': "Basic " +
base64.b64encode("nouser:badpass")}
+ resp = self.request('/plugins/kimchi/vms', None, 'GET', hdrs)
+ self.assertEquals(401, resp.status)
+
+ # Test REST API
+ hdrs = {'AUTHORIZATION': ''}
+ req = json.dumps({'username': 'nouser', 'password':
'badpass'})
+ resp = self.request('/login', req, 'POST', hdrs)
+ self.assertEquals(401, resp.status)
+
+ def test_auth_browser_no_httpba(self):
+ # Kimchi detects REST requests from the browser by looking for a
+ # specific header
+ hdrs = {"X-Requested-With": "XMLHttpRequest"}
+
+ # Try our request (Note that request() will add a valid HTTPBA header)
+ resp = self.request('/plugins/kimchi/vms', None, 'GET', hdrs)
+ self.assertEquals(401, resp.status)
+ self.assertEquals(None, resp.getheader('WWW-Authenticate'))
+
+ def test_auth_session(self):
+ hdrs = {'AUTHORIZATION': '',
+ 'Content-Type': 'application/json',
+ 'Accept': 'application/json'}
+
+ # Test we are logged out
+ resp = self.request('/tasks', None, 'GET', hdrs)
+ self.assertEquals(401, resp.status)
+
+ # Execute a login call
+ user, pw = mockmodel.fake_user.items()[0]
+ req = json.dumps({'username': user, 'password': pw})
+ resp = self.request('/login', req, 'POST', hdrs)
+ self.assertEquals(200, resp.status)
+
+ user_info = json.loads(resp.read())
+ self.assertEquals(sorted(user_info.keys()),
+ ['groups', 'roles', 'username'])
+ roles = user_info['roles']
+ for tab, role in roles.iteritems():
+ self.assertEquals(role, u'admin')
+
+ cookie = resp.getheader('set-cookie')
+ hdrs['Cookie'] = cookie
+
+ # Test we are logged in with the cookie
+ resp = self.request('/tasks', None, 'GET', hdrs)
+ self.assertEquals(200, resp.status)
+
+ # Execute a logout call
+ resp = self.request('/logout', '{}', 'POST', hdrs)
+ self.assertEquals(200, resp.status)
+ del hdrs['Cookie']
+
+ # Test we are logged out
+ resp = self.request('/tasks', None, 'GET', hdrs)
+ self.assertEquals(401, resp.status)
+
+ def test_get_param(self):
+ # Create a mock ISO file
+ mockiso = '/tmp/mock.iso'
+ open('/tmp/mock.iso', 'w').close()
+
+ # Create 2 different templates
+ req = json.dumps({'name': 'test-tmpl1', 'cdrom':
mockiso})
+ self.request('/plugins/kimchi/templates', req, 'POST')
+
+ req = json.dumps({'name': 'test-tmpl2', 'cdrom':
mockiso})
+ self.request('/plugins/kimchi/templates', req, 'POST')
+
+ # Remove mock iso
+ os.unlink(mockiso)
+
+ # Get the templates
+ resp = self.request('/plugins/kimchi/templates')
+ self.assertEquals(200, resp.status)
+ res = json.loads(resp.read())
+ self.assertEquals(2, len(res))
+
+ # Get a specific template
+ resp = self.request('/plugins/kimchi/templates?name=test-tmpl1')
+ self.assertEquals(200, resp.status)
+ res = json.loads(resp.read())
+ self.assertEquals(1, len(res))
+ self.assertEquals('test-tmpl1', res[0]['name'])
diff --git a/src/wok/plugins/kimchi/tests/test_storagepoolxml.py
b/src/wok/plugins/kimchi/tests/test_storagepoolxml.py
new file mode 100644
index 0000000..7e45cca
--- /dev/null
+++ b/src/wok/plugins/kimchi/tests/test_storagepoolxml.py
@@ -0,0 +1,171 @@
+#
+# Project Kimchi
+#
+# Copyright IBM, Corp. 2015
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+import lxml.etree as ET
+import unittest
+
+from wok.plugins.kimchi.model.libvirtstoragepool import StoragePoolDef
+
+
+class StoragepoolXMLTests(unittest.TestCase):
+ def test_get_storagepool_xml(self):
+ poolDefs = [
+ {'def':
+ {'type': 'dir',
+ 'name': 'unitTestDirPool',
+ 'path': '/var/temp/images'},
+ 'xml':
+ """
+ <pool type='dir'>
+ <name>unitTestDirPool</name>
+ <target>
+ <path>/var/temp/images</path>
+ </target>
+ </pool>
+ """},
+ {'def':
+ {'type': 'netfs',
+ 'name': 'unitTestNFSPool',
+ 'source': {'host': '127.0.0.1',
+ 'path': '/var/export'}},
+ 'xml':
+ """
+ <pool type='netfs'>
+ <name>unitTestNFSPool</name>
+ <source>
+ <host name='127.0.0.1'/>
+ <dir path='/var/export'/>
+ </source>
+ <target>
+ <path>/var/lib/kimchi/nfs_mount/unitTestNFSPool</path>
+ </target>
+ </pool>
+ """},
+ {'def':
+ {'type': 'logical',
+ 'name': 'unitTestLogicalPool',
+ 'source': {'devices': ['/dev/hda',
'/dev/hdb']}},
+ 'xml':
+ """
+ <pool type='logical'>
+ <name>unitTestLogicalPool</name>
+ <source>
+ <device path="/dev/hda" />
+ <device path="/dev/hdb" />
+ </source>
+ <target>
+ <path>/dev/unitTestLogicalPool</path>
+ </target>
+ </pool>
+ """},
+ {'def':
+ {'type': 'iscsi',
+ 'name': 'unitTestISCSIPool',
+ 'source': {
+ 'host': '127.0.0.1',
+ 'target':
'iqn.2003-01.org.linux-iscsi.localhost'}},
+ 'xml':
+ """
+ <pool type='iscsi'>
+ <name>unitTestISCSIPool</name>
+ <source>
+ <host name='127.0.0.1' />
+ <device path='iqn.2003-01.org.linux-iscsi.localhost'/>
+ </source>
+ <target>
+ <path>/dev/disk/by-id</path>
+ </target>
+ </pool>
+ """},
+ {'def':
+ {'type': 'iscsi',
+ 'name': 'unitTestISCSIPoolPort',
+ 'source': {
+ 'host': '127.0.0.1',
+ 'port': 3266,
+ 'target':
'iqn.2003-01.org.linux-iscsi.localhost'}},
+ 'xml':
+ """
+ <pool type='iscsi'>
+ <name>unitTestISCSIPoolPort</name>
+ <source>
+ <host name='127.0.0.1' port='3266' />
+ <device path='iqn.2003-01.org.linux-iscsi.localhost'/>
+ </source>
+ <target>
+ <path>/dev/disk/by-id</path>
+ </target>
+ </pool>
+ """},
+ {'def':
+ {'type': 'iscsi',
+ 'name': 'unitTestISCSIPoolAuth',
+ 'source': {
+ 'host': '127.0.0.1',
+ 'target': 'iqn.2003-01.org.linux-iscsi.localhost',
+ 'auth': {'username': 'testUser',
+ 'password': 'ActuallyNotUsedInPoolXML'}}},
+ 'xml':
+ """
+ <pool type='iscsi'>
+ <name>unitTestISCSIPoolAuth</name>
+ <source>
+ <host name='127.0.0.1' />
+ <device path='iqn.2003-01.org.linux-iscsi.localhost'/>
+ <auth type='chap' username='testUser'>
+ <secret type='iscsi'
usage='unitTestISCSIPoolAuth'/>
+ </auth>
+ </source>
+ <target>
+ <path>/dev/disk/by-id</path>
+ </target>
+ </pool>
+ """},
+ {'def':
+ {'type': 'scsi',
+ 'name': 'unitTestSCSIFCPool',
+ 'path': '/dev/disk/by-path',
+ 'source': {
+ 'name': 'scsi_host3',
+ 'adapter': {
+ 'type': 'fc_host',
+ 'wwpn': '0123456789abcdef',
+ 'wwnn': 'abcdef0123456789'}}},
+ 'xml':
+ """
+ <pool type='scsi'>
+ <name>unitTestSCSIFCPool</name>
+ <source>
+ <adapter type='fc_host' name='scsi_host3'
+ wwnn='abcdef0123456789'
wwpn='0123456789abcdef'></adapter>
+ </source>
+ <target>
+ <path>/dev/disk/by-path</path>
+ </target>
+ </pool>
+ """}]
+
+ for poolDef in poolDefs:
+ defObj = StoragePoolDef.create(poolDef['def'])
+ xmlStr = defObj.xml
+
+ parser = ET.XMLParser(remove_blank_text=True)
+ t1 = ET.fromstring(xmlStr, parser)
+ t2 = ET.fromstring(poolDef['xml'], parser)
+ self.assertEquals(ET.tostring(t1), ET.tostring(t2))
diff --git a/src/wok/plugins/kimchi/tests/test_template.py
b/src/wok/plugins/kimchi/tests/test_template.py
new file mode 100644
index 0000000..c7de182
--- /dev/null
+++ b/src/wok/plugins/kimchi/tests/test_template.py
@@ -0,0 +1,387 @@
+# -*- coding: utf-8 -*-
+#
+# Project Kimchi
+#
+# Copyright IBM, Corp. 2015
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+import json
+import os
+import unittest
+from functools import partial
+
+from wok.plugins.kimchi.config import READONLY_POOL_TYPE
+from wok.plugins.kimchi.mockmodel import MockModel
+
+from utils import get_free_port, patch_auth, request, run_server
+
+
+model = None
+test_server = None
+host = None
+port = None
+ssl_port = None
+cherrypy_port = None
+
+
+def setUpModule():
+ global test_server, model, host, port, ssl_port, cherrypy_port
+
+ patch_auth()
+ model = MockModel('/tmp/obj-store-test')
+ host = '127.0.0.1'
+ port = get_free_port('http')
+ ssl_port = get_free_port('https')
+ cherrypy_port = get_free_port('cherrypy_port')
+ test_server = run_server(host, port, ssl_port, test_mode=True,
+ cherrypy_port=cherrypy_port, model=model)
+
+
+def tearDownModule():
+ test_server.stop()
+ os.unlink('/tmp/obj-store-test')
+
+
+class TemplateTests(unittest.TestCase):
+ def setUp(self):
+ self.request = partial(request, host, ssl_port)
+ model.reset()
+
+ def test_tmpl_lifecycle(self):
+ resp = self.request('/plugins/kimchi/templates')
+ self.assertEquals(200, resp.status)
+ self.assertEquals(0, len(json.loads(resp.read())))
+
+ # Create a template without cdrom and disk specified fails with 400
+ t = {'name': 'test', 'os_distro': 'ImagineOS',
+ 'os_version': '1.0', 'memory': 1024, 'cpus':
1,
+ 'storagepool': '/plugins/kimchi/storagepools/alt'}
+ req = json.dumps(t)
+ resp = self.request('/plugins/kimchi/templates', req, 'POST')
+ self.assertEquals(400, resp.status)
+
+ # Create a template
+ t = {'name': 'test', 'cdrom': '/tmp/mock.iso'}
+ req = json.dumps(t)
+ resp = self.request('/plugins/kimchi/templates', req, 'POST')
+ self.assertEquals(201, resp.status)
+
+ # Verify the template
+ keys = ['name', 'icon', 'invalid', 'os_distro',
'os_version', 'cpus',
+ 'memory', 'cdrom', 'disks',
'storagepool', 'networks',
+ 'folder', 'graphics', 'cpu_info']
+ tmpl = json.loads(
+ self.request('/plugins/kimchi/templates/test').read()
+ )
+ self.assertEquals(sorted(tmpl.keys()), sorted(keys))
+
+ # Verify if default disk format was configured
+ self.assertEquals(tmpl['disks'][0]['format'], 'qcow2')
+
+ # Clone a template
+ resp = self.request('/plugins/kimchi/templates/test/clone',
'{}',
+ 'POST')
+ self.assertEquals(303, resp.status)
+
+ # Verify the cloned template
+ tmpl_cloned = json.loads(
+ self.request('/plugins/kimchi/templates/test-clone1').read()
+ )
+ del tmpl['name']
+ del tmpl_cloned['name']
+ self.assertEquals(tmpl, tmpl_cloned)
+
+ # Delete the cloned template
+ resp = self.request('/plugins/kimchi/templates/test-clone1',
'{}',
+ 'DELETE')
+ self.assertEquals(204, resp.status)
+
+ # Create a template with same name fails with 400
+ req = json.dumps({'name': 'test', 'cdrom':
'/tmp/mock.iso'})
+ resp = self.request('/plugins/kimchi/templates', req, 'POST')
+ self.assertEquals(400, resp.status)
+
+ # Create an image based template
+ open('/tmp/mock.img', 'w').close()
+ t = {'name': 'test_img_template',
+ 'disks': [{'base': '/tmp/mock.img'}]}
+ req = json.dumps(t)
+ resp = self.request('/plugins/kimchi/templates', req, 'POST')
+ self.assertEquals(201, resp.status)
+ os.remove('/tmp/mock.img')
+
+ # Test disk format
+ t = {'name': 'test-format', 'cdrom':
'/tmp/mock.iso',
+ 'disks': [{'index': 0, 'size': 10, 'format':
'vmdk'}]}
+ req = json.dumps(t)
+ resp = self.request('/plugins/kimchi/templates', req, 'POST')
+ self.assertEquals(201, resp.status)
+ tmpl = json.loads(
+ self.request('/plugins/kimchi/templates/test-format').read()
+ )
+ self.assertEquals(tmpl['disks'][0]['format'], 'vmdk')
+
+ def test_customized_tmpl(self):
+ # Create a template
+ t = {'name': 'test', 'cdrom': '/tmp/mock.iso'}
+ req = json.dumps(t)
+ resp = self.request('/plugins/kimchi/templates', req, 'POST')
+ self.assertEquals(201, resp.status)
+ tmpl = json.loads(
+ self.request('/plugins/kimchi/templates/test').read()
+ )
+
+ # Update name
+ new_name = u'k������h��Tmpl'
+ new_tmpl_uri = '/plugins/kimchi/templates/%s' \
+ % new_name.encode('utf-8')
+ req = json.dumps({'name': new_name})
+ resp = self.request('/plugins/kimchi/templates/test', req,
'PUT')
+ self.assertEquals(303, resp.status)
+ resp = self.request(new_tmpl_uri)
+ update_tmpl = json.loads(resp.read())
+ self.assertEquals(new_name, update_tmpl['name'])
+ del tmpl['name']
+ del update_tmpl['name']
+ self.assertEquals(tmpl, update_tmpl)
+
+ # Update icon
+ req = json.dumps({'icon': 'kimchi/images/icon-fedora.png'})
+ resp = self.request(new_tmpl_uri, req, 'PUT')
+ self.assertEquals(200, resp.status)
+ update_tmpl = json.loads(resp.read())
+ self.assertEquals('kimchi/images/icon-fedora.png',
update_tmpl['icon'])
+
+ # Update os_distro and os_version
+ req = json.dumps({'os_distro': 'fedora', 'os_version':
'21'})
+ resp = self.request(new_tmpl_uri, req, 'PUT')
+ self.assertEquals(200, resp.status)
+ update_tmpl = json.loads(resp.read())
+ self.assertEquals('fedora', update_tmpl['os_distro'])
+ self.assertEquals('21', update_tmpl['os_version'])
+
+ # Update cpus
+ req = json.dumps({'cpus': 2})
+ resp = self.request(new_tmpl_uri, req, 'PUT')
+ self.assertEquals(200, resp.status)
+ update_tmpl = json.loads(resp.read())
+ self.assertEquals(2, update_tmpl['cpus'])
+
+ # Update memory
+ req = json.dumps({'memory': 2048})
+ resp = self.request(new_tmpl_uri, req, 'PUT')
+ self.assertEquals(200, resp.status)
+ update_tmpl = json.loads(resp.read())
+ self.assertEquals(2048, update_tmpl['memory'])
+
+ # Update cpu_info
+ resp = self.request(new_tmpl_uri)
+ cpu_info = json.loads(resp.read())['cpu_info']
+ self.assertEquals(cpu_info, {})
+ self.assertEquals(cpu_info.get('topology'), None)
+
+ cpu_info_data = {'cpu_info': {'topology': {'sockets': 1,
+ 'cores': 2,
+ 'threads': 1}}}
+ resp = self.request(new_tmpl_uri, json.dumps(cpu_info_data), 'PUT')
+ self.assertEquals(200, resp.status)
+ update_tmpl = json.loads(resp.read())
+ self.assertEquals(update_tmpl['cpu_info'],
cpu_info_data['cpu_info'])
+
+ # Update cdrom
+ cdrom_data = {'cdrom': '/tmp/mock2.iso'}
+ resp = self.request(new_tmpl_uri, json.dumps(cdrom_data), 'PUT')
+ self.assertEquals(200, resp.status)
+ update_tmpl = json.loads(resp.read())
+ self.assertEquals(update_tmpl['cdrom'], cdrom_data['cdrom'])
+
+ # Update disks
+ disk_data = {'disks': [{'index': 0, 'size': 10},
+ {'index': 1, 'size': 20}]}
+ resp = self.request(new_tmpl_uri, json.dumps(disk_data), 'PUT')
+ self.assertEquals(200, resp.status)
+ resp = self.request(new_tmpl_uri)
+ self.assertEquals(200, resp.status)
+ updated_tmpl = json.loads(resp.read())
+ self.assertEquals(updated_tmpl['disks'], disk_data['disks'])
+
+ # For all supported types, edit the template and check if
+ # the change was made.
+ disk_types = ['bochs', 'cloop', 'cow', 'dmg',
'qcow', 'qcow2',
+ 'qed', 'raw', 'vmdk', 'vpc']
+ for disk_type in disk_types:
+ disk_data = {'disks': [{'index': 0, 'format':
disk_type,
+ 'size': 10}]}
+ resp = self.request(new_tmpl_uri, json.dumps(disk_data), 'PUT')
+ self.assertEquals(200, resp.status)
+
+ resp = self.request(new_tmpl_uri)
+ self.assertEquals(200, resp.status)
+ updated_tmpl = json.loads(resp.read())
+ self.assertEquals(updated_tmpl['disks'], disk_data['disks'])
+
+ # Update folder
+ folder_data = {'folder': ['mock', 'isos']}
+ resp = self.request(new_tmpl_uri, json.dumps(folder_data), 'PUT')
+ self.assertEquals(200, resp.status)
+ update_tmpl = json.loads(resp.read())
+ self.assertEquals(update_tmpl['folder'], folder_data['folder'])
+
+ # Update graphics
+ req = json.dumps({'graphics': {'type': 'spice'}})
+ resp = self.request(new_tmpl_uri, req, 'PUT')
+ self.assertEquals(200, resp.status)
+ update_tmpl = json.loads(resp.read())
+ self.assertEquals('spice',
update_tmpl['graphics']['type'])
+
+ req = json.dumps({'graphics': {'type': 'vnc',
'listen': 'fe00::0'}})
+ resp = self.request(new_tmpl_uri, req, 'PUT')
+ self.assertEquals(200, resp.status)
+ update_tmpl = json.loads(resp.read())
+ self.assertEquals('vnc',
update_tmpl['graphics']['type'])
+ self.assertEquals('fe00::0',
update_tmpl['graphics']['listen'])
+
+ def test_customized_network(self):
+ # Create a template
+ t = {'name': 'test', 'cdrom': '/tmp/mock.iso'}
+ req = json.dumps(t)
+ resp = self.request('/plugins/kimchi/templates', req, 'POST')
+ self.assertEquals(201, resp.status)
+
+ # Create networks to be used for testing
+ networks = [{'name': u'k������h��-��et', 'connection':
'isolated'},
+ {'name': u'nat-network', 'connection':
'nat'},
+ {'name': u'subnet-network', 'connection':
'nat',
+ 'subnet': '127.0.100.0/24'}]
+
+ # Verify the current system has at least one interface to create a
+ # bridged network
+ interfaces = json.loads(
+ self.request('/plugins/kimchi/interfaces?type=nic').read()
+ )
+ if len(interfaces) > 0:
+ iface = interfaces[0]['name']
+ networks.append({'name': u'bridge-network',
'connection': 'bridge',
+ 'interface': iface})
+ networks.append({'name': u'bridge-network',
'connection': 'bridge',
+ 'interface': iface, 'vlan_id': 987})
+
+ tmpl_nets = []
+ for net in networks:
+ self.request('/plugins/kimchi/networks', json.dumps(net),
'POST')
+ tmpl_nets.append(net['name'])
+ req = json.dumps({'networks': tmpl_nets})
+ resp = self.request('/plugins/kimchi/templates/test', req,
'PUT')
+ self.assertEquals(200, resp.status)
+
+ def test_customized_storagepool(self):
+ # Create a template
+ t = {'name': 'test', 'cdrom': '/tmp/mock.iso'}
+ req = json.dumps(t)
+ resp = self.request('/plugins/kimchi/templates', req, 'POST')
+ self.assertEquals(201, resp.status)
+
+ # MockModel always returns 2 partitions (vdx, vdz)
+ partitions = json.loads(
+ self.request('/plugins/kimchi/host/partitions').read()
+ )
+ devs = [dev['path'] for dev in partitions]
+
+ # MockModel always returns 3 FC devices
+ fc_devs = json.loads(
+ self.request('/plugins/kimchi/host/devices?_cap=fc_host').read()
+ )
+ fc_devs = [dev['name'] for dev in fc_devs]
+
+ poolDefs = [
+ {'type': 'dir', 'name':
u'k������h��UnitTestDirPool',
+ 'path': '/tmp/kimchi-images'},
+ {'type': 'netfs', 'name':
u'k������h��UnitTestNSFPool',
+ 'source': {'host': 'localhost',
+ 'path': '/var/lib/kimchi/nfs-pool'}},
+ {'type': 'scsi', 'name':
u'k������h��UnitTestSCSIFCPool',
+ 'source': {'adapter_name': fc_devs[0]}},
+ {'type': 'iscsi', 'name':
u'k������h��UnitTestISCSIPool',
+ 'source': {'host': '127.0.0.1',
+ 'target':
'iqn.2015-01.localhost.kimchiUnitTest'}},
+ {'type': 'logical', 'name':
u'k������h��UnitTestLogicalPool',
+ 'source': {'devices': [devs[0]]}}]
+
+ for pool in poolDefs:
+ self.request('/plugins/kimchi/storagepools', json.dumps(pool),
+ 'POST')
+ pool_uri = '/plugins/kimchi/storagepools/%s' \
+ % pool['name'].encode('utf-8')
+ self.request(pool_uri + '/activate', '{}', 'POST')
+
+ req = None
+ if pool['type'] in READONLY_POOL_TYPE:
+ resp = self.request(pool_uri + '/storagevolumes')
+ vols = json.loads(resp.read())
+ if len(vols) > 0:
+ vol = vols[0]['name']
+ req = json.dumps({'storagepool': pool_uri,
+ 'disks': [{'volume': vol}]})
+ else:
+ req = json.dumps({'storagepool': pool_uri})
+
+ if req is not None:
+ resp = self.request('/plugins/kimchi/templates/test', req,
+ 'PUT')
+ self.assertEquals(200, resp.status)
+
+ def test_tmpl_integrity(self):
+ # Create a network and a pool for testing template integrity
+ net = {'name': u'nat-network', 'connection':
'nat'}
+ self.request('/plugins/kimchi/networks', json.dumps(net),
'POST')
+
+ pool = {'type': 'dir', 'name': 'dir-pool',
'path': '/tmp/dir-pool'}
+ self.request('/plugins/kimchi/storagepools', json.dumps(pool),
'POST')
+ pool_uri = '/plugins/kimchi/storagepools/%s' \
+ % pool['name'].encode('utf-8')
+ self.request(pool_uri + '/activate', '{}', 'POST')
+
+ # Create a template using the custom network and pool
+ t = {'name': 'test', 'cdrom': '/tmp/mock.iso',
+ 'networks': ['nat-network'],
+ 'storagepool': '/plugins/kimchi/storagepools/dir-pool'}
+ req = json.dumps(t)
+ resp = self.request('/plugins/kimchi/templates', req, 'POST')
+ self.assertEquals(201, resp.status)
+
+ # Try to delete network
+ # It should fail as it is associated to a template
+ resp = self.request('/plugins/kimchi/networks/nat-network',
'{}',
+ 'DELETE')
+ self.assertIn("KCHNET0017E",
json.loads(resp.read())["reason"])
+
+ # Update template to release network and then delete it
+ params = {'networks': []}
+ req = json.dumps(params)
+ self.request('/plugins/kimchi/templates/test', req, 'PUT')
+ resp = self.request('/plugins/kimchi/networks/nat-network',
'{}',
+ 'DELETE')
+ self.assertEquals(204, resp.status)
+
+ # Try to delete the storagepool
+ # It should fail as it is associated to a template
+ resp = self.request('/plugins/kimchi/storagepools/dir-pool',
'{}',
+ 'DELETE')
+ self.assertEquals(400, resp.status)
+
+ # Verify the template
+ res = json.loads(self.request('/plugins/kimchi/templates/test').read())
+ self.assertEquals(res['invalid']['cdrom'],
['/tmp/mock.iso'])
diff --git a/src/wok/plugins/kimchi/tests/test_utils.py
b/src/wok/plugins/kimchi/tests/test_utils.py
new file mode 100644
index 0000000..bcb14e2
--- /dev/null
+++ b/src/wok/plugins/kimchi/tests/test_utils.py
@@ -0,0 +1,69 @@
+#
+# Project Kimchi
+#
+# Copyright IBM, Corp. 2015
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+import unittest
+
+from wok.exception import InvalidParameter
+from wok.utils import convert_data_size
+
+
+class UtilsTests(unittest.TestCase):
+ def test_convert_data_size(self):
+ failure_data = [{'val': None, 'from': 'MiB'},
+ {'val': self, 'from': 'MiB'},
+ {'val': 1, 'from': None},
+ {'val': 1, 'from': ''},
+ {'val': 1, 'from': 'foo'},
+ {'val': 1, 'from': 'kib'},
+ {'val': 1, 'from': 'MiB',
'to': None},
+ {'val': 1, 'from': 'MiB',
'to': ''},
+ {'val': 1, 'from': 'MiB',
'to': 'foo'},
+ {'val': 1, 'from': 'MiB',
'to': 'kib'}]
+
+ for d in failure_data:
+ if 'to' in d:
+ self.assertRaises(InvalidParameter, convert_data_size,
+ d['val'], d['from'], d['to'])
+ else:
+ self.assertRaises(InvalidParameter, convert_data_size,
+ d['val'], d['from'])
+
+ success_data = [{'got': convert_data_size(5, 'MiB',
'MiB'),
+ 'want': 5},
+ {'got': convert_data_size(5, 'MiB',
'KiB'),
+ 'want': 5120},
+ {'got': convert_data_size(5, 'MiB',
'M'),
+ 'want': 5.24288},
+ {'got': convert_data_size(5, 'MiB',
'GiB'),
+ 'want': 0.0048828125},
+ {'got': convert_data_size(5, 'MiB',
'Tb'),
+ 'want': 4.194304e-05},
+ {'got': convert_data_size(5, 'KiB',
'MiB'),
+ 'want': 0.0048828125},
+ {'got': convert_data_size(5, 'M',
'MiB'),
+ 'want': 4.76837158203125},
+ {'got': convert_data_size(5, 'GiB',
'MiB'),
+ 'want': 5120},
+ {'got': convert_data_size(5, 'Tb',
'MiB'),
+ 'want': 596046.4477539062},
+ {'got': convert_data_size(5, 'MiB'),
+ 'want': convert_data_size(5, 'MiB',
'B')}]
+
+ for d in success_data:
+ self.assertEquals(d['got'], d['want'])
diff --git a/src/wok/plugins/kimchi/tests/test_vmtemplate.py
b/src/wok/plugins/kimchi/tests/test_vmtemplate.py
new file mode 100644
index 0000000..0bca215
--- /dev/null
+++ b/src/wok/plugins/kimchi/tests/test_vmtemplate.py
@@ -0,0 +1,116 @@
+#
+# Project Kimchi
+#
+# Copyright IBM, Corp. 2013-2015
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+import os
+import unittest
+import uuid
+
+from wok.xmlutils.utils import xpath_get_text
+
+from wok.plugins.kimchi.osinfo import get_template_default
+from wok.plugins.kimchi.vmtemplate import VMTemplate
+
+
+class VMTemplateTests(unittest.TestCase):
+ def setUp(self):
+ self.iso = '/tmp/mock.iso'
+ open(self.iso, 'w').close()
+
+ def tearDown(self):
+ os.unlink(self.iso)
+
+ def test_minimal_construct(self):
+ disk_bus = get_template_default('old', 'disk_bus')
+ memory = get_template_default('old', 'memory')
+ nic_model = get_template_default('old', 'nic_model')
+ fields = (('name', 'test'), ('os_distro',
'unknown'),
+ ('os_version', 'unknown'), ('cpus', 1),
+ ('memory', memory), ('networks', ['default']),
+ ('disk_bus', disk_bus), ('nic_model', nic_model),
+ ('graphics', {'type': 'vnc', 'listen':
'127.0.0.1'}),
+ ('cdrom', self.iso))
+
+ args = {'name': 'test', 'cdrom': self.iso}
+ t = VMTemplate(args)
+ for name, val in fields:
+ self.assertEquals(val, t.info.get(name))
+
+ def test_construct_overrides(self):
+ graphics = {'type': 'spice', 'listen':
'127.0.0.1'}
+ args = {'name': 'test', 'disks': [{'size': 10},
{'size': 20}],
+ 'graphics': graphics, "cdrom": self.iso}
+ t = VMTemplate(args)
+ self.assertEquals(2, len(t.info['disks']))
+ self.assertEquals(graphics, t.info['graphics'])
+
+ def test_specified_graphics(self):
+ # Test specified listen
+ graphics = {'type': 'vnc', 'listen':
'127.0.0.1'}
+ args = {'name': 'test', 'disks': [{'size': 10},
{'size': 20}],
+ 'graphics': graphics, 'cdrom': self.iso}
+ t = VMTemplate(args)
+ self.assertEquals(graphics, t.info['graphics'])
+
+ # Test specified type
+ graphics = {'type': 'spice', 'listen':
'127.0.0.1'}
+ args['graphics'] = graphics
+ t = VMTemplate(args)
+ self.assertEquals(graphics, t.info['graphics'])
+
+ # If no listen specified, test the default listen
+ graphics = {'type': 'vnc'}
+ args['graphics'] = graphics
+ t = VMTemplate(args)
+ self.assertEquals(graphics['type'],
t.info['graphics']['type'])
+ self.assertEquals('127.0.0.1',
t.info['graphics']['listen'])
+
+ def test_to_xml(self):
+ graphics = {'type': 'spice', 'listen':
'127.0.0.1'}
+ vm_uuid = str(uuid.uuid4()).replace('-', '')
+ if os.uname()[4] in ['ppc', 'ppc64', 'ppc64le']:
+ maxmem = 3328
+ else:
+ maxmem = 3072
+ t = VMTemplate({'name': 'test-template', 'cdrom':
self.iso,
+ 'max_memory': maxmem << 10})
+ xml = t.to_vm_xml('test-vm', vm_uuid, graphics=graphics)
+ self.assertEquals(vm_uuid, xpath_get_text(xml, "/domain/uuid")[0])
+ self.assertEquals('test-vm', xpath_get_text(xml,
"/domain/name")[0])
+ expr = "/domain/devices/graphics/@type"
+ self.assertEquals(graphics['type'], xpath_get_text(xml, expr)[0])
+ expr = "/domain/devices/graphics/@listen"
+ self.assertEquals(graphics['listen'], xpath_get_text(xml, expr)[0])
+ expr = "/domain/maxMemory/@slots"
+ self.assertEquals('2', xpath_get_text(xml, expr)[0])
+
+ def test_arg_merging(self):
+ """
+ Make sure that default parameters from osinfo do not override user-
+ provided parameters.
+ """
+ graphics = {'type': 'vnc', 'listen':
'127.0.0.1'}
+ args = {'name': 'test', 'os_distro': 'opensuse',
'os_version': '12.3',
+ 'cpus': 2, 'memory': 2048, 'networks':
['foo'],
+ 'cdrom': self.iso, 'graphics': graphics}
+ t = VMTemplate(args)
+ self.assertEquals(2, t.info.get('cpus'))
+ self.assertEquals(2048, t.info.get('memory'))
+ self.assertEquals(['foo'], t.info.get('networks'))
+ self.assertEquals(self.iso, t.info.get('cdrom'))
+ self.assertEquals(graphics, t.info.get('graphics'))
diff --git a/src/wok/plugins/kimchi/tests/test_yumparser.py
b/src/wok/plugins/kimchi/tests/test_yumparser.py
new file mode 100644
index 0000000..be5e95c
--- /dev/null
+++ b/src/wok/plugins/kimchi/tests/test_yumparser.py
@@ -0,0 +1,162 @@
+#
+# Project Kimchi
+#
+# Copyright IBM, Corp. 2015
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+import os
+import tempfile
+import unittest
+
+from wok.rollbackcontext import RollbackContext
+
+from wok.plugins.kimchi.model import model
+from wok.plugins.kimchi.yumparser import delete_repo_from_file, get_repo_files
+from wok.plugins.kimchi.yumparser import get_yum_packages_list_update
+from wok.plugins.kimchi.yumparser import get_yum_repositories
+from wok.plugins.kimchi.yumparser import write_repo_to_file, YumRepoObject
+
+
+TEMP_REPO_FILE = ''
+
+
+def _is_yum_distro():
+ inst = model.Model('test:///default')
+ repo_type = inst.capabilities_lookup()['repo_mngt_tool']
+ return repo_type == 'yum'
+
+
+def _create_fake_repos(repo_file_name):
+ repo1 = YumRepoObject('fake-repo-1', repo_file_name)
+ repo2 = YumRepoObject('fake-repo-2', repo_file_name)
+ repo3 = YumRepoObject('fake-repo-3', repo_file_name)
+ repo4 = YumRepoObject('fake-repo-4', repo_file_name)
+ repos = [repo1, repo2, repo3, repo4]
+ return repos
+
+
+def _create_empty_repo_file():
+ data = """
+#
+# This is a repository file with no repositories at all
+# No repositories must be added after reading this file.
+#
+ """
+ _, tmp_file_name = tempfile.mkstemp(suffix='.repo',
+ dir='/etc/yum.repos.d')
+ with open(tmp_file_name, 'w') as f:
+ f.writelines(data)
+
+ return tmp_file_name
+
+
+def _create_fake_repos_file():
+ _, tmp_file_name = tempfile.mkstemp(suffix='.repo',
+ dir='/etc/yum.repos.d')
+
+ fake_repos = _create_fake_repos(tmp_file_name)
+ file_data = ''
+ for repo in fake_repos:
+ file_data += str(repo) + '\n'
+
+ with open(tmp_file_name, 'w') as f:
+ f.writelines(file_data)
+
+ return tmp_file_name
+
+
+def _generate_yumcheckupdate_output():
+ output = """
+Repository 'REPOSITORY1' is missing name in configuration, using id
+Repository 'REPOSITORY1-OPTIONAL' is missing name in configuration, using id
+
+PACKAGE1.noarch 20150611.-gg-FAKE1 REPOSITORY1
+PACKAGE2.x86_64 20150611.-no-FAKE2 REPOSITORY2
+PACKAGE3.dot.dot.i386 20150611.-re-FAKE3 REPOSITORY3
+
+Obsoleting Packages
+OBSOLETE4.dot.dot.i386 20150611.FAKE4 REPOSITORY4
+OBSOLETE5.dot.dot.fakearch 20150611.FAKE5 REPOSITORY5
+ """
+ return output
+
+
+(a)unittest.skipIf(not _is_yum_distro(), 'Skipping: YUM exclusive test')
+def setUpModule():
+ global TEMP_REPO_FILE
+ TEMP_REPO_FILE = _create_fake_repos_file()
+
+
+(a)unittest.skipIf(not _is_yum_distro(), 'Skipping: YUM exclusive test')
+def tearDownModule():
+ os.remove(TEMP_REPO_FILE)
+
+
+(a)unittest.skipIf(not _is_yum_distro(), 'Skipping: YUM exclusive test')
+class YumParserTests(unittest.TestCase):
+
+ def test_get_yum_repositories(self):
+ repo_files = get_repo_files()
+ repo_objects = get_yum_repositories()
+ self.assertGreaterEqual(len(repo_objects), len(repo_files))
+
+ def test_empty_repo_file(self):
+ with RollbackContext() as rollback:
+ repos = get_yum_repositories()
+ tmp_file_name = _create_empty_repo_file()
+ rollback.prependDefer(os.remove, tmp_file_name)
+ repos_after = get_yum_repositories()
+ self.assertEqual(len(repos_after), len(repos))
+
+ def test_update_repo_attributes(self):
+ repos = get_yum_repositories()
+ fake_repo_2 = repos['fake-repo-2']
+ fake_repo_2.disable()
+ fake_repo_2.name = 'This is a fake repo'
+ fake_repo_2.baseurl = 'http://a.fake.repo.url'
+ fake_repo_2.gpgkey = 'file://a/fake/gpg/key.fake'
+ fake_repo_2.gpgcheck = False
+ fake_repo_2.metalink = 'this is not a true metalink'
+ fake_repo_2.mirrorlist = 'fake mirrorlist'
+ write_repo_to_file(fake_repo_2)
+
+ repos = get_yum_repositories()
+ fake_repo_2 = repos['fake-repo-2']
+ self.assertEqual(False, fake_repo_2.enabled)
+ self.assertEqual(False, fake_repo_2.gpgcheck)
+ self.assertEqual('This is a fake repo', fake_repo_2.name)
+ self.assertEqual('http://a.fake.repo.url', fake_repo_2.baseurl)
+ self.assertEqual('file://a/fake/gpg/key.fake', fake_repo_2.gpgkey)
+ self.assertEqual('this is not a true metalink', fake_repo_2.metalink)
+ self.assertEqual('fake mirrorlist', fake_repo_2.mirrorlist)
+
+ def test_delete_repo_from_file(self):
+ repos = get_yum_repositories()
+ fake_repo_3 = repos['fake-repo-3']
+ delete_repo_from_file(fake_repo_3)
+
+ repos = get_yum_repositories()
+ repos_id = repos.keys()
+ self.assertNotIn('fake-repo-3', repos_id)
+
+ def test_yum_checkupdate_parsing(self):
+ output = _generate_yumcheckupdate_output()
+ packages = get_yum_packages_list_update(output)
+ self.assertEqual(len(packages), 3)
+ self.assertEqual(packages[0].ui_from_repo, 'REPOSITORY1')
+ self.assertEqual(packages[1].version, '20150611.-no-FAKE2')
+ self.assertEqual(packages[2].name, 'PACKAGE3.dot.dot')
+ self.assertEqual(packages[2].arch, 'i386')
diff --git a/src/wok/plugins/kimchi/tests/utils.py
b/src/wok/plugins/kimchi/tests/utils.py
new file mode 100644
index 0000000..ecaa87f
--- /dev/null
+++ b/src/wok/plugins/kimchi/tests/utils.py
@@ -0,0 +1,260 @@
+#
+# Project Kimchi
+#
+# Copyright IBM, Corp. 2013-2015
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+#
+
+import base64
+import cherrypy
+import grp
+import httplib
+import inspect
+import json
+import os
+import socket
+import ssl
+import sys
+import threading
+import time
+import unittest
+from contextlib import closing
+from lxml import etree
+
+import wok.server
+from wok.config import config, PluginPaths
+from wok.auth import User, USER_NAME, USER_GROUPS, USER_ROLES, tabs
+from wok.exception import NotFoundError, OperationFailed
+from wok.utils import wok_log
+
+from wok.plugins.kimchi import mockmodel
+
+
+_ports = {}
+
+# provide missing unittest decorators and API for python 2.6; these decorators
+# do not actually work, just avoid the syntax failure
+if sys.version_info[:2] == (2, 6):
+ def skipUnless(condition, reason):
+ if not condition:
+ sys.stderr.write('[expected failure] ')
+ raise Exception(reason)
+ return lambda obj: obj
+
+ unittest.skipUnless = skipUnless
+ unittest.expectedFailure = lambda obj: obj
+
+ def assertGreater(self, a, b, msg=None):
+ if not a > b:
+ self.fail('%s not greater than %s' % (repr(a), repr(b)))
+
+ def assertGreaterEqual(self, a, b, msg=None):
+ if not a >= b:
+ self.fail('%s not greater than or equal to %s'
+ % (repr(a), repr(b)))
+
+ def assertIsInstance(self, obj, cls, msg=None):
+ if not isinstance(obj, cls):
+ self.fail('%s is not an instance of %r' % (repr(obj), cls))
+
+ def assertIn(self, a, b, msg=None):
+ if a not in b:
+ self.fail("%s is not in %b" % (repr(a), repr(b)))
+
+ def assertNotIn(self, a, b, msg=None):
+ if a in b:
+ self.fail("%s is in %b" % (repr(a), repr(b)))
+
+ unittest.TestCase.assertGreaterEqual = assertGreaterEqual
+ unittest.TestCase.assertGreater = assertGreater
+ unittest.TestCase.assertIsInstance = assertIsInstance
+ unittest.TestCase.assertIn = assertIn
+ unittest.TestCase.assertNotIn = assertNotIn
+
+
+def get_free_port(name='http'):
+ global _ports
+ if _ports.get(name) is not None:
+ return _ports[name]
+ sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
+ with closing(sock):
+ try:
+ sock.bind(("0.0.0.0", 0))
+ except:
+ raise Exception("Could not find a free port")
+ _ports[name] = sock.getsockname()[1]
+ return _ports[name]
+
+
+def run_server(host, port, ssl_port, test_mode, cherrypy_port=None,
+ model=None, environment='development'):
+
+ if cherrypy_port is None:
+ cherrypy_port = get_free_port('cherrypy_port')
+
+ if ssl_port is None:
+ ssl_port = get_free_port('https')
+
+ args = type('_', (object,),
+ {'host': host, 'port': port, 'ssl_port':
ssl_port,
+ 'cherrypy_port': cherrypy_port, 'max_body_size':
'4*1024',
+ 'ssl_cert': '', 'ssl_key': '',
+ 'test': test_mode, 'access_log': '/dev/null',
+ 'error_log': '/dev/null', 'environment':
environment,
+ 'log_level': 'debug'})()
+ if model is not None:
+ setattr(args, 'model', model)
+
+ s = wok.server.Server(args)
+ t = threading.Thread(target=s.start)
+ t.setDaemon(True)
+ t.start()
+ cherrypy.engine.wait(cherrypy.engine.states.STARTED)
+ return s
+
+
+def silence_server():
+ """
+ Silence server status messages on stdout
+ """
+ cherrypy.config.update({"environment": "embedded"})
+
+
+def running_as_root():
+ return os.geteuid() == 0
+
+
+def _request(conn, path, data, method, headers):
+ if headers is None:
+ headers = {'Content-Type': 'application/json',
+ 'Accept': 'application/json'}
+ if 'AUTHORIZATION' not in headers.keys():
+ user, pw = mockmodel.fake_user.items()[0]
+ hdr = "Basic " + base64.b64encode("%s:%s" % (user, pw))
+ headers['AUTHORIZATION'] = hdr
+ conn.request(method, path, data, headers)
+ return conn.getresponse()
+
+
+def request(host, port, path, data=None, method='GET', headers=None):
+ # verify if HTTPSConnection has context parameter
+ if "context" in inspect.getargspec(httplib.HTTPSConnection.__init__).args:
+ context = ssl._create_unverified_context()
+ conn = httplib.HTTPSConnection(host, port, context=context)
+ else:
+ conn = httplib.HTTPSConnection(host, port)
+
+ return _request(conn, path, data, method, headers)
+
+
+def get_remote_iso_path():
+ """
+ Get a remote iso with the right arch from the distro files shipped
+ with kimchi.
+ """
+ host_arch = os.uname()[4]
+ remote_path = ''
+ with open(os.path.join(PluginPaths('kimchi').conf_dir, 'distros.d',
+ 'fedora.json')) as fedora_isos:
+ # Get a list of dicts
+ json_isos_list = json.load(fedora_isos)
+ for iso in json_isos_list:
+ if (iso.get('os_arch')) == host_arch:
+ remote_path = iso.get('path')
+ break
+
+ return remote_path
+
+
+class FakeUser(User):
+ auth_type = "fake"
+ sudo = True
+
+ def __init__(self, username):
+ self.user = {}
+ self.user[USER_NAME] = username
+ self.user[USER_GROUPS] = None
+ self.user[USER_ROLES] = dict.fromkeys(tabs, 'user')
+
+ def get_groups(self):
+ return sorted([group.gr_name for group in grp.getgrall()])[0:3]
+
+ def get_roles(self):
+ if self.sudo:
+ self.user[USER_ROLES] = dict.fromkeys(tabs, 'admin')
+ return self.user[USER_ROLES]
+
+ def get_user(self):
+ return self.user
+
+ @staticmethod
+ def authenticate(username, password, service="passwd"):
+ try:
+ return mockmodel.fake_user[username] == password
+ except KeyError, e:
+ raise OperationFailed("WOKAUTH0001E", {'username':
'username',
+ 'code': e.message})
+
+
+def patch_auth(sudo=True):
+ """
+ Override the authenticate function with a simple test against an
+ internal dict of users and passwords.
+ """
+ config.set("authentication", "method", "fake")
+ FakeUser.sudo = sudo
+
+
+def normalize_xml(xml_str):
+ return etree.tostring(etree.fromstring(xml_str,
+ etree.XMLParser(remove_blank_text=True)))
+
+
+def wait_task(task_lookup, taskid, timeout=10):
+ for i in range(0, timeout):
+ task_info = task_lookup(taskid)
+ if task_info['status'] == "running":
+ wok_log.info("Waiting task %s, message: %s",
+ taskid, task_info['message'])
+ time.sleep(1)
+ else:
+ return
+ wok_log.error("Timeout while process long-run task, "
+ "try to increase timeout value.")
+
+
+# The action functions in model backend raise NotFoundError exception if the
+# element is not found. But in some tests, these functions are called after
+# the element has been deleted if test finishes correctly, then NofFoundError
+# exception is raised and rollback breaks. To avoid it, this wrapper ignores
+# the NotFoundError.
+def rollback_wrapper(func, resource, *args):
+ try:
+ func(resource, *args)
+ except NotFoundError:
+ # VM has been deleted already
+ return
+
+
+# This function is used to test storage volume upload.
+# If we use self.request, we may encode multipart formdata by ourselves
+# requests lib take care of encode part, so use this lib instead
+def fake_auth_header():
+ headers = {'Accept': 'application/json'}
+ user, pw = mockmodel.fake_user.items()[0]
+ hdr = "Basic " + base64.b64encode("%s:%s" % (user, pw))
+ headers['AUTHORIZATION'] = hdr
+ return headers
diff --git a/src/wok/plugins/kimchi/ui/Makefile.am
b/src/wok/plugins/kimchi/ui/Makefile.am
new file mode 100644
index 0000000..21fe703
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/Makefile.am
@@ -0,0 +1,20 @@
+#
+# Kimchi
+#
+# Copyright IBM, Corp. 2013
+#
+# 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.
+
+SUBDIRS = config css images js pages spice-html5
+
+uidir = $(datadir)/wok/plugins/kimchi/ui
diff --git a/src/wok/plugins/kimchi/ui/config/Makefile.am
b/src/wok/plugins/kimchi/ui/config/Makefile.am
new file mode 100644
index 0000000..e3b3d19
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/config/Makefile.am
@@ -0,0 +1,22 @@
+#
+# Kimchi
+#
+# Copyright IBM, Corp. 2013
+#
+# 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.
+
+xmldir = $(datadir)/wok/plugins/kimchi/ui/config
+
+dist_xml_DATA = \
+ tab-ext.xml \
+ $(NULL)
diff --git a/src/wok/plugins/kimchi/ui/config/tab-ext.xml
b/src/wok/plugins/kimchi/ui/config/tab-ext.xml
new file mode 100644
index 0000000..ee88c88
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/config/tab-ext.xml
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="utf-8"?>
+<tabs-ext>
+ <tab>
+ <access role="admin" mode="admin"/>
+ <access role="user" mode="none"/>
+
+ <title>Host</title>
+ <path>plugins/kimchi/host.html</path>
+ </tab>
+ <tab>
+ <access role="admin" mode="admin"/>
+ <access role="user" mode="byInstance"/>
+
+ <title>Guests</title>
+ <path>plugins/kimchi/guests.html</path>
+ </tab>
+ <tab>
+ <access role="admin" mode="admin"/>
+ <access role="user" mode="none"/>
+
+ <title>Templates</title>
+ <path>plugins/kimchi/templates.html</path>
+ </tab>
+ <tab>
+ <access role="admin" mode="admin"/>
+ <access role="user" mode="read-only"/>
+
+ <title>Storage</title>
+ <path>plugins/kimchi/storage.html</path>
+ </tab>
+ <tab>
+ <access role="admin" mode="admin"/>
+ <access role="user" mode="read-only"/>
+
+ <title>Network</title>
+ <path>plugins/kimchi/network.html</path>
+ </tab>
+</tabs-ext>
diff --git a/src/wok/plugins/kimchi/ui/css/Makefile.am
b/src/wok/plugins/kimchi/ui/css/Makefile.am
new file mode 100644
index 0000000..5071d29
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/css/Makefile.am
@@ -0,0 +1,26 @@
+#
+# Kimchi
+#
+# Copyright IBM, Corp. 2013
+#
+# 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.
+
+EXTRA_DIST = theme-default
+
+cssdir = $(datadir)/wok/plugins/kimchi/ui/css
+dist_css_DATA = theme-default.min.css
+
+theme-default.min.css: theme-default/*.css
+ cat $^ > $@
+
+CLEANFILES = theme-default.min.css
diff --git a/src/wok/plugins/kimchi/ui/css/theme-default/guest-edit.css
b/src/wok/plugins/kimchi/ui/css/theme-default/guest-edit.css
new file mode 100644
index 0000000..b661159
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/css/theme-default/guest-edit.css
@@ -0,0 +1,424 @@
+/*
+ * Project Kimchi
+ *
+ * Copyright IBM, Corp. 2013-2015
+ *
+ * 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.
+ */
+#guest-edit-window {
+ font-size: 13px;
+ height: 420px;
+ width: 820px;
+}
+
+#guest-edit-window #action-button-container {
+ padding-right: 0;
+}
+
+#guest-edit-window #guest-edit-button-cancel {
+ margin-left: 10px;
+}
+
+#guest-edit-tabs {
+ background: transparent;
+ border: none;
+ height: 100%;
+ padding: 0;
+}
+
+#form-guest-edit-general {
+ padding: 1em;
+}
+
+#form-guest-edit-general .edit-general-inline {
+ display: inline-block;
+}
+
+#form-guest-edit-storage input[readonly] {
+ background: none;
+ border-color: transparent;
+ text-overflow: ellipsis;
+}
+
+.guest-edit-fieldset {
+ padding-right: 0;
+}
+
+.guest-edit-wrapper-label {
+ height: 30px;
+ line-height: 30px;
+ margin-top: 10px;
+ vertical-align: top;
+ min-width: 100px;
+ font-weight: lighter;
+ font-family: 'Helvetica Neue', Helvetica, Arial;
+}
+
+#form-guest-edit-storage .guest-edit-wrapper-label {
+ width: 60px;
+}
+
+.guest-edit-wrapper-controls {
+ width: 470px;
+ margin-top: 5px;��
+}
+
+#form-guest-edit-storage .guest-edit-wrapper-controls {
+ width: 486px;
+}
+
+.guest-edit-wrapper-controls input[type="text"] {
+ font-size: 16px;
+ height: 30px;
+ width: 450px;
+ border: 1px solid #CCCCCC;
+}
+
+.guest-edit-wrapper-controls input[type="text"][disabled] {
+ color: #bbb;
+ background-color: #fafafa;
+ cursor: not-allowed;
+ border: 1px solid #CCCCCC;
+}
+
+.guest-edit-cdrom-row-container {
+ max-height: 180px;
+ overflow: auto;
+}
+
+.guest-edit-cdrom-row-container input[type="text"] {
+ width: 400px;
+}
+
+#form-guest-edit-storage .header,
+.guest-edit-snapshot .header,
+.guest-edit-interface .header,
+#form-guest-edit-permission .ldap .header {
+ margin-bottom: 8px;
+ padding-bottom: 2px;
+ font-weight: bold;
+ border-bottom: 1px solid #999999;
+ overflow: hidden;
+}
+
+#form-guest-edit-storage .body .item,
+.guest-edit-snapshot .body .item,
+.guest-edit-snapshot .task .item,
+.guest-edit-interface .body .item {
+ margin: 5px 0;
+}
+
+#form-guest-edit-storage .cell,
+.guest-edit-interface .cell {
+ display: inline-block;
+ width: 200px;
+}
+
+.guest-edit-snapshot .cell {
+ display: inline-block;
+}
+
+.guest-edit-snapshot .sel {
+ width: 25px;
+ vertical-align: top;
+}
+
+.guest-edit-snapshot .icon {
+ background: url('../images/theme-default/kimchi-loading15x15.gif')
no-repeat;
+ display: block;
+ width: 16px;
+ height: 16px;
+ vertical-align: middle;
+ margin-left: 2px;
+}
+
+.guest-edit-snapshot .name {
+ width: 400px;
+}
+
+.guest-edit-snapshot .created {
+ width: 270px;
+}
+
+#form-guest-edit-storage .cell.dev {
+ width: 60px;
+}
+
+#form-guest-edit-storage .cell.path {
+ width: 440px;
+}
+
+#form-guest-edit-storage .cell.dev input,
+#form-guest-edit-storage .cell.path input {
+ box-sizing: border-box;
+ width: 100%;
+}
+
+.guest-edit-interface .body select {
+ width: 180px;
+ padding: 0px;
+}
+
+#form-guest-edit-storage .action-area,
+.guest-edit-snapshot .action-area,
+.guest-edit-interface .action-area {
+ float: right;
+}
+
+#form-guest-edit-storage .action-area {
+ line-height: 24px;
+}
+
+#form-guest-edit-storage button,
+.guest-edit-snapshot button,
+.guest-edit-interface button {
+ width: 20px;
+ height: 20px;
+}
+
+#form-guest-edit-storage .body button:not(:last-child),
+.guest-edit-interface .body button:not(:last-child) {
+ margin-right: 2px;
+}
+
+.guest-edit-snapshot .hide,
+.guest-edit-interface .hide {
+ display: none!important;
+}
+
+.guest-edit-permission .pam {
+ height: 220px;
+ padding: 5px 10px!important;
+}
+
+.guest-edit-permission .hide {
+ display: none;
+}
+
+.guest-edit-permission .pam .column {
+ display: inline-block;
+ vertical-align: top;
+}
+
+.guest-edit-permission .pam .title {
+ margin-bottom: 3px;
+}
+
+.guest-edit-permission .pam input[type="text"] {
+ margin-bottom: 3px;
+ font-size: 12px;
+ width: 97%;
+}
+
+.guest-edit-permission .pam .body {
+ border: 1px solid #999999;
+ font-size: 12px;
+ padding: 1px;
+ height: 192px;
+ overflow: auto;
+}
+
+.guest-edit-permission .pam .body .head {
+ margin-bottom: 3px;
+ font-weight: bold;
+ background: linear-gradient(to bottom, #E5E5E5 0%, #C4C4C4 100%) repeat scroll 0 0
transparent;
+}
+
+.guest-edit-permission .pam .body .item {
+ padding: 2px 3px;
+ margin-bottom: 1px;
+ cursor: pointer;
+}
+
+.guest-edit-permission .pam .body .item:hover {
+ background-color: #AAAAAA;
+}
+
+.guest-edit-permission .pam .body .item-picked {
+ background-color: #BBBBBB;
+}
+
+.guest-edit-permission .pam .body .item .icon {
+ display: inline-block;
+ height: 15px;
+ width: 15px;
+ vertical-align: bottom;
+}
+
+.guest-edit-permission .pam .body .item .user-icon {
+ background: url('../images/theme-default/user.png') no-repeat scroll;
+ background-size: 15px 15px;
+}
+
+.guest-edit-permission .pam .body .item .group-icon {
+ background: url('../images/theme-default/group.png') no-repeat scroll;
+ background-size: 15px 15px;
+}
+
+.guest-edit-permission .pam .body .column-user {
+ width: 48%;
+}
+.guest-edit-permission .pam .body .column-group {
+ width: 50%;
+}
+
+.guest-edit-permission .pam .control {
+ width: 5%;
+}
+
+.guest-edit-permission .pam .control button {
+ width: 26px;
+ margin-left: 7px;
+}
+
+.guest-edit-permission .pam .control button:first-child {
+ margin-top: 110px;
+ margin-bottom: 2px;
+}
+
+.guest-edit-permission .pam .control .ui-button-text-only .ui-button-text {
+ padding: 2px 8px;
+}
+
+.guest-edit-permission .pam .avail {
+ width: 46%;
+}
+
+.guest-edit-permission .pam .selected {
+ width: 46%;
+ float: right;
+}
+
+#form-guest-edit-permission .ldap .body .item {
+ margin: 8px 0;
+}
+
+#form-guest-edit-permission .ldap .cell {
+ width: 250px;
+}
+
+#form-guest-edit-permission .ldap .action-area {
+ float: right;
+ line-height: 24px;
+}
+
+#form-guest-edit-permission .ldap button {
+ width: 20px;
+ height: 20px;
+}
+
+#form-guest-edit-permission input[type="text"] {
+ width: 300px;
+}
+
+#form-guest-edit-permission .ldap .header button {
+ margin-bottom: 1px;
+}
+
+#form-guest-edit-permission .ldap .checked {
+ border-color: red;
+ border-style: solid;
+ border-width: 1px;
+}
+
+#form-guest-edit-permission .ldap .checked.hide {
+ display: none;
+}
+
+.guest-edit-pci {
+ height: 79%;
+ overflow: auto;
+ font-size: 12px;
+}
+
+.guest-edit-pci .guest-scroll-indent {
+ width: 783px;
+}
+
+.guest-edit-pci .filter {
+ height: 35px;
+ margin-right: 5px;
+ overflow: hidden;
+}
+
+.guest-edit-pci .group {
+ float: right;
+}
+
+.guest-edit-pci .filter .control {
+ border: 1px solid #AAAAAA;
+ font-size: 12px;
+ background-color: white;
+}
+
+.guest-edit-pci .filter select {
+ border-right: 0px!important;
+ border-radius: 7px 0px 0px 7px;
+ padding: 2px 2px 2px 7px;
+ width: 100px;
+ height: 24px;
+}
+
+.guest-edit-pci .filter select option {
+ padding-left: 7px;
+}
+
+.guest-edit-pci .filter input {
+ border-radius: 0px 7px 7px 0px;
+ padding: 3px 3px 3px 10px;
+ width: 200px;
+ height: 16px;
+ font-style: italic;
+}
+
+.guest-edit-pci .header {
+ margin-bottom: 8px;
+ padding-bottom: 2px;
+ font-weight: bold;
+ border-bottom: 1px solid #999999;
+}
+
+.guest-edit-pci .item {
+ margin-bottom: 4px;
+ overflow: hidden;
+}
+
+.guest-edit-pci .cell {
+ display: inline-block;
+ vertical-align: middle;
+ margin-right: 10px;
+ overflow: hidden;
+ text-overflow: ellipsis;
+ white-space: nowrap;
+}
+
+.guest-edit-pci .item button {
+ width: 20px;
+ height: 20px;
+ float: right;
+}
+
+.guest-edit-pci .name {
+ width: 18%;
+ max-width: 18%;
+}
+
+.guest-edit-pci .product {
+ width: 45%;
+ max-width: 45%;
+}
+
+.guest-edit-pci .vendor {
+ width: 25%;
+ max-width: 25%;
+}
diff --git a/src/wok/plugins/kimchi/ui/css/theme-default/guest-storage-add.css
b/src/wok/plugins/kimchi/ui/css/theme-default/guest-storage-add.css
new file mode 100644
index 0000000..9cc41e8
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/css/theme-default/guest-storage-add.css
@@ -0,0 +1,81 @@
+/*
+ * Project Kimchi
+ *
+ * Copyright IBM, Corp. 2014
+ *
+ * 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.
+ */
+#guest-storage-add-window {
+ font-size: 13px;
+ height: 600px;
+ width: 700px;
+}
+
+.guest-storage-add-fieldset {
+ padding: 1em;
+}
+
+#guest-storage-add-window .btn {
+ width: 587px;
+}
+
+#form-guest-storage-add .form-section .field {
+ overflow: visible;
+}
+
+#guest-storage-add-window input[type="text"] {
+ font-size: 16px;
+ height: 38px;
+ background: #fff;
+ -webkit-border-radius: 5px;
+ border-radius: 5px;
+ box-shadow: 2px 2px 2px #eee inset;
+ border-top: 1px solid #bbb;
+ border-left: 1px solid #bbb;
+ padding-left: 10px;
+ width: 600px;
+}
+
+#guest-storage-add-window input[type="text"][disabled] {
+ color: #bbb;
+ background-color: #fafafa;
+ cursor: not-allowed;
+}
+
+.guest-storage-add-wrapper-label, .guest-storage-add-wrapper-controls {
+ display: inline-block;
+}
+
+.guest-storage-add-wrapper-label {
+ height: 38px;
+ line-height: 38px;
+ margin-top: 5px;
+ vertical-align: top;
+ width: 80px;
+}
+
+.guest-storage-add-wrapper-controls {
+ width: 470px;
+}
+
+#vm-storage-button-add[disabled] {
+ background: #c0c0c0;
+ color: #ddd;
+ padding-left: 26px;
+}
+
+#vm-storage-button-add.loading[disabled] {
+ background: url("../../images/theme-default/loading.gif") 7px center
no-repeat #c0c0c0;
+ color: #ddd;
+ padding-left: 26px;
+}
diff --git a/src/wok/plugins/kimchi/ui/css/theme-default/host.css
b/src/wok/plugins/kimchi/ui/css/theme-default/host.css
new file mode 100644
index 0000000..a0cccb1
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/css/theme-default/host.css
@@ -0,0 +1,287 @@
+/*
+ * Project Kimchi
+ *
+ * Copyright IBM, Corp. 2013-2014
+ *
+ * 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.
+ */
+.host-panel {
+ font-size: 12px;
+ margin-bottom: 100px;
+}
+
+.host-panel .logo-container, .host-panel .info-container,
+.host-panel .section-label, .host-panel .section-value {
+ display: inline-block;
+ vertical-align: top;
+}
+
+.host-panel .section-label {
+ display: inline-block;
+ margin-right: 1em;
+ vertical-align: top;
+}
+
+.host-panel .logo {
+ background: url("plugins/kimchi/images/icon-vm.png") no-repeat left top;
+ height: 128px;
+ width: 128px;
+}
+
+.host-panel .hostname {
+ text-decoration: underline;
+}
+
+.host-panel .action-panel {
+ margin-top: 2em;
+ padding-left: 10px;
+}
+
+.host-panel .button-icon {
+ background: url("../images/theme-default/host-icon-sprite.png") no-repeat
+ left top;
+ display: inline-block;
+ height: 12px;
+ width: 12px;
+}
+
+.host-panel .action-icon-stop {
+ background-position: -14px 0;
+}
+
+.host-panel .action-icon-restart {
+ background-position: -28px 0;
+}
+
+.host-panel .action-icon-download {
+ background-position: -42px 0;
+}
+
+.host-panel .action-icon-connect {
+ background-position: -56px 0;
+}
+
+.host-panel .action-icon-add {
+ background-position: -70px 0;
+}
+
+.host-panel .action-icon-edit {
+ background-position: -84px 0;
+}
+
+.host-panel .action-icon-remove {
+ background-position: -98px 0;
+}
+
+.host-panel button:disabled .action-icon-start {
+ background-position: 0 -14px;
+}
+
+.host-panel button:disabled .action-icon-stop {
+ background-position: -14px -14px;
+}
+
+.host-panel button:disabled .action-icon-restart {
+ background-position: -28px -14px;
+}
+
+.host-panel button:disabled .action-icon-download {
+ background-position: -42px -14px;
+}
+
+.host-panel button:disabled .action-icon-connect {
+ background-position: -56px -14px;
+}
+
+.host-panel button:disabled .action-icon-add {
+ background-position: -70px -14px;
+}
+
+.host-panel button:disabled .action-icon-edit {
+ background-position: -84px -14px;
+}
+
+.host-panel button:disabled .action-icon-remove {
+ background-position: -98px -14px;
+}
+
+.host-panel .info-container {
+ padding-top: 16px;
+ width: 890px;
+}
+
+.host-panel .section-header {
+ background: #EEE;
+ border-radius: 5px;
+ cursor: pointer;
+ line-height: 2em;
+ margin: 1em 0 1em;
+ padding-left: 6px;
+}
+
+.host-panel .section-header:hover {
+ background: #06f;
+ color: white;
+}
+
+.host-panel .section-content {
+ padding-left: 1em;
+}
+
+.host-panel .section-header .arrow {
+ border-color: transparent;
+ border-style: solid;
+ display: inline-block;
+ margin-right: 6px;
+ width: 0;
+}
+
+.host-panel .section-header[aria-expanded="true"] .arrow {
+ border-top-color: black;
+ border-width: 8px 4px 0;
+ border-bottom: none;
+}
+
+.host-panel .section-header[aria-expanded="true"]:hover .arrow {
+ border-top-color: white;
+}
+
+.host-panel .section-header[aria-expanded="false"] .arrow {
+ border-left-color: black;
+ border-right: none;
+ border-width: 4px 0 4px 8px;
+}
+
+.host-panel .section-header[aria-expanded="false"]:hover .arrow {
+ border-left-color: white;
+}
+
+.host-panel .section-row {
+ line-height: 1.6em;
+ margin-bottom: 1em;
+}
+
+.host-panel .section-label {
+ width: 100px;
+}
+
+#frequency-textbox {
+ width: 20px;
+}
+
+#container-chart-cpu,
+#container-chart-memory,
+#container-chart-disk-io,
+#container-chart-network-io {
+ border: 1px solid white;
+ box-shadow: 2px 2px 2px gray, 2px -2px 2px gray, -2px -2px 2px gray, -2px
+ 2px 2px gray;
+ height: 100px;
+ width: 500px;
+}
+
+#container-chart-disk-io .disk-write,
+#container-chart-network-io .network-sent {
+ stroke: #f80;
+}
+
+/* Debug Report */
+.cell-text-wrapper {
+ margin-left: 10px;
+}
+
+.host-panel #available-reports-grid {
+ border-color: #ddd;
+ height: 400px;
+ width: 850px;
+}
+
+.host-panel select#available-reports-list {
+ width: 300px;
+}
+
+.host-panel select#available-reports-list option {
+ margin: .2em 1em;
+}
+
+.debug-report-name,
+.debug-report-time {
+ width: 424px;
+}
+
+#id-debug-img {
+ background: url(../images/theme-default/kimchi-loading15x15.gif) 12px
+ center no-repeat;
+ padding-left: 23px;
+}
+
+/* End of Debug Report */
+
+/* Software Updates */
+.host-panel #software-updates-grid {
+ border-color: #ddd;
+ height: 300px;
+ width: 850px;
+}
+
+.software-update-name,
+.software-update-repos {
+ width: 224px;
+}
+
+.software-update-version,
+.software-update-arch {
+ width: 200px;
+}
+
+.host-panel #software-updates-progress-textarea {
+ border: 1px solid #ddd;
+ box-sizing: border-box;
+ height: 100px;
+ padding: .2em .5em;
+ resize: vertical;
+ width: 852px;
+}
+/* End of Software Updates */
+
+/* Repository */
+.host-panel #repositories-grid {
+ border-color: #ddd;
+ height: 200px;
+ width: 850px;
+}
+
+.host-panel #repositories-grid .repository-id {
+ width: 120px;
+}
+
+.host-panel #repositories-grid .repository-name {
+ width: 640px;
+}
+
+.host-panel #repositories-grid .repository-enabled {
+ width: 88px;
+}
+
+.host-panel #repositories-grid .repository-baseurl.deb {
+ width: 400px;
+}
+
+.host-panel #repositories-grid .repository-enabled.deb {
+ width: 100px;
+}
+
+.host-panel #repositories-grid .repository-gpgcheck.deb {
+ width: 150px;
+}
+/* End of Repository */
diff --git a/src/wok/plugins/kimchi/ui/css/theme-default/icon.css
b/src/wok/plugins/kimchi/ui/css/theme-default/icon.css
new file mode 100644
index 0000000..f82d45d
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/css/theme-default/icon.css
@@ -0,0 +1,106 @@
+/*
+ * Project Kimchi
+ *
+ * Copyright IBM, Corp. 2013-2015
+ *
+ * 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.
+ */
+
+ /* Generated at
http://colorzilla.com/gradient-editor/ */
+
+.btn.loading {
+ box-shadow: none;
+ cursor: default;
+}
+
+.btn.loading .icon {
+ background: url(../images/theme-default/icon-load.png) center
+ center no-repeat;
+}
+
+.btn.pause-gray .icon {
+ background: url(../images/theme-default/ac22_pause_grey.png) center
+ center no-repeat;
+}
+
+.btn.resume-gray .icon {
+ background: url(../images/theme-default/ac24_resume_grey.png) center
+ center no-repeat;
+}
+
+.icon.reset {
+ background: url(../images/theme-default/icon-reset.png) center
+ center no-repeat;
+}
+
+.icon.power-up {
+ background: url(../images/theme-default/icon-power-up.png) center
+ center no-repeat;
+}
+
+.icon.power-down {
+ background: url(../images/theme-default/icon-power-down.png) center
+ center no-repeat;
+}
+
+.icon.pause {
+ background: url(../images/theme-default/ac22_pause.png) center
+ center no-repeat;
+}
+
+.icon.resume {
+ background: url(../images/theme-default/ac24_resume.png) center
+ center no-repeat;
+}
+
+.icon.search {
+ background: url(../images/theme-default/icon-search.png) no-repeat
+ center center;
+}
+
+.icon.sort {
+ background: url(../images/theme-default/icon-sort.png) no-repeat
+ center center;
+}
+
+.icon.design {
+ background: url(../images/theme-default/icon-design.png) no-repeat
+ center center;
+}
+
+.icon.list {
+ background: url(../images/theme-default/icon-list.png) no-repeat
+ center center;
+}
+
+.icon.detail {
+ background: url(../images/theme-default/icon-detail.png) no-repeat
+ center center;
+}
+
+.icon.add {
+ line-height: 32px;
+ text-align: center;
+ text-shadow: -1px -1px 1px #aaa, 1px 1px 1px #eee;
+ font-size: 38px;
+ font-weight: bold;
+ color: #7cae0a;
+}
+
+.icon.tree {
+ width: 42px;
+ background: url(../images/theme-default/icon-tree.png) no-repeat
+ center center;
+}
+
+
diff --git a/src/wok/plugins/kimchi/ui/css/theme-default/list.css
b/src/wok/plugins/kimchi/ui/css/theme-default/list.css
new file mode 100644
index 0000000..8c78623
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/css/theme-default/list.css
@@ -0,0 +1,326 @@
+/*
+ * Project Kimchi
+ *
+ * Copyright IBM, Corp. 2013-2015
+ *
+ * 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.
+ */
+.list-vm {
+ margin: 10px;
+}
+
+/* Generated at
http://colorzilla.com/gradient-editor/ */
+.list-vm>li {
+ margin-bottom: 10px;
+ background: #ffffff;
+ background: -moz-linear-gradient(top, #ffffff 0%, #e5e5e5 100%);
+ background: -webkit-gradient(linear, left top, left bottom,
+ color-stop(0%, #ffffff), color-stop(100%, #e5e5e5));
+ background: -webkit-linear-gradient(top, #ffffff 0%, #e5e5e5 100%);
+ background: -o-linear-gradient(top, #ffffff 0%, #e5e5e5 100%);
+ background: -ms-linear-gradient(top, #ffffff 0%, #e5e5e5 100%);
+ background: linear-gradient(to bottom, #ffffff 0%, #e5e5e5 100%);
+ filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffff',
+ endColorstr='#e5e5e5', GradientType=0);
+ border: 1px solid #ccc;
+ color: #333;
+ -webkit-border-radius: 8px;
+ -moz-border-radius: 8px;
+ border-radius: 8px;
+}
+
+.list-vm li>* {
+ height: 130px;
+ display: table-cell;
+ vertical-align: top;
+ position: relative;
+ border-left: 1px solid #ccc;
+ border-right: 1px solid #fff;
+}
+
+.list-vm li>*:FIRST-CHILD {
+ border-left: none;
+}
+
+.list-vm li>*:LAST-CHILD {
+ border-right: none;
+}
+
+.list-vm li>.guest-tile{
+ text-align: center;
+ vertical-align: middle;
+}
+
+.list-vm .handle {
+ display: block;
+ width: 50px;
+ height: 130px;
+ box-sizing: border-box;
+ box-shadow: inset 4px 4px 4px #0289e2, inset -4px -4px 4px #04385d;
+ background: #0b6bad url(../images/theme-default/arrow_out.png) center
+ center no-repeat;
+ border-top-right: 1px solid #CCC;
+ -webkit-border-top-right-radius: 8px;
+ -moz-border-top-right-radius: 8px;
+ border-top-right-radius: 8px;
+ border-bottom-right: 1px solid #CCC;
+ -webkit-border-bottom-right-radius: 8px;
+ -moz-border-bottom-right-radius: 8px;
+ border-bottom-right-radius: 8px;
+}
+
+.list-vm .subtitle {
+ color: #666;
+ font-size: 13px;
+ text-align: center;
+ line-height: 10px;
+ font-weight: bold;
+}
+
+.list-vm .tile .imgload {
+ display: none;
+}
+
+.list-vm .tile.shutoff .imgactive {
+ max-height: 110px;
+ max-width: 170px;
+ height: auto;
+ width: auto;
+ display:inline;
+ border: none;
+ position: relative;
+}
+
+.list-vm .tile.paused .imgactive {
+ max-height: 110px;
+ max-width: 170px;
+ height: auto;
+ width: auto;
+ display:inline;
+ border: none;
+ position: relative;
+}
+
+.list-vm .tile.running .imgactive{
+ max-height: 110px;
+ max-width: 170px;
+ height: auto;
+ width: auto;
+ display:inline;
+ border: none;
+ cursor: crosshair;
+ cursor: -moz-zoom-in;
+ cursor: -webkit-zoom-in;
+}
+
+.list-vm .tile .overlay {
+ max-height: 110px;
+ max-width: 170px;
+ height: auto;
+ width: auto;
+ position:absolute;
+ bottom:0;
+ right:0;
+ display:none;
+}
+
+.guest-type {
+ width: 257px;
+}
+
+.guest-cpu {
+ width: 91px;
+}
+
+.guest-network {
+ width: 91px;
+}
+
+.guest-storage {
+ width: 91px;
+}
+
+.guest-tile {
+ width: 190px;
+}
+
+.guest-users {
+ width: 93px;
+}
+
+.guest-actions {
+ width: 125px;
+ min-width: 125px;
+}
+
+.guest-handle {
+ width: 50px;
+}
+
+.guest-general {
+ padding: 10px;
+ border-bottom: 1px solid #ccc;
+ width: 237px;
+}
+
+.guest-ip {
+ padding: 0 10px;
+ border-top: 1px solid #fff;
+}
+
+.guest-general .title {
+ color: #666;
+ font-size: 16px;
+ font-weight: normal;
+ height: 25px;
+ line-height: 25px;
+ text-shadow: -1px -1px 1px #ccc, 1px 1px 1px #fff;
+ max-width: 237px;
+ overflow: hidden;
+ text-overflow: ellipsis;
+ white-space: nowrap;
+}
+
+.guest-general .text {
+ font-weight: bold;
+ color: #999;
+ font-size: 11px;
+ text-shadow: -1px -1px 1px #ccc, 1px 1px 1px #fff;
+}
+
+.guest-users .top {
+ border-bottom: 1px solid #ccc;
+ padding: 3px 10px;
+}
+
+.guest-users .bottom {
+ border-top: 1px solid #fff;
+ padding: 3px 10px;
+}
+
+.guest-users .users {
+ height: 45px;
+ line-height: 45px;
+ background: url(../images/theme-default/icon-user.png) left
+ center no-repeat;
+ padding-left: 50px;
+ font-size: 36px;
+ font-weight: bold;
+}
+
+.guest-users .snapshots {
+ height: 40px;
+ line-height: 40px;
+ background: url(../images/theme-default/icon-camera.png) left
+ center no-repeat;
+ padding-left: 50px;
+ font-size: 36px;
+ font-weight: bold;
+}
+
+.guest-users .mini-text {
+ font-size: 11px;
+ font-weight: normal;
+ text-shadow: -1px -1px 1px #ccc, 1px 1px 1px #fff;
+}
+
+.guest-actions .top {
+ padding: 7px 10px;
+ width: 200px;
+}
+
+.guest-actions .top button {
+ display: inline-block;
+ width: 42px;
+ height: 42px;
+}
+
+@-moz-document url-prefix() {
+ .guest-actions .top button span {
+ margin-left: -3px;
+ margin-top: -1px;
+ }
+}
+
+.guest-actions .bottom {
+ padding: 0 10px;
+}
+
+.list-vm .tile {
+ max-width: 170px;
+ max-height: 110px;
+ width: auto;
+ height: auto;
+ margin: 10px;
+}
+
+.list-vm .tile:not(.shutoff) && .tile:not(.paused) img {
+ box-shadow: -1px -1px 2px rgb(0, 0, 0, .25), 3px 3px 3px #fff;
+}
+
+.list-vm .shutoff {
+ position: relative;
+ box-shadow: none !important;
+}
+
+.list-vm .shutoff img {
+ opacity: 0.4;
+}
+
+.list-vm .paused {
+ position: relative;
+ box-shadow: none !important;
+}
+
+.list-vm .paused img {
+ opacity: 0.6;
+}
+
+.list-title {
+ color: #666;
+ font-weight: bold;
+ font-size: 12px;
+ overflow: hidden;
+ margin: 10px;
+}
+
+.list-title li {
+ display: table-cell;
+ padding: 0 1px;
+}
+
+.list-no-result {
+ font-size: 16px;
+ height: 48px;
+ line-height: 48px;
+ text-shadow: -1px -1px 1px #ccc, 1px 1px 1px #fff;
+ padding-left: 10px;
+}
+
+.guest-pending {
+ margin: 10px;
+}
+
+.guest-pending .icon {
+ background: url('../images/theme-default/kimchi-loading15x15.gif')
no-repeat;
+ display: inline-block;
+ width: 20px;
+ height: 20px;
+ vertical-align: middle;
+}
+
+.guest-pending .text {
+ color: #666666;
+ margin-left: 5px;
+ text-shadow: -1px -1px 1px #CCCCCC, 1px 1px 1px #FFFFFF;
+}
diff --git a/src/wok/plugins/kimchi/ui/css/theme-default/network.css
b/src/wok/plugins/kimchi/ui/css/theme-default/network.css
new file mode 100644
index 0000000..fc8a24f
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/css/theme-default/network.css
@@ -0,0 +1,267 @@
+/*
+ * Project Kimchi
+ *
+ * Copyright IBM, Corp. 2013-2015
+ *
+ * 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.
+ */
+
+.network {
+ margin: 5px;
+}
+
+.network .grid-control {
+ height: 40px;
+ padding: 5px 0;
+}
+
+.network .grid-control .filter {
+ width: 300px;
+ padding: 5px;
+ float: right;
+}
+
+.network .list .column-name {
+ width: 20%;
+ max-width: 20%;
+ text-overflow: ellipsis;
+}
+
+.network .list .column-state {
+ width: 10%;
+}
+
+.network .list .column-type {
+ width: 15%;
+}
+
+.network .list .column-interface {
+ width: 15%;
+}
+
+.network .list .column-space {
+ width: 25%;
+}
+
+.network .list .column-action {
+ display: inline-block;
+ float: right;
+ height: 40px;
+}
+
+.network .list .hide-action-item {
+ display: none;
+}
+
+.network .list .menu-container {
+ display: none;
+ top: 58px;
+}
+
+.network .list .action-button {
+ float: right;
+ margin-top: 2px;
+ margin-left: 5px;
+}
+
+.network .list .action-button-icon {
+ background: url("../images/theme-default/arrow-down-black.png") no-repeat
+ scroll center center transparent;
+}
+
+.network .list .ui-state-disabled {
+ margin: 0px;
+}
+
+.network .list .network-state {
+ display: inline-block;
+ height: 16px;
+ width: 16px;
+ border-radius: 8px;
+ margin-left: 10px;
+}
+
+.network .list .nw-loading {
+ background: #c0c0c0 url(../images/theme-default/loading.gif)
+ center no-repeat;
+}
+
+.network .list .up {
+ background: linear-gradient(to bottom, #BFD255 0%, #8EB92A 50%,
+ #72AA00 51%, #9ECB2D 100%) repeat scroll 0 0 transparent;
+}
+
+.network .list .down {
+ background: linear-gradient(to bottom, #AFAFAF 0%, #AFAFAF 50%,
+ #AFAFAF 51%, #AFAFAF 100%) repeat scroll 0 0 transparent;
+}
+
+.network-config {
+ font-family: Arial;
+ font-size: 12px;
+ margin-bottom: 40px;
+ display: none;
+}
+
+.network-config .section-container {
+ margin-top: 20px;
+}
+
+.network-config .section-container:first-child {
+ margin-top: 10px;
+}
+
+.network-config .section-container:last-child {
+ height: 200px;
+}
+
+.network-config .section-container .bridged-inline {
+ display: inline-block;
+ vertical-align: top;
+ max-width: 520px;
+}
+
+.network-config .section-header {
+ font-size: 14px;
+ font-weight: lighter;
+}
+
+.network-config .section-content {
+ margin-top: 10px;
+}
+
+.network-config input[type="text"] {
+ border: 1px solid #CCCCCC;
+ font-size: 16px;
+ height: 30px;
+ width: 300px;
+ line-height: 30px;
+ padding: 0 5px;
+}
+
+.network-config input.invalid-field[type="text"] {
+ border-color: #FF4444;
+}
+
+.network-config input.invalid-field[type="text"][disabled] {
+ border-color: #666666;
+}
+
+.network-config input[type="radio"] {
+ margin-right: 5px;
+ margin-top: 0px;
+}
+
+.network-config select {
+ color: #666666;
+ border: solid 1px;
+ background-color: white;
+ padding: 3px 4px 3px 0;
+}
+
+.network-config .input-container {
+ height: 20px;
+}
+
+.network-config label {
+ vertical-align: top;
+}
+
+.network-type-wrapper-controls input[type="text"] {
+ height: 38px;
+ line-height: 38px;
+ background: #fff;
+ -webkit-border-radius: 5px;
+ border-radius: 5px;
+ box-shadow: 2px 2px 2px #eee inset;
+ border-top: 1px solid #bbb;
+ border-left: 1px solid #bbb;
+ padding: 0 10px;
+ margin-top: 5px;
+ width: 50px;
+}
+
+.network-type-wrapper-controls > .dropdown {
+ margin: 5px 0 0 1px;
+ width: 180px;
+}
+
+.network-type-wrapper-controls input[type="text"][disabled] {
+ color: #bbb;
+ background-color: #fafafa;
+ cursor: not-allowed;
+}
+
+.network-type-wrapper-controls span[type="text"] {
+ padding: 0 10px;
+}
+
+.bridge-option-column {
+ display: inline-block;
+ vertical-align: middle;
+}
+
+.bridge-option-column label {
+ margin-left: 42px;
+}
+
+.network-type-wrapper-controls {
+ width: 80px;
+ display: inline-block;
+ vertical-align: top;
+ padding: 5px 5px 5px 22px;
+}
+
+#enableVlan {
+ margin-left: 42px;
+ vertical-align: middle;
+}
+
+#labelEnableVlan {
+ vertical-align: middle;
+}
+
+#labelNetworkVlanID {
+ margin-left: 42px;
+ vertical-align: middle;
+ display: none;
+}
+
+#networkVlanID {
+ width: 80px;
+ vertical-align: middle;
+ display: none;
+}
+
+.network-config .input-hint-icon {
+ margin: -1px 1px 0 0;
+ display: inline-block;
+}
+
+.network-config .input-hint {
+ margin-top: 3px;
+}
+
+.network-config .input-hint-text {
+ color: #999999;
+ font-weight: lighter;
+ font-size: 12px;
+}
+
+.ui-state-default a {
+ color: #212121;
+}
+
+#networkConfig {
+ padding-left: 30px;
+}
diff --git a/src/wok/plugins/kimchi/ui/css/theme-default/report-add.css
b/src/wok/plugins/kimchi/ui/css/theme-default/report-add.css
new file mode 100644
index 0000000..8020182
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/css/theme-default/report-add.css
@@ -0,0 +1,37 @@
+/*
+ * Project Kimchi
+ *
+ * Copyright IBM, Corp. 2013-2015
+ *
+ * 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.
+ */
+#report-add-window {
+ height: 300px;
+ width: 400px;
+}
+
+#report-add-window .field {
+ font-size: 12px;
+}
+
+#report-name-textbox {
+ margin: 0;
+ width: 100%;
+}
+
+.info-add-debug-report {
+ font-size: 12px;
+ color: #999999;
+ font-weight: lighter;
+ font-family: 'Helvetica Neue', Helvetica, Arial;
+}
\ No newline at end of file
diff --git a/src/wok/plugins/kimchi/ui/css/theme-default/report-rename.css
b/src/wok/plugins/kimchi/ui/css/theme-default/report-rename.css
new file mode 100644
index 0000000..2fb2698
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/css/theme-default/report-rename.css
@@ -0,0 +1,39 @@
+/*
+ * Project Kimchi
+ *
+ * Copyright IBM, Corp. 2014-2015
+ *
+ * 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.
+ */
+#report-rename-window {
+ height: 300px;
+ width: 400px;
+}
+
+#report-rename-window .field {
+ font-size: 12px;
+}
+
+#report-name-textbox {
+ -moz-box-sizing: border-box;
+ box-sizing: border-box;
+ margin: 0;
+ width: 100%;
+}
+
+.info-debug-report-rename {
+ font-size: 12px;
+ color: #999999;
+ font-weight: lighter;
+ font-family: 'Helvetica Neue', Helvetica, Arial;
+}
diff --git a/src/wok/plugins/kimchi/ui/css/theme-default/repository-add.css
b/src/wok/plugins/kimchi/ui/css/theme-default/repository-add.css
new file mode 100644
index 0000000..4344569
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/css/theme-default/repository-add.css
@@ -0,0 +1,42 @@
+/*
+ * Project Kimchi
+ *
+ * Copyright IBM, Corp. 2014-2015
+ *
+ * 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.
+ */
+#repository-add-window {
+ height: 500px;
+ width: 1000px;
+}
+
+#repository-add-window span.required {
+ color: red;
+ padding-left: 5px;
+ vertical-align: top;
+}
+
+#repository-add-window .textbox-wrapper input[type="text"] {
+ box-sizing: border-box;
+ width: 100%;
+}
+
+#repository-add-window .textbox-wrapper label {
+ vertical-align: middle;
+}
+
+#isMirrorLabel {
+ font-size: 14px;
+ font-weight: lighter;
+ font-family: 'Helvetica Neue', Helvetica, Arial;
+}
\ No newline at end of file
diff --git a/src/wok/plugins/kimchi/ui/css/theme-default/repository-edit.css
b/src/wok/plugins/kimchi/ui/css/theme-default/repository-edit.css
new file mode 100644
index 0000000..383a7fe
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/css/theme-default/repository-edit.css
@@ -0,0 +1,88 @@
+/*
+ * Project Kimchi
+ *
+ * Copyright IBM, Corp. 2014-2015
+ *
+ * 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.
+ */
+.yum div#repository-edit-window {
+ height: 680px;
+ width: 1000px;
+}
+
+.deb div#repository-edit-window {
+ height: 480px;
+ width: 1000px;
+}
+
+
+.repository-edit-fieldset {
+ float: left;
+ padding: 0 30px;
+ width: 95%;
+}
+
+.repository-edit-wrapper-label, .repository-edit-wrapper-controls {
+ display: inline-block;
+ height: 30px;
+ line-height: 30px;
+ font-size: 14px;
+ vertical-align: top;
+}
+
+.repository-edit-wrapper-label {
+ margin-top: 10px;
+ width: 150px;
+}
+
+.repository-edit-wrapper-controls label {
+ vertical-align: middle;
+}
+
+.repository-edit-wrapper-controls {
+ width: 100%;
+}
+
+.repository-edit-wrapper-controls input[type="text"] {
+ font-size: 16px;
+ height: 30px;
+ line-height: 30px;
+ padding: 0 10px;
+ width: 100%;
+ -moz-box-sizing: border-box;
+ box-sizing: border-box;
+ border: 1px solid #CCCCCC;
+}
+
+
+.repository-edit-wrapper-controls input[type="text"][readonly] {
+ color: #bbb;
+ background-color: #fafafa;
+}
+
+
+.repository-edit-wrapper-controls input[type="text"][disabled] {
+ color: #bbb;
+ background-color: #fafafa;
+ cursor: not-allowed;
+}
+
+
+.deb .yum{
+ display: none;
+}
+
+
+.yum .deb{
+ display: none;
+}
diff --git a/src/wok/plugins/kimchi/ui/css/theme-default/storage.css
b/src/wok/plugins/kimchi/ui/css/theme-default/storage.css
new file mode 100644
index 0000000..88447b5
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/css/theme-default/storage.css
@@ -0,0 +1,550 @@
+/*
+ * Project Kimchi
+ *
+ * Copyright IBM, Corp. 2013-2015
+ *
+ * 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.
+ */
+/* STORAGE */
+.storage {
+ margin: 5px;
+}
+
+
+.storage .grid-control {
+ height: 40px;
+ padding: 5px 0;
+}
+
+.storage .grid-control .filter {
+ width: 300px;
+ padding: 5px;
+ float: right;
+}
+
+.storage-allocate-padding-user {
+ padding-right: 108px;
+}
+
+.usage {
+ float: right;
+ margin-right: 30px;
+}
+
+.list-storage .storage-li>.guest-tile {
+ text-align: center;
+ vertical-align: middle;
+}
+
+.list-storage .subtitle {
+ color: #666;
+ font-size: 13px;
+ text-align: center;
+ line-height: 10px;
+ font-weight: bold;
+}
+
+.list-storage .tile .imgload {
+ display: none;
+ max-height: 110px;
+ max-width: 170px;
+ height: auto;
+ width: auto;
+}
+
+.list-storage .tile .imgactive {
+ max-height: 110px;
+ max-width: 170px;
+ height: auto;
+ width: auto;
+}
+
+.storage-volum {
+ height: 40px;
+ width: 186px;
+ display: table-cell;
+ vertical-align: top;
+ position: relative;
+ border-left: 1px solid #ccc;
+ border-right: 1px solid #fff;
+}
+
+.storage-name {
+ width: 15%;
+}
+
+.storage-state {
+ width: 10%;
+}
+
+.storage-type {
+ width: 10%;
+}
+
+.storage-capacity {
+ width: 10%;
+}
+
+.storage-allocate {
+ width: 10%;
+}
+
+.storage-location {
+ width: 30%;
+}
+
+.storage-button {
+ width: 9%;
+}
+
+.handle {
+ width: 2%;
+}
+
+.status-dot {
+ background: #72AA00;
+ background: linear-gradient(to bottom, #BFD255 0%, #8EB92A 50%,
+ #72AA00 51%, #9ECB2D 100%) repeat scroll 0 0 transparent;
+ border: 1px solid #72AA00;
+ border-radius: 13px;
+ box-shadow: 3px 3px 3px #FFFFFF, -3px -3px 3px #DDDDDD;
+ height: 13px;
+ width: 13px;
+ margin-left: 10px;
+}
+
+.toolable {
+ position: relative;
+}
+
+.toolable .tooltip {
+ display: none;
+ border: 2px solid #0B6BAD;
+ background: #fff;
+ padding: 6px;
+ position: absolute;
+ color: #666666;
+ font-weight: bold;
+ font-size: 11px;
+ -webkit-border-radius: 5px;
+ -moz-border-radius: 5px;
+ border-radius: 5px;
+ z-index: 100;
+ top: -300%;
+ left: -140%;
+ white-space: nowrap;
+}
+
+.toolable:hover .tooltip {
+ display: block;
+}
+
+.toolable .tooltip:after {
+ -moz-border-bottom-colors: none;
+ -moz-border-left-colors: none;
+ -moz-border-right-colors: none;
+ -moz-border-top-colors: none;
+ border-color: #fff transparent transparent;
+ border-image: none;
+ border-style: solid;
+ border-width: 7px;
+ content: "";
+ display: block;
+ left: 15px;
+ position: absolute;
+ bottom: -14px;
+}
+
+.toolable .tooltip:before {
+ -moz-border-bottom-colors: none;
+ -moz-border-left-colors: none;
+ -moz-border-right-colors: none;
+ -moz-border-top-colors: none;
+ border-color: #0B6BAD transparent transparent;
+ border-image: none;
+ border-style: solid;
+ border-width: 8px;
+ content: "";
+ display: block;
+ left: 14px;
+ position: absolute;
+ bottom: -18px;
+}
+
+.inactive {
+ background: #E80501;
+ background: linear-gradient(to bottom, #E88692 0%, #E84845 50%,
+ #E80501 51%, #E84845 100%) repeat scroll 0 0 transparent;
+ border: 1px solid #FF340C;
+}
+
+.storage-volumes {
+ width: 90px;
+}
+
+.storage-actions {
+ width: 125px;
+}
+
+.storage-action {
+ width: 70px;
+}
+
+.detail-view-icon {
+ background: url(../images/large_details_icon.png) no-repeat center
+ center;
+ height: 30px;
+ width: 42px;
+}
+
+.volumes {
+ background: #73716F;
+ width: 1004px;
+ display: none;
+ margin-top: 10px;
+ border: 1px solid rgb(204, 204, 204);
+}
+
+.volumeslist {
+ padding: 7px;
+ max-height: 272px;
+ min-height: 136px;
+ overflow: auto;
+ color: #ffffff;
+}
+
+.volumes>.footer {
+ height: 48px;
+ z-index: 100;
+ box-shadow: 0 -1px 1px rgba(0, 0, 0, 0.15);
+}
+
+.volume-title {
+ float: left;
+ padding: 4px;
+ margin-bottom: 5px;
+ width: 130px;
+}
+
+.pool-empty {
+ text-align:center;
+ line-height:136px;
+}
+.volume-title>.volume-name {
+ font-size: 14px;
+ font-weight: normal;
+ padding-bottom: 5px;
+ max-width: 120px;
+ overflow: hidden;
+ text-overflow: ellipsis;
+ white-space: nowrap;
+}
+
+.volume-box {
+ border-radius: 8px;
+ background: white;
+ color: #666666;
+ float: left;
+ height: 100px;
+ margin: 7px;
+ padding: 10px;
+ width: 205px;
+ border: 1px solid rgb(204, 204, 204);
+}
+
+.volume-box .volume-state {
+ font-size: 75%;
+}
+
+.volume-box .label {
+ color: white;
+ font-weight: bold;
+ padding: 1px 5px;
+ text-shadow: none;
+}
+
+.volume-box .used {
+ background-color: #FF7121;
+ border-radius: 5px 5px 5px 5px;
+}
+
+.volume-box .free {
+ background: none repeat scroll 0 0 #72AA00;
+ border-radius: 5px 5px 5px 5px;
+}
+
+.volume-setting {
+ float: right;
+ padding: 5px;
+}
+
+.volume-setting>* {
+ height: 16px;
+ width: 16px;
+ border: none;
+ float: left;
+ padding: 2px;
+ cursor: pointer;
+}
+
+.field>select {
+ height: 30px;
+ width: 160px;
+ font-size: 14px;
+ padding-left: 8px;
+}
+
+.clear {
+ clear: both;
+}
+
+.volume-text {
+ color: #999999;
+ float: left;
+ font-size: 10px;
+ font-weight: bold;
+ height: 18px;
+ line-height: 18px;
+ width: 142px;
+ max-width: 85px;
+ overflow: hidden;
+ text-overflow: ellipsis;
+}
+
+.volume-textquota {
+ color: #999999;
+ float: left;
+ font-size: 10px;
+ font-weight: bold;
+ height: 18px;
+ line-height: 18px;
+ width: 142px;
+ max-width: 95px;
+ overflow: hidden;
+ text-overflow: ellipsis;
+}
+
+.volume-type-position {
+ display: inline;
+ padding-right: 5px;
+ clear: both;
+ width: 90px;
+ border-right: 1px solid #999;
+ float: left;
+ white-space: nowrap;
+}
+
+.volume-quota-position {
+ display: inline;
+ width: 90px;
+ padding-left: 5px;
+ float: left;
+ border-left: 1px solid #eee;
+ white-space: nowrap;
+}
+
+.list-storage .storage-li[data-stat="active"]>.handle>.arrow-down {
+ background: url(../images/theme-default/arrow-down.png) no-repeat center
+ center;
+ height: 18px;
+ width: 18px;
+}
+
+.list-storage .storage-li[data-stat="inactive"]>.handle>.arrow-down {
+ background: url(../images/theme-default/arrow-down-disable.png) no-repeat
+ center center;
+ height: 18px;
+ width: 18px;
+}
+
+.arrow-up {
+ background: url(../images/theme-default/arrow-up.png) no-repeat center
+ center;
+ height: 18px;
+ width: 18px;
+}
+
+.storage-icon {
+ border: 1px solid #CCCCCC;
+ border-radius: 8px 8px 8px 8px;
+ height: 40px;
+ width: 40px;
+ margin: 0 10px 10px 0;
+ float: left;
+ display: inline;
+}
+
+.volume-default {
+ background: url(../images/theme-default/icon-volume-default.png)
+ no-repeat center center;
+}
+
+.icon-raw {
+ background: url(../images/theme-default/icon-raw.png) no-repeat center
+ center;
+}
+
+.icon-qcow2 {
+ background: url(../images/theme-default/icon-qcow2.png) no-repeat center
+ center;
+}
+
+.icon-iso {
+ background: url(../images/theme-default/icon-iso.png) no-repeat center
+ center;
+}
+
+.host-partition {
+ padding-left:13px;
+}
+
+.host-partition>div {
+ font-size: 13px;
+ height: 18px;
+ padding: 10px;
+ color: #666;
+ float: left;
+ max-width: 200px;
+ overflow: hidden;
+ text-overflow: ellipsis;
+ font-weight: bold;
+ line-height: 18px;
+ white-space: nowrap;
+}
+
+.storage-type-wrapper-controls {
+ width: 300px;
+ display: inline-block;
+ vertical-align: top;
+ padding: 5px 5px 5px 22px;
+}
+
+.storage-type-wrapper-controls input[type="text"] {
+ height: 38px;
+ line-height: 38px;
+ background: #fff;
+ -webkit-border-radius: 5px;
+ border-radius: 5px;
+ box-shadow: 2px 2px 2px #eee inset;
+ border-top: 1px solid #bbb;
+ border-left: 1px solid #bbb;
+ padding: 0 10px;
+ margin-top: 5px;
+ width: 250px;
+}
+
+.storage-type-wrapper-controls > .dropdown {
+ margin: 5px 0 0 1px;
+ width: 200px;
+}
+
+.storage-type-wrapper-controls input[type="text"][disabled] {
+ color: #bbb;
+ background-color: #fafafa;
+ cursor: not-allowed;
+}
+
+.storage-add-input-width {
+ width: 285px;
+}
+
+.form-section .storage-field {
+ overflow: visible;
+}
+
+.storage-base-input-width {
+ width: 300px;
+}
+
+.storage-window {
+ width: 600px;
+ height: 700px;
+}
+
+.storage-port-width {
+ width:40px;
+}
+
+.storage-auth-width {
+ width: 150px;
+}
+
+.storage-window .form-section .field {
+ overflow: visible;
+}
+
+#pool-loading {
+ margin: 10px 15px;
+ background: #C0C0C0 url(../images/theme-default/loading.gif) 7px
+ center no-repeat;
+ padding: 0 20px 0 26px;
+}
+
+.storage-admin .filter-select {
+ display: inline-block;
+ position: relative;
+}
+
+#iscsiportId, .storage-admin .filter-select input {
+ border: 1px solid #CCCCCC;
+ border-radius: 1px;
+ font-size: 14px;
+ padding: 3px 3px 3px 10px;
+ height: 30px;
+}
+
+.storage-admin .filter-select input::-ms-clear {
+ display: none;
+}
+
+#iSCSIServer input {
+ width: 410px;
+}
+
+#iscsiportId {
+ width: 60px;
+}
+
+#iSCSITarget input {
+ width: 493px;
+}
+
+/* Progress bar */
+.volume-progress {
+ clear: both;
+ width: 140px;
+}
+
+.volume-progress .progress-bar-outer {
+ background: #ccc;
+ height: 4px;
+ overflow: hidden;
+ width: 100%;
+}
+
+.volume-progress .progress-bar-inner {
+ background: #090;
+ height: 100%;
+ width: 0%;
+}
+
+.volume-progress .progress-label {
+ color: #999;
+ font-size: 10px;
+ line-height: 16px;
+}
+
+.volume-progress .progress-transferred {
+ float: right;
+}
+/* End of Progress bar */
diff --git a/src/wok/plugins/kimchi/ui/css/theme-default/storagepool-add-volume.css
b/src/wok/plugins/kimchi/ui/css/theme-default/storagepool-add-volume.css
new file mode 100644
index 0000000..6e8a551
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/css/theme-default/storagepool-add-volume.css
@@ -0,0 +1,36 @@
+/*
+ * Project Kimchi
+ *
+ * Copyright IBM, Corp. 2014
+ *
+ * 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.
+ */
+#sp-add-volume-window {
+ height: 400px;
+ width: 500px;
+}
+
+#sp-add-volume-window .textbox-wrapper input[type="text"] {
+ box-sizing: border-box;
+ width: 100%;
+}
+
+#sp-add-volume-window .textbox-wrapper label {
+ vertical-align: middle;
+}
+
+#sp-add-volume-window input[type="text"][disabled] {
+ color: #bbb;
+ background-color: #fafafa;
+ cursor: not-allowed;
+}
diff --git a/src/wok/plugins/kimchi/ui/css/theme-default/template-edit.css
b/src/wok/plugins/kimchi/ui/css/theme-default/template-edit.css
new file mode 100644
index 0000000..7c93117
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/css/theme-default/template-edit.css
@@ -0,0 +1,175 @@
+/*
+ * Project Kimchi
+ *
+ * Copyright IBM, Corp. 2013-2015
+ *
+ * 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.
+ */
+#template-edit-window {
+ font-size: 13px;
+ height: 500px;
+ width: 800px;
+}
+
+#edit-template-tabs {
+ background: none repeat scroll 0 0 transparent;
+ border: medium none;
+ height: 100%;
+ padding: 0;
+}
+
+#edit-template-tabs .form-template-inline-wrapper {
+ display: inline-block;
+ vertical-align: top;
+}
+
+.template-edit-wrapper-label {
+ vertical-align: top;
+ min-width: 100px;
+ height: 35px;
+ line-height: 35px;
+ margin: 7px 0 8px;
+}
+
+.template-edit-wrapper-controls {
+ vertical-align: top;
+ width: 400px;
+}
+
+.template-edit-wrapper-controls input[type="text"] {
+ height: 38px;
+ line-height: 38px;
+ background: #fff;
+ -webkit-border-radius: 5px;
+ border-radius: 5px;
+ box-shadow: 2px 2px 2px #eee inset;
+ box-sizing: border-box;
+ -moz-box-sizing: border-box;
+ -webkit-box-sizing: border-box;
+ border-top: 1px solid #bbb;
+ border-left: 1px solid #bbb;
+ padding: 0 10px;
+ margin-top: 5px;
+ width: 100%;
+}
+
+.template-edit-wrapper-controls > .dropdown {
+ margin: 5px 0 0 1px;
+ width: 372px;
+}
+
+.template-edit-wrapper-controls input[type="text"][disabled] {
+ color: #bbb;
+ background-color: #fafafa;
+ cursor: not-allowed;
+}
+
+#edit-template-tabs .template-tab-header {
+ margin-bottom: 8px;
+ padding-bottom: 2px;
+ font-weight: bold;
+ border-bottom: 1px solid #999999;
+ overflow: hidden;
+}
+
+#edit-template-tabs .template-tab-header .action-area {
+ float: right;
+ height: 20px;
+ width: 20px;
+}
+
+#edit-template-tabs .template-interface-cell {
+ display: inline-block;
+ width: 250px;
+}
+
+#edit-template-tabs .template-storage-cell{
+ display: inline-block;
+ width: 180px;
+}
+
+#edit-template-tabs .template-storage-cell label {
+ height: 25px;
+ padding: 2px;
+ border: 1px;
+}
+
+#form-template-storage .template-tab-body select {
+ width: 140px;
+}
+
+#form-template-storage .template-tab-body input {
+ width: 56px;
+ height: 17px;
+}
+
+#form-template-storage .template-tab-body .template-storage-name {
+ width: 170px;
+}
+
+#form-template-storage .template-tab-body .template-storage-disk-format {
+ width: 160px;
+}
+
+#edit-template-tabs .template-tab-body input[readonly] {
+ background: none repeat scroll 0 0 rgba(0, 0, 0, 0);
+ border-color: transparent;
+ text-overflow: ellipsis;
+}
+
+#edit-template-tabs .template-tab-body .item {
+ height: 25px;
+}
+
+#form-template-interface .template-tab-body select {
+ width: 180px;
+}
+
+#edit-template-tabs .template-tab-body .action-area {
+ float: right;
+}
+
+#edit-template-tabs .template-tab-body .action-area button {
+ width: 20px;
+ height: 20px;
+}
+
+#edit-template-tabs .hide {
+ display: none;
+}
+
+#form-template-processor select,
+#form-template-processor input[type="text"] {
+ margin-left: 10px;
+}
+
+#form-template-processor input[type="checkbox"] {
+ margin-right: 5px;
+}
+
+#form-template-processor .manual {
+ margin-top: 10px;
+ margin-left: -3px;
+}
+
+#form-template-processor .topology {
+ margin: 10px 30px;
+}
+
+#form-template-processor .topology div {
+ margin-bottom: 10px;
+}
+
+#form-template-processor .topology select {
+ width: 80px;
+}
diff --git a/src/wok/plugins/kimchi/ui/css/theme-default/template.css
b/src/wok/plugins/kimchi/ui/css/theme-default/template.css
new file mode 100644
index 0000000..27fe404
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/css/theme-default/template.css
@@ -0,0 +1,85 @@
+/*
+ * Project Kimchi
+ *
+ * Copyright IBM, Corp. 2013-2014
+ *
+ * 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.
+ */
+.tile-template>li>label:hover .summary {
+ opacity: 0.1;
+}
+
+.tile-template>li>label:hover .list-info {
+ top: 0;
+}
+
+.tile-template .summary {
+ -webkit-transition: opacity 0.25s;
+ -moz-transition: opacity 0.25s;
+ transition: opacity 0.25s;
+}
+
+.tile-template .list-info {
+ -webkit-transition: top 0.25s;
+ -moz-transition: top 0.25s;
+ transition: top 0.25s;
+ position: absolute;
+ top: 100%;
+ width: 100%;
+}
+
+.tile-template .list-info>li {
+ border-bottom: 1px dotted #ccc;
+ padding: 5px;
+ font-size: 12px;
+ line-height: 20px;
+ overflow: hidden;
+ width: 96%;
+}
+
+.tile-template .list-info>li>label {
+ display: inline-block;
+ color: #111;
+ width: auto;
+ text-align: left;
+ cursor: pointer;
+}
+
+.tile-template .list-info>li>span {
+ float: right;
+ color: #444693;
+ width: auto;
+ text-align: right;
+}
+
+.os-icon {
+ text-align: center;
+}
+
+.os-icon .title {
+ display: block;
+ font-size: 14px;
+ margin-bottom: 5px;
+ overflow: hidden;
+ width: 260px;
+ word-break: break-all;
+ word-wrap: break-word;
+ height: 50px;
+ line-height: 25px;
+}
+
+.os-icon img {
+ margin-top: 7px;
+ width: 64px;
+ height: 64px;
+}
diff --git a/src/wok/plugins/kimchi/ui/css/theme-default/template_add.css
b/src/wok/plugins/kimchi/ui/css/theme-default/template_add.css
new file mode 100644
index 0000000..f1e28c5
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/css/theme-default/template_add.css
@@ -0,0 +1,317 @@
+/*
+ * Project Kimchi
+ *
+ * Copyright IBM, Corp. 2013-2015
+ *
+ * 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.
+ */
+.page-list {
+ position: absolute;
+ left: 0;
+ right: 0;
+ top: 0;
+ bottom: 0;
+ overflow: hidden;
+}
+
+.page {
+ position: absolute;
+ left: 100%;
+ width: 100%;
+ height: 100%;
+ overflow: auto;
+}
+
+.page>header {
+ position: relative;
+ overflow: hidden;
+}
+
+.button-group {
+ margin-left: 5px;
+}
+
+.back {
+ float: left; display : block;
+ width: 50px;
+ height: 52px;
+ background: url(../images/theme-default/icon-back.png) center
+ center no-repeat;
+ cursor: pointer;
+ display: block;
+}
+
+.step-title {
+ color: #333;
+ font-size: 18px;
+ font-weight: normal;
+ padding: 15px 10px;
+}
+
+.step-choose>li>a {
+ display: block;
+ margin: 0 10px 10px;
+ padding: 20px 10px 20px 65px;
+ border: 2px solid #ccc;
+ background: url(../images/theme-default/icon-local.png) 15px
+ center no-repeat;
+ cursor: pointer;
+}
+
+.step-choose>li>a.local {
+ background-image: url(../images/theme-default/icon-local.png);
+}
+
+.step-choose>li>a.remote {
+ background-image: url(../images/theme-default/icon-remote.png);
+}
+
+.step-choose>li>a:HOVER {
+ border: 2px solid #06C;
+}
+
+.step-subtitle {
+ font-size: 16px;
+ height: 48px;
+ line-height: 48px;
+ color: #06C;
+ margin: 0 10px;
+ font-weight: bold;
+ text-shadow: -1px -1px 1px #eaeaea, 1px 1px 1px #fff;
+}
+
+.custom-iso-field {
+ position: relative;
+ padding: 0 10px 10px;
+}
+
+.custom-iso-field>.input-wrapper {
+ margin-right: 110px;
+}
+
+.custom-iso-field>.input-wrapper>input.text {
+ padding: 10px;
+ color: #333;
+ font-size: 13px;
+ background: #fff;
+ -webkit-border-radius: 5px;
+ -moz-border-radius: 5px;
+ border-radius: 5px;
+ box-shadow: 2px 2px 2px #eee inset;
+ border-top: 1px solid #bbb;
+ border-left: 1px solid #bbb;
+ width: 100%;
+}
+
+.custom-iso-field>button {
+ position: absolute;
+ top: -6px;
+ right: 8px;
+}
+
+.iso-field .button-field {
+ padding: 0 20px;
+ text-align: right;
+}
+
+.check-all {
+ display: inline-block;
+ position: relative;
+ height: 38px;
+ line-height: 38px;
+ margin: 5px;
+ font-size: 13px;
+}
+
+.check-all input {
+ margin: 0 5px 0 0;
+}
+
+.box {
+ background: #ffffff;
+ background: -moz-linear-gradient(top, #ffffff 0%, #e5e5e5 100%);
+ background: -webkit-gradient(linear, left top, left bottom,
+ color-stop(0%, #ffffff), color-stop(100%, #e5e5e5));
+ background: -webkit-linear-gradient(top, #ffffff 0%, #e5e5e5 100%);
+ background: -o-linear-gradient(top, #ffffff 0%, #e5e5e5 100%);
+ background: -ms-linear-gradient(top, #ffffff 0%, #e5e5e5 100%);
+ background: linear-gradient(to bottom, #ffffff 0%, #e5e5e5 100%);
+ filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffff',
+ endColorstr='#e5e5e5', GradientType=0);
+ border: 1px solid #ccc;
+ color: #333;
+ text-shadow: -1px -1px 1px #ccc, 1px 1px 1px #fff;
+ -webkit-border-radius: 8px;
+ -moz-border-radius: 8px;
+ border-radius: 8px;
+}
+
+.box:HOVER {
+ border: 1px solid #aaa;
+ -webkit-box-shadow: #bbb 0px 0px 5px;
+ box-shadow: #bbb 0px 0px 5px;
+}
+
+.box-iso {
+ padding: 10px;
+ margin: 5px;
+ overflow: hidden;
+}
+
+.iso-icon {
+ float: left;
+ width: 58px;
+ height: 58px;
+ margin: 0 5px 0 0;
+ border: 1px solid #CCCCCC;
+ border-radius: 8px;
+ background: url(../images/icon-vm.png) center center no-repeat;
+ background-size: 58px;
+}
+
+.iso-icon.centos {
+ background-image: url(../images/icon-centos.png);
+}
+
+.iso-icon.debian {
+ background-image: url(../images/icon-debian.png);
+}
+
+.iso-icon.fedora {
+ background-image: url(../images/icon-fedora.png);
+}
+
+.iso-icon.opensuse {
+ background-image: url(../images/icon-opensuse.png);
+}
+
+.iso-icon.ubuntu {
+ background-image: url(../images/icon-ubuntu.png);
+}
+
+.iso-icon.gentoo {
+ background-image: url(../images/icon-gentoo.png);
+}
+
+.list-iso {
+ overflow: hidden;
+ margin: 5px;
+}
+
+.list-iso li {
+ float: left;
+ width: 320px;
+}
+
+.list-iso>li>label {
+ display: block;
+ cursor: pointer;
+}
+
+.list-iso>li>label>input[type="checkbox"] {
+ display: none;
+}
+
+.list-iso>li>label>input[type="checkbox"]:CHECKED+.box-iso {
+ border: 1px solid rgb(11, 107, 173);
+ -webkit-box-shadow: rgb(11, 107, 173) 0px 0px 4px;
+ box-shadow: rgb(11, 107, 173) 0px 0px 4px;
+}
+
+.iso-title {
+ margin: 0;
+ display: block;
+ position: relative;
+ height: 23px;
+ line-height: 23px;
+ font-size: 14px;
+ font-weight: normal;
+ max-width: 100%;
+ overflow: hidden;
+ text-overflow: ellipsis;
+ white-space: nowrap;
+}
+
+.iso-title>label>input {
+ display: block;
+ position: absolute;
+ top: 0;
+ right: 2px;
+}
+
+.iso-info {
+ margin-top: 5px;
+ overflow: hidden;
+}
+
+.iso-info-col {
+ float: left;
+ width: 50%;
+ -moz-box-sizing: border-box;
+ box-sizing: border-box;
+ padding: 0 0 0 5px;
+}
+
+.iso-info-col:FIRST-CHILD {
+ padding: 0 5px 0 0;
+ border-right: 1px solid #999;
+}
+
+.iso-info-item {
+ font-weight: bold;
+ color: #999;
+ font-size: 11px;
+ line-height: 18px;
+ max-width: 106px;
+ overflow: hidden;
+ text-overflow: ellipsis;
+ white-space: nowrap;
+}
+
+#iso-search {
+ margin: 10px 15px;
+}
+
+#iso-search-loading {
+ margin: 10px 15px;
+ background: #C0C0C0 url(../images/theme-default/loading.gif) 7px
+ center no-repeat;
+ padding: 0 20px 0 26px;
+}
+
+#iso-more-loading {
+ background: #C0C0C0 url(../images/theme-default/loading.gif) 7px
+ center no-repeat;
+ padding: 0 20px 0 26px;
+}
+
+#vm-image-local-box .body {
+ margin: 30px 0 0 26px;
+}
+
+#vm-image-local-box .body input {
+ background: none repeat scroll 0 0 #FFFFFF;
+ border-left: 1px solid #BBBBBB;
+ border-radius: 5px 5px 5px 5px;
+ border-top: 1px solid #BBBBBB;
+ box-shadow: 2px 2px 2px #EEEEEE inset;
+ color: #333333;
+ font-size: 13px;
+ padding: 10px;
+ margin-left: 10px;
+ width: 600px;
+}
+
+#vm-image-local-box .body button {
+ margin-left: 10px;
+}
diff --git a/src/wok/plugins/kimchi/ui/css/theme-default/template_list.css
b/src/wok/plugins/kimchi/ui/css/theme-default/template_list.css
new file mode 100644
index 0000000..3161a33
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/css/theme-default/template_list.css
@@ -0,0 +1,267 @@
+/*
+* Project Kimchi
+*
+* Copyright IBM, Corp. 2013-2014
+*
+* 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.
+*/
+.list-template.framework {
+ float: left;
+ clear: both;
+}
+
+.template-box {
+ border-radius: 8px 8px 8px 8px;
+ box-shadow: none;
+ color: #666666;
+ float: left;
+ height: auto;
+ margin: 10px 11px 10px 0;
+ padding: 10px;
+ width: 308px;
+}
+
+.template-title {
+ font-size: 16px;
+ height: 25px;
+ line-height: 25px;
+}
+
+.template-icon {
+ border: 1px solid #CCCCCC;
+ border-radius: 8px 8px 8px 8px;
+ height: 58px;
+ margin: 0 10px 10px 0;
+ width: 48px;
+}
+
+.template-icon img {
+ width: 58px;
+}
+
+.template-text {
+ color: #999999;
+ float: left;
+ font-size: 11px;
+ font-weight: bold;
+ height: 18px;
+ line-height: 18px;
+ width: 142px;
+ display: table;
+}
+
+.white-box {
+ background: #ffffff;
+ background: -moz-linear-gradient(top, #ffffff 0%, #e5e5e5 100%);
+ background: -webkit-gradient(linear, left top, left bottom,
+ color-stop(0%, #ffffff), color-stop(100%, #e5e5e5));
+ background: -webkit-linear-gradient(top, #ffffff 0%, #e5e5e5 100%);
+ background: -o-linear-gradient(top, #ffffff 0%, #e5e5e5 100%);
+ background: -ms-linear-gradient(top, #ffffff 0%, #e5e5e5 100%);
+ background: linear-gradient(to bottom, #ffffff 0%, #e5e5e5 100%);
+ filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffff',
+ endColorstr='#e5e5e5', GradientType=0);
+ border: 1px solid #CCCCCC;
+ color: #333333;
+ text-shadow: -1px -1px 1px #CCCCCC, 1px 1px 1px #FFFFFF;
+}
+
+.row-select {
+ -moz-border-bottom-colors: none;
+ -moz-border-left-colors: none;
+ -moz-border-right-colors: none;
+ -moz-border-top-colors: none;
+ background: linear-gradient(to bottom, #FFFFFF 0%, #E5E5E5 100%) repeat
+ scroll 0 0 transparent;
+ border-color: #999999 #AAAAAA #AAAAAA #999999;
+ border-image: none;
+ border-radius: 5px 5px 5px 5px;
+ border-right: 1px solid #AAAAAA;
+ border-style: solid;
+ border-width: 1px;
+ float: left;
+ font-size: 13px;
+ height: 42px;
+ line-height: 42px;
+ margin: 5px 0 0 10px;
+ padding-left: 10px;
+ text-align: left;
+ text-shadow: -1px -1px 1px #AAAAAA, 1px 1px 1px #FFFFFF;
+ width: 100px;
+}
+
+.bevel3 {
+ box-shadow: -2px -2px 2px #EAEAEA, 2px 2px 2px #FFFFFF, 3px 3px 3px white
+ inset, -3px -3px 3px rgba(0, 0, 0, 0.25) inset;
+ color: #333333;
+}
+
+.row-drop {
+ left: 10px;
+ position: relative;
+ top: 50px;
+}
+
+.template-action-hidden {
+ visibility: hidden;
+}
+
+.template-action-show {
+ visibility: visible;
+ display: block;
+}
+
+template-hidden {
+ display: none;
+}
+
+.select-drop {
+ background: none repeat scroll 0 0 #EEEEEE;
+ border: 2px solid #096AAD;
+ border-radius: 5px 5px 5px 5px;
+ box-shadow: 6px 6px 6px;
+ height: 147px;
+ left: 0;
+ position: absolute;
+ top: 8px;
+ width: 250px;
+ z-index: 2147483647;
+}
+
+.button-drop {
+ background: linear-gradient(to bottom, #EEEEEE 0%, #CCCCCC 10px, #CCCCCC
+ 96%, #A5A5A5 100%) repeat scroll 0 0 transparent;
+}
+
+.action-bevel {
+ box-shadow: -1px -1px 1px #CCCCCC, 1px 1px 1px #EEEEEE;
+}
+
+.template-border {
+ border: 1px solid rgb(204, 204, 204);
+}
+
+.template-button-position {
+ position: relative;
+ left: 250px;
+ top: 55px;
+ z-index: 5555;
+}
+
+.tempate-action-position {
+ float: right;
+ width: 83px;
+ margin: 0;
+}
+
+.template-actiontext-position {
+ width: 250px;
+ height: 160px;
+}
+
+.template-line {
+ left: 200px;
+}
+
+.template-os-position {
+ padding-right: 10px;
+ clear: both;
+ width: 142px;
+ border-right: 1px solid #999;
+ float: left;
+}
+
+.template-cpu-position {
+ border-left: 1px solid #eee;
+ padding-left: 10px;
+ float: left;
+ width: 132px;
+}
+
+.template-icon-position {
+ float: left;
+ height: 58px;
+ width: 58px;
+}
+
+.template-icon img.template-type-icon-position {
+ width: 20px;
+ height: 20px;
+ position: relative;
+ top: -15px;
+ left: 49px;
+}
+
+.template-title-position {
+ float: left;
+ width: 120px;
+}
+
+.template-results {
+ background: linear-gradient(to bottom, #FFFFFF 35px, rgba(255, 255, 255, 0)
+ 100%) repeat scroll 0 0 transparent;
+ float: left;
+ height: 60px;
+ margin-bottom: -22px;
+ padding-left: 10px;
+ width: 1014px;
+}
+
+.select-row-action {
+ background: linear-gradient(to bottom, #FFFFFF 0%, #E5E5E5 100%) repeat
+ scroll 0 0 transparent;
+ border: 1px solid #CCCCCC;
+ border-radius: 5px 5px 5px 5px;
+ float: left;
+ font-size: 13px;
+ height: 38px;
+ line-height: 38px;
+ margin: 10px 10px 0;
+ text-align: center;
+ text-shadow: -1px -1px 1px #CCCCCC, 1px 1px 1px #FFFFFF;
+ width: 230px;
+}
+
+.select-row-delete {
+ background: linear-gradient(to bottom, #FF3019 0%, #CF0404 100%) repeat
+ scroll 0 0 transparent;
+ border: 1px solid #B10F14;
+ border-radius: 5px 5px 5px 5px;
+ color: #FFFFFF;
+ float: left;
+ font-size: 13px;
+ font-weight: bold;
+ height: 38px;
+ line-height: 38px;
+ margin: 10px 10px 0;
+ text-align: center;
+ text-shadow: -1px -1px 1px #9E0505, 1px 1px 1px #FC5D4C;
+ width: 230px;
+}
+
+.template-general .title {
+ color: black;
+ font-size: 16px;
+ font-weight: normal;
+ height: 25px;
+ line-height: 25px;
+ text-shadow: -1px -1px 1px #ccc, 1px 1px 1px #fff;
+ max-width: 130px;
+ overflow: hidden;
+ text-overflow: ellipsis;
+ white-space: nowrap;
+}
+
+.processing {
+ cursor: wait;
+}
diff --git a/src/wok/plugins/kimchi/ui/images/Makefile.am
b/src/wok/plugins/kimchi/ui/images/Makefile.am
new file mode 100644
index 0000000..ca3ee6e
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/images/Makefile.am
@@ -0,0 +1,22 @@
+#
+# Kimchi
+#
+# Copyright IBM, Corp. 2013
+#
+# 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.
+
+SUBDIRS = theme-default
+
+imagedir = $(datadir)/wok/plugins/kimchi/ui/images
+
+dist_image_DATA = *.png
diff --git a/src/wok/plugins/kimchi/ui/images/icon-centos.png
b/src/wok/plugins/kimchi/ui/images/icon-centos.png
new file mode 100644
index 0000000000000000000000000000000000000000..5afb7b4b63462412d825f63542beb1f7e26b3d7f
GIT binary patch
literal 4734
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
M07*qoM6N<$f~4IfuK)l5
literal 0
HcmV?d00001
diff --git a/src/wok/plugins/kimchi/ui/images/icon-debian.png
b/src/wok/plugins/kimchi/ui/images/icon-debian.png
new file mode 100644
index 0000000000000000000000000000000000000000..ff49a39696fdfa5f232b0e79de04d90af6557111
GIT binary patch
literal 4239
zcmWldc{o(>8^+K0B4eq^STcyLC8fm@!jx?!k~OkNF}Cb}Swoa9yKG_XYqDi0W6jcx
zC0mvdLx$`|mf!0-*E#39&L4B$=e+mxx$kG*X=$o5(WB@g2x3yhC~1Rx!0Aax3$A#1
zi(YV}wNzJCf=*74%%=P}@C5!6W9SM&49uq|Y;el&5Ij8Nrlz5MW{R4FiCvo15Ud74
z2rf0Hd%9i|WRph^IbX1yXgpi!Ht!PpLl;+a!^1gV-yve$#8&Jx@#3Ynv<Eq*mI5Bt
z{erdHuKa90*RGB%#FiQfAgi@Wa9r?Ynf+eHVA)}QX-$j<ZNvj6dNq6dAahv%Me`?<
zWAh5P=Q+-8HOwKld|TF=X1r&-*Z;HXj&^=^uUj3mKTsU@lL-%UV|(yS7&2E#@1R(O
zE{v*P`mJ!C{oP}T@WVTKY&*1|)Q0QC#1QXj$;2-A%;rziL#UO*fm8R#Mb~i6N`a>k
zd^Ta7qk6*&mW;meARE^3uKMJ*X>rK3M8NH(iA-@+rnraYRaDpRUU)b4{Tu(*=8XM$
zVjkhhHeBo~pOCj;N)hS51*&guadEz9r<ZJGj#v3_Tk1?^g;BY$Qt(uJR)UtHcP61|
z!$Y3#jXqN(o_2~LK}z%Jc@mx{+?uDL<Z#!twX<(4<hZ3&pTW=F6?!#_)`@#<vlwZX
zen_8;e)4x6=gD;6-!-$<y_@<D4W}7nBtAs_qXIYb5~%acG8gnVkt?`y<FGb#svWgE
zG)}c)Yw{79-hhyU?P_xjg?WeBSG`~A)id6VfI$Nup3JvkBD4L*0Y<1MvzM_c++@vv
z&fCt!+d{R<2yU21V%+ffn&w>YpNoQTbj;}KOHu!pMdMZQ?;7!iLanAE&t4Jz!$o&9
zw7UeqU+|NoyqMEP@`9CY{F0Rrbgq?&6tR0Wo+0(X4a+6@WbvZ-PeFv`_#ykz7cbcz
zP@<dSXw*=f8+~o!;Rz_8EEKDHW&TDD&e^m%zemd1N7Y$`t~H-v=Q%<A?ap)6(a7v&
zuHLQJ2<=BL_(=+HKHGBG$zwc*_cF|s^6~Kk$#=ltDZ7K!_uS{>zfU#a{=_gNv?mTd
z^117?>;k8Ll5=n6?GzfixVzNbV$c|it*tj{<DLe81=O!IXD6zxSN?!U^1_HEsh`AA
zgte;qzB<W*61K}#SmN(V<a~yXola%Rn_sLa{L{Fgkn3Y$#Ye*@@IN%moAs%Si;)a%
zUu4O(cTWs(h4AvEZy#_|cmd9s98adXspJL?&!8UV54{Ezq;!>QZ3n}m#r;wd?=yR4
z9aWIH(!E>G9Vc}3rS)qwpJk+djpxVQsJ(8pXG&faD`!^p5im`Oq*lKh+}D_@BbjGr
zE1o&OOJ`Kdb~%!kXq;6c#|XYR&Y7lBjP(7ZSfSCp<s1FT@Q*j$>YXqZ%u>s~_e*P=
z+@Ipl@tL`LT=4RQRi_;57t`=4H7Bkv{)f*0M|*FSW;pD~jm=mf<&NO#zKXC@jkq-A
zgSF#HQo$?_eFZ=GAfM+FwPvzX{uc#QE{LLP4_%K|@NUi-OY^IA!d+2pd_}|!i6;Ac
z{`peE#oF75?^ym$-9}(dt}+%-(eqAn+||I;Y=yv=4*t>M_c6W}J9wv#djXNjG!?yn
z<YPXS=`W=H=+6i0dtN3b?sJ>noJ{*fDwHj}TFMo+vNQjtXs!Fvzr~?4-eq6yjaIk+
zO+f)c{O1cQcFj|Re$wTKo2mDSIr&{`>%64$_0an;y!)hN&}KF#IAZ8V`Gni2Mv5@e
zIn|H>(4uScIQ9kOBvJXLvtsuZSkdF7SEHGY6v0vJfX56a3TeuH6b>5bw5fMOq8sZ1
zuw`-*XE~?O`CR(epP!wG-~DU#^*h*rg0fxoJZWBn+eAZ*+Ck2L*GFwR&ErQ0Uzkd|
z-^7c1dv9zceP2kcl`5olboNpCtsd2`E^Xq+c}o0qWE}n5dn2GJLUq`NTq$z9>>hZr
z^^yM%GF9xfFiSeDL}*d!-`aiA$QbX!h-J`&tjivj4%nJJ?*jlbpmwE(&>n;47ip&7
zKk|4W67IK=*V$oQyKF8*#jFBPnE&e0h4eK}b?9$>+p>Yp2u6-6Y;L$EnL&%V_A543
zbMKrDm#?5V?P-_mi$~eti1@N~FFJc~gQv^v@^wxb@w1%I=+gbKmDNl}Z?#{Rbj-X?
zWv|NK1EhoD5)Qhc(2_B5-@RJ(Z@>R<Z~aY?#I*^z$tgA71Ew2>2Q%#d{9nnaRe68t
zQ?^WFaVjd?jTa2KU)<?vNv>_lnzDT{6{nTNpoL=6nsn$AE{cWg*^C5UJ<;aVTSqCa
zZ{D3wuX_qqS$8ad+CIV7YcTzvrkWxi;!*OQL7=HFK7Cy|mEI2Pl@G3`Lsy=I02GS(
zI*%|fD>GUsfK=<06aBr;B)+zPuf^VuzGwHkGAUAnurCU`gM7W+mMijsH<uU?wQ>F{
zmIBbI<9CJC#Hm$P@3ZrYP9S-)phPahF5wkQbbk${%2QnY%X92w$%Dm{*cT7Ac3S2>
z$_!`@O6>Y{Zrb~M0`tgm9=o78cu1NDj^L~^`J62nO6Y4Dv_TB-EeY$h7)d;AhGQ(6
zdE^EpGsN2vnSqr2rC)Tv_qO6hA{`qRk;e6(>fzDh?HBr62>A*pud1hPlZI!PTm-$C
z1kt%eW==$YgM0-Ab(NW1b(&=K2bMJG;f4rA3JK;%H%k&5Xj98FGDon5HdChcYw)Km
zMpul_58hpTDxBqt*qH?&>&#de`jN?5FH}NPkaPD99|kM`1hEUhatL;xCFxkk%*;90
z*2|9ZJm1d=b?b)|4dlZOH+}?9a}b$i*?*kUykQsIJog4N&J(dSswMFyiyf2xg*{iy
zT|gxrgt1fI=%1QLc5t^Rw6o0Ak~r`j4yoc>5Jfr6^4>=O2g1t9VR=x2YS0bV(U;^O
zUZ0^9A&DkSG~n(xRv%yvB&V})`OgnC&KA9{_$(u2s=r{nDhaG{>z<6Ni!#+m@c?C(
z@bQSDPO%76;SYIP1R|@!I9g2^ChTLYRXeJ@LY~Y{bx{A+N30**in3<sy-#r1+)2dd
zE(TfEjhQ*KJhq~`G{9`!hzPjqQQ<BZ>1Xy<en)K`Su|*(CLM40Pd?3K+Rz-Xqz+}Z
zebO!qT}L&w^`|O#?Z1`gWE`!gbsPU*;eYNH+cIBOIZ|_s(S<bFcvg@pF6VwmD(w0_
zG%d+SJRjl_k(Co|DHj43Xe?AKkPiz(3Vt%|6D~>c0TyKQDcfuvB#a%M6Jc|iBT6uv
zvXEBE<$*XS<$0!FqthntEPP})&6U^upt*NNKox4TYc=kr3javZY>=KgbWNw%|GSav
zdfwv*YhTW7BCu2THBf-i+2;z7rYo0s8<5_?zlF})pv!`>xgsjat!DNLs^+rermoFM
zd7oVC%7OvS=n9a}7UiA$Qz%dCy`Pu?-KtP5VTS9@`SZiF$vW$(8^vY2yhz4p?k=cg
zG#&f0{Qam++74<`?a}#xoxSsvXA7WRkUYO6iWTNE_PO;2oZvfWrymO=3hO6aEpd6#
zGsP_5n1c5;R@Q~<Bh7#@`{){O;b29}><j#ilZKkw*JS!*Cme&mVWl6RE0>YJ7G}5F
zq}$2j>Zk94!W3eQe6I1LsN#Dm;IpLll@|lO(=CwXpwR3;9!NV-$DIxCdAuhog-fKG
zB6i>ulRHuWv^23|@5m=%>@y#v^ZOk8ygGJkBxo$^y5$fL4&YR`VJPYp7py1Qf#1pb
zm0m=Dbp-PQ-_4b->GwU_8}d_M3R<KIg!Oh2`a69ZNdr|tf4qcRg#~+0;h1gttZt&W
z*Y^`CfX7p7H*!Payd)uwz*qc1MpAM}I>jsp#kv>I!Y+nj3sfwuVI%@Zl;k$U3p~QU
z?{4VvB4oNf!{-`vA=h=H|M^TiT>UQ)!DWesl&g)Ka@hcFRzVig)~2et!Z{2hRo@0_
z;=il$*wZ8FQ+$w%kzEX`u70BX)-I?&I+ZyCwo?8G%0aNulk~LCb3YWcjl&fuR;;Lg
zRXj6hoaYaGgn6-(u`ViHi1|`kg08y$J^78f2WT}@1=9dPx6?SMJky^Fei(#A!?lFX
zK*M{YxR{ZiPZz|pNc!$K#Y-xVsZM?zXW1u}Kbc!gD)Sx&+y(g{vF;2Y_Tv6u?uws6
z#Ezs9#*mzzM0oJ$i~-yrNiq^I6gH|M&5s85sW;H>i=Y^Z%TYj=tt9o>uJYtM%T7tX
z#hUKk^}$ZR#0^RVl}UXL!M@nJ5=jf}9A~E^T>E6q#a17`Pq$LXJwGHtSTvh2&+7f7
zB7`WD)i5S^nr%kB^N_#wwF8&PSy=?K^yIdJ(oX0)h<0W|`DzCXL&A+C*smZR-brpQ
z)KgrlQuKF4Z$J9!vibXiTfh@l{1V?yYzJA6&5o=o3#fcbnCDcN?EPEb0#}_Rc7!#(
zqB!24C)uTVMoRNTL-BTHGj;PQN|8yHUUsjnsS9Fzz-6<&G@a#Q<-$U*!7C=6EImbQ
z@@vQL>l1s>a?h_SPQo2~0+)#hD65C@1E6NYPqcH%wcVv(q-_Vu3!VDnrrPWvSK4q%
zy8XOpD-!pe6IS%URrG3oW~^6EsGRs#$d(F}XOlU+d|pKTayBB3HMnZWwCsR86>I|M
zZHAo2LuNim%NJhRX<_Hp6c9m+KrdAp?9k_R`h7U()OqZi3^CdeZ4--<d%u7z4BTvS
z=<kF5LOzIlQ7;?jmz<U;5x@d}S<?_#5JC-tEsjgveWEoSUbf3*kxPW0&K0iG=2*e7
zM5>*$kE1WSP(kRfeN4w&UL@V?_lEVil+Xce>CX#$We4_?fr?JmZOx2{hFX7hS3V&3
zfzhcVD8@=$8W!;Flly9=&%RbjH~e%CD~RVab$--igf60n0?ZyAC!3?}t1<>GZMU1j
z8y`Tkf5#>B3TDYZ2xEn=>xxR$r*oQa7`^^aoxmE$Ug}v65X)}oy?bx`y5tP%ZAiYw
zG7SC@`FW@89!O(vYXWqIpfdsmZUzKw^(+Xlw_rI7R5n#4adm^k_ZO5c_|M$^MvZ_R
znv&o;L_$a$j&OB7S{Dv+Md?f2jyAuFQnfsE9jC`6KyFs8N`cjd;~|f@;*>L?%NG{}
z81Oolu%c?}D)rfw5ql24N=SUVkES5^7P5MCi`sHsEFRuURfmZXk<t;H;Rce9T^Wjl
zM~7l>g+S)X-n{j7vK6$m5CGs{DADOO1&@CxWSdxF2voy31`xPJUC%8zKD%NV;FAX2
z;Ky%i*SdqYhrAIsdpFdU82muK?2!s%u7ElyfvkJFhIXJxv~{()R7^WaIaUt55>y1L
zoBqS8T-QI|q9Tj|*cQhPMSKeG6^On8D-sM8Wfs&7@ZkeV6Xel0cqEucPp3Tt4z*;c
zBkS49vL~kh3_~~iz4OSJcX0~sbtIb4s+$(yP2DCuy_6gJq{ir)mI?XwH*CzRR=19N
zfF&XK`BUPZvth;^U!R|CcqdUnmK-<fj=rQgx6k9!#KIbd#ejbfAV^JFQ>pB}dEoy6
D^V29c
literal 0
HcmV?d00001
diff --git a/src/wok/plugins/kimchi/ui/images/icon-fedora.png
b/src/wok/plugins/kimchi/ui/images/icon-fedora.png
new file mode 100644
index 0000000000000000000000000000000000000000..7b9dd06d1f766a3285cd0fb587c0be4114bfac47
GIT binary patch
literal 4449
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
S9$oyI0D9VncWN{pBmW0TFKp8Q
literal 0
HcmV?d00001
diff --git a/src/wok/plugins/kimchi/ui/images/icon-gentoo.png
b/src/wok/plugins/kimchi/ui/images/icon-gentoo.png
new file mode 100644
index 0000000000000000000000000000000000000000..50d928fbfa30560fe873cf3de438a8f0c10a8f96
GIT binary patch
literal 15307
zcmV;+J2b?JP)<h;3K|Lk000e1NJLTq004jh004jp1^@s6!#-il00006VoOIv0RI60
z0RN!9r;`8x010qNS#tmY4#NNd4#NS*Z>VGd000McNliru-3uHIHU<90ip~H4AOJ~3
zK~#9!?Y(!HWLJ6T|2gNz%ALEXyQgPHqfrJ4fh3R+AhPZC+K<Do?Z^IMOmYC5j7{*8
z!5F+?ytYXO2X?VY0)d1C5?}*X0%eUfGa60qo}P}CZanAw{;2An>guYV9!V1bo#(lI
zL*1&by6^YA`F)Qt#t5DmKexmFss9BA5Fmsw>$?33z^@qMr|^LoAq2)4zJKHPV!fvG
z8io+^QmuKC)@(Ie3;-p8Fh+=~6ymUuJS?TSUnzZyZCgitUsRs=;;ogRcToJ)0ATh=
znfvZK<iv@(FsP?*ier8=iX}=}Xd^K+HV|M0AVIA7r3gR@gC)VX44!AOEIy-2KGfe=
zc;w2fHl$!Z0f5uy%Qe~h_1E0_`dUrDGYqXvYHV9+8`C7Zv}~kwK!^tM5eRW~FN8!|
z&HF3~fQlpHC_w8JDZsWgj%5<xH#3%_|M-`Gb=x(@7+49RCjf9V3IFYH-tnUHg85hw
z*;|v;v6ZngSYRZ=vXRopvTTH~5W+%Q65qFQ9f4&D3<9kUNur4&O&lwX(M_cRgk|A4
zHqy38qlhT1Auu?W!L?P8$#9>W(XV*%FK)g2XIVs?P5>}M2)_BHTmQ0Bldp^uXDrbU
z#yB8sq~%~)F4A%-7F-6097;tC#}QbzKnl>hZ8Kn+$4Wtx8sgXx)KeB06RNcsgFy<g
zYzJvc(j+2{L!{8Sj=^{Jo=jH!!!P{urVsrr>I<g@0E7_c+ArSn)_P#QEr^_~G9KU{
zEC<W-a2%iEVV{u=4!u1R*M(GpRx63E^-+Rr4a%%MU)qdmY$}CnEu~UPD3?RDHb_fi
zSr*1<(j)|}aBNM+H<6#=V<QvJJD+;dhTvxf2&WVP4Z{D|Z-$}xw_4!33Lk`vB|U7{
zr&P)@G2yXkv&69>O*<1)H3_d;uj`}Nbr%pUAJf<`EW}hQ3H5pm7%baHU`W#ljKY?R
zY}SzR#e4floWH*8(vfnKXkpvp2>`5j#8HChyXLyD{BT<sitDO1=gd_57~x~t9<G;T
zpg+gi=Xh+~2uX63Sgk}`p5+>hI?4f-LD0NrRD%<A1VJ13(7N#*!%#Cj7ZTKCwAM(=
zLI_Z41V-anid@FvXT@uWHu#@->Qe_orL>SzJOO}Xji20pk38^5<=yqV{njw?(PWU8
zhv(-hl?puNVwVjYFc`!Vt8OR!(yVV40j;yW{WWclo~tfgpj~&Mxu2d62!aHqQiPNU
z2`Y(^LStK+Le7xM$zR*NIe+c8vkU480IV^-`lXu+Ci3@H1FxiX1|u`LUY0_k#05{v
zuyre@i?>g#B3A3HS1Yfpc7nIu+YW?oAZX<}#=!J+NDxFQt+0duDNt#I6b8@M6be)d
zz0O6KUq0~2Pm@SE;Q-KDV_BB@`qkfkU9IN*O%(fRkwMxSa`_%MY$$Ts(}l6u<CJa!
zVFkhUN)RlGge4HHxURc!4%0=UY*j3q|95saAPgI#LCA(j5}jaK2G3EHO5)xZ|I+A_
ze_E8p6AFOYBMS@+^_pw`-}in{t9e(%I*S$=JU35I?*LD`#9?>@bKD<n5bcCt0Rq)R
zaMeL1w7;*Lve+hmOjBWuW6kVrog`Hltq{^e>jWuGLs9f~+|z5l<GC*w`B1f*id@e6
z`2)bdM-GX5?zyiRSN*$dfj^O&EXWMGd@rM;Jv{9aX?*`NIu3LL2<;$f1wyMBP`ZO?
z=%7e;wHTUar7?};AV`^?570(8olIa%iY*MTqbTIrIWXk@;$_bm*mb&cgcBAGy!Xf3
z&y7O=mRgX_DUm^1If^|4oOM>7^DlT5v%V90CB|xcewAu9FOQxJv5I?ibnq%b>Z32W
zZkXn=ZiE<&24NtRvGLpji{*%VJwh9e5Dv;H!dQ|n>TOXJ@BGg7Q|}W(y#2KFx;~y?
z${2$X!hGXP-?=0V+}rA57A3OSPJzC@A<lo2$L7tC5AnO{2CZ8=S6Jo*s<ZCUNm=a1
z1(xokDJG&=vrrCDu|gTu2vHk_B@M2vDHhpZ>~*es<}>>rKAlX)#|;3+7^IZuYgd2!
z;y84FT#s@nlfm&y3=R(Rl#5-4hED+T+eE?&J)n)~t=CL*uT&S)vCY@8%>MOiAS_u5
z7+5Gr1VN0^8bd=gSORRR$YnK!qV=-py>RHCYPD2kv)0cJ0E7_c>sNp0$x-0k9mF|O
zGPrJ$p^*_Txzwho=fo1flU|@y!`-Xe6-3otKWNnlRydWGh)<g%$sAP<k6H_c`T06Z
zYqU}rG*TF(G<a4@Z?C*#cr0`Ilb>8je`Wx1-B)kAAgnp})WR%^EVf%<c*6!RyVRyw
zIyuBYYI`D<h~5f-t{`Z$9+pKxo29Vq7w8ahY6Za3d8HB&h6&nev{ncVmNeLwqL4GD
zXTW*NGoRUa,}e5@Z(DOb7fYv0`%2i86H$VZdKvU3a%k8sH)r-1m4Uu7%_mets#
z1(pQaVH54wMDw~h`g+svgA|S9<xRGow{Ac_@6l7rB89}VY(SD~L85FHE0&l(l-%{*
zn`S;IgfK~>fBHCpQX1Q~%-6nf^FpPTDJfF`nPF&ToJ%itO<(^h=5Gd(rfoC6Im?%>
z>ki^!`C11TvT2JQn6?OGyKX>Jl$0w0X`+_7fs|kgjb|&0MIIhI%Q=5TZ$9oHaDI9?
zfNfjm+N*EAvsQCU+GIg^^bd@1;f1FG@c{&8i3==kOEZ3%JIIwYe#Pu>;Q}i-0G&Ak
zOQvJXebD%fQZYj|>mh{1k~Ufkl$L~v&HSR+y7z&2=DvFuE?aMM>uCXi>%V&QKL&OC
zB4x4|;ZrE}bLO@z8%9qfJGUtgWDDV2iM{65B&6ghAi5H}g9vB`LdJI}6|zX#%sD`!
zj3iEN7AsbMao+sbcWylV>XQkAM+E>Ogt_sX-+ywwDqa<<42BGzUu5G%FK3@~3S|DV
zzOU8f1T7%ws1JzMx<RX~Z`U1`a!^GlPSASZvbP;cPbrIS*+|()XVXTIYMV;kVsSxy
z{Ko4KfA(a7;J9^wG*$fQ`?qB(b78Gq&5)Wr(k?JIKE`Fwu*qajKL9N01FbrMN*h^4
zY1-XVXx9tY+B!LkTCIcD(6*tmuht@xIBA5RjY0^pq{g*VN<HQg$4}3{>N%qUConnn
zxH*91*e0k&pQ;BA+IR@zQR?Yu+qTn__`2a25ZZvWFpi7yGniZfQ|iI=4`52Y;JQaS
zL#qz3N*@sG-=thA3YL7!ONaTaM<(kdg+NFfV;Xuvl-SJA%Pn!;t>5tN14D4)p6hXO
z0HrkFz3~T^))v$)^)QbjkLUHW?VJ%Vy7=@Vev%++HAoY%ZE(HDj0*yY!p5=VKqd>>
zEZFwZ@17)x>BA7m>+=tEOffS@Q_Wg~N3EOyjvlAVP^s3NRzt(TETzGg38ex^KY8+V
zpEG=)<H%FX0c_hcX{f#!B`z8dAwBx~``CKs=|OmvA`Tx$OihCCL;nD#rx%mWVsbf*
z$U`Whs$r%M`={WcU9fW}V)`&bD}>`<#>O!dn=qc&BKwzgfi8+4on$^O=d9KfmRNyh
z35reSP>6<tp|v2@4vQ5*T66BX`Fm5paY{Kr9L0R^+dq0)P%)pXM|m`P{OkZ1TrkMl
z=bif5A4iD&2f%Y-Y#h@X1-#>K#E<Vh%#rCC3VDZO-owviDHc5jhYPqFflwd~^b}yj
z2-t4pHw6Lg-E%Y}Nv($qw0H|wae)^9z$(2!L$w~FlxifJ7=x6$kz<h2Wb^7RFL>d|
zhqTs02yt=&AcQd2efg%TTGbtnbrB=;jE-*PvS&DCbEg&n#=t`lA+&;X&u7ICx_dj~
z>aW~KrBcSVHJOadV!2Eqo1q>Al!`^hh6fni*vHUF54HoAg5d!eY9^~_4SOCzgyAtj
zU{(i<+8soll))8%0BW^}G)<ciRX5Ao6ggj$DX4e9@P)(wD~^?TJVe5}@&RhqI^VqJ
z+b>t47}j`zjqCah4V`-80~|Vtn4N*GTUV;f`zPT){&PRo>H_(!<h*UeNU5k+Ep%#O
z$Z+sTg`eDWKfCw!ko6qSJZlpZTLw`_Y|3TC<})z14QFh{?Ae2;R+^$fbr1!nQI@!D
z`-`IhU2)FQJcDHri=)?aIgfe(Nun@DqKyF!wGe>6yy07irR!Snh@w=uu65#dfP5im
zY+=16O>K;^K{^x*J&cW?7Fs@2hoM@7$-_reyS0W-er~5wNu4vsi)`E6gI0CosEj2O
zq^KZ>I6QTTfdP*&nnw^ZH8sf>ufB=<cOGQ14i9ce#8KljH*dydvmIgrZ4Mw>0nlmz
zw21!ptdkY@1KEs+>)6Y6j@n3+wyB2}Va<B`4c|Ka0nf9IQu@RL;M0Hq&v}({rZx^n
zG)lBeJy{B+Q$PE)Zpi5{gaiBG2R}gU+mDzn8zDtNJ}>b-O&l$vk_t(*ND?ie)FQT3
z;o|dq@kE*Px0OhAh4TCYy*a@hw>-cj`;QPN@Zf`um;%6-Eg05e0<z>PX0>Oq)f8;S
zhF~S9$Yxwz$7w2u0%HWJu^J$#+kbxJ4Tt}?ZCmDq17O334WBexg0MkYIF3tCPs6iz
zn%MfJsUnUw^Yd{3eelqIf-|;kK&2sZP(>#}qY7BY=(LPcRnlkyla?u!B)fO)VB>HG
zDa*_)Ea1BVKlt7c33Wmc!mb@n+DJI#jE0ig&GWZJ>=jl(3$<k@4$#3*V1R7K!LjXS
z>%bUEsx9iFB&^x5z2Sz#fBRVc1ji)d?LWF*danD6##jj9AT1l$^C=cNEsCd?%rs*R
zN@<cr6UUl*4bIv;NEpQk5faqqsMjW`*QPLP4wEjBMl+=G3=Rtv3W_6Bd)Uw~fEuo?
zIcwVxxBcKJ2nS|o6OJ5i{Nil(XiR})iGnt<Aev8o6$cQj#lsQ^G8qS_MI0E8f*`8f
zuld#ulkYw;05A|G%0kGzv>j~Q!j`h(xjIeK8!fBh=n+DYDov^sNur3Nl(43`{PL$_
z+bKe%O(%=Os05=UAVv}sh4bY6gs?tO5|=q^OP0gaQ#`z54}16TWBc}pFr@5#L}40z
zCfKyO$pu&g2&}$N8^>q`$qJyf>ITg~l5JTHPJn1~0-GR|sL+4Mb>BMpKORl|Kprcc
zTA!cWBrL~rTo2o|acqgvDYe>(bWk4O7#Rk~wJ^q@wI)q9ahwtcF(xsDp~i6}X`&Fc
zsM{D2reS7@1dD(l-?I~)ED{C_<T9F}fdX5$odG7LyjW*`wke<6l|fds^iE2l=%ygH
zDTAv30c5i-mL-=#pp78WHuX>-)9e?%dHsRo4kycF*#1;&)hkjY!m;pt2iLVQMlm;M
zh@#V@gU0wcrch|;BuXjLrYHzPMQt%6NhOx!5Jhq0iMRS=G0kh5dYp2>)*^?eXUX`A
zAXsE_axa(&twNHd&g>D>8fsoG`#Z?}_Rw%^h`5s|Xcq&m;vtuHu`IEI6C}!_T9-H`
zd&~7V9^AGtZyrA#AgtGOcieIhF*Z)t!_7Llj$vWG!v4KYu6l}xl(2Cea(NFh7-LAa
zA&L!)i!tY&dl3r@bsWb*iUu1MLeS_V(g3>B3eOj$N}$3TLWkH^%s|Ouadr}w1gJEj
zTuD|deWEiEIuUS{;@8FvR@~pgL<GoXJY*9D#s~}+sghJ`5?g2PxbcS%WR||?V|D}u
zLHOY0)I8Rm_jB15S0S7f&yqwz!h!t}8Q&A56DwV>r(&FWCT4CP5k(&LdWbQm5dew|
zLS)&p<wEYi@8)WyJom8Ym<7+by<EoWvn)Ao+cGPKz;i6-=NCwYjYZ1h;v!D$kn>WK
zI;5#X9IF)yXeaY;iI~!WZaRn%O$U%^QSoUx7A==di^E8?IgXmoIpetmVchgWHbR|g
z3bh)=f#T?Yl#1@t*5l>1*LJZQ@wrcY_J@L$1N-+7-t=vxo#O>Bd_I<?h=PEJAC_q2
zi17)GIK^h+MHfO8+DuM)1VMn-rtyFRjqi@}yyw5--e+8yd7kfxp!I#f^V@ISIy{j5
zaDT6VRk=D_3bl*SHobYxS?6uQBoR@d2$RN)Tk`I~Y9oHxgj;G<rdx>E^b{^joi>Gg
zX{NUld<g_Bc^R8~+ZOnqO&FzU-T1Gm0g*sZ=c(VhdFFFMh~GaJ2#y&GxcXneVBLHF
zBa70?WUKW8sjxX?%NbnujLR^wA_^47IE;^ZY}tA=h;ph%5WpRGAf~5ND%EO3RvLvA
z;MkgcR*)~*e^M+tpSt+sOxhmrc*P(5#UIzB=<kF<^cQ@7`B#65@|;JIWI*J&@S+LM
zf3h%91dr@)B$>2#Cs`37VrAm!T8Sd9A!5@4fK~gJ;~+{&6Wyp*7GMd5V=D?dO={IH
z{KXfI-TRn>L2rHIyT4xx^p%d?!$L(eIzB*}W_i&szZl<kN$N34Vki|eY(4|}22L#q
z(iHBz6EQVqm|v(Y^I5GEEWmLzzDJtNTR+lL{ppKeICOXWXZ-GOzvlK!o_fX8#x`6)
zJ+jcoqo;R>=RQA2p@7-BqfvX%UQE(4Lb#qRp?1QrgZN9w<yxbSO5;9-V<|jGQ!Ei>
zOR9Lu#XU*4QnYme;BVglk+DNl)%{88GB7wyoLG!*9OHrQlbnCy#cbO)LEg_1)nbIO
z7#VSx*aY4w%n&jL4je%2*a7nk3H5r===mcc2?GoYOM+t?EU9DLGG*H)5a={X5-&}3
zU!3A6X~P4W&-e1wOY&^l0+WZJR_l-`(y0ZF>9B8Fpt=J9mc>gO2$pwk#D~V`RBLhb
zGa4ae$5LcGO`+F(_u0?td2Tm4uL}S|2=gbe`t$vspBt~#HNM}=hT&nN1S&O&kv?0u
zO>p_spG;Uzi6f2gIgE`7Mn=JQP8|^97<TVQ?B5TSYDy5q2q~}}8>19S9HNpKV-z&H
z3pO8W<4Ie#$KX&eXP@OTz7ZDY8^mudM(vs_*ji5BDKm(+<4z!G;{vTfXbmU^p(ak!
z<ri(Ka2-uPr}6UY;w!J{z3VaM1HAS1fB6qnGxb-+8idG`q&B&Ho=m1dF5g2GSqR7D
z>Cd>3GdGVCRTU~RWV06I<AQ-9u<TO@geZckDa3&TP%dkNK#?fjGz1$@+h~JI8|>7v
zE%F7I;bE5z8z7T`FgV(&tUY<OQ?m)v-fg5qjzGu6kWL_2OAIv6D>a2u4Io>>VA~4c
zH57Zz{Ii}_?CV79bpznfU;n{Oy}nRes79Q7&IE-*fx|P3!$%@4D?_nRL<-4#EoF3U
zf@eJAB6^EC;+i5&p^%e|jS2b(FqXq99n~sgZVt+2s8kzyf@#{2p|%YfUr;DOq0k__
zU?t((%gj}W-bJRpccJN=8PqXDs6`K0#roT3ek%~-*bqjI>LW>`1+HsraygBgO<wt|
zEBijxPVeK&2ztY-|KjsAbG6^uG%-RpE6HWEI9{HGs>{Kt8o6vgy`?<$Bn9CyGCayz
z=WU^w$q)w`l|Vix86AcGL5zKhfzbN%lBAIyu64u1x71#yy|k<o@s~=?+u8rBV$xP6
zusuVlP5En|{jHA6b{(MABCXamsctk(kWyjWnv8467Si&wpIs`o(|g^PyVhD{yq-VF
zXFX=-YD`a8IdE`}IIL65M4W$SmXRUN)a(={Rd_;E4;Ogoz8&0g$NeZL#V<;N#IR$R
z=B_&thxQ|q__S~*8^^);ej`0xwr29Q*!ipC`g9KXESHZR<Mp+ohil%uMh=4ON-Vk5
zFk6C=Xe~iG#T#y(e8r;{0ZR|+ZEt+{uT4#tzdSNHfJ&<Dn~r$e#iRIM5h+~|4o0}_
zJ`j@277*IT&u8c@^#eBNJZUQ#&qYOsG%`4jWMl+JHh|}!;_y<lm{jYdEPqvTX%{hI
z%xW%R*61%p7Zb3X^4Codpe-h+6$Bwozd*wxaBV}z*Vvipj%Q!lb4e@Bj|%`xT|oZ$
z<!^b1u>E)Ed<$V>GWiViwV2Ht25{^gwwFN&7o`Q0vnkTfVhIN+Yzp}zem2LJGdI%P
zmq!JVMg~g?`UhZa6taa=1cYYwkW!7RA=L(guDt}-vI5p=26CJZAl3ju7`7^s4FLGQ
z!po*S^NO5!)BtG42FPYJ<`uvHroTbhuX9{YZy`%hDMK}gNVP#~hiooSZ~q9=a!3+b
ztZ8Nz6Z(7lK?|gCDD{;XpBQCq;{a&@Ndyu@Z;xPf42nG`83-)^=(@Fb7i&3Rv*D!a
zP#{7VMeuk5&;bN#dQ^NV1-1pgr}1-!#qxodz32s-KKrNv&<cWAzU(cponNf}?}33L
zLp?cqOF1f)8c~v<jbw45PH$fy{evUq^L?Zm7Ai5*a}kAnFTUfE#L&}MWOU;Owrm|m
z#}J1gwV_xNjEzE1Z*wt_Qw)H0bAWd3->kL-+HL=10ic`x-wpzROs-KMk;}v6!G<ry
z_rcFW7#z9z%4ZHdf5|iWm>NU~A<QdY`sQC)tku6UJk&4y3NE><N4*xHQ$;qPVScg3
z!hDrtsh7TiVS0N9u^o>ib9Ls*DVF7t_X}t($>g$ZI%AxPO`}L5Na~Gr=u#61rQSwb
z+=&LjvJS8$3Oe-^I*vw@-O9r{)&{f#z^wFcE(L^E0isDo--A*K`UhZW5VLo0qtwkv
zuxv=<#a)*_qqJ>VKYgq{f({=k^YM@TUC-Wwv)}ey`>B0JmqIo}oWvxFCZF@k<$Mkw
zS)f{tv2B<Bff0K82gzh|lxr!64p(vP3|YT`C2btnXUmxrjE)cC*fvS6@ymOAV0;1!
z#S;Vqv$D(B3fsRG2xfKT$rXhntsTX>5q`Zffc1!gmiLa0!{8wF^)+sroJ1U)1YFRm
zAt=ure9p6n#+T^+xHO46bnq}^<0Iw|Ui#+OXrunB;LD6HG=)+gZ6Hkr#hgn%pJ8sH
z#==4!gH1kPWO!sFekMnv1iSXklF63H`Z+9NlgSm>Fh0WA#z9=^5Z4U?!Pc!XyrDBE
zJkbC+o>sFRBY|xSAnkF0E*`*k=TC=2dVArFGoa9-L{HBm4jl$<L2aha%;e64zxJCK
zJ-z^F7Yi?Y>07>+&x&VN7G}iI&>-1D2CW74dO}a$BVWi6Mw*$~GEoGcmtk~#Gnq^d
zBWxbpeS}hR2-~)?Etj62e)7c}ThH2vNG<AR#WSw3@ck1DfQ~vqn-ZuytT|wgLjgP<
z?SC!VFC|>`6v*dS-m-rhF*64<(=loF2$lH*2mj~qK7APgk9(`w<_BN(rq{l^=;a3Q
zs0H;igRsuvU_XVTO%Nw6P6p&M4jV^%NHrXpsj_?L{dj(c(Xq{(b4DKq#jd?`6pQ^#
zA2~=67pa%4_;!Yko5t~d>y(&^t8)H3<n}F<hne;y53@1@NF0lWwaR<3GFxbw_RatG
zl&3(htxQiFDA%AiZ<w1|U~zUDPn6ALaReRL*!kci{N2Ytw^^z5mSRp1S(YH1%MztY
zvonXrvnBogy(ndvnX9t65R%L18Q*vYo}VL1G``b|@0Ktk%iz!`&wo*NeeLBRgB8$G
z_P6-@mFnIfU|q$bU0lCwg?&wzu=jcA9hLd5V{!qp>wd-lLkrw{?_E^ON4WIK#r^-^
z%YJEMiS8%VxY~Bk7C!cW-nHldeB%AXmB4*crDp9>sm3;fjBDX}g47r$r)Qa)Utq95
z%a$$u7#;G!eRrbM8e;=vWV{|U8F~kXdEN_75b=*G+E%83wb%Qtn6+)LUDn~wmF;~8
zTbfjf)_#U9Jqt0gX;Ww7M=4_WgNj|d5ApCL2biCq!*vqswQ$9~C*@H#(RRNOV#}*u
z{<cdCdHbWiMf({U$3j_}R4bBHbNI*tj%_hCnB%Oo&Ze*DOlqNvHa`7>!#w{51>?9U
zFQKHX3}_Pv%Q=4?DumlBgS)YL(}nG~R}n9X6Jua>6gF<`tQOq=0PNa*gq@E}GIMx8
zmIxW>vso-xLeui&PU>7T#)!Rp58l3c^Z4a2`Moz?JUU!>S1x1!x18^gq$!C~#A!-4
zKSFQMIn+W2WqgK)hI#Jui^lU$JkgC=hfEfoaj_!Nca3{n3AL;e98F7T#BfZLJ)4FN
zzar{qU|;~YoY7f@*s%+7$L;&L^WOXLT#NJ09$?3g9ptmUR2PDql+wa#7IvO=X1Zz9
z7{(ZJ<jCBeLqq+){5!w-+Og5G(%<!!ykE_@HWTCLQpj(k-X#9W=m=L`l{c<;QeDCw
zxj>8lwjvvN1qWzX_*fmXUGaG>C=g<0*6<20(DL3=sgVZX>8n4o4{`I&ySe-R2PqbO
zCN{V{v~w3i*Gba?N}11EEmggz&BBrAZF`>e`q%yG;bLK9f0%d}<1w~z1JAzdB*}b(
zXkB8atGTC-y~vbqi~8wq?%qdX?qzdu?zx?bf8Y?}x^L~}CwD(UU$4)m4OtFNPxHvG
z?VPc31Hujtyz^bJ+Sp2So6}$z6N&4ux%ak8S@wsCj}ac5w~TY;v)z+gaALa5)b-kj
z%cftG3rMqi2AfWz;~3`N(v6u6oYRH)lhcTA-+X{O?|p!gp)7+v4m);DGCjSA4gE!I
z&m|1Y|NN*kf==Y@|K^wPm?>B6{zSPTGn{qy1eZQtp4@7qHYZRgkKgeoe$ohK9MkF3
z&CAz1as@cE%d&b?(}?T7wU0aQdVnn(dr5;ucI`Pttv<_!{tP2S15C|KS3dgD*A(07
zeJVMC`Pwx<=>Pf`@7TXsb~1@_v79^?J!O>hpCrx6=R(KO{yPYB(Wb$-%l}Tgz$)#3
zN#?g{`K_a;2PP&u6aVlu;+n7T=H3T(aKTx_?A@PH^~nGL8%#+=K~%GsAPK3}ry1$b
zGT4`6c5ab0uK(_1N(z0vXZ>|wyY;zoXn&_xcSNFHT(8J8E+1j@7IE@Dd~NFyu37EV
zVL|FOJArkP`R!oq=HwX~g5fSp?Hrs$eC2BovupQm&OLLG2OoSGFAG`+q~Rh1J$dT2
z8gXi_{_x+t`hRw!wLH1A%ruFA+Z&>~eN(mOibQ#2bNxK`c^gg*@!L$mV{rn}%|XQa
za`$9=E7`Vo^s=S5(AXHJ8}aw-M_m2oUF_Sxk8PX#xc`Bj6nkwZHuhqhkWJ&m#9^I8
z8HW13mrfo!(s82OCzJS6N^{*cw|}Nywf-Os9a21c`-gbWb4n*a`=^y|ZS4YDO|w?n
z-OczHq75|d9l@50JY`#az_ciPEgr_Dux_c;`3pa|(}*u$^8j&NX2Vd9?GHW7=va=S
zfgDE;A7bO!0CUqvh@yy0#y;y!Z+&^an_hd;M8FrW`Kl<1jki|I*3-ho#R#9_kzt<m
z+&rFl3X?&X)+JWm3p`h``Y!7WubcI+q3j6(;~OEH?O+KSxa*!&eCexqQtEL@qbgI=
zhZx(CqrW#pr96vcL1kf)xw$fyE8hIU554xU*D`8O1^~=;-?+6`r1pVw*~-SLi;+H?
zHjnbGXZxqTuR!ZEw5=d8W_<uyI$t7??xgK^5i9K!ma@@{u#?{-Rq&%*Lh<!)+`*aK
zMmVr<KXJUk&_I@+qDvIalO!?qN`=Z|Kq}L(eE1`8`1ND8l|9iSz+8XrZJS8!Jqs0!
zRQU+Y=bUrLx#Uv&)OQ$aI)7Ho*ki>4Sjnna9k=`NMcaE?DBnsJ+lI|sI`f4nMttX{
zGB<tyE-t+A3?6u32N^G9sJ}?YH$?RrqA((gB7$l}V$}CP@{u?E`eSYo@mR<8*WUJQ
z6<Ob_RBaONW7!!le(E^qo-a?2_EM&Ec5ZvE{(3>M%E{j$P|ztbl*z(|4V{U<P)2<1
z>yzB~;BL-6XPgHg+(|wYFf>rW5)rk^G;y4O5`@)&Sfx8Z^3m5nXT6;LgaAMYVQ%=w
zZLf~%*2n9CL#jO-FVE$dkFx0$YWnT7pDwa{6)BDZf+etY<FulSeUE{G!A66tZf4%q
zU*5stnHhR}JoX<vKwnAG*Hc93h}oF~s5D06Q>#^pm0B3tlsPX9<8=$x#}xotYb?t$
zH+=K9zpgFHH#S1K9+_;3XFh9~4Wp;eq7vQGvX@=Lrn_Ihb>=TSbvl8d&G#$Xh(9vc
zSd*aB*!~dWi(k2$`NhNJvssJ@819o~Gae=hIC6MDQC!EdvIJ2LrB&=?%=qj6>{aS`
zp2On?fG~*2WPS6kYj6L@>VkY#5H*&R$rbx})|CSc4xdKL$uyficFM^=mUE_){lB7@
zPX|ALdpzH^V0fglkku+>FNGi8S{K(|cNbwaM<HLNr`MvC6G%dIROiU_LBhC(#3zXp
zluoNy@!-4P^Tz0SAI0MWfNCY6P|TWdef_piR~N<0!q`C>k7CaNS6<mi|KRCGe4{&8
z=XR3)W*y&Lh?VADtFk9sroI9E3=DR89+fKM`WvVD-hbYMlp)1pp0N?1tPgRxK$6s%
zn>kFXLeMTCNOg4N;rRm_KL3diJ*tL%_Tw@03&pIt{%g1WOLbBHUJ$z&e0qBOdFGXU
zr@UWKH+O!gx;)xgKkFp^GVAZA{57wYicl<e59MBS?Ze!^{b6h;C7<&+W1@sDBdV1d
zOd7H{H-{#{wX>+ykg90^dp`JQ6Z3P6kJ^}iOaRbYH`)GeU#c#MUk?)pgHN${fM;IW
zd-@SyH=I7J8a2>a6dWTt=%_bObf*2Xejs3IxHHRF3hsSCi?3dL7t_--*tTL~yqErx
zi_ul8<#}`xQeIrd2t^@ZA`TS^)&1}Kz@JVWIWi}DdW)PA09ck~Zv5tL*Ouq`Z;d1l
zpF*jRD=t5MiLbj<<#tWb=r-$H+5H-Mf40+|<<|rF(XEmA#<y-qsSvHJJmtc3uuPpO
zEE7i+(x^_YT1QAI6?;g+lrXODc;|axb9PV<g`atBsZx*06ZoC$Z~szdo?oj+9tNLm
zzL%#zeUQ<Or!Vo_OSM;I?C8!FJDqCxkEJ6R1H}?1m+Soc{zHgw-FSdI@7{@!DSf>b
zTQ?7(lL}hJ)a&!a)e2#h0E%KMi%wy&JoCffc*%di^89UE9v_qa(EvaQVQ#$s*8f$T
z=biP)LmLl2)5}vX9_EZQPkqPGc0WJ5nV8X`PJh*=yO@Y{-**}V0~o85OIIWAx=ZoZ
zYwu)!p+XSO^R%aICFdKGxPm1V)ygajb92oVO=Eg{vsl7reqrX5@BYB+U-fvp?~fY*
zLI`u?b+=p<R=K%WcS*I6;}$vZ{87$5Pn_~jq3y))R-B>N=+(DM7g#6ZjcJr&m%2nY
z=NAz-+&IY(ZrzDeF|L<z;dvV|X$?byG%=O(4AWCHC<Sp`rLQ-K=Xq4B<=4LF18?})
z;~l#>E*+p!4!G%t|2i|Ob8`?lDD5Jx44XC$vw8DrLj0zOZ<&?rmb9#6wP<Pg0hnWZ
z|5`_>r_pC<l>{>I@FR#XedS*E95{kj0h>4VFflqp999rQg9@3MndHdy0vJK9Hb-x7
z79j=Y%Hn^2?+4#_?THB7ts4Mg5b?uXe`JX$cWbR8NwovAk+Z*PvrVCR8qNA9;g>8r
z)1f-I{d|Ro(5%l2Tmph^H;6Agh`wqKam#HruD$-p)aoI=uejhz8}Xf#II18>&`FKS
zLkF2(2(YA}TAQI*@Nr!ys@JPeegB8va{q~n+OAt#XR^Mr;_R1#3Vn%oFu3INJ&bS6
z(AU>Yg4E3x{N^Nf{#yEfx+SdJVG+mn(rn$0)wlZq%u0f{|FCQhdiz!rUz<jb{ujS|
zkbl4Chg7Ny3=cb8`jiP=E5N7-qv|Bl9FIJ*m-)pA&$Wr81&Re9-}m;_YxUCm{_4#S
zoXC*<x;enL*L?T4lZao5m4h)Zj+0@-Xdi=vAgx9mU6`Y3Pl(3qEKOVZaWCU;b-|ir
zHC|k+CCjn;@pf<k2pX~bzP`>-uSbZx@78?#yZ5kX-z1Kea>->|@kBxzSHZ+2X_X|Z
zv1jirMjP^3mnd8yoAt0AdB?lo|N2WRmD&lPNb3TC5W?K>^&ftsT9qi{f^;eM^wHZZ
z$YdMcv|0-r&FTe}1zqgquHfj#Mb>Dq-ifelDt5=ynso&?TwRL2^!`2j5qI6S$ajBq
z7nQ|DHjeeMb;|%rR6$#y(h8W6YPrn5{bd{*iUpTAu3=jeZPLGe?+4!eXD2IDYh6~r
zb=Q9XS`)gzRF6DTmBsN2Ol%rs>zS~$!gjaB$BxyqodPOdT(%s;1Y65aH(j!G*42-%
z!?~0VcHilHR|CX-_Zt4=hxf2+?_qQjaLLmevtE;;bx0aju<e8c2j-cXsglh)WPHFR
zD3uTf_2+*0qi_4JG3Iew9QrW<K&6TsZ@N|5v54wb%L>yB8lRrt5hf-IjE%RIHnYaE
z>TLixp5M2M=<P)7)@5U@>ua(7HYIS$snaQRYe4LL81B1&jyvw&#i2t}Y}-1-*l+=r
z)Dc3FBsI_hQp7y4eTtwSQ7m~_BEfMi;;0^{X|nkvAA9@c$xhQ>697U8^OdW=bxp>~
z|4Kc~kf;ononvr#jI+<SaNVP<U#@fQyjDN@v4GIcEL$=Ap>t#9E;)I}(|OaF28YWR
zI&1hd^N1ZgQht2bZtj0@ACiP8UoeUzQiM>AS)bIgWX$4Xne7iwVo5>P7g$z`@419g
z__ch&|Mhph=XIxK`K_)xK$<GP@XufAEfq_@QZEZIR%6*%*T?rQtft~8m;B+f%Nn`e
zW`A2sb$ebNqC=~+#_Dc}hLwkCmR>DKV)W7Tc0#wa{8gapVB!@^7`H<|f+$7o+-cac
zbAj7`vYo@zb8Oo>z}Rq}I1WIhq-h<aB5WD6W9NSM?wh5M^KdNH{CtO6z4p3~{oOl0
zTCWGEEH$<(0363QSAYKNmzxxfmKb3pu&^DMY_>^!K*^&kWOZcyodD1lDO)kk#Txp+
z(#qh?KSp#>;PlZ%jP<r!Z~aGpc6GC*rS~10LOk?f%>57U=AQd@QY`vhaoJ`}8W2TQ
z1QA-r2on)TW$yUNLsTm<eWg6E8)G{HgPgC|t1teCPrmoIQ(c?6rWN3M&WE%~5yC?V
zi4-=Lw8`b0?NM7-#p==xdrdB2IyhF$+M=MNOSThh*Xx+=Z6anZht6UR@!)pNp1rf&
ze#gDk!hk1Tu#rMm5JeSS+n~}AL<*+P<m4p(b;|?fvv~#w3OIISmCYoPcl`Z7UU126
zw{DSt|B3gU`qKPv2z<{Q-j;d#^Iud$Wr#zMIQ22YCztQ%yeH)vHh(+YmtEG(T|)sp
zUS-#GAY9j4JF~`nR<nED4zBD-A$ILFJn~45oe%G4@7{g%_2<~Uv6ou4jOR&I8X$$i
zsDL!7@{@ZW;=ukR3=RyC&)Y~5k*2BETE6*{pMLL0>h(ZmGCrrn=*j`kKL4C^69ulY
z8mnxIqvfzmuGJ;S53+e|)}a7)QUqb$1^H_MU_CRv{WM?bT!o_y?4LwD{9wX?>3OCn
zr-_pqPq}b2Nn9n4>eyBS8Z1&&S|tdp+;;nR(nPa);|5&cpjAMU$g1aMMnC$uZ?Ash
zQ|~!Vmfc<h0CAiUM9F3mrg%Aluq0B0MxwP|u8NVOLt~^)BA^QgXea!!fY2>KW4aO9
ztmWEncGMKB&AO>M*tK18U}}+>>3JO2P{@Jn_{32eDHDXz7*f)>4yMlBLXDlf_L9qF
z$PZ?)tdum3sRiOoPkq|Czx9WI^jn(KaM+z?ziZy}_7879Z)6*mZDFMXtp!>cRGN~e
zUF7~cW&bL|i|&Dz^%B)|Jz1$cxGwZ`@ZB3=wu*T8A$WNA5e^-i!E+75#E8@&Ed@ej
zTPZ4y3BwAG)zJ3m7V1n*P1E07YOJnKLZuQDN6A&6{-^hR?{7aI2u{<{RRn0Qhwr=V
zL7w%TXJR`NtprLNj8>G(ibBC!a~YIlIe^yV3lO3Uk&iR7U;w9~;Nf(T^K$`W*A94S
z`y_kzPGT9=SRP&pEXUw@AcZ1LV#1(;(IKv#5CjqBYMpYqLQkoHM4)xT{6g(UrPXhK
z@-y!#pAJ2k9u)wLFlv6TjBq?GW3aVE8Bkg?KU*iCFDxfSwmO1zOF+o9hzL#d8VzMp
zo1^FLzJXOhkSur6FfG7YPs+9>8`-#-+-fE<y@=SgD`w~RX?E@2k4Y6hMGMCfc&^0r
z!IGLJj;IGUqOgMRX{3w^f|yDzBnSdL$H%0aauBdsslNPk|NQ>X96mfNKJm$SpVq`*
z69ASa7K5P9p4|u7vSkyN0$YJj3}Kj{RKqvEWV>szl8Cwk7g!R4LN(4+TWx(;9Y7x+
z2Qa4b-Eui76j!b>pn-jd5ZfON*uQ6reFqMaB#OaO79$Lft;iQ_90!s(q`FWcs4rq!
zid;^RBz2NRQ>z68VS<Vq*McOz-Lb;wfA(|lul&<z-zUUrPx>_gP%c-*M?U!Rot`VX
z^+&fbv1Kc^Coo2%j7BNNfqiAhCyJ~5|I6&&bg%|Guzj%(CGdD3X2x%rbxup)fz%*&
z><Re6_veY~Rc7X9m|rY2v0)G?3~^GYShC1vUE(lgZm~>ItDw_>QprWim?(^i6Gg2S
zQm-k3T7njYQBr^1KYjN7|5&Xy!nZ#y#9z}7@V2+S|DrHRf07u7@$s|RFus{HCdLWt
zhA0B99Y#irWV6n?W&fiAz?u)Ur3_n}#xg0zQX@$N(U1^9g4neu;M!{*#1;~zQw~i}
zv1NP^DJ>QjD+~{1$z=se6tcK5Pf)L+Rfy{-N+p*#uA?=CK}@xpP_4v7u_7_?j;EbB
za^5Rm_lMfHBtMO#D*z7d`hobshi_E9y#+Fbab{-gT=A@DGSoXjSXV@mKx@g^cn_X$
zt=9fK5dL@pAjBF(r`gacZIoN(@{rGg<3g;U62kT!Rla%6UG$W4_?ZmVT8*BfL#4b(
zwQd+0$xz7BnDMhS&1GX#lDNV^zmGN%N-5IBP_Ly_$`O@D{e5a%@pC@$>G%DJpYqWa
z073}!C$D_#jgI5IAP93vKhLI(V?6tL&n2lvM0HIRgE1B(8%p>YtGfx<Wxu9Rpo=Il
zrm@tkv>NN<WU`G0iqeKe!)zIT_@ha7Y~M>?PYy5R02Z#3aAbOh=_8A5+1yX5U=!Bs
zEY8mXAW;NCnS5U2dzv&&NK-`=X%^=LDwUXetdLgxuNyZFzwDjw{L_@5fw5*d_~kEs
z%SC;~+)r#T%i(E5Z-0r=(Jeglsw+t9ny?lV#Rj7#`Fw_fA-@r=6I}?uPE)Y`eyt%0
zno5h^VD)~cQFUWvBT#wo{T1%N?=aO`jjSgzIws?LC^WOvlPoM&nV9IOuO~yLyhy!L
z!?FaHG{j*QAwmiT8*NgOxIz3{C1!4}PPv+3EOo$fdH!cU^Ztj*<*FzYa{SB#-~;dZ
zn7#Ai192%^B9|{RznHS^?5)f!7@qZ<D=6l2MD>IyXe<ydq)oAup;UBMu<B!SfhAL~
z2?VVmiXlmw;a}Ns;J9vs#Y-EoAOUW_{UEz{%@RccM#uCNGc1-D@w^;Tq-Y(`Q_7Ib
z*euM=6GsuYC6Q8-CUsO=Czlgg7Nki+lEkDbEG~vjO_vGd6x$Uq`PYB_;J=*iHvQuc
z03n2V<;&jm8<y>U(Xu@Hdxps6^UN<ML}`|Zty{S4l8ew$LL4gMNHrEvGLlTj#q%sY
z&%(9^mL-r@ORT?TrLERgIg+$-k7YMzyW=$WmfP5rfXS&EJ9kX+$ivfsMhJ!L7;3dT
z3ky~H`$`NCdE{~qLMv+3T9fc#bV8B@U?MU;xSl|zszG?ANfVfvtulFJ5o64!FS~5;
zk6-utHz#STg!NOZ=sjuxBuUD*Z~VUa@)vKYDx))%s$qO=9N*7@%ux#r1A{|ce#NEq
z_Vkd1F)CIhu|g@+QiLH92n@2RAj)Q=#OB_TSW+UbCb65F?SgcmT8lU`TV?O=BkbEd
zO+5(E7^F1x_hr%Auy6k~eWffLhO+eadBkBtwNgQ=6e$f#g{UM160%u~j4#nfktQjr
zQfSjye*M6qd1mIzKQ0yA|MBV1d|>y_;;dgc0G7rdzw#~b2*c!EqoX6tEhLmH38m5i
zBSQmt`63dJTsF`77hizqW)MhpYS5`drHwQlt&et75(tD8SW<!|ux){~8?4<J(^xn{
zB^;hw<o<geA*{z}t*FHjT3f_P6-R0`hB!^>FSwkwbqLE6)GBp?dL6A|j7fkLbOI(J
zla*w%4j9wW?$e~%6w+d@9I|Wo)IllqZ+-srfBl20sTnam+|SSYSQh|<5at!X|Hg&Q
zn+Hl+-{ATMs)5J;$&kL@er(HQelcNaXn<lq!^HR~nS7p1wt(%qARF03rY-$P8%?S-
z(^Io7&PU81S)^R9P_0+-{VY-#G_Y8%vRJ8+q$!p#IF4Y;ra>k~i>NfBUJHoA0G*~F
z6k0_X-7x8lPVijF7yO2Pp&O1YV+;mCq72)29S$nx>K|SG?;rW+AP9x;d;GkNbr*-e
z<`3WcsxVIfp^*33GSP=+c_3Vj@Ti6s`zC8t%L$oG4%_!}q=Qn1f&M;*hx@Q4gkemY
zN@_twrBZ7Y^fXg<)6`(wHbGR!aU5#(ki}}1Ovb0TkfFC^G0>OCmXIV7^;!+fk{F#J
z1Xz|p7==<1Vc00KwxlAL%djN7jWNp`LUP}ZL(I)rU-89%|H!9*)>-{y27nO4y!@qa
zx=9<JTP$SQG+HE0B?t#US43J4J07X9?@+*#&mW_Z^@&4GkV>Xz7Kmew=lWzaS%O*>
zV+^kEA*6*cid^2Mkk1oE31JYB^=*24d|XFjv|3I(H%4JhiV(V?Hwc4P32{;<3Tnhr
z4JpC%Y%Hsh%+l&$Fu?r}O;M@VUzW?~|Lv2X_{%s+QeoQ`PXJ(zF*`fYXa4?QiaT~6
zTu{a^F`OriQfl=&xoiR3^Krc_`9d$Y?c=*H2%AJ{gn&#YkB~NC5JE1ml98sGG)<SI
zI2w&(Tgc_cN*as;6vk+@N}Gj<4IrpABu(Om2+%1~N*vp6<S|&*GU=5uJoNB1<x22-
zzHfi&Q=fWYcsiwKo%R4&;sSs4ia)<NOw5ndB;w3Xee{%a2n(ciNtM8HJcP7SN}{#E
zc6=<$LRvOLN{-foiH0@M?5}1xn$~MjU<}6S<qfSds0Pa?0j){Xm^h9boidxia$N`4
zaj<L)jG-Px>^rn@@bFCKEmu5k%m4e+H@;f`yt4bp41gsN{K4<P`AW~v{6`^YGuZ23
zHBC7otY-gv7qBqG0xYC-uxz_A^P7&>qpZ1+Zz$x^YEsLRU^J<UQE7tKG3W$iR0AMd
zH<p=8QdHV-95}Xv=XqGRL;!OOHD>2)|GDSD{9k?bD<Au2bFI852>)0Cu&fWf<SoAx
zDfP9p&KR}|8Pm)N7Np96&{)Dj8H12EmUPevY}>(gJZ#57V1W@$7H`nHQC@6NO+S3t
zXy~`h6-3i~Ylw_gDYVj9mWAs&IF5r-nsOzm9-LadcK>AM_22x)$ETi{?I!>LOXDBk
z_hEU{kN57r_@d1d#jI}3`sLLQk1AbD8hGoB2Me>*&SOO^pyj^S`tqjsu9RwQ+F)B2
z(y~yg(T8U$d-fe%eA~ZY{Wo8DVz!?o04((e{@ves!@Hh*-sszNnN(t&Mgos$N#hZs
zF~f~%h>2xtw<gNA)`+!g?#=fCN-gOG074y^tyT_B)js%d|M#!|3LuUX;W+jaR6SV$
zSen^F2tN3s&x`2;+dsBxEca^1@tb{lbX&8`l_uHIbTG4m;DSc(VVbICr;U`7AXH2q
zsqU>*<F{RL*^|C7apoE37k}YO^8^`BApn-Sfl^quZC?4xcjS8u@`7UC`=>(QJy%)=
zV?;~!&e0@5(>nW`38zY>D5cTb5JZY{HQ8Pdl25y?^X1ucJoAOmf2h`oQzXK+pP22Z
z4FK91gAjt3yyP#6TPKPer8MViZLYE{xlKyWGKO)}6zZumsnTYz*5;8kH4iIoZWBU0
zRIaJ%eN)lFZ(j3PNs~)FA=7_~0I)pLG{te8<6_fFDIukNf;vA70C-}Y-s6dB_5=W)
d7(dVB{|A}{iGK_`5CH%H002ovPDHLkV1nH%iLU?v
literal 0
HcmV?d00001
diff --git a/src/wok/plugins/kimchi/ui/images/icon-opensuse.png
b/src/wok/plugins/kimchi/ui/images/icon-opensuse.png
new file mode 100644
index 0000000000000000000000000000000000000000..83fe4d5df0f59b52dd609b3bd16838f4d2570ab8
GIT binary patch
literal 3046
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
literal 0
HcmV?d00001
diff --git a/src/wok/plugins/kimchi/ui/images/icon-ubuntu.png
b/src/wok/plugins/kimchi/ui/images/icon-ubuntu.png
new file mode 100644
index 0000000000000000000000000000000000000000..d92c00f357b6b0e1542413f6aaf0de8ef4b8d130
GIT binary patch
literal 4818
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
T?|XFr3GiA;OR-Yk^22`sn~zF<
literal 0
HcmV?d00001
diff --git a/src/wok/plugins/kimchi/ui/images/icon-vm.png
b/src/wok/plugins/kimchi/ui/images/icon-vm.png
new file mode 100644
index 0000000000000000000000000000000000000000..50dac50c5a0ee59f4e79170434f53bb3b94390e3
GIT binary patch
literal 2976
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
literal 0
HcmV?d00001
diff --git a/src/wok/plugins/kimchi/ui/images/theme-default/Makefile.am
b/src/wok/plugins/kimchi/ui/images/theme-default/Makefile.am
new file mode 100644
index 0000000..7e11d75
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/images/theme-default/Makefile.am
@@ -0,0 +1,20 @@
+#
+# Kimchi
+#
+# Copyright IBM, Corp. 2013
+#
+# 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.
+
+imagedir = $(datadir)/wok/plugins/kimchi/ui/images/theme-default
+
+dist_image_DATA = *.png *.gif
diff --git a/src/wok/plugins/kimchi/ui/images/theme-default/ac22_pause.png
b/src/wok/plugins/kimchi/ui/images/theme-default/ac22_pause.png
new file mode 100644
index 0000000000000000000000000000000000000000..9258aee87f0e2f430cf1fb12a4588f763f3c0a62
GIT binary patch
literal 1219
zcmbVMO>Em#9CtTbM!QYZ3R7EwV!5LOiP*7Yo5gCV96yIfTDmTcw6Ieh`=v3h{fzyx
zq`hSAssY^&+X3-;7(IbDF^V*#0ostNNpJ&chiPJ(*f=3gfS^*?io$c-6b{vpux!5%
z|9-#!$NT^N=IF@FyE^+iDT>;a83s8r_K~M&M+bTTG<W|x8G5l^z+<R{tA-CL)j~x`
zXB=Y!=AdCszxFL0q^RvBJ72(s>><TO4r_!Mw&r+*O;LkGHP0|7A*PFP!giC)FJE3`
zXxmCMN2P2m>uIoT56}2;Y-S{H&P<vKiy3-}9;_)uz=7DHYtED#D77TBrmK*7xXm&2
z8U#-!nRTZM*-=_UKBOf!9yMb;Ps=jPi;^t!FVI4a7q}R?<tQ&IlB@_X(i;~;toc?+
z$$|8SEwV~7WsE(A<EqsvTaB~GpWygJA`xl`LX;q)!L*BwTGS2tTM7UMrf+-LMlKyH
z8bwsWNrrg39)ja#vzx+hu#qT|GOlKL9M8r$#|h(FLkBnq|8ZkWbdaC+AeVyys`w^3
zk5Ye&Omg>VLm`lOqa5~aawx_WKxV~(F3x}?L%y(<Z7H#MN&~u_5<ptiMV?RbaS4!>
zrVD8v@O(>SE3PK#KozA#S`-LU7gZ6cs;KfBkmKouAhfs{H^7E#!j@f|*xleBd?Z)V
zd}v_g=MkD}RlsN&VHA{+M{8p;{oGO8wNN#9K0KcFXaV%?<Iqa`$f4KrtJquEkBR>k
z_d3`5KRM%wGhA34|0<T&7OB8+x>@>UvDrM(B^~3F);Mrp0;H{e&j2-FyH#9mHixz+
zsjfH1Eo=U_E3<{C2X?pDPc)w0Q`h${U)cTry;r_#-0i-(^1+#R+i$(o+oLyy)rrPR
zGqQa6RQ*y<Z%_B&waD#}Gs^kZ<Eed1jiuqwm$peKfB56{kCElaPu<xWX*Tygy#8yQ
z9UWc(m4ngZo|4tA&$sX2aW%f${zc=`{>0DYC!VN3CJ3Lly+xgTeKuD)G@tA0Klky%
zS!JL@nLTnk9qqeZzOi_&{C$L3`Rl_Qi*JAZ>Yq=2M&<4|=XMg!2b~wc+G{MR(t(fO
w>*#y%<Tu#??U}`^+b$Q*9#iveH;<`QTL-02da<sDMK=7cWb_g6NosuVZ*kO>5C8xG
literal 0
HcmV?d00001
diff --git a/src/wok/plugins/kimchi/ui/images/theme-default/ac22_pause_grey.png
b/src/wok/plugins/kimchi/ui/images/theme-default/ac22_pause_grey.png
new file mode 100644
index 0000000000000000000000000000000000000000..7cde85bcb26ca808b9b02d5336872f10556585a0
GIT binary patch
literal 1175
zcmbVMUue{J98c{SYPo?ZqV0n};)|2JOMXc%y~}#Gy(HIO+0}Br&chc?lV97|CciBC
z)w`CVuHZZen`;>q!NH~v?x9Y7Dzb+TRHmS);FB+cii#l4hoNGz{?hikJroBENq)cY
zFW=AS`#;Bfx;rB48`m=o6UlXI1-drUXUp1;>HE>d^Q&~(O7s%x#RH^l_=st@a6bY$
z#~4HfWLRTgUPmnqQ$JuAOQe+lTrsf|H$t6w#qlVbVOm-%o?#9n0{YRQ?WWlmzt6G2
zw$kjLM4r!kDjKpo$9>d0-d!}uhs~75w(bHg6@?Nwh!~*ajJSbPNwbT*3f+gt919jz
z$Z(ona;lW?0V?(pNW{gM$wLTaIS!?SEW;=ecqni@z2z8`l!UAZ&0zUrsWsmkPzqXh
z*%p=3><}TI!g1wtIbIgy*dOFzDwPU31R+K>V!@b8j7rQ6w$~Um6qvs45gWT8WHkEm
zC`q%_)1?p`FP~o_c7x?a(Ufr&!{cC_=Nu=DYf(EO1@w;_t7-?uF%NMC6yQ<cr1cos
zUIWwIeb`W_NWD>Z`!+3#F`{8})Il!EX=#>ziCea%@M1>QbU7nvSxJ{5%s?@rQAyQ>
zEYu*Zajb?-3eBR(C#7sshY;#gQphxC+ck+-)ufnJ#Tqu}2E=epRI_VSyUSSdgIGoN
zkwLIu#CW9E0X;*Q;9v-QK<$;mjy<+(;d1b4Se~V5HRRg|k(Kqa0~YhE*sIv*rT>b1
z32XhIoN?3{E^Ll}HB0S?c3`+&X?-fJ3=eYY#Q1bH&XxYUOvmcaoYr2f-0PoTSZJ+J
zGaKuFVj6^FlarIb%*@=_c<offl__vP^D+Rfmu6?npH+9yD5o}m%``PNmBebKF#qJ%
zwr}PRFLb?o`wG|fbgrw;O`ZPatR9U<r+E2BU)xQvuUdEVLEBd+HjQdmH|(hH-!gr<
z+Sf6Ag+FlTSN+W9@AgUu?sylUrsSi4bUlxpeCF-_aZPc)@rz)Bzwqs$H?Lnl-1+nE
zZNlC5ogI&|9~C0kBj>)K9Pawz@pRkY`;PY=8`;oyq>edy=*0QyXoDR7Dsp<a_FHEE
F#Cyajgunm*
literal 0
HcmV?d00001
diff --git a/src/wok/plugins/kimchi/ui/images/theme-default/ac24_resume.png
b/src/wok/plugins/kimchi/ui/images/theme-default/ac24_resume.png
new file mode 100644
index 0000000000000000000000000000000000000000..6f1f16f52f2c000a7413e22a0105c5d0b09c7a2b
GIT binary patch
literal 1341
zcmeAS@N?(olHy`uVBq!ia0vp^Qa~)h!3HFsG`&3vq$EpRBT9nv(@M${i&7aJQ}UBi
z6+Ckj(^G>|6H_V+Po~;1FfgZOhD4M^`1)8S=jZArg4F0$<Q4#RGcefLR}>^BXQ!4Z
zB&DWj=GiK}-@RW+Av48RDcsc8z_-9TH6zobswg$M$}c3jDm&RSMakYy!KT6rXh3di
zNuokUZcbjYRfVk**jy_h8zii+qySb@l5ML5aa4qFfP!;=QL2Kep0RGSfuW&-nVFuU
ziK&^Hp^k!)fuWJU0T7w#8k$&{npqi{D?ot~(6*wKG^-#NH>h1eo~=?wNlAf~zJ7Um
zxn8-kUVc%!zM-Y1CCCgTBVC{h-Qvo;lEez#ykcdT2`;I{$wiq3C7Jno3Lp~`lk!VT
zY?Xj6g?J&iz}FXUa9%MqpnyT9Uy)d#Z>VRWpPLKv7g%+1Nl+@n8CX>phg24%>IbD3
z=a&{G1LGr28KxN+cK9s<DFnL4%D*TR7%7Q4F8Rr&xv6<2o-VdZKpDN1%oHmVGXql#
zXG>!vb2k%L6GKBMLt|4HCnFbUS0gt=7ehms8QAn18<-kc7?=Qc8Ua<hnpheen>)I>
zSh!jkI9dYZ2Bz0Duec;JFF6%vZzj-Qs9rO?daay`QWHz^i$e1Ab6_bTAS1sdzc?em
zK*2fKOhF?&GcP5-yjT+yJrLizq!wkCrKY$Q<>xAZ!`CVki~T0%g!~QBn?g>Q=>r|3
z4@w+Ji3KJEOo1RKJm~{D@XV8%2h1@=z^w7aYe@nF17ohIi(^Q|tu52`dL3~PIG%1+
z{qdYj)BS{nN)a4Uzgfz@U5|{==-~Rr(X?J+hS&Y0>>I9~a|+n7!)e0@qjPDSCqysa
zelqu;f#OV^&$nmJ^%d*n=n)W<QMqBXLNn7=f3xbe`~%;@s_sSHJo4k~OgVK%Rrc$T
zR+%%`o}PbiUixvh#eaiq9=uWhwou#SM&C=8Uq&o5x)^q~e*7C)>7$^?RXt(u(xzEy
zOPU;}B=89}ep{<6u&4Nh>w+5DRCa}Vt_$zQ-(mgo)$`M{6pJ-XGfMySzIu_fqb8xM
zIo&>rjjbj2?e)nA^GjETTIn!NmEN#PGO#~*Y439ez4xkDnXXRN&Pke}eTMr4>oZ;x
zKDC3Jd3;tjEd1V+bK{)Y%G$QIDJfg_xop@z_u<1l?(CE;R_hhlnjVf9c&{M6XkYI=
z$N!Fd8jm^dX^2q>UEnA^L2H7Q^pY(86$;1V><mnqe;9lYxu>o-;m`U@4@9nbC@(Pk
bs(gUqpHO<9rrQcmP=V&@>gTe~DWM4fDsR{!
literal 0
HcmV?d00001
diff --git a/src/wok/plugins/kimchi/ui/images/theme-default/ac24_resume_grey.png
b/src/wok/plugins/kimchi/ui/images/theme-default/ac24_resume_grey.png
new file mode 100644
index 0000000000000000000000000000000000000000..1714ba2d00294e99222f833b8cf5e33da31448f9
GIT binary patch
literal 1282
zcmeAS@N?(olHy`uVBq!ia0vp^Qa~)h!3HFsG`&3vq$EpRBT9nv(@M${i&7aJQ}UBi
z6+Ckj(^G>|6H_V+Po~;1FfgZOhD4M^`1)8S=jZArg4F0$<Q4#RGcefLR}>^BXQ!4Z
zB&DWj=GiK}-@RW+Av48RDcsc8z_-9TH6zobswg$M$}c3jDm&RSMakYy!KT6rXh3di
zNuokUZcbjYRfVk**jy_h8zii+qySb@l5ML5aa4qFfP!;=QL2Kep0RGSfuW&-nVFuU
ziK&^Hp^k!)fuWJU0T7w#8k$&{npqi{D?ot~(6*wKG^-#NH>h1eo~=?wNlAf~zJ7Um
zxn8-kUVc%!zM-Y1CCCgTBVC{h-Qvo;lEez#ykcdT2`;I{$wiq3C7Jno3Lp~`lk!VT
zY?Xj6g?J&iz}FXUa9%MqpnyT9Uy)d#Z>VRWpPLKv7g%+1Nl+@n8CX>phg24%>IbD3
z=a&{G1LGr28KxN+cK9s<DFnL4%D*TR7%7Q4F8Rr&xv6<2o-VdZKpDN1%oHmVGXql#
zXG>!vb2k%L6GKBMLt|4HCnFbUS0gt=7ehms8QAn1xSBb;n7f#|S-2V*8oHV|I=Y#<
zS~!~;n_HL~7+4y?^m^tMmn7yTr^4*b1lkMLYl2s=m2**QVo82cNPd0}ECmE)<d@_Z
zXXF<sI0u_4XoP3xrR0|vYl5N&;#-&0qRg_?6t|-MTm^9WT4iFf-^84dzae^4$O$uj
zpkwqwi32IIz=VJ)5X6KheIN&(c~bL$Ii?7hH7ag6?Pg$LH1c$D45_%aXWGTy76pMe
z#*54EzIj}xurI?=?19(<x7iySHaBM<W7^hSeW!Y#j`idYMV)ys4*D7$JRonE*5IhM
zRONpX$ECYRU+uDc`!t~V)3Qvv1uJ>(TJRk9Wv+EDZnJyEl{9T%m!aDtjZ3lzucwwy
zndkU9=XRJJn_^3`-z1gDJsMmxyH<Q*>Nrw(reMu$E6&J{ZI{m9FXEiM!sA2qLEql4
zs%w7|zTdl|J2^M+!yb)}zAv@<{Ec(`CoA{--l4?RW_EbR_l}&24;eYxZZ#R+pPI&d
z%xQ`#>*>!j(GTAm-0<OWJhe&0QQ7NqNc)}Uh8%(S3rsu0FXRj4E66fk{VliT+D?am
zJVmW*?k+Ywy~(S-d0FN!6W0ZWZ4v(^pOtgWf7`vVwxRwd<J#Omaudp{ISm*X#7kc9
TIKK2Js8sTF^>bP0l+XkKJo~{m
literal 0
HcmV?d00001
diff --git a/src/wok/plugins/kimchi/ui/images/theme-default/arrow-down-black.png
b/src/wok/plugins/kimchi/ui/images/theme-default/arrow-down-black.png
new file mode 100644
index 0000000000000000000000000000000000000000..2c05f00498232213a081497051c94d16537daab8
GIT binary patch
literal 2942
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
literal 0
HcmV?d00001
diff --git a/src/wok/plugins/kimchi/ui/images/theme-default/arrow-down-disable.png
b/src/wok/plugins/kimchi/ui/images/theme-default/arrow-down-disable.png
new file mode 100644
index 0000000000000000000000000000000000000000..2d04c841780fa57153d4a73f3bee69824f6efb57
GIT binary patch
literal 472
zcmV;}0Vn>6P)<h;3K|Lk000e1NJLTq000sI000sQ1^@s6R?d!B00004b3#c}2nYxW
zd<bNS0004xNkl<ZIE~%Wzi-W99L4e1`D&V|3LS(5xxKfOSt3TG2s0reX(TMQ_!VNZ
zh#xUYy4w5!VnqmI7D4*Gx9xXeu`;OkG58Xc5{txVd6FmRyg%nW5C821>bed}RaJVu
z-XEK1W@bjQKFOP^uIrRiwwF?NFD@>w`cp_<*TXo4o7h=lGtOZe`|G;?Ev(<~594T(
zsU*8_bqJG5_F)J&FwyV#r}1`TV&Z3z5gcomk6{7tsw5ARJWBF0$yk!pxP+}gLS|=Y
zD@@`{k_|}~lH5)*RpB8{;0~6s7Kd?pFc^G=4F-d%l(IL;xg?vCXak&2@+z$eMsNj(
zunvoOf(uEWmQoJlV*92Gcz`2#-Rt!}fB!epM{yie-&A{vTWzIrd}!03$IEWF3*UoU
z*c$A?b!=&`-(z*FzuPW)(d~B27vC}v%+1XOJ8-Q%hub=j+dA{(<Ky3XehPy5`T1ZQ
zPT~OW;VhnaI-O<uUxJ`%8l{wtE$BX;bvm7;l{_m>(==7nG=J^?H}eT{w|+~olSG{W
O0000<MNUMnLSTa0@YLi0
literal 0
HcmV?d00001
diff --git a/src/wok/plugins/kimchi/ui/images/theme-default/arrow-down.png
b/src/wok/plugins/kimchi/ui/images/theme-default/arrow-down.png
new file mode 100644
index 0000000000000000000000000000000000000000..3f5239bbb93ad8660f47d3def443e42b8f57c6e6
GIT binary patch
literal 537
zcmV+!0_OdRP)<h;3K|Lk000e1NJLTq000sI000sQ1^@s6R?d!B00004b3#c}2nYxW
zd<bNS0005dNkl<ZIE~$sze^Nw7>A$d6~#>G7g3=>Q#G^&cL#z*Q$%}FLnMWF=;0ky
z&|yo<#f2xjw6^sJL}L+>rbk<lQf`6m4I+8ox1kd>!=xqXGrqjf!~62S@ZUy&d_HeP
zq|VMxrlzL$3=a<v_W}piuaVE^O(~t<*x0zVwzk%>S4p8z=mPEn&wyM2ed+_?sd}|g
zDEv`2GBVPo-j0Z3L|jmxbYwD_l6og14yzZ{&P*orF`Lb<HX4l`lF`x89-yE;RF9}l
zbve`-b+%nN6cP8-Dsb{wNx57Obtoe4t4Gy!^@UpO$Y!%&)b|n5ubx)BBjTLem&@fE
z3kwV107|7&q?E1zkJS?@?IFtQCjrLB#sGR!N;UNca6sJv-T~w4LQ3g6@CfJw)`1z|
zW~<d&nVz2hdHyY<_X2sKxVf6T1Uv_ZQc9<Q@4!o-0xV5VP6BKfwPpJw;xbSN`rGAI
zU|+lcHBd|`E!OMxw8`x__5A$&`oO@zVnocUXCvZxM07_)Q+=!60+uHxCbn_E{h7JB
zIR*y@SJZj6S3RS?Qp*wXxmK&~V0NswHRI#sG@H$1z%}5F`k`8_wsvE7O{G$aN~QAG
b{J+T$+X03p_V~Q~00000NkvXXu0mjf`lS0g
literal 0
HcmV?d00001
diff --git a/src/wok/plugins/kimchi/ui/images/theme-default/arrow-up.png
b/src/wok/plugins/kimchi/ui/images/theme-default/arrow-up.png
new file mode 100644
index 0000000000000000000000000000000000000000..40ce708941a35d8e1578e3cafb13d330fcf37c10
GIT binary patch
literal 510
zcmV<a0RjGrP)<h;3K|Lk000e1NJLTq000sI000sQ1^@s6R?d!B00004b3#c}2nYxW
zd<bNS0005CNkl<ZIE~$rJ!?~O6vlt&78gOQf)-b$iZ2KSmn<r{=pcRoKR^>nFL|-K
z<P!wcpd?CfHn&cG04E2BSc>ALR0_q4C<tzXLwz0xuM%P+9mQw+bI$X7&N+YhZxw$l
zw%cuhqd)?D=yW<$dy{E}EXzXDIorAIN0Jt@ESnlU6=eH_?XILNk}lfr+Foe2S`+*K
zNN6^jGZAqXSOrdwgb8>L+_1gY?RIxYeKVtvMx(I@xN7?WaJqnO0H1(4;DGH5z`IhZ
zv^5+KzfWAv_T^%QGm=8mhNNXlHA$}}Vf&cvySA^_>-FFM07%nxFK`XWfmt9TVjW16
zBv}KHbRM`}OccO3AO%)?z24WTR;&AgMW7iGM~Z-T;AX$ye=$07nx?00KLjoTVfzbk
z2gnoK%eGs#=OiKNne7_za{MEDz1|z!4M|TW+4iBrpCyv!CC%!mp4eWr{k-4rdmL2U
z@s;he?Z=XKB<+(lALVlSxb1s@BVsAf^X*B1aaAgn!;<a;2P2}E09!x<ShBq<2*Aq9
z%4gsfPy;rTJkJGe0^5VZV7HuK`Ut!&82^}l07Tsjb=)@&!~g&Q07*qoM6N<$f&;VO
AtpET3
literal 0
HcmV?d00001
diff --git a/src/wok/plugins/kimchi/ui/images/theme-default/arrow_out.png
b/src/wok/plugins/kimchi/ui/images/theme-default/arrow_out.png
new file mode 100644
index 0000000000000000000000000000000000000000..f5b4b8ed7de68dc79673472aab7c9672233bc8a7
GIT binary patch
literal 3048
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
literal 0
HcmV?d00001
diff --git a/src/wok/plugins/kimchi/ui/images/theme-default/group.png
b/src/wok/plugins/kimchi/ui/images/theme-default/group.png
new file mode 100644
index 0000000000000000000000000000000000000000..1160bd97178375f202c3c20fef689ddf4a6dcfae
GIT binary patch
literal 1703
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
literal 0
HcmV?d00001
diff --git a/src/wok/plugins/kimchi/ui/images/theme-default/host-icon-sprite.png
b/src/wok/plugins/kimchi/ui/images/theme-default/host-icon-sprite.png
new file mode 100644
index 0000000000000000000000000000000000000000..da1cd3f2562a5905a526446bcc8fc18bea06c734
GIT binary patch
literal 1034
zcmV+l1oiugP)<h;3K|Lk000e1NJLTq003?P000^Y1^@s6R_JLg00006VoOIv0RI60
z0RN!9r;`8x010qNS#tmY3ljhU3ljkVnw%H_000McNliru-3t>283nlSO%wnC03B&m
zSad^gZEa<4bN~PV002XBWnpw>WFU8GbZ8()Nlj2>E@cM*00VAGL_t(&-tAexPZU8E
z{`PW&1_K4^OH?eZvAftnL5(5A#KOeLoryLc6xvbn7idfrLqY*-qLqe%L|Ypgg$i36
z(dbjkBSwPpvl)`j+}`fa-u^(2muzw~^LF01^X{8@Zysm_jzUN2Fh`A~Pjc5hKFL~I
z+Z}W#NVXC{Y>}KuY7;pNNspw5tO0f7IFeP8D-r4|QCJ)u*CII!fKd<0S(2@?9Y=DD
z<R_9!@=PZG-V7bLl9r_@9LG4P1)Rq+9Y?Z{<af)|`7qr|9MBxV)c`acbbCfT&pQC{
z%j$mX<hUFic+YA-2XN6mak_;`9K$+|XK?mUTkTPj&CIsEF5cU<hDHKoBi7iJvbM^i
z*Tus8!czN9a>$8s1<N-8RRC8_`$GnE?vb2Jz_2+0dq-p)ngI3#?S24@sTh|bQ+;d5
zH%uEL`5>TIAzA4bYua?6Ovagcnjz|Ai5Da5sM6$aQ8E^l$E3xZb^24#IlFC{{Sv!X
zdPZ`HoHhZhMyRZj95%WP!xe@3m<5`5?4yL_;89M%??>JmIN;83>nfaa#_lVU`y{Vr
z67H9I<>i9?7&xxqKI>29L{6meTNYI%0Emdw!G8E&QVE-1Rcq#UWYToK0q{&jHq+Sd
zU}FNnI)H(=d=J2sh`dW;({;UEMO8gxC-hsZHn6+_8Cz8V%OQ7`GXQ2(brnD(BP{Cx
z=6&CP5~WnH*XNDysWO?Qs#^et%pdJCfS-x(Dpi%PY)T=^F&E8^3~dd>ISl}e&Opgd
z>jQ8Oz$E}@0sK%^x9UJ%4m8_i!$G%aL_`u-2dYWWvJAJ-u<F2q`TaRWw_eh}pDyEv
z>yyFRKMi0z&>mIQrid&iVqA_4oV3~tBC;bQJ7_QMEcIHnC?X#LytKL>s%r052kP~D
zY<0ls{5RDBFDZ*`N~hftRMj`pW7t-CT|^!ky^4A7udB@<*0kwB7vI-)nq=l_0(fe5
zkBi7gBF9Bcoc6<NF-#g4k&RAyOj^9%=3_<YamMC0fYCtLR}r}oxmAjYmj^hLTt`+1
zRCTyh@)?Dxh{Y^e+NuMpIv5&N7WDCVBl5M=0B!+z9Oa;-3`iRt9+5!hy{f(jFa_X-
zh^)1x14RNBkv{-#tLjpkD=*u5$B=13xe4GPc-8~JKL<=Y@!??g0{{R307*qoM6N<$
Ef;%S0RsaA1
literal 0
HcmV?d00001
diff --git a/src/wok/plugins/kimchi/ui/images/theme-default/icon-back.png
b/src/wok/plugins/kimchi/ui/images/theme-default/icon-back.png
new file mode 100644
index 0000000000000000000000000000000000000000..eca9948ca7f0c4eaa3c36d20e4fb2d72ac79b2d8
GIT binary patch
literal 244
zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=ffJ-JULvArbCxuSRn<C<w3y#71eK
zT)K72v}tTjuGj8VdL~>5@BMC(b=2TTSM%q?EFRVyo~rsxN}a;s^<!54Nr^X)q~g@x
z^JN^q%lN$@{6O#y=>_6_at*5DZ*m1wnKN6b$4D%Y<YV4)Sh2y?LNY=0pS;7ws8U8N
zRxu8ago~UK3wje6O$2ieNH=}5eE-k*!lQ-zA6s=>GtE7+RQk>%v4gUYTRgh7os8Nz
s0?gB1y)!t(JaL}EzvtS*278#<8D&)ztBkXBf!<*7boFyt=akR{0KU{)8UO$Q
literal 0
HcmV?d00001
diff --git a/src/wok/plugins/kimchi/ui/images/theme-default/icon-camera.png
b/src/wok/plugins/kimchi/ui/images/theme-default/icon-camera.png
new file mode 100644
index 0000000000000000000000000000000000000000..f181545ed44db658aa6373c28ca33724f84a3d05
GIT binary patch
literal 4860
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
literal 0
HcmV?d00001
diff --git a/src/wok/plugins/kimchi/ui/images/theme-default/icon-design.png
b/src/wok/plugins/kimchi/ui/images/theme-default/icon-design.png
new file mode 100644
index 0000000000000000000000000000000000000000..c8931dae58e4d3d95d7a1ebba04ed0481f4b74ff
GIT binary patch
literal 4562
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
literal 0
HcmV?d00001
diff --git a/src/wok/plugins/kimchi/ui/images/theme-default/icon-detail.png
b/src/wok/plugins/kimchi/ui/images/theme-default/icon-detail.png
new file mode 100644
index 0000000000000000000000000000000000000000..978df03ca7480d0f9ebb3b4f1a1f73226fcbe246
GIT binary patch
literal 3079
zcmV+i4EXbjP)<h;3K|Lk000e1NJLTq000~S000{Z1^@s6ZwT)!00009a7bBm000XU
z000XU0RWnu7ytkYPiaF#P*7-ZbZ>KLZ*U+<Lqi~Na&Km7Y-Iodc-oy)XH-+^7Crag
z^g>IBfRsybQWXdwQbLP>6p<z>Aqfylh#{fb6;Z(vMMVS~$e@S=j*ftg6;Uh<iVD~V
z<RPMtgQJLw%KPDaqifc@_vX$1wbwr9tn;0-&j-K=43<bUQ8j=JsX`tR;Dg7+#^K~H
zK!FM*Z~zbpvt%K2{UZSY_<lS*D<Z%Lz5oGu(+dayz)hRLFdT>f59&ghTmgWD0l;*T
zI7<kC6aYYajzXpYKt=(8otP$50H6c_V9R4-;{Z@C0AMG7=F<Rxo%or10RUT+Ar%3j
zkpLhQWr#!oXgdI`&sK^>09Y^p6lP1rIRMx#05C~cW=H_Aw*bJ-5DT&Z2n+x)QHX^p
z00esgV8|mQcmRZ%02D^@S3L16t`O%c004NIvOKvYIYoh62rY33S640`D9%Y2D-<?i
z0%4j!F2Z@488U%158(66005wo6%pWr^Zj_v4zAA5HjcIqUoGmt2LB>rV&neh&#Q1i
z007~1e$oCcFS8neI|hJl{-P!B1ZZ9hpmq0)X0i`JwE&>$+E?>%_<lS*MWK+n+1cgf
z<k(8YLR(?VSAG6x!e78w{cQPuJpA|d;J)G{fihizM+Erb!p!tcr5w+a34~(Y=8s4G
zw+sLL9n&JjNn*KJDiq^U5^;`1nvC-@r6P$!k}1U{(*I=Q-z@tBKHoI}uxdU5dyy@u
zU1J0GOD7Ombim^G008p4Z^6_k2m^p<gW=D2|L;HjN1!DDfM!XOaR2~bL?kX$%CkSm
z2mk;?pn)o|K^yeJ7%adB9Ki+L!3+FgHiSYX#KJ-lLJDMn9CBbOtb#%)hRv`YDqt_v
zKpix|QD}yfa1JiQRk#j4a1Z)n2%f<xynzV>LC6RbVIkUx0b+_+BaR3cnT7Zv!AJxW
zizFb)h!jyGOOZ85F;a?DAXP{m@;!0_Ifq<Ex{*7`05XF7hP+2Hl!3BQJ=6@fL%FCo
z8iYoo3(#bAF`ADSpqtQgv>H8(HlgRxt7s3}k3K`kFu>>-2Q$QMFfPW!La{h336o>X
zu_CMttHv6zR;&ZNiS=X8v3CR#fknUxHUxJ<AYmRsNLWl*PS{AOARHt#5!wki2?K;t
z!Y3k=s7tgax)J%r7-BLphge7~Bi0g+6E6^Zh(p9TBoc{3GAFr^0!gu?RMHaCM$&Fl
zBk3%un>0uoBa_M6WNWeqIg~6QE69c9o#eyhGvpiOA@W-aonk<7r1(?fC{oI5N*U!4
z<uv66WtcKSRim0x-Ke2d5jBrmLam{;Qm;{ms1r1GnmNsb7D-E`t)i9F8fX`2_i3-_
zbh;7Ul^#x)&{xvS=|||7=mYe33=M`AgU5(xC>fg=2N-7=cNnjjOr{yriy6mMFgG#l
znCF=fnQv8CDz++o6_Lscl}eQ+l^ZHARH>?_s@|##Rr6KLRFA1%Q+=*RRWnoLsR`7U
zt5vF<Q0r40Q)j6=sE4X&sBct1q<&fbi3VB2Ov6t@q*0);U*o*SAPZv|vv@2aYYnT0
zb%8a+Cb7-ge0D0knEf5Qi#@8Tp*ce{N;6lpQuCB%KL_KOarm5cP6_8Ir<e17iry6O
zDdH&`rZh~sF=bq9s+O0QSgS~@QL9Jmy*94xr=6y~MY~!1fet~(N+(<=M`w@D1)b+p
z*;C!83a1uLJv#NSE~;y#8=<>IcfW3@?wFpwUVxrVZ>QdQz32KIeJ}k~{cZZE^+ya?
z2D1z#2HOnI7(B%_ac?{wFUQ;QQA1tBKtrWrm0_3Rgps+?Jfqb{jYbcQX~taRB;#$y
zZN{S}1|}gUOHJxc?wV3fxuz+mJ4`!F$IZ;mqRrNsHJd##*D~ju=bP7?-?v~|cv>vB
zsJ6IeNwVZxrdjT`yl#bBIa#GxRa#xMMy;K#CDyyGyQdMSxlWT#tDe?p!?5wT$+oGt
z8L;Kp2HUQ-ZMJ=3XJQv;x5ci*?vuTfeY$;({XGW_huIFR9a<fJbF^|4I#xQ~n$Dc=
zKYhjYmgz5NSkDm8*fZm{6U!;YX`NG>(?@3)XSs8O^N5RyOM=TTmp(3=8^+zpz2r)C
z^>JO{deZfso3oq3?Wo(Y?l$ge?uXo;%ru`Vo>?<<(8I_>;8Eq#KMS9gFl*neeosSB
zfoHYnBQIkwkyowPu(zdms`p{<7e4kra-ZWq<2*OsGTvEV%s0Td$hXT+!*8Bnh2KMe
zBmZRodjHV?r+_5^X9J0WL4jKW`}lf%A-|44I@@LTvf1rHjG(ze6+w@Jt%Bvjts!X0
z?2xS?_ve_-k<Mujg;0Lz*3buG=3$G&ehepthlN*$KaOySSQ^nWmo<0M+(UEUMEXRQ
zMBbZcF;6+KElM>iKB_KiJlZ$9G`c^=E@oNG)mWWaNo-3TIW8)$Hg0Ub-~8?KhvJ>$
z3*&nim@mj(aCxE5!t{lw7O5^0EIO7zOo&c6l<+|iDySBWCGrz@C5{St!X3hAA}`T4
z(TLbXTq+(;@<=L8dXnssyft|w#WSTW<++3>sgS%(4NTpeI-VAqb|7ssJvzNHgOZVu
zaYCvgO_R1~>SyL=cFU|~g|hy|Zi}}s9+d~lYqOB71z9Z$wnC=pR9Yz4DhIM>Wmjgu
z&56o6maCpC&F##y%G;1PobR9i?GnNg;gYtchD%p19a!eQtZF&3JaKv33gZ<8D~47E
ztUS1iwkmDaPpj=$m#%)jCVEY4fnLGNg2A-`YwHVD3gv};>)hAvT~AmqS>Lr``i7kw
zJ{5_It`yrBmlc25DBO7E8;5VoznR>Ww5hAaxn$2~(q`%A-YuS64wkBy=9dm`4cXeX
z4c}I@?e+FW+b@^RDBHV(wnMq2zdX3SWv9u`%{xC-q*U}&`cyXV(%rRT*Z6MH?i+i&
z_B8C(+grT%{XWUQ+f@NoP1R=AW&26{v-dx)iK^-Nmiuj8txj!m?Z*Ss1N{dh4z}01
z)YTo*JycSU)+_5r4#yw9{+;i4Ee$peRgIj+;v;ZGdF1K$3E%e~4LaI(jC-u%2h$&R
z9cLXcYC@Xwnns&bn)_Q~Te?roKGD|d-g^8;+aC{{G(1^(O7m37Y1-+6)01cN&y1aw
zoqc{T`P^XJqPBbIW6s}d4{z_f5Om?vMgNQEJG?v2T=KYd^0M3I6IZxbny)%vZR&LD
zJpPl@Psh8QyPB@KTx+@RdcC!KX7}kEo;S|j^u2lU7XQ}Oo;f|;z4Ll+_r>@1-xl3|
zawq-H%e&ckC+@AhPrP6BK<z=<L*0kfKU@CX*zeqbYQT4(^U>T#_XdT7&;F71j}Joy
zkC~6lh7E@6o;W@^IpRNZ{ptLtL(gQ-CY~4mqW;US7Zxvm_|@yz&e53Bp_lTPlfP|z
zrTyx_>lv@x#=^!PzR7qqF<$gm`|ZJZ+;<)Cqu&ot<a{81DF0~rvGr5Xr~8u`lav1h
z1DNytV>2z=0000WV@Og>004R=004l4008;_004mL004C`008P>0026e000+nl3&F}
z0003pNkl<Zc-rjNKTg9i6oB#Xy(D%}o3>nnl_4EC2vUxQI+vN_AT9x__!AOR{8;RY
z1Gt^yB}1fqdbWR3#LT$lDgi`f18jgRKr?<n06p*yd;-TZzG$3t_o~{RVW?ncyKx-%
zfTdtr6h$W@TUA9wvKGy37>3~ys8aA(L~fjOR8@tl<__KhYv3ydCsloR&fR(Mvrkyp
z^$Sn~LkjjHa#U5$v8B$r67Z*63Vbw8^WeR&7K=rxs#%H>SKGEvfB-?v3=t7CtAJ}@
z1r(WvlgR7`H~@zfTmws>O6Q!>;deAR{%5iB-gm0no#6~a2w~Uv{T`T34pp@ik*$bi
zzci{knAz-bb~rnn9nKDOI*c5e=x~|QVX`;?ufSUhYK;2$%(<rln4-f;F8$~IHvo#L
Voc;M?!D;{i002ovPDHLkV1gS<wu1lw
literal 0
HcmV?d00001
diff --git a/src/wok/plugins/kimchi/ui/images/theme-default/icon-iso.png
b/src/wok/plugins/kimchi/ui/images/theme-default/icon-iso.png
new file mode 100644
index 0000000000000000000000000000000000000000..d76290427e75fd1c6ad914acde114e065760b30d
GIT binary patch
literal 4188
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
literal 0
HcmV?d00001
diff --git a/src/wok/plugins/kimchi/ui/images/theme-default/icon-list.png
b/src/wok/plugins/kimchi/ui/images/theme-default/icon-list.png
new file mode 100644
index 0000000000000000000000000000000000000000..7b3b595ffce5fab49dbd2588cebd113922b9dcbd
GIT binary patch
literal 2983
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
literal 0
HcmV?d00001
diff --git a/src/wok/plugins/kimchi/ui/images/theme-default/icon-load.png
b/src/wok/plugins/kimchi/ui/images/theme-default/icon-load.png
new file mode 100644
index 0000000000000000000000000000000000000000..2ad195ca84691697a63e720003fe48b1573590f9
GIT binary patch
literal 3678
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
literal 0
HcmV?d00001
diff --git a/src/wok/plugins/kimchi/ui/images/theme-default/icon-local.png
b/src/wok/plugins/kimchi/ui/images/theme-default/icon-local.png
new file mode 100644
index 0000000000000000000000000000000000000000..092026fbc9301b311d5e9bb8556450cd6fa93ff9
GIT binary patch
literal 425
zcmV;a0apHrP)<h;3K|Lk000e1NJLTq001BW001Be1^@s6b9#F80004SNkl<ZSV!%a
z3vt3g5QaekH~<v14oDTWC}^snNB{>oAXQKt6bFEU4h~uc@P9LR3`t0`$1CkjcIF>Q
z*t`919|`SN&DO3teyag!GGNU>tY)1DHtd`Hld3fqfJmEsRc%!8`;+c3%hpx_Ji6dr
zeNLr`5o9L6cj-q0VqLVZ41l1V9EcBzGKAPd&d)A55WwWD41m-PrH%9=eL5Hm1ScLz
zKs-q71%w$Ok>{)QEA=H(%5{jb2W11MBXLb*rtDM(VtLT<1drSXA%U~LlyK#4<|ZQx
zKtSK|rZF;-`9tBJnv7$BY{yeSU}(lm%ufOkxykSV*^VE}`TGjNJva~pDUni>;Q^NV
z!FN1mI5{$xq`|G_pu{>%1^`eUcl@n_d;Y$@93}&R-4#xD_7?vNfKufiBn3yO<4teR
z&<t20%)x;V1vtCbMGG5%Kal|*JiIRJuq_#g+|#gkXM(Nb#Z~_aZ_d;J)SiJoPBKc^
Ts5X1J00000NkvXXu0mjf;iIrQ
literal 0
HcmV?d00001
diff --git a/src/wok/plugins/kimchi/ui/images/theme-default/icon-power-down.png
b/src/wok/plugins/kimchi/ui/images/theme-default/icon-power-down.png
new file mode 100644
index 0000000000000000000000000000000000000000..2c653bc6af72f628cea721d618849d912c1aa186
GIT binary patch
literal 4372
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
O0000<MNUMnLSTY^CsYvt
literal 0
HcmV?d00001
diff --git a/src/wok/plugins/kimchi/ui/images/theme-default/icon-power-up.png
b/src/wok/plugins/kimchi/ui/images/theme-default/icon-power-up.png
new file mode 100644
index 0000000000000000000000000000000000000000..a4575f90120e56d21d42dc4fbefcfc571a30ef71
GIT binary patch
literal 4367
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
JPDHLkV1k37QX&8V
literal 0
HcmV?d00001
diff --git a/src/wok/plugins/kimchi/ui/images/theme-default/icon-qcow2.png
b/src/wok/plugins/kimchi/ui/images/theme-default/icon-qcow2.png
new file mode 100644
index 0000000000000000000000000000000000000000..a5220093e8143db08887f31decf8af059d654ba7
GIT binary patch
literal 4684
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
O0000<MNUMnLSTX?tJj49
literal 0
HcmV?d00001
diff --git a/src/wok/plugins/kimchi/ui/images/theme-default/icon-raw.png
b/src/wok/plugins/kimchi/ui/images/theme-default/icon-raw.png
new file mode 100644
index 0000000000000000000000000000000000000000..b5def8f3dddd81a3a570f3acbd3b206684275cbf
GIT binary patch
literal 4679
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
JPDHLkV1mo3<ud>P
literal 0
HcmV?d00001
diff --git a/src/wok/plugins/kimchi/ui/images/theme-default/icon-remote.png
b/src/wok/plugins/kimchi/ui/images/theme-default/icon-remote.png
new file mode 100644
index 0000000000000000000000000000000000000000..e316dc0701db28b51db92b5e6e6985f3b82b25e9
GIT binary patch
literal 1005
zcmV<J0}}j+P)<h;3K|Lk000e1NJLTq001BW001Be1^@s6b9#F8000BDNkl<ZSVxuC
zkM$Ep5C?FmK&Zf@0<Z$l3WN#>6^IoWD-bF$Rv=bjr~s(IPytwh&gb4t+~2yJgn4gX
z_U7i#cjw>b{=F}wr=k9R@DltW_(__-kKfP1r{Fiif86T!{tb$P{S+*?ptle(fc%)i
zrZ(3A?8EYhCh&)Jd`!n~j${J3HGw`(IUuisf1V+j0pRS<bj<d*U|>$STt9S{)PJ7(
zfPR;t@3<HNa2vsa_?S1Uo8B1ztR^Fe;IA_{5O;j_00jLjgG=|zJXe!R>6en;`8EBp
zf7E881<<Gcl#w3B?=iuYtOrr@rFr4}E(5pvF7r(ZS^)bH>h_+b4FIL_UPB3ZDI06N
zck32V>z5Dl?iGL;S~`Lqg3Y!YA<v@`lSO6YT=$!x5uHm>0646Uo!D$ySQCgdn?4Im
z$nfq4e<o{J066+8SmV_U&w!lMH&FmUBby)@;aB#YzYTtyzhXWFK$rfW!ELWmA5^Rj
z^$c0a*I*;8$pi$3zF<Ik|19l2KLg+pEd6Q<z%kg|_T)wy@lx{%x=(xhHO7FD`;M?b
zrLWfj2q-nx?Q4Pp;_qN%!+_pl0IU@W_)8;jA;gw{09twrfB@<)ZO(`zEbyALC7(MV
z=SS~Hb6*Nod(Xfq)q4Q`NsWFh?nACLY9_UndZ0#Spns`<*jZ|t@=TWiP*U?<@G-d3
z+1j_~YXIo#3qa_~z_y601klYI%%l_`y<r-FY6;j{R5OtL8{<Rpr{E8xCY%|sg*p{v
zq(-W200l(JoJZ62I^=9+U~58X)cV?jDZLipi?kns7Nqa`+9NeB+ZaM>5h=y_D>d*q
z0zmB)EVaFD`E6ZQnXByEB0?PK&PVBRbfYDNw%3TP+Uk>fzs6x}w1$8biyu4YK>;|#
zgECxOwWGB1-;Xfa2!Q$D2U~nwtTNOzr(jvAjX1n&2y1WDdkaRep7_-1MVjvztlVzD
z1b=RkLuQev4-m7FYyn99?t*UB8VKJS{|^K{H+-MEGJq6_p4JdlUERVnn;8M;pOMcz
z;6~Kh??yd<wiKgGltZ>|^y)%zuWBE-xuECN&j659JO=BBQ?Ob0jP}9GWC3Z&YqW-f
zuVV%Gd?#b0?&TD6LF?bqA<nfz^+rE(J&+}V?(&7S3;w^pngJ+>Zft9{UogPPIW30(
z11kt{RbwevCi+9V27nRgoN#>SQ#x}Ra)Ffy_}MgV=C=T7;{bt|1Xd-gY^d)sgI~b+
b->ZKC*A4Oh7Gf$=00000NkvXXu0mjfz>VSq
literal 0
HcmV?d00001
diff --git a/src/wok/plugins/kimchi/ui/images/theme-default/icon-reset.png
b/src/wok/plugins/kimchi/ui/images/theme-default/icon-reset.png
new file mode 100644
index 0000000000000000000000000000000000000000..eae8449a556d68a44c28144727f7bb3c5d2fc13c
GIT binary patch
literal 4576
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
KMNUMnLSTYcw5GuT
literal 0
HcmV?d00001
diff --git a/src/wok/plugins/kimchi/ui/images/theme-default/icon-search.png
b/src/wok/plugins/kimchi/ui/images/theme-default/icon-search.png
new file mode 100644
index 0000000000000000000000000000000000000000..b38cf6cba2ae18095f990c7dd3736365d9965fe1
GIT binary patch
literal 4197
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
literal 0
HcmV?d00001
diff --git a/src/wok/plugins/kimchi/ui/images/theme-default/icon-sort.png
b/src/wok/plugins/kimchi/ui/images/theme-default/icon-sort.png
new file mode 100644
index 0000000000000000000000000000000000000000..78e8b3930368c9ee163ea6f28a0c5a1d631241a9
GIT binary patch
literal 3421
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
literal 0
HcmV?d00001
diff --git a/src/wok/plugins/kimchi/ui/images/theme-default/icon-tree.png
b/src/wok/plugins/kimchi/ui/images/theme-default/icon-tree.png
new file mode 100644
index 0000000000000000000000000000000000000000..5f7ed5312dac8d3bfb26010ea6555682f5a43f3d
GIT binary patch
literal 3526
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
A0ssI2
literal 0
HcmV?d00001
diff --git a/src/wok/plugins/kimchi/ui/images/theme-default/icon-user.png
b/src/wok/plugins/kimchi/ui/images/theme-default/icon-user.png
new file mode 100644
index 0000000000000000000000000000000000000000..f4258d420b98a019332bc742e15d53497e1012cf
GIT binary patch
literal 5366
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
U)&>o#U;qFB07*qoM6N<$f|wvR(EtDd
literal 0
HcmV?d00001
diff --git a/src/wok/plugins/kimchi/ui/images/theme-default/icon-volume-default.png
b/src/wok/plugins/kimchi/ui/images/theme-default/icon-volume-default.png
new file mode 100644
index 0000000000000000000000000000000000000000..ac906c7723e9c26900c347cf5e47e3192a5b2f88
GIT binary patch
literal 4265
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
LNkvXXu0mjfnm8lp
literal 0
HcmV?d00001
diff --git a/src/wok/plugins/kimchi/ui/images/theme-default/kimchi-loading15x15.gif
b/src/wok/plugins/kimchi/ui/images/theme-default/kimchi-loading15x15.gif
new file mode 100644
index 0000000000000000000000000000000000000000..aaa4f85a0560dcb59d4bb70154a9144417aae926
GIT binary patch
literal 1653
zcmZ?wbhEHb6krfwcz&0`fx$V3fzy*s(30KRoyj+pP0*a%B9B4Xkl)0X$H9|dJd8D}
zo<ZDBSSFF7*jZT0OhTc9Q7nTgk3rREDud*7MxI>8&Ju=(ISf+93MQOdag7Y~1hic{
z8T#{u6)cohTNtM^7+W$J#50+i$>`cj=^O84k`pyFn#{1$Ur8%a&i6QjtgEuCfQhw>
zh77A6gQ$gokA@_-E$2dp^>Sv?oMy2Rvbjr`S1FsTIOwZtnQE_R*m$2oUC1KhF@wT7
z#vS5TPBXdYi#jqhIC*|#&}Xr)`pY25?86wZk@$x}Azj<#4}*rAu{Vcnu(UhJUj}_&
zGsWW!mvn9Irz#jqI|d0m<_4Kq$D4?%x#%8bJFV#KwS(tqvz9fdTmMyIV-~+CKU<>^
zTODbStQ;$e9OEp8kfaJrQB(IojUXN?PfLA&1ruKlE$<Ybz{O>Dnh|c+IZj3l84L_z
z+ZiGkGQ_8gg)Ec{ZB|VbVu;;p8Ir+}TJcZ8St};J)7e)ugI_wAy~kUSA^Gq;v#nzB
zo6<uZ9TN=&l6EuXHCx41&a>X&p6tkweNrgxtWY&KLrITauKX0wDL;*ZSPITdWuHCl
z7S2#|o1wN-skGcGd-j}YNrw7v?ff;HUH7htly%83WoVk=SR=P3TA8QnVNZtdt|Td^
z4tBRT;l<gOCKJSuq^f)gOk<w3o@>%d>z1S5joVY2V;E+x4Cszxn7#dGQiZ}|@k{wq
ze5<)H#@>~ixp+mvx~nC^*GqKvReGJxyd=J8Z|Hp0)LG8{Q?7j|(|J;(^S(;?X-VtX
z{Ej0{$vo>WNUb@RHtpd12Emt&YTJ7ve>HRaY*WxWB$BmO<7<oVrMfE&d+u577yI7H
zdv${AuTG6`J!)PD74G*(XRN&WpI$)mKewN2NU*bGfUA+70W%{51B2pE7EU3C{|q`n
zHZYS2Ffee)GW_S1@z}87U^9oXR?LYF3lFyoD0|KE*tqCuBO@a=9coY=j!k!j<aB0i
zc<9u4hfS*nq@!EHIP1=djf>s;v1`@Ep>^V-!(BqkNq@`*laF`Fn|H~0Zd!7(0h{Hf
zM42F;^~FLc<zy?bzucZ38xtI`nPf?{Nk)rZI#dI#a%KcAJ>AR3%!JJ}Tb!mjcL>V+
z&Dl|qe5_B>QtnB`#6;Il`9QBD85<TlO;@&EX5(p~fXzf_h=~b~c^s@tPtrczcWUF8
zl$)Y)G4W`lxU|rj6$Xj!z4E$EBA!9O@K)2-%Q<1V)NzW4rQ4Q{qQ@s^Df6<iU^CYa
zVJ@$f%ZvcUgKd2BZZRt+Jap&~-N|`mN5EtIK6cxtnin4*pO_@<TefG1V5)aFPwc)q
zGcP6L3rdhvk&Uz{R5;QluAbJjV`8#<o~Uk<jm4+?Cwh5=mxY`NNH{%#3wux+Vs{|2
sX~(-16pJpOC{Q`pufUDnn>s|9;tWh`McC5^G?`;~3OSj#0+YEl0GD)I?EnA(
literal 0
HcmV?d00001
diff --git a/src/wok/plugins/kimchi/ui/images/theme-default/loading.gif
b/src/wok/plugins/kimchi/ui/images/theme-default/loading.gif
new file mode 100644
index 0000000000000000000000000000000000000000..60d46d2683817f81a678c5e3eef14ef35089d119
GIT binary patch
literal 2190
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
L$~1kj8oc@+?)_VM
literal 0
HcmV?d00001
diff --git a/src/wok/plugins/kimchi/ui/images/theme-default/user.png
b/src/wok/plugins/kimchi/ui/images/theme-default/user.png
new file mode 100644
index 0000000000000000000000000000000000000000..c57a81a92757ef31c424a4e6c741f71db62a1092
GIT binary patch
literal 1322
zcmV+_1=aeAP)<h;3K|Lk000e1NJLTq001BW001Be1^@s6b9#F80000PbVXQnQ*UN;
zcVTj606}DLVr3vnZDD6+Qe|Oed2z{QJOBU$%t=H+RCwCFS6xgTRTRGSvwt(QEW2!%
zZEC<RY*%PmU|~TT(9l}brY~)zO*HkzHZ`VcV>GER{yyo84?Y{zXpHs6S4l9Y#$eJ`
zmI9TeNz<hS;wC6n(*0#;*YAuwlVv;L6r^`@m^(Xj@A=NT=X~eDmCI%J$6w2=dc>kV
zY@@+(9ODK4xF85;1zu=k91CHOq^hbvsYP|PR4&aWrYD(|;jiDtI5Pm<(b&U^nWnhO
zZnuB!bUFte4hIuOQ3F&emDt+a8q4K!YCf0$1oO+2)4!@#0EkwQl5$ualok1!EXhHq
z%gJmu8{>K206<bG6ogDB^F}6}*^Ol{S=pO6{k6PaIG$r3kLNqL+Z|Ng3M1<QNK>wD
z0wClKm&?WQ4U=X0#ew+2^IHe7-h8rlfP@r~VhtmXu2yJ}XCzr-e!u_2cz2($B>?5B
zi|2UO+S2;E!|Bj0HB)Q`0>S806y@n{9{~c7$%@p!ndP-YM`IIhEY=e{_Fn+RjXY4D
zb{x;w(OtLDQsClyUxV+7?FS)7Fxa?e#qxE6tFbYV-gXdDdWFN`J9K{(0F)I&&kRj$
zI|#vW?8M0vpCb(|D<`nShlY!hry^t9K7x{3LJ-PdzWUnvKdl1r@A9)#r$@fP4l7&p
zK#etB9o>b2g9B$ST)a@CRMeTzOi1}V@4bC5&=`2jO0Zg@ViXxFP-BUi$(LJN_Ksfp
z=3D3WYuB~o(FYyT;UkCH$jA$KK}644v0lp-vto3ht%C^2h1~xbJa874jpHaz!TRjf
zY@!{XyqnEtPcAMl+BGYX^P$j_DNIKpA3+{;9_VVv`tOm%b^yJ6^VZZ?maAd3z0;0@
z^8+}4h*+&yEHYHNtJz%k6}(OoDNW5J6wD))C57Iu_-s)vYB2+#M<hwQVt3em#0U9&
zo&oSVtQoZgARg=c6uf^<=YBd{Y`}8a9F^U1Jl{ry%u<!a_#1N%?h2Ge@cpwW*%8Sl
zF#ymAiApspWGS6aAB88zHwA!z8&qWFXDTRUy%7gEZ}J3fMsuAPv~1!2Wj+Ec3L+D2
zqQ(OhuzFCF7qC8cf8~C7W^Vd{X+O}>78M%&4WH3QB-PYQo53<|<J#h5P&Rc-l^#J?
ztdGi32J7nTKEUIfrfCS5pT-%6Ny$cqM^~a*D~g8DbG5~0>&O6nb1AyN(`O36>+`;^
zE8i^Fw<;AciT(!v#fQ?cbAMMCx}7NsJl&F=7!*g?e<hVl1yaAKR6|o}Z|D*QkY09o
zN@#y%ln=dSY#kHg^-=2m9;N1QW$4+`+|+aik2gd;`n?U_M)dhR4nPNiKf{Ix&_Fij
z3wd5}JSG6RifhF^Mi%tOdm`1jyVF9%1!9s64=8STpq4mxa*!S{s%Us%UnHDGZax<4
zb!iSYtJOTviuu)rdkcFeCVpX4i3FROnWX~qzgZm!1kk2;v%da**4x{|>b>>js0Gj0
z79%RJ$03IxgUidyp5)ymo1dR&^T~O(w6w(16;L1%wz|4%C<yKjGVr{ij5;GUFVxVY
zR|qke<XXV1A0cCv`|^h6xNTp%_8-x2w{KCTwpR&x%A<1^#8<T}S=9xRvL(nY<R)Z}
gniR8!<R1YB09_*wa#VgYhyVZp07*qoM6N<$f^kM~^#A|>
literal 0
HcmV?d00001
diff --git a/src/wok/plugins/kimchi/ui/js/Makefile.am
b/src/wok/plugins/kimchi/ui/js/Makefile.am
new file mode 100644
index 0000000..c9d1218
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/js/Makefile.am
@@ -0,0 +1,27 @@
+#
+# Kimchi
+#
+# Copyright IBM, Corp. 2013
+#
+# 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.
+
+EXTRA_DIST = src
+
+jsdir = $(datadir)/wok/plugins/kimchi/ui/js
+
+dist_js_DATA = kimchi.min.js $(filter-out kimchi.min.js, $(wildcard *.js))
+
+kimchi.min.js: src/*.js
+ cat $(sort $^) > $@
+
+CLEANFILES = kimchi.min.js
diff --git a/src/wok/plugins/kimchi/ui/js/src/kimchi.api.js
b/src/wok/plugins/kimchi/ui/js/src/kimchi.api.js
new file mode 100644
index 0000000..fde803a
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/js/src/kimchi.api.js
@@ -0,0 +1,1355 @@
+/*
+ * Project Kimchi
+ *
+ * Copyright IBM, Corp. 2013-2015
+ *
+ * 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.
+ */
+var kimchi = {
+
+ widget: {},
+
+ trackingTasks: [],
+
+ /**
+ *
+ * Get host capabilities
+ * suc: callback if succeed err: callback if failed
+ */
+ getCapabilities : function(suc, err, done) {
+ done = typeof done !== 'undefined' ? done: function(){};
+ wok.requestJSON({
+ url : "plugins/kimchi/config/capabilities",
+ type : "GET",
+ contentType : "application/json",
+ dataType : "json",
+ success: suc,
+ error: err,
+ complete: done
+ });
+ },
+
+ /**
+ * Get the i18 strings.
+ */
+ getI18n: function(suc, err, url, sync) {
+ wok.requestJSON({
+ url : url ? url : 'plugins/kimchi/i18n.json',
+ type : 'GET',
+ resend: true,
+ dataType : 'json',
+ async : !sync,
+ success : suc,
+ error: err
+ });
+ },
+
+ /**
+ * Get the host static information.
+ */
+ getHost: function(suc, err) {
+ wok.requestJSON({
+ url : 'plugins/kimchi/host',
+ type : 'GET',
+ resend: true,
+ contentType : 'application/json',
+ dataType : 'json',
+ success : suc,
+ error: err
+ });
+ },
+
+ /**
+ * Get the dynamic host stats (usually used for monitoring).
+ */
+ getHostStats : function(suc, err) {
+ wok.requestJSON({
+ url : 'plugins/kimchi/host/stats',
+ type : 'GET',
+ contentType : 'application/json',
+ headers: {'Wok-Robot': 'wok-robot'},
+ dataType : 'json',
+ success : suc,
+ error: err
+ });
+ },
+
+ /**
+ * Get the historic host stats.
+ */
+ getHostStatsHistory : function(suc, err) {
+ wok.requestJSON({
+ url : 'plugins/kimchi/host/stats/history',
+ type : 'GET',
+ resend: true,
+ contentType : 'application/json',
+ headers: {'Wok-Robot': 'wok-robot'},
+ dataType : 'json',
+ success : suc,
+ error: err
+ });
+ },
+
+ /**
+ *
+ * Create a new Virtual Machine. Usage: kimchi.createVM({ name: 'MyUbuntu',
+ * template: '/templates/ubuntu_base' }, creationSuc, creationErr);
+ *
+ * settings: name *(optional)*: The name of the VM. Used to identify the VM
+ * in this API. If omitted, a name will be chosen based on the template
+ * used. template: The URI of a Template to use when building the VM
+ * storagepool *(optional)*: Assign a specific Storage Pool to the new VM
+ * suc: callback if succeed err: callback if failed
+ */
+ createVM : function(settings, suc, err) {
+ wok.requestJSON({
+ url : "plugins/kimchi/vms",
+ type : "POST",
+ contentType : "application/json",
+ data : JSON.stringify(settings),
+ dataType : "json"
+ }).done(suc).fail(err);
+ },
+
+ /**
+ *
+ * Create a new Template. settings name: The name of the Template. Used to
+ * identify the Template in this API suc: callback if succeed err: callback
+ * if failed
+ */
+ createTemplate : function(settings, suc, err) {
+ wok.requestJSON({
+ url : "plugins/kimchi/templates",
+ type : "POST",
+ contentType : "application/json",
+ data : JSON.stringify(settings),
+ dataType : "json",
+ success: suc,
+ error: err
+ });
+ },
+
+ deleteTemplate : function(tem, suc, err) {
+ wok.requestJSON({
+ url : 'plugins/kimchi/templates/' + encodeURIComponent(tem),
+ type : 'DELETE',
+ contentType : 'application/json',
+ dataType : 'json',
+ success : suc,
+ error : err
+ });
+ },
+
+ cloneTemplate : function(tem, suc, err) {
+ wok.requestJSON({
+ url : 'plugins/kimchi/templates/' + encodeURIComponent(tem) +
"/clone",
+ type : 'POST',
+ contentType : 'application/json',
+ dataType : 'json',
+ success : suc,
+ error : err
+ });
+ },
+
+ listTemplates : function(suc, err) {
+ wok.requestJSON({
+ url : 'plugins/kimchi/templates',
+ type : 'GET',
+ contentType : 'application/json',
+ dataType : 'json',
+ success : suc,
+ error : err
+ });
+ },
+
+ /**
+ * Retrieve the information of a template by the given name.
+ */
+ retrieveTemplate : function(templateName, suc, err) {
+ wok.requestJSON({
+ url : 'plugins/kimchi/templates/' +
encodeURIComponent(templateName),
+ type : 'GET',
+ contentType : 'application/json',
+ dataType : 'json'
+ }).done(suc);
+ },
+
+ /**
+ * Update a template with new information. TODO: Update me when the RESTful
+ * API is available. Now work it around by remove the template and then
+ * recreate it with new information.
+ */
+ updateTemplate : function(name, settings, suc, err) {
+ $.ajax({
+ url : 'plugins/kimchi/templates/' + encodeURIComponent(name),
+ type : 'PUT',
+ contentType : 'application/json',
+ data : JSON.stringify(settings),
+ dataType : 'json'
+ }).done(suc).fail(err);
+ },
+
+ /**
+ * Create a new Storage Pool. settings name: The name of the Storage Pool
+ * path: The path of the defined Storage Pool type: The type of the defined
+ * Storage Pool capacity: The total space which can be used to store volumes
+ * The unit is MBytes suc: callback if succeed err: callback if failed
+ */
+ createStoragePool : function(settings, suc, err) {
+ wok.requestJSON({
+ url : 'plugins/kimchi/storagepools',
+ type : 'POST',
+ contentType : 'application/json',
+ data : JSON.stringify(settings),
+ dataType : 'json'
+ }).done(suc).fail(err);
+ },
+
+ updateStoragePool : function(name, content, suc, err) {
+ $.ajax({
+ url : "plugins/kimchi/storagepools/" + encodeURIComponent(name),
+ type : 'PUT',
+ contentType : 'application/json',
+ dataType : 'json',
+ data : JSON.stringify(content)
+ }).done(suc).fail(err ? err : function(data) {
+ wok.message.error(data.responseJSON.reason);
+ });
+ },
+
+ startVM : function(vm, suc, err) {
+ wok.requestJSON({
+ url : 'plugins/kimchi/vms/' + encodeURIComponent(vm) +
'/start',
+ type : 'POST',
+ contentType : 'application/json',
+ dataType : 'json',
+ success : suc,
+ error : err
+ });
+ },
+
+ poweroffVM : function(vm, suc, err) {
+ wok.requestJSON({
+ url : 'plugins/kimchi/vms/' + encodeURIComponent(vm) +
'/poweroff',
+ type : 'POST',
+ contentType : 'application/json',
+ dataType : 'json',
+ success : suc,
+ error : err
+ });
+ },
+
+ shutdownVM : function(vm, suc, err) {
+ wok.requestJSON({
+ url : 'plugins/kimchi/vms/' + encodeURIComponent(vm) +
'/shutdown',
+ type : 'POST',
+ contentType : 'application/json',
+ dataType : 'json',
+ success : suc,
+ error : err
+ });
+ },
+
+ resetVM : function(vm, suc, err) {
+ wok.requestJSON({
+ url : 'plugins/kimchi/vms/' + encodeURIComponent(vm) +
'/reset',
+ type : 'POST',
+ contentType : 'application/json',
+ dataType : 'json',
+ success : suc,
+ error : err
+ });
+ },
+
+ suspendVM : function(vm, suc, err) {
+ wok.requestJSON({
+ url : 'plugins/kimchi/vms/' + encodeURIComponent(vm) +
'/suspend',
+ type : 'POST',
+ contentType : 'application/json',
+ dataType : 'json',
+ success : suc,
+ error : err
+ });
+ },
+
+ resumeVM : function(vm, suc, err) {
+ wok.requestJSON({
+ url : 'plugins/kimchi/vms/' + encodeURIComponent(vm) +
'/resume',
+ type : 'POST',
+ contentType : 'application/json',
+ dataType : 'json',
+ success : suc,
+ error : err
+ });
+ },
+
+ /**
+ * Retrieve the information of a given VM by its name.
+ *
+ * @param vm VM name
+ * @param suc callback for success
+ * @param err callback for error
+ */
+ retrieveVM : function(vm, suc, err) {
+ $.ajax({
+ url : 'plugins/kimchi/vms/' + encodeURIComponent(vm),
+ type : 'GET',
+ contentType : 'application/json',
+ dataType : 'json',
+ success: suc,
+ error: err
+ });
+ },
+
+ /**
+ * Update a VM with new information.
+ */
+ updateVM : function(name, settings, suc, err) {
+ $.ajax({
+ url : "plugins/kimchi/vms/" + encodeURIComponent(name),
+ type : 'PUT',
+ contentType : 'application/json',
+ data : JSON.stringify(settings),
+ dataType : 'json',
+ success: suc,
+ error: err
+ });
+ },
+
+ deleteVM : function(vm, suc, err) {
+ wok.requestJSON({
+ url : 'plugins/kimchi/vms/' + encodeURIComponent(vm),
+ type : 'DELETE',
+ contentType : 'application/json',
+ dataType : 'json',
+ success : suc,
+ error : err
+ });
+ },
+
+ vncToVM : function(vm) {
+ wok.requestJSON({
+ url : 'plugins/kimchi/config',
+ type : 'GET',
+ dataType : 'json'
+ }).done(function(data, textStatus, xhr) {
+ proxy_port = data['display_proxy_port'];
+ wok.requestJSON({
+ url : "plugins/kimchi/vms/" + encodeURIComponent(vm) +
"/connect",
+ type : "POST",
+ dataType : "json"
+ }).done(function() {
+ url = 'https://' + location.hostname + ':' + proxy_port;
+ url += "/console.html?url=";
+ url +=
encodeURIComponent("plugins/kimchi/novnc/vnc_auto.html");
+ url += "&port=" + proxy_port;
+ /*
+ * From python documentation base64.urlsafe_b64encode(s)
+ * substitutes - instead of + and _ instead of / in the
+ * standard Base64 alphabet, BUT the result can still
+ * contain = which is not safe in a URL query component.
+ * So remove it when needed as base64 can work well without it.
+ * */
+ url += "&path=?token=" +
wok.urlSafeB64Encode(vm).replace(/=*$/g, "");
+ url += "&wok=" + location.port;
+ url += '&encrypt=1';
+ window.open(url);
+ });
+ }).error(function() {
+ wok.message.error.code('KCHAPI6002E');
+ });
+ },
+
+ spiceToVM : function(vm) {
+ wok.requestJSON({
+ url : 'plugins/kimchi/config',
+ type : 'GET',
+ dataType : 'json'
+ }).done(function(data, textStatus, xhr) {
+ proxy_port = data['display_proxy_port'];
+ wok.requestJSON({
+ url : "plugins/kimchi/vms/" + encodeURIComponent(vm) +
"/connect",
+ type : "POST",
+ dataType : "json"
+ }).done(function(data, textStatus, xhr) {
+ url = 'https://' + location.hostname + ':' + proxy_port;
+ url += "/console.html?url=plugins/kimchi/spice_auto.html";
+ url += "&port=" + proxy_port + "&listen=" +
location.hostname;
+ /*
+ * From python documentation base64.urlsafe_b64encode(s)
+ * substitutes - instead of + and _ instead of / in the
+ * standard Base64 alphabet, BUT the result can still
+ * contain = which is not safe in a URL query component.
+ * So remove it when needed as base64 can work well without it.
+ * */
+ url += "&token=" + wok.urlSafeB64Encode(vm).replace(/=*$/g,
"");
+ url += "&wok=" + location.port;
+ url += '&encrypt=1';
+ window.open(url);
+ });
+ }).error(function() {
+ wok.message.error.code('KCHAPI6002E');
+ });
+ },
+
+ listVMs : function(suc, err) {
+ wok.requestJSON({
+ url : 'plugins/kimchi/vms',
+ type : 'GET',
+ contentType : 'application/json',
+ headers: {'Wok-Robot': 'wok-robot'},
+ dataType : 'json',
+ resend: true,
+ success : suc,
+ error : err
+ });
+ },
+
+ listTemplates : function(suc, err) {
+ wok.requestJSON({
+ url : 'plugins/kimchi/templates',
+ type : 'GET',
+ contentType : 'application/json',
+ dataType : 'json',
+ resend: true,
+ success : suc,
+ error : err
+ });
+ },
+
+ listStoragePools : function(suc, err) {
+ wok.requestJSON({
+ url : 'plugins/kimchi/storagepools',
+ type : 'GET',
+ contentType : 'application/json',
+ dataType : 'json',
+ resend: true,
+ success : suc,
+ error : err
+ });
+ },
+
+ listStorageVolumes : function(poolName, suc, err) {
+ $.ajax({
+ url : 'plugins/kimchi/storagepools/' + encodeURIComponent(poolName) +
'/storagevolumes',
+ type : 'GET',
+ contentType : 'application/json',
+ dataType : 'json',
+ success : suc,
+ error : err
+ });
+ },
+
+ listIsos : function(suc, err) {
+ wok.requestJSON({
+ url : 'plugins/kimchi/storagepools/kimchi_isos/storagevolumes',
+ type : 'GET',
+ contentType : 'application/json',
+ dataType : 'json',
+ success : suc,
+ error : err
+ });
+ },
+
+ listDistros : function(suc, err) {
+ wok.requestJSON({
+ url : 'plugins/kimchi/config/distros',
+ type : 'GET',
+ contentType : 'application/json',
+ dataType : 'json',
+ success : suc,
+ error : err
+ });
+ },
+
+ stepListDeepScanIsos : function(suc, err) {
+ var deepScanHandler = {
+ stop : false
+ };
+ var isoPool = 'iso' + new Date().getTime();
+ kimchi.createStoragePool({
+ name : isoPool,
+ type : 'kimchi-iso',
+ path : '/'
+ }, function(result) {
+ var taskId = result.task_id;
+ function monitorTask() {
+ if (deepScanHandler.stop) {
+ return;
+ }
+ kimchi.getTask(taskId, function(result) {
+ var status = result.status;
+ if (status === "finished") {
+ if (deepScanHandler.stop) {
+ return;
+ }
+ kimchi.listStorageVolumes(isoPool, function(isos) {
+ if (deepScanHandler.stop) {
+ return;
+ }
+ suc(isos, true);
+ }, err);
+ } else if (status === "running") {
+ if (deepScanHandler.stop) {
+ return;
+ }
+ kimchi.listStorageVolumes(isoPool, function(isos) {
+ if (deepScanHandler.stop) {
+ return;
+ }
+ suc(isos, false);
+ setTimeout(monitorTask, 2000);
+ }, err);
+ } else if (status === "failed") {
+ if (deepScanHandler.stop) {
+ return;
+ }
+ err(result.message);
+ }
+ }, err);
+ }
+ setTimeout(monitorTask, 2000);
+ }, err);
+ return deepScanHandler;
+ },
+
+ getTask : function(taskId, suc, err) {
+ wok.requestJSON({
+ url : 'tasks/' + encodeURIComponent(taskId),
+ type : 'GET',
+ contentType : 'application/json',
+ dataType : 'json',
+ success : suc,
+ error : err
+ });
+ },
+
+ getTasksByFilter : function(filter, suc, err, sync) {
+ wok.requestJSON({
+ url : 'tasks?' + filter,
+ type : 'GET',
+ contentType : 'application/json',
+ dataType : 'json',
+ async : !sync,
+ success : suc,
+ error : err
+ });
+ },
+
+ deleteStoragePool : function(poolName, suc, err) {
+ $.ajax({
+ url : 'plugins/kimchi/storagepools/' + encodeURIComponent(poolName),
+ type : 'DELETE',
+ contentType : 'application/json',
+ dataType : 'json',
+ success : suc,
+ error : err
+ });
+ },
+
+ changePoolState : function(poolName, state, suc, err) {
+ if (state === 'activate' || state === 'deactivate')
+ $.ajax({
+ url : 'plugins/kimchi/storagepools/' +
encodeURIComponent(poolName) + '/' + state,
+ type : 'POST',
+ contentType : 'application/json',
+ dataType : 'json',
+ success : suc,
+ error : err
+ });
+ },
+
+ listNetworks : function(suc, err) {
+ wok.requestJSON({
+ url : 'plugins/kimchi/networks',
+ type : 'GET',
+ contentType : 'application/json',
+ dataType : 'json',
+ resend : true,
+ success : suc,
+ error : err ? err : function(data) {
+ wok.message.error(data.responseJSON.reason);
+ }
+ });
+ },
+
+ toggleNetwork : function(name, on, suc, err) {
+ var action = on ? "activate" : "deactivate";
+ wok.requestJSON({
+ url : 'plugins/kimchi/networks/' + encodeURIComponent(name) +
'/' + action,
+ type : 'POST',
+ contentType : 'application/json',
+ dataType : 'json',
+ success : suc,
+ error : err ? err : function(data) {
+ wok.message.error(data.responseJSON.reason);
+ }
+ });
+ },
+
+ createNetwork : function(network, suc, err) {
+ wok.requestJSON({
+ url : 'plugins/kimchi/networks',
+ type : 'POST',
+ contentType : 'application/json',
+ dataType : 'json',
+ data : JSON.stringify(network),
+ success : suc,
+ error : err ? err : function(data) {
+ wok.message.error(data.responseJSON.reason);
+ }
+ });
+ },
+
+ getInterfaces : function(suc, err) {
+ wok.requestJSON({
+ url : 'plugins/kimchi/interfaces',
+ type : 'GET',
+ contentType : 'application/json',
+ dataType : 'json',
+ resend : true,
+ success : suc,
+ error : err ? err : function(data) {
+ wok.message.error(data.responseJSON.reason);
+ }
+ });
+ },
+
+ deleteNetwork : function(name, suc, err) {
+ wok.requestJSON({
+ url : 'plugins/kimchi/networks/' + encodeURIComponent(name),
+ type : 'DELETE',
+ contentType : 'application/json',
+ dataType : 'json',
+ success : suc,
+ error : err ? err : function(data) {
+ wok.message.error(data.responseJSON.reason);
+ }
+ });
+ },
+
+ listReports : function(suc, err) {
+ wok.requestJSON({
+ url : 'plugins/kimchi/debugreports',
+ type : 'GET',
+ contentType : 'application/json',
+ dataType : 'json',
+ resend: true,
+ success : suc,
+ error : err
+ });
+ },
+
+ trackTask : function(taskID, suc, err, progress) {
+ var onTaskResponse = function(result) {
+ var taskStatus = result['status'];
+ switch(taskStatus) {
+ case 'running':
+ progress && progress(result);
+ setTimeout(function() {
+ kimchi.trackTask(taskID, suc, err, progress);
+ }, 2000);
+ break;
+ case 'finished':
+ suc && suc(result);
+ break;
+ case 'failed':
+ err && err(result);
+ break;
+ default:
+ break;
+ }
+ };
+
+ kimchi.getTask(taskID, onTaskResponse, err);
+ if(kimchi.trackingTasks.indexOf(taskID) < 0)
+ kimchi.trackingTasks.push(taskID);
+ },
+
+ createReport: function(settings, suc, err, progress) {
+ var onResponse = function(data) {
+ taskID = data['id'];
+ kimchi.trackTask(taskID, suc, err, progress);
+ };
+
+ wok.requestJSON({
+ url : 'plugins/kimchi/debugreports',
+ type : "POST",
+ contentType : "application/json",
+ data : JSON.stringify(settings),
+ dataType : "json",
+ success : onResponse,
+ error : err
+ });
+ },
+
+ renameReport : function(name, settings, suc, err) {
+ $.ajax({
+ url : "plugins/kimchi/debugreports/" + encodeURIComponent(name),
+ type : 'PUT',
+ contentType : 'application/json',
+ data : JSON.stringify(settings),
+ dataType : 'json',
+ success: suc,
+ error: err
+ });
+ },
+
+ deleteReport: function(settings, suc, err) {
+ var reportName = encodeURIComponent(settings['name']);
+ wok.requestJSON({
+ url : 'plugins/kimchi/debugreports/' + reportName,
+ type : 'DELETE',
+ contentType : 'application/json',
+ dataType : 'json',
+ success : suc,
+ error : err
+ });
+ },
+
+ downloadReport: function(settings, suc, err) {
+ window.open(settings['file']);
+ },
+
+ shutdown: function(settings, suc, err) {
+ var reboot = settings && settings['reboot'] === true;
+ var url = 'plugins/kimchi/host/' + (reboot ? 'reboot' :
'shutdown');
+ wok.requestJSON({
+ url : url,
+ type : 'POST',
+ contentType : 'application/json',
+ dataType : 'json',
+ success : suc,
+ error : err
+ });
+ },
+
+ listHostPartitions : function(suc, err) {
+ wok.requestJSON({
+ url : 'plugins/kimchi/host/partitions',
+ type : 'GET',
+ contentType : 'application/json',
+ dataType : 'json',
+ success : suc,
+ error : err
+ });
+ },
+
+ getStorageServers: function(type, suc, err) {
+ var url = 'plugins/kimchi/storageservers?_target_type=' + type;
+ wok.requestJSON({
+ url : url,
+ type : 'GET',
+ contentType : 'application/json',
+ dataType : 'json',
+ success : suc,
+ error : err ? err : function(data) {
+ wok.message.error(data.responseJSON.reason);
+ }
+ });
+ },
+
+ getStorageTargets: function(server,type, suc, err) {
+ var url = 'plugins/kimchi/storageservers/' + server +
'/storagetargets?_target_type=' + type;
+ wok.requestJSON({
+ url : url,
+ type : 'GET',
+ contentType : 'application/json',
+ timeout: 2000,
+ dataType : 'json',
+ success : suc,
+ error : err
+ });
+ },
+
+ getStoragePool: function(poolName, suc, err) {
+ var url = 'plugins/kimchi/storagepools/' + encodeURIComponent(poolName);
+ wok.requestJSON({
+ url : url,
+ type : 'GET',
+ contentType : 'application/json',
+ timeout: 2000,
+ dataType : 'json',
+ success : suc,
+ error : err
+ });
+ },
+
+ getStoragePoolVolume: function(poolName, volumeName, suc, err) {
+ var url = 'plugins/kimchi/storagepools/' + encodeURIComponent(poolName) +
'/storagevolumes/' + encodeURIComponent(volumeName);
+ wok.requestJSON({
+ url : url,
+ type : 'GET',
+ contentType : 'application/json',
+ timeout: 2000,
+ dataType : 'json',
+ success : suc,
+ error : err
+ });
+ },
+
+ addVMStorage : function(settings, suc, err) {
+ var vm = encodeURIComponent(settings['vm']);
+ delete settings['vm'];
+ wok.requestJSON({
+ url : 'plugins/kimchi/vms/' + vm + '/storages',
+ type : 'POST',
+ contentType : 'application/json',
+ data : JSON.stringify(settings),
+ dataType : 'json',
+ success : suc,
+ error : err
+ });
+ },
+
+ retrieveVMStorage : function(settings, suc, err) {
+ var vm = encodeURIComponent(settings['vm']);
+ var dev = encodeURIComponent(settings['dev']);
+ wok.requestJSON({
+ url : "plugins/kimchi/vms/" + vm + '/storages/' + dev,
+ type : 'GET',
+ contentType : 'application/json',
+ dataType : 'json',
+ success: suc,
+ error: err
+ });
+ },
+
+ replaceVMStorage : function(settings, suc, err) {
+ var vm = encodeURIComponent(settings['vm']);
+ var dev = encodeURIComponent(settings['dev']);
+ wok.requestJSON({
+ url : 'plugins/kimchi/vms/' + vm + '/storages/' + dev,
+ type : 'PUT',
+ contentType : 'application/json',
+ data : JSON.stringify({
+ path: settings['path']
+ }),
+ dataType : 'json',
+ success : suc,
+ error : err
+ });
+ },
+
+ deleteVMStorage : function(settings, suc, err) {
+ var vm = settings['vm'];
+ var dev = settings['dev'];
+ wok.requestJSON({
+ url : 'plugins/kimchi/vms/' + encodeURIComponent(vm) +
+ '/storages/' + encodeURIComponent(dev),
+ type : 'DELETE',
+ contentType : 'application/json',
+ dataType : 'json',
+ success : suc,
+ error : err
+ });
+ },
+
+ listVMStorages : function(params, suc, err) {
+ var vm = encodeURIComponent(params['vm']);
+ var type = params['storageType'];
+ var url = 'plugins/kimchi/vms/' + vm + '/storages';
+ if(type) {
+ url += '?type=' + type;
+ }
+ wok.requestJSON({
+ url : url,
+ type : 'GET',
+ contentType : 'application/json',
+ dataType : 'json',
+ success : suc,
+ error : err
+ });
+ },
+
+ listSoftwareUpdates : function(suc, err) {
+ wok.requestJSON({
+ url : 'plugins/kimchi/host/packagesupdate',
+ type : 'GET',
+ contentType : 'application/json',
+ dataType : 'json',
+ resend: true,
+ success : suc,
+ error : err
+ });
+ },
+
+ updateSoftware : function(suc, err, progress) {
+ var taskID = -1;
+ var onResponse = function(data) {
+ taskID = data['id'];
+ trackTask();
+ };
+
+ var trackTask = function() {
+ kimchi.getTask(taskID, onTaskResponse, err);
+ };
+
+ var onTaskResponse = function(result) {
+ var taskStatus = result['status'];
+ switch(taskStatus) {
+ case 'running':
+ progress && progress(result);
+ setTimeout(function() {
+ trackTask();
+ }, 200);
+ break;
+ case 'finished':
+ case 'failed':
+ suc(result);
+ break;
+ default:
+ break;
+ }
+ };
+
+ wok.requestJSON({
+ url : 'plugins/kimchi/host/swupdate',
+ type : "POST",
+ contentType : "application/json",
+ dataType : "json",
+ success : onResponse,
+ error : err
+ });
+ },
+
+ createRepository : function(settings, suc, err) {
+ wok.requestJSON({
+ url : "plugins/kimchi/host/repositories",
+ type : "POST",
+ contentType : "application/json",
+ data : JSON.stringify(settings),
+ dataType : "json",
+ success: suc,
+ error: err
+ });
+ },
+
+ retrieveRepository : function(repository, suc, err) {
+ var reposID = encodeURIComponent(repository);
+ wok.requestJSON({
+ url : "plugins/kimchi/host/repositories/" + reposID,
+ type : 'GET',
+ contentType : 'application/json',
+ dataType : 'json',
+ success : suc,
+ error : err
+ });
+ },
+
+ updateRepository : function(name, settings, suc, err) {
+ var reposID = encodeURIComponent(name);
+ $.ajax({
+ url : "plugins/kimchi/host/repositories/" + reposID,
+ type : 'PUT',
+ contentType : 'application/json',
+ data : JSON.stringify(settings),
+ dataType : 'json',
+ success : suc,
+ error : err
+ });
+ },
+
+ enableRepository : function(name, enable, suc, err) {
+ var reposID = encodeURIComponent(name);
+ $.ajax({
+ url : "plugins/kimchi/host/repositories/" + reposID +
+ '/' + (enable === true ? 'enable' :
'disable'),
+ type : 'POST',
+ contentType : 'application/json',
+ dataType : 'json',
+ success : suc,
+ error : err
+ });
+ },
+
+ deleteRepository : function(repository, suc, err) {
+ var reposID = encodeURIComponent(repository);
+ wok.requestJSON({
+ url : 'plugins/kimchi/host/repositories/' + reposID,
+ type : 'DELETE',
+ contentType : 'application/json',
+ dataType : 'json',
+ success : suc,
+ error : err
+ });
+ },
+
+ listRepositories : function(suc, err) {
+ wok.requestJSON({
+ url : 'plugins/kimchi/host/repositories',
+ type : 'GET',
+ contentType : 'application/json',
+ dataType : 'json',
+ resend: true,
+ success : suc,
+ error : err
+ });
+ },
+
+ getHostFCDevices: function(suc, err) {
+ var url = 'plugins/kimchi/host/devices?_cap=fc_host';
+ wok.requestJSON({
+ url : url,
+ type : 'GET',
+ contentType : 'application/json',
+ dataType : 'json',
+ success : suc,
+ error : err ? err : function(data) {
+ wok.message.error(data.responseJSON.reason);
+ }
+ });
+ },
+
+ getGuestInterfaces: function(name, suc, err) {
+ var url = 'plugins/kimchi/vms/' + encodeURIComponent(name) +
'/ifaces';
+ wok.requestJSON({
+ url : url,
+ type : 'GET',
+ contentType : 'application/json',
+ dataType : 'json',
+ success : suc,
+ error : err || function(data) {
+ wok.message.error(data.responseJSON.reason);
+ }
+ });
+ },
+
+ createGuestInterface : function(name, interface, suc, err) {
+ wok.requestJSON({
+ url : 'plugins/kimchi/vms/' + encodeURIComponent(name) +
'/ifaces',
+ type : 'POST',
+ contentType : 'application/json',
+ dataType : 'json',
+ data : JSON.stringify(interface),
+ success : suc,
+ error : err || function(data) {
+ wok.message.error(data.responseJSON.reason);
+ }
+ });
+ },
+
+ deleteGuestInterface : function(vm, mac, suc, err) {
+ wok.requestJSON({
+ url : 'plugins/kimchi/vms/' + encodeURIComponent(vm) +
'/ifaces/' + encodeURIComponent(mac),
+ type : 'DELETE',
+ contentType : 'application/json',
+ dataType : 'json',
+ success : suc,
+ error : err ? err : function(data) {
+ wok.message.error(data.responseJSON.reason);
+ }
+ });
+ },
+
+ updateGuestInterface : function(vm, mac, interface, suc, err) {
+ $.ajax({
+ url : 'plugins/kimchi/vms/' + encodeURIComponent(vm) +
'/ifaces/' + encodeURIComponent(mac),
+ type : 'PUT',
+ contentType : 'application/json',
+ data : JSON.stringify(interface),
+ dataType : 'json',
+ success: suc,
+ error: err ? err : function(data) {
+ wok.message.error(data.responseJSON.reason);
+ }
+ });
+ },
+
+ getUserById : function(data, suc, err) {
+ wok.requestJSON({
+ url : 'plugins/kimchi/users?_user_id=' + data.user_id,
+ type : 'GET',
+ contentType : 'application/json',
+ dataType : 'json',
+ resend : true,
+ async : false,
+ success : suc && suc(data),
+ error : err ? err : function(data) {
+ wok.message.error(data.responseJSON.reason);
+ }
+ });
+ },
+
+ getUsers : function(suc, err) {
+ wok.requestJSON({
+ url : 'plugins/kimchi/users',
+ type : 'GET',
+ contentType : 'application/json',
+ dataType : 'json',
+ resend : true,
+ success : suc,
+ error : err ? err : function(data) {
+ wok.message.error(data.responseJSON.reason);
+ }
+ });
+ },
+
+ getGroups : function(suc, err) {
+ wok.requestJSON({
+ url : 'plugins/kimchi/groups',
+ type : 'GET',
+ contentType : 'application/json',
+ dataType : 'json',
+ resend : true,
+ success : suc,
+ error : err ? err : function(data) {
+ wok.message.error(data.responseJSON.reason);
+ }
+ });
+ },
+
+ getHostPCIDevices : function(suc, err) {
+ wok.requestJSON({
+ url : 'plugins/kimchi/host/devices?_passthrough=true&_cap=pci',
+ type : 'GET',
+ contentType : 'application/json',
+ dataType : 'json',
+ resend : true,
+ success : suc,
+ error : err ? err : function(data) {
+ wok.message.error(data.responseJSON.reason);
+ }
+ });
+ },
+
+ getPCIDeviceCompanions : function(pcidev, suc, err) {
+ wok.requestJSON({
+ url : 'plugins/kimchi/host/devices?_passthrough_affected_by=' +
pcidev,
+ type : 'GET',
+ contentType : 'application/json',
+ dataType : 'json',
+ resend : true,
+ success : suc,
+ error : err ? err : function(data) {
+ wok.message.error(data.responseJSON.reason);
+ }
+ });
+ },
+
+ getISCSITargets : function(server, port, suc, err) {
+ server = encodeURIComponent(server);
+ port = port ? '&_server_port='+encodeURIComponent(port) :
'';
+ wok.requestJSON({
+ url : 'plugins/kimchi/storageservers/' + server +
'/storagetargets?_target_type=iscsi' + port,
+ type : 'GET',
+ contentType : 'application/json',
+ dataType : 'json',
+ resend : true,
+ success : suc,
+ error : err ? err : function(data) {
+ wok.message.error(data.responseJSON.reason);
+ }
+ });
+ },
+
+ getPeers : function(suc, err) {
+ wok.requestJSON({
+ url : 'plugins/kimchi/peers',
+ type : 'GET',
+ contentType : 'application/json',
+ dataType : 'json',
+ resend : true,
+ success : suc,
+ error : err ? err : function(data) {
+ wok.message.error(data.responseJSON.reason);
+ }
+ });
+ },
+
+ getVMPCIDevices : function(id, suc, err) {
+ wok.requestJSON({
+ url : 'plugins/kimchi/vms/' + encodeURIComponent(id) +
'/hostdevs',
+ type : 'GET',
+ contentType : 'application/json',
+ dataType : 'json',
+ resend : true,
+ success : suc,
+ error : err ? err : function(data) {
+ wok.message.error(data.responseJSON.reason);
+ }
+ });
+ },
+
+ addVMPCIDevice : function(vm, device, suc, err) {
+ wok.requestJSON({
+ url : 'plugins/kimchi/vms/'+ encodeURIComponent(vm)
+'/hostdevs',
+ type : 'POST',
+ contentType : 'application/json',
+ dataType : 'json',
+ data : JSON.stringify(device),
+ success : suc,
+ error : err ? err : function(data) {
+ wok.message.error(data.responseJSON.reason);
+ }
+ });
+ },
+
+ removeVMPCIDevice : function(vm, device, suc, err) {
+ wok.requestJSON({
+ url : 'plugins/kimchi/vms/'+ encodeURIComponent(vm)
+'/hostdevs/' + encodeURIComponent(device),
+ type : 'DELETE',
+ contentType : 'application/json',
+ dataType : 'json',
+ success : suc,
+ error : err ? err : function(data) {
+ wok.message.error(data.responseJSON.reason);
+ }
+ });
+ },
+
+ /**
+ * Create a new volume with capacity
+ */
+ createVolumeWithCapacity: function(poolName, settings, suc, err) {
+ wok.requestJSON({
+ url : 'plugins/kimchi/storagepools/' + encodeURIComponent(poolName) +
'/storagevolumes',
+ type : 'POST',
+ contentType : "application/json",
+ data : JSON.stringify(settings),
+ dataType : "json",
+ success : suc,
+ error : err
+ });
+ },
+
+ /**
+ * Upload volume content
+ */
+ uploadVolumeToSP: function(poolName, volumeName, settings, suc, err) {
+ var url = 'plugins/kimchi/storagepools/' + encodeURIComponent(poolName) +
'/storagevolumes/' + encodeURIComponent(volumeName);
+ var fd = settings['formData'];
+ wok.requestJSON({
+ url : url,
+ type : 'PUT',
+ data : fd,
+ processData : false,
+ contentType : false,
+ dataType: 'json',
+ success : suc,
+ error : err
+ });
+ },
+
+ /**
+ * Add a volume to a given storage pool by URL.
+ */
+ downloadVolumeToSP: function(settings, suc, err) {
+ var sp = encodeURIComponent(settings['sp']);
+ delete settings['sp'];
+ wok.requestJSON({
+ url : 'plugins/kimchi/storagepools/' + sp +
'/storagevolumes',
+ type : 'POST',
+ data : JSON.stringify(settings),
+ contentType : 'application/json',
+ dataType : 'json',
+ success : suc,
+ error : err
+ });
+ },
+
+ cloneGuest: function(vm, suc, err) {
+ wok.requestJSON({
+ url : 'plugins/kimchi/vms/' + encodeURIComponent(vm) +
"/clone",
+ type : 'POST',
+ contentType : 'application/json',
+ dataType : 'json',
+ success : suc,
+ error : err ? err : function(data) {
+ wok.message.error(data.responseJSON.reason);
+ }
+ });
+ },
+
+ listSnapshots : function(vm, suc, err) {
+ wok.requestJSON({
+ url : 'plugins/kimchi/vms/' + encodeURIComponent(vm) +
'/snapshots',
+ type : 'GET',
+ contentType : 'application/json',
+ dataType : 'json',
+ resend : true,
+ success : suc,
+ error : err ? err : function(data) {
+ wok.message.error(data.responseJSON.reason);
+ }
+ });
+ },
+
+ getCurrentSnapshot : function(vm, suc, err, sync) {
+ wok.requestJSON({
+ url : 'plugins/kimchi/vms/' + encodeURIComponent(vm) +
'/snapshots/current',
+ type : 'GET',
+ contentType : 'application/json',
+ dataType : 'json',
+ async : !sync,
+ resend : true,
+ success : suc,
+ error : err ? err : function(data) {
+ wok.message.error(data.responseJSON.reason);
+ }
+ });
+ },
+
+ revertSnapshot : function(vm, snapshot, suc, err) {
+ wok.requestJSON({
+ url : 'plugins/kimchi/vms/' + encodeURIComponent(vm) +
'/snapshots/' + encodeURIComponent(snapshot) + '/revert',
+ type : 'POST',
+ contentType : 'application/json',
+ dataType : 'json',
+ success : suc,
+ error : err ? err : function(data) {
+ wok.message.error(data.responseJSON.reason);
+ }
+ });
+ },
+
+ createSnapshot : function(vm, suc, err) {
+ wok.requestJSON({
+ url : 'plugins/kimchi/vms/' + encodeURIComponent(vm) +
'/snapshots',
+ type : 'POST',
+ contentType : 'application/json',
+ dataType : 'json',
+ success : suc,
+ error : err ? err : function(data) {
+ wok.message.error(data.responseJSON.reason);
+ }
+ });
+ },
+
+ deleteSnapshot : function(vm, snapshot, suc, err) {
+ wok.requestJSON({
+ url : 'plugins/kimchi/vms/' + encodeURIComponent(vm) +
'/snapshots/' + encodeURIComponent(snapshot),
+ type : 'DELETE',
+ contentType : 'application/json',
+ dataType : 'json',
+ success : suc,
+ error : err ? err : function(data) {
+ wok.message.error(data.responseJSON.reason);
+ }
+ });
+ },
+
+ getCPUInfo : function(suc, err) {
+ wok.requestJSON({
+ url : 'plugins/kimchi/host/cpuinfo',
+ type : 'GET',
+ contentType : 'application/json',
+ dataType : 'json',
+ resend : true,
+ success : suc,
+ error : err ? err : function(data) {
+ wok.message.error(data.responseJSON.reason);
+ }
+ });
+ }
+};
diff --git a/src/wok/plugins/kimchi/ui/js/src/kimchi.guest_add_main.js
b/src/wok/plugins/kimchi/ui/js/src/kimchi.guest_add_main.js
new file mode 100644
index 0000000..6be6f9a
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/js/src/kimchi.guest_add_main.js
@@ -0,0 +1,86 @@
+/*
+ * Project Kimchi
+ *
+ * Copyright IBM, Corp. 2013-2014
+ *
+ * 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.
+ */
+kimchi.guest_add_main = function() {
+ var showTemplates = function() {
+ wok.topic('templateCreated').unsubscribe(showTemplates);
+ kimchi.listTemplates(function(result) {
+ if (result && result.length) {
+ $('#prompt-create-template').addClass('hidden');
+ $('#prompt-choose-template').removeClass('hidden');
+ var html = '';
+ var tmpl = $('#tmpl-template').html();
+ $.each(result, function(index, value) {
+ html += wok.substitute(tmpl, value);
+ });
+ $('#templateTile').html(html);
+ return;
+ }
+
+ $('#btn-create-template').on('click', function(event) {
+ wok.topic('templateCreated').subscribe(showTemplates);
+
+ wok.window.open('plugins/kimchi/template-add.html');
+
+ event.preventDefault();
+ });
+
+ $('#prompt-choose-template').addClass('hidden');
+ $('#prompt-create-template').removeClass('hidden');
+ }, function(err) {
+ wok.message.error(err.responseJSON.reason);
+ });
+ };
+
+ function validateForm() {
+ if (!$('input[name=template]:checked', '#templateTile').val()) {
+ return false;
+ }
+ return true;
+ }
+
+ $('#form-vm-add').change(function() {
+ if (validateForm()) {
+ $('#vm-doAdd').attr('disabled', false);
+ }
+ });
+
+ var addGuest = function(event) {
+ $('#vm-doAdd').attr('disabled', true);
+ $('#vm-doAdd').attr('style', 'display:none');
+ $('#vm-doAdding').attr('style', 'display');
+ var formData = $('#form-vm-add').serializeObject();
+ kimchi.createVM(formData, function() {
+ kimchi.listVmsAuto();
+ wok.window.close();
+ }, function(jqXHR, textStatus, errorThrown) {
+ $('#vm-doAdd').attr('style', 'display');
+ $('#vm-doAdding').attr('style', 'display:none');
+ var reason = jqXHR &&
+ jqXHR['responseJSON'] &&
+ jqXHR['responseJSON']['reason'];
+ wok.message.error(reason);
+ });
+
+ return false;
+ };
+
+ $('#form-vm-add').on('submit', addGuest);
+ $('#vm-doAdd').on('click', addGuest);
+
+ showTemplates();
+};
diff --git a/src/wok/plugins/kimchi/ui/js/src/kimchi.guest_edit_main.js
b/src/wok/plugins/kimchi/ui/js/src/kimchi.guest_edit_main.js
new file mode 100644
index 0000000..7105c88
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/js/src/kimchi.guest_edit_main.js
@@ -0,0 +1,759 @@
+/*
+ * Project Kimchi
+ *
+ * Copyright IBM, Corp. 2013-2015
+ *
+ * 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.
+ */
+kimchi.guest_edit_main = function() {
+ var buttonContainer = $('#action-button-container');
+ $('#guest-edit-tabs').tabs({
+ beforeActivate: function(event, ui) {
+ var display_list = null;
+ if(kimchi.thisVMState === "running") {
+ display_list = ['form-guest-edit-permission'];
+ } else {
+ display_list = ['form-guest-edit-general',
'form-guest-edit-permission'];
+ }
+ $(buttonContainer).addClass('hidden');
+ var deactivated = ui['newPanel'];
+ if(display_list.indexOf($(deactivated).attr('id')) >= 0) {
+ $(buttonContainer).removeClass('hidden');
+ }
+ }
+ });
+
+ var guestEditForm = $('#form-guest-edit-general');
+ var saveButton = $('#guest-edit-button-save');
+ var authType;
+
+ var refreshCDROMs = function() {
+ kimchi.listVMStorages({
+ vm: kimchi.selectedGuest
+ }, function(storages) {
+ var container = $('#form-guest-edit-storage .body');
+ $(container).empty();
+ $.each(storages, function(index, storage) {
+ storage['vm'] = kimchi.selectedGuest;
+ rowHTML = $('#' + storage['type'] +
'-row-tmpl').html();
+ var templated = wok.substitute(rowHTML, storage);
+ container.append(templated);
+ });
+
+ $('.replace', container).button({
+ icons: {
+ primary: 'ui-icon-pencil'
+ },
+ text: false
+ });
+
+ $('.detach', container).button({
+ icons: {
+ primary: 'ui-icon-trash'
+ },
+ text: false
+ });
+ if (kimchi.thisVMState === 'running') {
+ $('.detach[data-type="cdrom"]', container).remove();
+ }
+
+ $('.save', container).button({
+ icons: {
+ primary: 'ui-icon-disk'
+ },
+ text: false
+ });
+
+ $('.cancel', container).button({
+ icons: {
+ primary: 'ui-icon-arrowreturnthick-1-w'
+ },
+ text: false
+ });
+ });
+ };
+
+ var initStorageListeners = function() {
+ var container = $('#form-guest-edit-storage .body');
+ var toggleCDROM = function(rowNode, toEdit) {
+ $('button.replace,button.detach', rowNode)
+ [(toEdit ? 'add' : 'remove') +
'Class']('hidden');
+ $('button.save,button.cancel', rowNode)
+ [(toEdit ? 'remove' : 'add') +
'Class']('hidden');
+ var pathBox = $('.path input', rowNode)
+ .prop('readonly', !toEdit);
+ toEdit && pathBox.select();
+ pathBox.val(pathBox.attr('value'));
+ };
+
+ var replaceCDROM = function(event) {
+ event.preventDefault();
+ kimchi.selectedGuestStorage = $(this).data('dev');
+ $('.item', container).each(function(i, n) {
+ toggleCDROM(n);
+ });
+ var rowNode = $('#cdrom-' + kimchi.selectedGuestStorage);
+ toggleCDROM(rowNode, true);
+ };
+
+ $(container).on('click', 'button.replace', replaceCDROM);
+
+ $(container).on('click', 'button.detach', function(e) {
+ e.preventDefault();
+ var settings = {
+ title : i18n['KCHAPI6004M'],
+ content : i18n['KCHVMCD6001M'],
+ confirm : i18n['KCHAPI6002M'],
+ cancel : i18n['KCHAPI6003M']
+ };
+ if ($(this).data('type') == "disk")
+ settings['content'] = i18n['KCHVMCD6009M'];
+
+ var dev = $(this).data('dev');
+ wok.confirm(settings, function() {
+ kimchi.deleteVMStorage({
+ vm: kimchi.selectedGuest,
+ dev: dev
+ }, function() {
+ wok.topic('kimchi/vmCDROMDetached').publish();
+ });
+ });
+ });
+
+ $(container).on('click', 'button.save', function(event) {
+ event.preventDefault();
+ var path = $('#cdrom-path-' + kimchi.selectedGuestStorage).val();
+ var settings = {
+ vm: kimchi.selectedGuest,
+ dev: kimchi.selectedGuestStorage,
+ path: path
+ };
+
+ kimchi.replaceVMStorage(settings, function(result) {
+ wok.topic('kimchi/vmCDROMReplaced').publish({
+ result: result
+ });
+ }, function(result) {
+ var errText = result['reason'] ||
+ result['responseJSON']['reason'];
+ wok.message.error(errText);
+ });
+ });
+
+ $(container).on('click', 'button.cancel', function(event) {
+ event.preventDefault();
+ var rowNode = $('#cdrom-' + kimchi.selectedGuestStorage);
+ toggleCDROM(rowNode);
+ });
+ };
+
+ var setupInterface = function() {
+ $(".add", "#form-guest-edit-interface").button({
+ icons: { primary: "ui-icon-plusthick" },
+ text: false
+ }).click(function(evt){
+ evt.preventDefault();
+ addItem({
+ id: -1,
+ mac: "",
+ network: "",
+ type: "network",
+ viewMode: "hide",
+ editMode: ""
+ });
+ });
+ var toggleEdit = function(item, on, itemId){
+ $("#label-mac-" + itemId, item).toggleClass("hide", on);
+ $("#edit-mac-" + itemId, item).toggleClass("hide", !on);
+ $("#label-network-" + itemId, item).toggleClass("hide",
false);
+ $("select", item).toggleClass("hide", true);
+ $(".action-area", item).toggleClass("hide");
+ };
+ var addItem = function(data) {
+ if (data.id == -1) {
+ data.id = $('#form-guest-edit-interface >
.body').children().size()
+ }
+ var itemNode =
$.parseHTML(wok.substitute($('#interface-tmpl').html(),data));
+ $(".body",
"#form-guest-edit-interface").append(itemNode);
+ $("select", itemNode).append(networkOptions);
+ if(data.network!==""){
+ $("select", itemNode).val(data.network);
+ }
+ $(".edit", itemNode).button({
+ disabled: kimchi.thisVMState === "running",
+ icons: { primary: "ui-icon-pencil" },
+ text: false
+ }).click(function(evt){
+ evt.preventDefault();
+ toggleEdit($(this).closest('div'), true, data.id);
+ });
+ $(".delete", itemNode).button({
+ icons: { primary: "ui-icon-trash" },
+ text: false
+ }).click(function(evt){
+ evt.preventDefault();
+ var item = $(this).parent().parent();
+ kimchi.deleteGuestInterface(kimchi.selectedGuest,
item.prop("id"), function(){
+ item.remove();
+ });
+ });
+ $(".save", itemNode).button({
+ icons: { primary: "ui-icon-disk" },
+ text: false
+ }).click(function(evt){
+ evt.preventDefault();
+ var item = $(this).parent().parent();
+ var interface = {
+ network: $("select", item).val(),
+ type: "network",
+ mac: $(":text", item).val()
+ };
+ var postUpdate = function(mac){
+ $("#label-network-" + data.id,
item).text(interface.network);
+ $("#label-mac-" + data.id, item).text(mac);
+ $("#edit-mac-" + data.id, item).val(mac);
+ toggleEdit(item, false, data.id);
+ };
+ if(item.prop("id")==""){
+ kimchi.createGuestInterface(kimchi.selectedGuest, interface,
function(data){
+ item.prop("id", data.mac);
+ postUpdate(data.mac);
+ });
+ }else{
+ if (item.prop('id') == interface.mac) {
+ toggleEdit(item, false, data.id);
+ } else {
+ kimchi.updateGuestInterface(kimchi.selectedGuest,
item.prop('id'),
+ interface, function(data){
+ item.prop("id", data.mac);
+ postUpdate(data.mac);
+ });
+ }
+ }
+ });
+ $(".cancel", itemNode).button({
+ icons: { primary: "ui-icon-arrowreturnthick-1-w" },
+ text: false
+ }).click(function(evt){
+ evt.preventDefault();
+ var item = $(this).parent().parent();
+ $("label", item).text()==="" ? item.remove() :
toggleEdit(item, false, data.id);
+ });
+ };
+ var networkOptions = "";
+ kimchi.listNetworks(function(data){
+ for(var i=0;i<data.length;i++){
+ var isSlected = i==0 ? " selected" : "";
+ networkOptions +=
"<option"+isSlected+">"+data[i].name+"</option>";
+ }
+ kimchi.getGuestInterfaces(kimchi.selectedGuest, function(data){
+ for(var i=0;i<data.length;i++){
+ data[i].viewMode = "";
+ data[i].editMode = "hide";
+ data[i].id = i;
+ addItem(data[i]);
+ }
+ });
+ });
+ };
+
+ var setupPermission = function() {
+ //set up for LDAP
+ $(".add", "#form-guest-edit-permission").button({
+ icons: { primary: "ui-icon-plusthick" },
+ text: false
+ }).click(function(evt){
+ evt.preventDefault();
+ addItem({
+ user: "",
+ freeze: false,
+ viewMode: "hide",
+ editMode: "",
+ checked: true
+ });
+ });
+ var addItem = function(data) {
+ var itemNode =
$.parseHTML(wok.substitute($('#ldap-user-tmpl').html(),data));
+ $(".body", "#form-guest-edit-permission
.ldap").append(itemNode);
+ $(".delete", itemNode).button({
+ icons: { primary: "ui-icon-trash" },
+ text: false
+ }).click(function(evt){
+ evt.preventDefault();
+ var item = $(this).parent().parent();
+ item.remove();
+ });
+ $("input").focusout(function() {
+ var item = $(this).parent().parent();
+ var user= $(this).val();
+ item.prop("id", user);
+ $("label", item).text(user);
+ });
+ $("input").focusin(function() {
+ $(this).removeClass("checked");
+ });
+
+ if (data.checked == true) {
+ $(".checked", itemNode).addClass("hide");
+ }
+ };
+ var toggleEdit = function(item, on){
+ $("label", item).toggleClass("hide", on);
+ $("input", item).toggleClass("hide", !on);
+ $(".action-area", item).toggleClass("hide");
+ };
+ //set up for PAM
+ var userNodes = {}, groupNodes = {};
+ authType = kimchi.capabilities['auth']
+ if (authType == 'pam') {
+ $("#form-guest-edit-permission .ldap").hide();
+ kimchi.retrieveVM(kimchi.selectedGuest, function(vm){
+ kimchi.getUsers(function(users){
+ kimchi.getGroups(function(groups){
+ var subArray = function(a1, a2){ //a1-a2
+ for(var i=0; i<a2.length; i++){
+ for(var j=0; j<a1.length; j++){
+ if(a2[i] == a1[j]){
+ a1.splice(j, 1);
+ break;
+ }
+ }
+ }
+ };
+ subArray(users, vm.users); subArray(groups, vm.groups);
+ init(users, groups, vm.users, vm.groups);
+ });
+ });
+ });
+ } else if (authType == 'ldap') {
+ $("#form-guest-edit-permission .pam").hide();
+ kimchi.retrieveVM(kimchi.selectedGuest, function(vm){
+ for (var i=0; i<vm.users.length; i++) {
+ addItem({
+ user: vm.users[i],
+ viewMode: "",
+ freeze: true,
+ editMode: "hide",
+ checked: true});
+ }
+ });
+ }
+ var sortNodes = function(container, isUser){
+ nodes = container.children();
+ var keys = [];
+ nodes.each(function(){
+ keys.push($("label", this).text());
+ });
+ keys.sort();
+ container.empty();
+ for(var i=0; i<keys.length; i++){
+ var itemNode = isUser ? userNodes[keys[i]] : groupNodes[keys[i]];
+ $(itemNode).click(function(){
+ $(this).toggleClass("item-picked");
+ });
+ container.append(itemNode);
+ }
+ };
+ var init = function(availUsers, availGroups, selUsers, selGroups){
+ var initNode = function(key, isUserNode){
+ var nodeGroups = isUserNode ? userNodes : groupNodes;
+ nodeGroups[key] =
$.parseHTML(wok.substitute($('#permission-item-pam').html(), {
+ val: key,
+ class: isUserNode? "user-icon" : "group-icon"
+ }));
+ };
+ for(var i=0; i<availUsers.length; i++){
+ initNode(availUsers[i], true);
+ $("#permission-avail-users").append(userNodes[availUsers[i]]);
+ sortNodes($("#permission-avail-users"), true);
+ }
+ for(var i=0; i<selUsers.length; i++){
+ initNode(selUsers[i], true);
+ $("#permission-sel-users").append(userNodes[selUsers[i]]);
+ sortNodes($("#permission-sel-users"), true);
+ }
+ for(var i=0; i<availGroups.length; i++){
+ initNode(availGroups[i], false);
+
$("#permission-avail-groups").append(groupNodes[availGroups[i]]);
+ sortNodes($("#permission-avail-groups"), false);
+ }
+ for(var i=0; i<selGroups.length; i++){
+ initNode(selGroups[i], false);
+ $("#permission-sel-groups").append(groupNodes[selGroups[i]]);
+ sortNodes($("#permission-sel-groups"), false);
+ }
+ };
+ var filterNodes = function(key, container){
+ container.children().each(function(){
+ $(this).css("display", $("label",
this).text().indexOf(key)==-1 ? "none" : "");
+ });
+ }
+ $("#permission-avail-searchBox").on("keyup", function() {
+ var key = $(this).val();
+ filterNodes(key, $("#permission-avail-users"));
+ filterNodes(key, $("#permission-avail-groups"));
+ });
+ $("#permission-sel-searchBox").on("keyup", function() {
+ var key = $(this).val();
+ filterNodes(key, $("#permission-sel-users"));
+ filterNodes(key, $("#permission-sel-groups"));
+ });
+ $('#permissionGo').button().click(function(evt) {
+ evt.preventDefault();
+
$("#permission-avail-users").children(".item-picked").appendTo("#permission-sel-users").removeClass("item-picked");
+ sortNodes($("#permission-sel-users"), true);
+
$("#permission-avail-groups").children(".item-picked").appendTo("#permission-sel-groups").removeClass("item-picked");
+ sortNodes($("#permission-sel-groups"), false);
+ $("#permission-sel-searchBox").val("");
+ filterNodes("", $("#permission-sel-users"));
+ filterNodes("", $("#permission-sel-groups"));
+ });
+ $('#permissionBack').button().click(function(evt) {
+ evt.preventDefault();
+
$("#permission-sel-users").children(".item-picked").appendTo("#permission-avail-users").removeClass("item-picked");
+ sortNodes($("#permission-avail-users"), true);
+
$("#permission-sel-groups").children(".item-picked").appendTo("#permission-avail-groups").removeClass("item-picked");
+ sortNodes($("#permission-avail-groups"), false);
+ $("#permission-avail-searchBox").val("");
+ filterNodes("", $("#permission-avail-users"));
+ filterNodes("", $("#permission-avail-groups"));
+ });
+ }
+ var setupPCIDevice = function(){
+ kimchi.getHostPCIDevices(function(hostPCIs){
+ kimchi.getVMPCIDevices(kimchi.selectedGuest, function(vmPCIs){
+ var pciEnabled = kimchi.capabilities.kernel_vfio;
+ for(var i=0; i<hostPCIs.length; i++){
+ var itemNode =
$.parseHTML(wok.substitute($('#pci-tmpl').html(),{
+ name: hostPCIs[i].name,
+ product: hostPCIs[i].product.description,
+ vendor: hostPCIs[i].vendor.description
+ }));
+ $(".body",
"#form-guest-edit-pci").append(itemNode);
+ var iconClass = "ui-icon-plus";
+ for(var j=0; j<vmPCIs.length; j++){
+ if(hostPCIs[i].name==vmPCIs[j].name){
+ iconClass = "ui-icon-minus";
+ break;
+ }
+ }
+ pciEnabled || $("button", itemNode).remove();
+ $("button", itemNode).button({
+ icons: { primary: iconClass },
+ text: false
+ }).click(function(){
+ var obj = $(this);
+ if(obj.button("option", "icons").primary ==
"ui-icon-minus"){
+ kimchi.removeVMPCIDevice(kimchi.selectedGuest,
obj.parent().prop("id"), function(){
+ kimchi.getVMPCIDevices(kimchi.selectedGuest,
function(vmPCIs1){
+ for(var k=0; k<hostPCIs.length; k++) {
+ $("button", "#" +
hostPCIs[k].name).button("option", "icons", {primary:
"ui-icon-plus"});
+ }
+ for(var k=0; k<vmPCIs1.length; k++) {
+ $("button", "#" +
vmPCIs1[k].name).button("option", "icons", {primary:
"ui-icon-minus"});
+ }
+ });
+ filterNodes($("select",
"#form-guest-edit-pci").val(), $("input",
"#form-guest-edit-pci").val());
+ });
+ } else {
+ kimchi.addVMPCIDevice(kimchi.selectedGuest, { name:
obj.parent().prop("id") }, function(){
+ kimchi.getVMPCIDevices(kimchi.selectedGuest,
function(vmPCIs1){
+ for(var k=0; k<vmPCIs1.length; k++) {
+ $("button", "#" +
vmPCIs1[k].name).button("option", "icons", {primary:
"ui-icon-minus"});
+ }
+ });
+ filterNodes($("select",
"#form-guest-edit-pci").val(), $("input",
"#form-guest-edit-pci").val());
+ });
+ }
+ });
+ kimchi.getPCIDeviceCompanions(hostPCIs[i].name, function(infoData) {
+ var pciTitle = i18n["KCHVMED6007M"] + "\n";
+ var haveCompanions = false;
+ for(var p=0; p<infoData.length; p++) {
+ if(infoData[p].device_type === "net") {
+ haveCompanions = true;
+ pciTitle += " " + infoData[p].name +
"\n";
+ pciTitle += " " +
i18n["KCHVMED6001M"] + " " + infoData[p].interface;
+ pciTitle += ", " +
i18n["KCHVMED6002M"] + " " + infoData[p].address;
+ pciTitle += ", " +
i18n["KCHVMED6003M"] + " " + infoData[p].link_type + "\n";
+ } else if(infoData[p].device_type === "storage") {
+ haveCompanions = true;
+ pciTitle += " " + infoData[p].name +
"\n";
+ pciTitle += " " +
i18n["KCHVMED6004M"] + " " + infoData[p].block;
+ pciTitle += ", " +
i18n["KCHVMED6005M"] + " " + infoData[p].drive_type;
+ pciTitle += ", " +
i18n["KCHVMED6006M"] + " " + infoData[p].model + "\n";
+ }
+ }
+ for(var q=0; q<infoData.length; q++) {
+ haveCompanions && $(".name", "#"
+ infoData[q].parent).attr("title", pciTitle);
+ haveCompanions && $(".product",
"#" + infoData[q].parent).attr("title", pciTitle);
+ haveCompanions && $(".vendor",
"#" + infoData[q].parent).attr("title", pciTitle);
+ }
+ });
+ }
+ });
+ });
+ var filterNodes = function(group, text){
+ text = text.toLowerCase();
+ $(".body",
"#form-guest-edit-pci").children().each(function(){
+ var textFilter = $(".name",
this).text().toLowerCase().indexOf(text)!=-1;
+ textFilter = textFilter || $(".product",
this).text().toLowerCase().indexOf(text)!=-1;
+ textFilter = textFilter || $(".vendor",
this).text().toLowerCase().indexOf(text)!=-1;
+ var display = "none";
+ var itemGroup = $("button", this).button("option",
"icons").primary;
+ if(textFilter){
+ if(group == "all"){
+ display = "";
+ }else if(group=="toAdd" &&
itemGroup=="ui-icon-plus"){
+ display = ""
+ }else if(group == "added" &&
itemGroup=="ui-icon-minus"){
+ display = ""
+ }
+ }
+ $(this).css("display", display);
+ });
+ };
+ $("select", "#form-guest-edit-pci").change(function(){
+ filterNodes($(this).val(), $("input",
"#form-guest-edit-pci").val());
+ });
+ $("input", "#form-guest-edit-pci").on("keyup",
function() {
+ filterNodes($("select", "#form-guest-edit-pci").val(),
$(this).val());
+ });
+ };
+
+ var setupSnapshot = function() {
+ var currentSnapshot;
+ var setCurrentSnapshot = function(aSnapshot){
+ if(!aSnapshot)
+ kimchi.getCurrentSnapshot(kimchi.selectedGuest, function(snapshot){
+ if(snapshot&&snapshot.name) aSnapshot = snapshot.name;
+ }, null, true);
+ if(aSnapshot){
+ if(currentSnapshot) $(".ui-icon-check",
"#"+currentSnapshot).addClass("hide");
+ $(".ui-icon-check",
"#"+aSnapshot).removeClass("hide");
+ currentSnapshot = aSnapshot;
+ }
+ };
+ var addItem = function(data, container) {
+ var itemNode =
$.parseHTML(wok.substitute($('#snapshot-tmpl').html(),data));
+ $("."+container,
"#form-guest-edit-snapshot").append(itemNode);
+ $(".delete", itemNode).button({
+ icons: { primary: "ui-icon-trash" },
+ text: false
+ }).click(function(evt){
+ evt.preventDefault();
+ var item = $(this).parent().parent();
+ $("button",
"#form-guest-edit-snapshot").button("disable");
+ kimchi.deleteSnapshot(kimchi.selectedGuest, item.prop("id"),
function(){
+ item.remove();
+ setCurrentSnapshot();
+ $("button",
"#form-guest-edit-snapshot").button("enable");
+ }, function(data){
+ wok.message.error(data.responseJSON.reason);
+ $("button",
"#form-guest-edit-snapshot").button("enable");
+ });
+ });
+ $(".revert", itemNode).button({
+ icons: { primary: "ui-icon-arrowthick-1-ne" },
+ text: false
+ }).click(function(evt){
+ evt.preventDefault();
+ var item = $(this).parent().parent();
+ $(".ui-icon-check", item).addClass("hide");
+ $(".icon", item).removeClass("hide");
+ $("button",
"#form-guest-edit-snapshot").button("disable");
+ kimchi.revertSnapshot(kimchi.selectedGuest, item.prop("id"),
function(){
+ $(".icon", item).addClass("hide");
+ $("button",
"#form-guest-edit-snapshot").button("enable");
+ setCurrentSnapshot(item.prop("id"));
+ kimchi.listVmsAuto();
+ wok.window.close();
+ }, function(data){
+ wok.message.error(data.responseJSON.reason);
+ $(".icon", item).addClass("hide");
+ $("button",
"#form-guest-edit-snapshot").button("enable");
+ });
+ });
+ };
+ var addOngoingItem = function(task){
+ var uri = task.target_uri;
+ addItem({
+ name: uri.substring(uri.lastIndexOf('/')+1, uri.length),
+ created: "",
+ listMode: "hide",
+ createMode: ""
+ }, 'task');
+ if(kimchi.trackingTasks.indexOf(task.id)==-1)
+ kimchi.trackTask(task.id, function(task){
+ listGeneratingSnapshots();
+ $("button",
"#form-guest-edit-snapshot").button("enable");
+ }, function(err){
+ wok.message.error(err.message);
+ listGeneratingSnapshots();
+ $("button",
"#form-guest-edit-snapshot").button("enable");
+ });
+ };
+ var listGeneratingSnapshots = function(){
+
kimchi.getTasksByFilter('status=running&target_uri='+encodeURIComponent('^/plugins/kimchi/snapshots/*'),
function(tasks) {
+ $(".task", "#form-guest-edit-snapshot").empty();
+ for(var i=0;i<tasks.length;i++){
+ addOngoingItem(tasks[i]);
+ }
+ if(tasks.length==0) listSnapshots();
+ });
+ };
+ var listSnapshots = function(){
+ kimchi.listSnapshots(kimchi.selectedGuest, function(data){
+ $(".body", "#form-guest-edit-snapshot").empty();
+ for(var i=0;i<data.length;i++){
+ data[i].created = new Date(data[i].created*1000).toLocaleString();
+ data[i].createMode = "hide";
+ data[i].listMode = "";
+ addItem(data[i], 'body');
+ }
+ setCurrentSnapshot();
+ });
+ };
+ listGeneratingSnapshots();
+ $(".add", "#form-guest-edit-snapshot").button({
+ icons: { primary: "ui-icon-plusthick" },
+ text: false
+ }).click(function(evt){
+ evt.preventDefault();
+ kimchi.createSnapshot(kimchi.selectedGuest, function(task){
+ $("button",
"#form-guest-edit-snapshot").button("disable");
+ addOngoingItem(task);
+ });
+ });
+ if(kimchi.thisVMState=="running") $("button",
"#form-guest-edit-snapshot").remove();
+ };
+
+ var initContent = function(guest) {
+ guest['icon'] = guest['icon'] ||
'plugins/kimchi/images/icon-vm.png';
+ $('#form-guest-edit-general').fillWithObject(guest);
+ kimchi.thisVMState = guest['state'];
+ refreshCDROMs();
+ $('#guest-edit-attach-cdrom-button').button({
+ icons: {
+ primary: "ui-icon-plusthick"
+ },
+ text: false
+ }).click(function(event) {
+ event.preventDefault();
+ wok.window.open("plugins/kimchi/guest-storage-add.html");
+ });
+ if(kimchi.thisVMState === "running") {
+ $("#form-guest-edit-general input").prop("disabled",
true);
+ } else {
+ $("#action-button-container").removeClass("hidden");
+ }
+
+ var onAttached = function(params) {
+ refreshCDROMs();
+ };
+ var onReplaced = function(params) {
+ refreshCDROMs();
+ };
+ var onDetached = function(params) {
+ refreshCDROMs();
+ };
+
+ initStorageListeners();
+ setupInterface();
+ setupPermission();
+ setupPCIDevice();
+ setupSnapshot();
+
+ wok.topic('kimchi/vmCDROMAttached').subscribe(onAttached);
+ wok.topic('kimchi/vmCDROMReplaced').subscribe(onReplaced);
+ wok.topic('kimchi/vmCDROMDetached').subscribe(onDetached);
+
+ kimchi.clearGuestEdit = function() {
+ wok.topic('kimchi/vmCDROMAttached').unsubscribe(onAttached);
+ wok.topic('kimchi/vmCDROMReplaced').unsubscribe(onReplaced);
+ wok.topic('kimchi/vmCDROMDetached').unsubscribe(onDetached);
+ };
+ };
+
+ kimchi.retrieveVM(kimchi.selectedGuest, initContent);
+
+ var generalSubmit = function(event) {
+ $(saveButton).prop('disabled', true);
+ var data=$('#form-guest-edit-general').serializeObject();
+ if(data['memory']!=undefined) {
+ data['memory'] = Number(data['memory']);
+ }
+ if(data['cpus']!=undefined) {
+ data['cpus'] = Number(data['cpus']);
+ }
+
+ kimchi.updateVM(kimchi.selectedGuest, data, function() {
+ kimchi.listVmsAuto();
+ wok.window.close();
+ }, function(err) {
+ wok.message.error(err.responseJSON.reason);
+ $(saveButton).prop('disabled', false);
+ });
+ }
+
+ var permissionSubmit = function(event) {
+ var content = { users: [], groups: [] };
+ authType = kimchi.capabilities['auth']
+ if (authType == 'pam') {
+ $("#permission-sel-users").children().each(function(){
+ content.users.push($("label", this).text());
+ });
+ $("#permission-sel-groups").children().each(function(){
+ content.groups.push($("label", this).text());
+ });
+ kimchi.updateVM(kimchi.selectedGuest, content, function(){
+ wok.window.close();
+ });
+ } else if (authType == 'ldap') {
+ $(saveButton).prop('disabled', true);
+ var errors = 0;
+
+ $(".body", "#form-guest-edit-permission
.ldap").children().each(function () {
+ var elem = $(this);
+ content.users.push(elem.attr("id"));
+
+ if (!$('input', elem).hasClass('hide')) {
+ var user = {'user_id': $(this).attr("id")};
+ kimchi.getUserById(user, null, function (data) {
+ errors += 1;
+ $("input", elem).addClass("checked");
+ });
+ }
+ });
+ if (errors == 0) {
+ kimchi.updateVM(kimchi.selectedGuest, content, function(){
+ wok.window.close();
+ });
+ } else {
+ $(saveButton).prop('disabled', false);
+ }
+ }
+ }
+
+ // tap map, "general": 0, "storage": 1, "interface": 2,
"permission": 3, "password": 4
+ var submit_map = {0: generalSubmit, 3:permissionSubmit};
+ var submitForm = function(event) {
+ var current = $('#guest-edit-tabs').tabs( "option",
"active" );
+ var submitFun = submit_map[current];
+ submitFun && submitFun(event);
+ event.preventDefault();
+ };
+
+ $(guestEditForm).on('submit', submitForm);
+ $(saveButton).on('click', submitForm);
+};
diff --git a/src/wok/plugins/kimchi/ui/js/src/kimchi.guest_main.js
b/src/wok/plugins/kimchi/ui/js/src/kimchi.guest_main.js
new file mode 100644
index 0000000..7dd5d84
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/js/src/kimchi.guest_main.js
@@ -0,0 +1,511 @@
+/*
+ * Project Kimchi
+ *
+ * Copyright IBM, Corp. 2013-2015
+ *
+ * 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.
+ */
+
+kimchi.sampleGuestObject = {
+ "name": "",
+ "uuid": "",
+ "state": "shutoff",
+ "persistent": true,
+ "icon": null,
+ "cpus": 0,
+ "memory": 0,
+ "stats": {
+ "net_throughput": 0,
+ "io_throughput_peak": 100,
+ "cpu_utilization": 0,
+ "io_throughput": 0,
+ "net_throughput_peak": 100
+ },
+ "screenshot": null,
+ "graphics": {
+ "passwd": null,
+ "passwdValidTo": null,
+ "type": "vnc",
+ "port": null,
+ "listen": "127.0.0.1"
+ },
+ "users": [],
+ "groups": [],
+ "access": "full"
+};
+
+kimchi.vmstart = function(event) {
+ var button=$(this);
+ if (!button.hasClass('loading')) {
+ button.addClass('loading');
+ var vm=$(this).closest('li[name=guest]');
+ var vm_id=vm.attr("id");
+ kimchi.startVM(vm_id, function(result) {
+ button.removeClass('loading');
+ kimchi.listVmsAuto();
+ }, function(err) {
+ button.removeClass('loading');
+ wok.message.error(err.responseJSON.reason);
+ }
+ );
+ } else {
+ event.preventDefault();
+ event.stopPropagation();
+ return;
+ }
+};
+
+kimchi.vmsuspend = function(event) {
+ var button=$(this);
+ if (!button.hasClass('pause-gray')) {
+ button.addClass('pause-gray');
+ var vm=$(this).closest('li[name=guest]');
+ var vm_id=vm.attr("id");
+ kimchi.suspendVM(vm_id, function(result) {
+ button.removeClass('pause-gray');
+ kimchi.listVmsAuto();
+ }, function(err) {
+ button.removeClass('pause-gray');
+ wok.message.error(err.responseJSON.reason);
+ }
+ );
+ } else {
+ event.preventDefault();
+ event.stopPropagation();
+ return;
+ }
+};
+
+kimchi.vmresume = function(event) {
+ var button=$(this);
+ if (!button.hasClass('resume-gray')) {
+ button.addClass('resume-gray');
+ var vm=$(this).closest('li[name=guest]');
+ var vm_id=vm.attr("id");
+ kimchi.resumeVM(vm_id, function(result) {
+ button.removeClass('resume-gray');
+ kimchi.listVmsAuto();
+ }, function(err) {
+ button.removeClass('resume-gray');
+ wok.message.error(err.responseJSON.reason);
+ }
+ );
+ } else {
+ event.preventDefault();
+ event.stopPropagation();
+ return;
+ }
+};
+
+kimchi.vmpoweroff = function(event) {
+ var button=$(this);
+ if (!button.hasClass('loading')) {
+ button.addClass('loading');
+ var vm=button.closest('li[name=guest]');
+ var vm_id=vm.attr("id");
+ var vmObject=vm.data();
+ var vm_persistent=vmObject.persistent == true;
+ var content_msg = vm_persistent ? i18n['KCHVM6003M'] :
+ i18n['KCHVM6009M'];
+ var settings = {
+ title : i18n['KCHVM6002M'],
+ content : content_msg,
+ confirm : i18n['KCHAPI6002M'],
+ cancel : i18n['KCHAPI6003M']
+ };
+ wok.confirm(settings, function() {
+ kimchi.poweroffVM(vm_id, function(result) {
+ button.removeClass('loading');
+ kimchi.listVmsAuto();
+ }, function(err) {
+ wok.message.error(err.responseJSON.reason);
+ });
+ }, function() {
+ });
+ } else {
+ event.preventDefault();
+ event.stopPropagation();
+ }
+};
+
+kimchi.vmshutdown = function(event){
+ var vm=$(this).closest('li[name=guest]');
+ var vm_id=vm.attr("id");
+ var settings = {
+ title : i18n['KCHVM6006M'],
+ content : i18n['KCHVM6007M'],
+ confirm : i18n['KCHAPI6002M'],
+ cancel : i18n['KCHAPI6003M']
+ };
+ wok.confirm(settings, function() {
+ kimchi.shutdownVM(vm_id, function(result) {
+ kimchi.listVmsAuto();
+ }, function(err) {
+ wok.message.error(err.responseJSON.reason);
+ }
+ );
+ }, function() {
+ });
+};
+
+kimchi.vmreset = function(event){
+ var vm=$(this).closest('li[name=guest]');
+ var vm_id=vm.attr("id");
+ var settings = {
+ title : i18n['KCHVM6004M'],
+ content : i18n['KCHVM6005M'],
+ confirm : i18n['KCHAPI6002M'],
+ cancel : i18n['KCHAPI6003M']
+ };
+ wok.confirm(settings, function() {
+ kimchi.resetVM(vm_id, function(result) {
+ kimchi.listVmsAuto();
+ }, function(err) {
+ wok.message.error(err.responseJSON.reason);
+ }
+ );
+ }, function() {
+ });
+};
+
+kimchi.vmdelete = function(event) {
+ var vm = $(this).closest('li[name=guest]');
+ var vm_id=vm.attr("id");
+ var settings = {
+ title : i18n['KCHVM6008M'],
+ content : i18n['KCHVM6001M'],
+ confirm : i18n['KCHAPI6002M'],
+ cancel : i18n['KCHAPI6003M']
+ };
+ wok.confirm(settings, function() {
+ kimchi.deleteVM(vm_id, function(result) {
+ kimchi.listVmsAuto();
+ }, function(err) {
+ wok.message.error(err.responseJSON.reason);
+ });
+ }, function() {
+ });
+};
+
+kimchi.vmedit = function(event) {
+ var vm = $(this).closest('li[name=guest]');
+ var vm_id=vm.attr("id");
+ kimchi.selectedGuest = vm_id;
+ wok.window.open({
+ url: 'plugins/kimchi/guest-edit.html',
+ close: function() {
+ kimchi.clearGuestEdit();
+ }
+ });
+};
+
+kimchi.openVmConsole = function(event) {
+ var vm=$(this).closest('li[name=guest]');
+ var vmObject=vm.data();
+ if (vmObject.graphics['type'] == 'vnc') {
+ kimchi.vncToVM(vm.attr('id'));
+ }
+ else if (vmObject.graphics['type'] == 'spice') {
+ kimchi.spiceToVM(vm.attr('id'));
+ }
+
+};
+
+kimchi.getVmsCurrentConsoleImgs = function() {
+ var res = new Object();
+ $('#guestList').children().each(function() {
+ res[$(this).attr('id')] =
$(this).find('img.imgactive').attr('src');
+ })
+ return res;
+};
+
+kimchi.getOpenMenuVmId = function() {
+ var result;
+ var openMenu = $('#guestList div[name="actionmenu"]
.popover:visible');
+ if(openMenu) {
+ var li_element=openMenu.closest('li');
+ result=li_element.attr('id');
+ }
+ return result;
+};
+
+kimchi.listVmsAuto = function() {
+ if (kimchi.vmTimeout) {
+ clearTimeout(kimchi.vmTimeout);
+ }
+ var getCreatingGuests = function(){
+ var guests = [];
+
kimchi.getTasksByFilter('status=running&target_uri='+encodeURIComponent('^/plugins/kimchi/vms/[^/]+$'),
function(tasks) {
+ for(var i=0;i<tasks.length;i++){
+ var guestUri = tasks[i].target_uri;
+ var guestName = guestUri.split('/')[2]
+ guests.push($.extend({}, kimchi.sampleGuestObject, {name: guestName,
isCreating: true}));
+ if(kimchi.trackingTasks.indexOf(tasks[i].id)==-1)
+ kimchi.trackTask(tasks[i].id, null, function(err){
+ wok.message.error(err.message);
+ }, null);
+ }
+ }, null, true);
+ return guests;
+ };
+ var getCloningGuests = function(){
+ var guests = [];
+
kimchi.getTasksByFilter('status=running&target_uri='+encodeURIComponent('^/plugins/kimchi/vms/.+/clone'),
function(tasks) {
+ for(var i=0;i<tasks.length;i++){
+ var guestUri = tasks[i].target_uri;
+ var guestName = guestUri.split('/')[2]
+ guests.push($.extend({}, kimchi.sampleGuestObject, {name: guestName,
isCloning: true}));
+ if(kimchi.trackingTasks.indexOf(tasks[i].id)==-1)
+ kimchi.trackTask(tasks[i].id, null, function(err){
+ wok.message.error(err.message);
+ }, null);
+ }
+ }, null, true);
+ return guests;
+ };
+ kimchi.listVMs(function(result, textStatus, jqXHR) {
+ if (result && textStatus=="success") {
+ result = getCloningGuests().concat(result);
+ result = getCreatingGuests().concat(result);
+ if(result.length) {
+ var listHtml = '';
+ var guestTemplate = kimchi.guestTemplate;
+ var currentConsoleImages = kimchi.getVmsCurrentConsoleImgs();
+ var openMenuGuest = kimchi.getOpenMenuVmId();
+ $('#guestList').empty();
+ $('#guestListField').show();
+ $('#noGuests').hide();
+
+ $.each(result, function(index, vm) {
+ var guestLI = kimchi.createGuestLi(vm, currentConsoleImages[vm.name],
vm.name==openMenuGuest);
+ $('#guestList').append(guestLI);
+ });
+ } else {
+ $('#guestListField').hide();
+ $('#noGuests').show();
+ }
+ }
+
+ kimchi.vmTimeout = window.setTimeout("kimchi.listVmsAuto();", 5000);
+ }, function(errorResponse, textStatus, errorThrown) {
+ if(errorResponse.responseJSON && errorResponse.responseJSON.reason) {
+ wok.message.error(errorResponse.responseJSON.reason);
+ }
+ kimchi.vmTimeout = window.setTimeout("kimchi.listVmsAuto();", 5000);
+ });
+};
+
+kimchi.createGuestLi = function(vmObject, prevScreenImage, openMenu) {
+ var result=kimchi.guestElem.clone();
+
+ //Setup the VM list entry
+ var vmRunningBool=(vmObject.state=="running");
+ var vmSuspendedBool = (vmObject.state=="paused");
+ var vmPoweredOffBool = (vmObject.state=="shutoff");
+ var vmPersistent = (vmObject.persistent == true);
+ result.attr('id',vmObject.name);
+ result.data(vmObject);
+
+ //Add the Name
+ var guestTitle=result.find('.title').attr('title',vmObject.name);
+ guestTitle.html(vmObject.name);
+
+ //Setup the VM console thumbnail display
+ var curImg = vmObject.icon;
+ if (vmObject.screenshot) {
+ curImg = vmObject.screenshot.replace(/^\//,'');
+ }
+ var load_src = curImg || 'plugins/kimchi/images/icon-vm.png';
+ var tile_src = prevScreenImage || vmObject['load-src'];
+ var liveTile=result.find('div[name=guest-tile] > .tile');
+ liveTile.addClass(vmObject.state);
+ liveTile.find('.imgactive').attr('src',tile_src);
+ var imgLoad=liveTile.find('.imgload');
+ imgLoad.on('load', function() {
+ var
oldImg=$(this).parent().find('.imgactive');
+
oldImg.removeClass("imgactive").addClass("imgload");
+ oldImg.attr("src","");
+
$(this).addClass("imgactive").removeClass("imgload");
+ $(this).off('load');
+ });
+ imgLoad.attr('src',load_src);
+
+ //Link the stopped tile to the start action, the running tile to open the console,
and the paused tile to resume
+ if(!(vmObject.isCloning || vmObject.isCreating)){
+ if (vmPoweredOffBool) {
+ liveTile.off("click", kimchi.openVmConsole);
+ liveTile.off("click", kimchi.vmresume);
+ liveTile.on("click", kimchi.vmstart);
+ liveTile.hover(function(event){$(this).find('.overlay').show()},
function(event){$(this).find('.overlay').hide()});
+ } else if (vmSuspendedBool) {
+ liveTile.off("click", kimchi.vmstart);
+ liveTile.off("click", kimchi.openVmConsole);
+ liveTile.on("click", kimchi.vmresume);
+ if(vmObject.state="paused") {
+
liveTile.find('.overlay').attr('src',"plugins/kimchi/images/theme-default/ac24_resume.png");
+ liveTile.find('.overlay').attr('alt',"Resume");
+ }
+ liveTile.hover(function(event){$(this).find('.overlay').show()},
function(event){$(this).find('.overlay').hide()});
+ } else {
+ liveTile.off("click", kimchi.vmstart);
+ liveTile.off("click", kimchi.vmresume);
+ liveTile.on("click", kimchi.openVmConsole);
+ }
+ }
+
+ //Setup the gauges
+ var stats=vmObject.stats;
+ var gaugeValue=0;
+ gaugeValue=parseInt(stats.net_throughput);
+ kimchi.circleGaugeInit(result,
"net_throughput",gaugeValue,(gaugeValue*100/stats.net_throughput_peak));
+ gaugeValue=parseInt(stats.io_throughput);
+ kimchi.circleGaugeInit(result,
"io_throughput",gaugeValue,(gaugeValue*100/stats.io_throughput_peak));
+ gaugeValue=parseInt(stats.cpu_utilization);
+ kimchi.circleGaugeInit(result,
"cpu_utilization",gaugeValue+"%",gaugeValue);
+
+ //Setup the VM Actions
+ var guestActions=result.find("div[name=guest-actions]");
+ guestActions.find(".shutoff-disabled").prop("disabled",
!vmRunningBool);
+ guestActions.find(".running-disabled").prop("disabled",
vmRunningBool);
+ guestActions.find(".non-persistent-disabled").prop("disabled",
!vmPersistent);
+ guestActions.find(".reset-disabled").prop("disabled",
vmPoweredOffBool || !vmPersistent);
+ guestActions.find(".pause-disabled").prop("disabled",
vmPoweredOffBool || !vmPersistent);
+
+ if (vmSuspendedBool) { //VM is paused
+ //Hide Start
+ guestActions.find(".running-hidden").hide();
+ //Hide Pause button and menu
+ guestActions.find(".pause-disabled").hide();
+ guestActions.find(".pause-hidden").hide();
+ }
+
+ if (vmRunningBool) { //VM IS running
+ //Hide Start
+ guestActions.find(".running-hidden").hide();
+ //Hide Resume
+ guestActions.find(".resume-hidden").hide();
+ }
+
+ if (vmPoweredOffBool) { //VM is powered off
+ //Hide PowerOff
+ guestActions.find(".shutoff-hidden").hide();
+ //Hide Pause
+ guestActions.find(".pause-hidden").hide();
+ //Hide Resume
+ guestActions.find(".resume-hidden").hide();
+ }
+
+ var consoleActions=guestActions.find("[name=vm-console]");
+
+ if ((vmObject.graphics['type'] == 'vnc') ||
(vmObject.graphics['type'] == 'spice')) {
+ consoleActions.on("click", kimchi.openVmConsole);
+ consoleActions.show();
+ } else { //we don't recognize the VMs supported graphics, so hide the
menu choice
+ consoleActions.hide();
+ consoleActions.off("click",kimchi.openVmConsole);
+ }
+
+ //Setup action event handlers
+ if(!(vmObject.isCloning || vmObject.isCreating)){
+ guestActions.find("[name=vm-start]").on({click : kimchi.vmstart});
+ guestActions.find("[name=vm-poweroff]").on({click :
kimchi.vmpoweroff});
+ if ((vmRunningBool) || (vmSuspendedBool)) {
+ //If the guest is not running, do not enable reset; otherwise, reset is
enabled (when running or paused)
+ guestActions.find("[name=vm-reset]").on({click : kimchi.vmreset});
+
+ //If the guest is not running, do not enable shutdown;otherwise, shutdown is enabled
(when running or paused)
+ guestActions.find("[name=vm-shutdown]").on({click :
kimchi.vmshutdown});
+ }
+
+ if (vmSuspendedBool) {
+ guestActions.find("[name=vm-resume]").on({click :
kimchi.vmresume});
+ }
+
+ if (vmRunningBool) {
+ guestActions.find("[name=vm-pause]").on({click :
kimchi.vmsuspend});
+ }
+
+ guestActions.find("[name=vm-edit]").on({click : kimchi.vmedit});
+ guestActions.find("[name=vm-delete]").on({click : kimchi.vmdelete});
+ guestActions.find("[name=vm-clone]").click(function(){
+ var guest = $(this).closest('li[name=guest]').attr("id");
+ wok.confirm({
+ title : i18n['KCHAPI6006M'],
+ content : i18n['KCHVM6010M'],
+ confirm : i18n['KCHAPI6002M'],
+ cancel : i18n['KCHAPI6003M']
+ }, function() {
+ kimchi.cloneGuest(guest, function(data){
+ kimchi.listVmsAuto();
+ });
+ }, null);
+ });
+
+ //Maintain menu open state
+ var actionMenu=guestActions.find("div[name=actionmenu]");
+ if (openMenu) {
+ $('.popover', actionMenu).toggle();
+ }
+
+ }else{
+ guestActions.find('.btn').attr('disabled', true);
+ $('.popover',
guestActions.find("div[name=actionmenu]")).remove();
+
+ result.find('.guest-pending').removeClass('hide-content');
+ pendingText = result.find('.guest-pending .text')
+ if(vmObject.isCloning)
+ pendingText.text(i18n['KCHAPI6009M']);
+ else
+ pendingText.text(i18n['KCHAPI6008M']);
+ }
+
+ return result;
+};
+
+kimchi.circleGaugeInit = function(topElement, divName, display, percentage){
+ var gauge=topElement.find('div[name="' + divName + '"]
.circleGauge');
+ if(gauge) {
+ var data=Object();
+ data.percentage = percentage;
+ data.display = display;
+ gauge.data(data);
+ }
+ gauge.circleGauge();
+ return(gauge);
+};
+
+kimchi.guestSetRequestHeader = function(xhr) {
+ xhr.setRequestHeader('Accept', 'text/html');
+};
+
+kimchi.guest_main = function() {
+ if(wok.tabMode['guests'] === 'admin') {
+ $('.tools').attr('style','display');
+ $("#vm-add").on("click", function(event) {
+ wok.window.open('plugins/kimchi/guest-add.html');
+ });
+ }
+ kimchi.guestTemplate = $('#guest-tmpl').html();
+
kimchi.guestElem=$('<div/>').html(kimchi.guestTemplate).find('li');
+ $('#guests-root-container').on('remove', function() {
+ kimchi.vmTimeout && clearTimeout(kimchi.vmTimeout);
+ });
+ kimchi.listVmsAuto()
+};
+
+kimchi.editTemplate = function(guestTemplate, oldPopStat) {
+ if (oldPopStat) {
+ return guestTemplate.replace("vm-action", "vm-action open");
+ }
+ return guestTemplate;
+};
diff --git a/src/wok/plugins/kimchi/ui/js/src/kimchi.guest_media_main.js
b/src/wok/plugins/kimchi/ui/js/src/kimchi.guest_media_main.js
new file mode 100644
index 0000000..b920527
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/js/src/kimchi.guest_media_main.js
@@ -0,0 +1,56 @@
+/*
+ * Project Kimchi
+ *
+ * Copyright IBM, Corp. 2014
+ *
+ * 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.
+ */
+kimchi.guest_media_main = function() {
+
+ var refreshCDROMs = function() {
+ kimchi.listVMStorages({
+ vm: kimchi.selectedGuest,
+ storageType: 'cdrom'
+ }, function(storages) {
+ var rowHTML = $('#cdrom-row-tmpl').html();
+ var container = $('#guest-edit-cdrom-row-container');
+ $(container).empty();
+
+ $.each(storages, function(index, storage) {
+ storage['vm'] = kimchi.selectedGuest;
+ var templated = wok.substitute(rowHTML, storage);
+ container.append(templated);
+ });
+
+ var replaceCDROM = function(event) {
+ event.preventDefault();
+ kimchi.selectedGuestStorage = $(this).data('dev');
+ wok.window.open("plugins/kimchi/guest-cdrom-edit.html");
+ };
+
+ $('input[type="text"][name="cdrom"]',
container).on('click', replaceCDROM);
+ $('.replace', container).on('click', replaceCDROM);
+ });
+ };
+
+ refreshCDROMs();
+
+ var onReplaced = function(params) {
+ refreshCDROMs();
+ };
+ wok.topic('kimchi/vmCDROMReplaced').subscribe(onReplaced);
+
+ kimchi.clearGuestMedia = function() {
+ wok.topic('kimchi/vmCDROMReplaced').unsubscribe(onReplaced);
+ };
+};
diff --git a/src/wok/plugins/kimchi/ui/js/src/kimchi.guest_storage_add.main.js
b/src/wok/plugins/kimchi/ui/js/src/kimchi.guest_storage_add.main.js
new file mode 100644
index 0000000..bc162e8
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/js/src/kimchi.guest_storage_add.main.js
@@ -0,0 +1,199 @@
+/*
+ * Project Kimchi
+ *
+ * Copyright IBM, Corp. 2014-2015
+ *
+ * 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.
+ */
+kimchi.guest_storage_add_main = function() {
+ var types = [{
+ label: 'cdrom',
+ value: 'cdrom',
+ },
+ {
+ label: 'disk',
+ value: 'disk',
+ }];
+ var typesRunning = [{
+ label: 'disk',
+ value: 'disk'
+ }];
+
+ var storageAddForm = $('#form-guest-storage-add');
+ var submitButton = $('#guest-storage-button-add');
+ var typeTextbox = $('input[name="type"]', storageAddForm);
+ var pathTextbox = $('input[name="path"]', storageAddForm);
+ var poolTextbox = $('input[name="pool"]', storageAddForm);
+ var volTextbox = $('input[name="vol"]', storageAddForm);
+
+ typeTextbox.change(function() {
+ var pathObject = {'cdrom': ".path-section", 'disk':
'.volume-section'}
+ selectType = $(this).val();
+ $.each(pathObject, function(type, value) {
+ if(selectType == type){
+ $(value).removeClass('hidden');
+ } else {
+ $(value).addClass('hidden');
+ }
+ });
+
+ if ($(".path-section").hasClass('hidden')) {
+ $(poolTextbox).val('default');
+ $(poolTextbox).change();
+ $(pathTextbox).val("");
+ }
+ else {
+ $(poolTextbox).val("");
+ $(volTextbox).val("");
+ }
+ });
+
+ kimchi.listStoragePools(function(result) {
+ var options = [];
+ if (result && result.length) {
+ $.each(result, function(index, storagePool) {
+ if ((storagePool.state=="active") && (storagePool.type
!== 'kimchi-iso')) {
+ options.push({
+ label: storagePool.name,
+ value: storagePool.name
+ });
+ }
+ });
+ wok.select('guest-add-storage-pool-list', options);
+ }
+ });
+
+ poolTextbox.change(function() {
+ var options = [];
+ kimchi.listStorageVolumes($(this).val(), function(result) {
+ var validVolType = { cdrom: /iso/, disk:
/^(raw|qcow|qcow2|bochs|qed|vmdk)$/};
+ $('#guest-disk').selectMenu();
+ if (result.length) {
+ $.each(result, function(index, value) {
+ // Only unused volume can be attached
+ if (value.used_by.length == 0 && (value.type !=
'file' || validVolType[selectType].test(value.format))) {
+ options.push({
+ label: value.name,
+ value: value.name
+ });
+ }
+ });
+ if (options.length) {
+ $(volTextbox).val(options[0].value);
+ $(volTextbox).change();
+ }
+ }
+ $('#guest-disk').selectMenu("setData", options);
+ });
+ });
+
+
+ typeTextbox.change(function() {
+ var pathObject = {'cdrom': ".path-section", 'disk':
'.volume-section'}
+ var selectType = $(this).val();
+ $.each(pathObject, function(type, value) {
+ if(selectType == type){
+ $(value).removeClass('hidden');
+ } else {
+ $(value).addClass('hidden');
+ }
+ });
+ });
+
+ if (kimchi.thisVMState === 'running') {
+ types =typesRunning;
+ $(typeTextbox).val('disk');
+ typeTextbox.change();
+ poolTextbox.change();
+ }
+ var selectType = $(typeTextbox).val();
+ wok.select('guest-storage-type-list', types);
+
+ var validateCDROM = function(settings) {
+ if (/^((https|http|ftp|ftps|tftp|\/).*)+$/.test(settings['path']))
+ return true;
+ else {
+ wok.message.error.code('KCHVMSTOR0001E');
+ return false;
+ }
+ }
+
+ var validateDisk = function(settings) {
+ if (settings['pool'] && settings['vol'])
+ return true;
+ else {
+ wok.message.error.code('KCHVMSTOR0002E');
+ return false;
+ }
+ }
+
+ validator = {cdrom: validateCDROM, disk: validateDisk};
+ var submitForm = function(event) {
+ if (submitButton.prop('disabled')) {
+ return false;
+ }
+
+ var formData = storageAddForm.serializeObject();
+ var settings = {
+ vm: kimchi.selectedGuest,
+ type: typeTextbox.val(),
+ };
+
+ $(submitButton).prop('disabled', true);
+ $.each([pathTextbox, poolTextbox, volTextbox], function(i, c) {
+ $(c).prop('disabled', true);
+ val = $(c).val()
+ if (val && val != '') {
+ settings[$(c).attr('name')] = $(c).val();
+ }
+ });
+ // Validate form for cdrom and disk
+ validateSpecifiedForm = validator[settings['type']];
+ if (!validateSpecifiedForm(settings)) {
+ $(submitButton).prop('disabled', false);
+ $.each([submitButton, pathTextbox, poolTextbox, volTextbox], function(i, c)
{
+ $(c).prop('disabled', false);
+ });
+ return false;
+ }
+ $(submitButton).addClass('loading').text(i18n['KCHVMCD6003M']);
+
+ kimchi.addVMStorage(settings, function(result) {
+ wok.window.close();
+ wok.topic('kimchi/vmCDROMAttached').publish({
+ result: result
+ });
+ }, function(result) {
+ var errText = result['reason'] ||
+ result['responseJSON']['reason'];
+ wok.message.error(errText);
+
+ $.each([submitButton, pathTextbox, poolTextbox, volTextbox], function(i, c)
{
+ $(c).prop('disabled', false);
+ });
+
$(submitButton).removeClass('loading').text(i18n['KCHVMCD6002M']);
+ });
+
+ event.preventDefault();
+ };
+
+ storageAddForm.on('submit', submitForm);
+ submitButton.on('click', submitForm);
+ pathTextbox.on('change input propertychange', function(event) {
+ $(submitButton).prop('disabled', $(this).val() === '');
+ });
+ volTextbox.on('change propertychange', function (event) {
+ $(submitButton).prop('disabled', $(this).val() === '');
+ });
+
+};
diff --git a/src/wok/plugins/kimchi/ui/js/src/kimchi.host.js
b/src/wok/plugins/kimchi/ui/js/src/kimchi.host.js
new file mode 100644
index 0000000..e2d2511
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/js/src/kimchi.host.js
@@ -0,0 +1,858 @@
+/*
+ * Project Kimchi
+ *
+ * Copyright IBM, Corp. 2013-2014
+ *
+ * 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.
+ */
+kimchi.host={};
+
+kimchi.host_main = function() {
+ var expand = function(header, toExpand) {
+ var controlledNode = $(header).attr('aria-controls');
+ $('#' + controlledNode)[toExpand ? 'removeClass' :
'addClass']('hidden');
+ $(header).attr('aria-expanded', toExpand ? 'true' :
'false');
+ };
+
+ var repositoriesGrid = null;
+ var initRepositoriesGrid = function(repo_type) {
+ var gridFields=[];
+ if (repo_type == "yum") {
+ gridFields=[{
+ name: 'repo_id',
+ label: i18n['KCHREPO6004M'],
+ 'class': 'repository-id'
+ }, {
+ name: 'config[repo_name]',
+ label: i18n['KCHREPO6005M'],
+ 'class': 'repository-name'
+ }, {
+ name: 'enabled',
+ label: i18n['KCHREPO6009M'],
+ 'class': 'repository-enabled'
+ }];
+ }
+ else if (repo_type == "deb") {
+ gridFields=[{
+ name: 'baseurl',
+ label: i18n['KCHREPO6006M'],
+ makeTitle: true,
+ 'class': 'repository-baseurl deb'
+ }, {
+ name: 'enabled',
+ label: i18n['KCHREPO6009M'],
+ 'class': 'repository-enabled deb'
+ }, {
+ name: 'config[dist]',
+ label: "dist",
+ 'class': 'repository-gpgcheck deb'
+ }, {
+ name: 'config[comps]',
+ label: "comps",
+ 'class': 'repository-gpgcheck deb'
+ }];
+ }
+ else {
+ gridFields=[{
+ name: 'repo_id',
+ label: i18n['KCHREPO6004M'],
+ 'class': 'repository-id'
+ }, {
+ name: 'enabled',
+ label: i18n['KCHREPO6009M'],
+ 'class': 'repository-enabled'
+ }, {
+ name: 'baseurl',
+ label: i18n['KCHREPO6006M'],
+ makeTitle: true,
+ 'class': 'repository-baseurl'
+ }];
+ }
+ repositoriesGrid = new wok.widget.Grid({
+ container: 'repositories-grid-container',
+ id: 'repositories-grid',
+ title: i18n['KCHREPO6003M'],
+ toolbarButtons: [{
+ id: 'repositories-grid-add-button',
+ label: i18n['KCHREPO6012M'],
+ onClick: function(event) {
+ wok.window.open({url:'plugins/kimchi/repository-add.html',
+ class: repo_type});
+ }
+ }, {
+ id: 'repositories-grid-enable-button',
+ label: i18n['KCHREPO6016M'],
+ disabled: true,
+ onClick: function(event) {
+ var repository = repositoriesGrid.getSelected();
+ if(!repository) {
+ return;
+ }
+ var name = repository['repo_id'];
+ var enable = !repository['enabled'];
+ $(this).prop('disabled', true);
+ kimchi.enableRepository(name, enable, function() {
+ wok.topic('kimchi/repositoryUpdated').publish();
+ });
+ }
+ }, {
+ id: 'repositories-grid-edit-button',
+ label: i18n['KCHREPO6013M'],
+ disabled: true,
+ onClick: function(event) {
+ var repository = repositoriesGrid.getSelected();
+ if(!repository) {
+ return;
+ }
+ kimchi.selectedRepository = repository['repo_id'];
+ wok.window.open({url:'plugins/kimchi/repository-edit.html',
+ class: repo_type});
+ }
+ }, {
+ id: 'repositories-grid-remove-button',
+ label: i18n['KCHREPO6014M'],
+ disabled: true,
+ onClick: function(event) {
+ var repository = repositoriesGrid.getSelected();
+ if(!repository) {
+ return;
+ }
+
+ var settings = {
+ title : i18n['KCHREPO6001M'],
+ content : i18n['KCHREPO6002M'],
+ confirm : i18n['KCHAPI6004M'],
+ cancel : i18n['KCHAPI6003M']
+ };
+
+ wok.confirm(settings, function() {
+ kimchi.deleteRepository(
+ repository['repo_id'],
+ function(result) {
+
wok.topic('kimchi/repositoryDeleted').publish(result);
+ }, function(error) {
+ }
+ );
+ });
+ }
+ }],
+ onRowSelected: function(row) {
+ var repository = repositoriesGrid.getSelected();
+ if(!repository) {
+ return;
+ }
+ $('#repositories-grid-remove-button').prop('disabled',
false);
+ $('#repositories-grid-edit-button').prop('disabled',
false);
+ var enabled = repository['enabled'];
+ $('#repositories-grid-enable-button')
+ .text(i18n[enabled ? 'KCHREPO6017M' :
'KCHREPO6016M'])
+ .prop('disabled', false);
+ },
+ frozenFields: [],
+ fields: gridFields,
+ data: listRepositories
+ });
+ };
+
+ var listRepositories = function(gridCallback) {
+ kimchi.listRepositories(function(repositories) {
+ if($.isFunction(gridCallback)) {
+ gridCallback(repositories);
+ }
+ else {
+ if(repositoriesGrid) {
+ repositoriesGrid.setData(repositories);
+ }
+ else {
+ initRepositoriesGrid();
+ repositoriesGrid.setData(repositories);
+ }
+ }
+ },
+ function(error) {
+ var message = error && error['responseJSON'] &&
error['responseJSON']['reason'];
+
+ if($.isFunction(gridCallback)) {
+ gridCallback([]);
+ }
+ repositoriesGrid &&
+ repositoriesGrid.showMessage(message || i18n['KCHUPD6008M']);
+ });
+
+ $('#repositories-grid-remove-button').prop('disabled', true);
+ $('#repositories-grid-edit-button').prop('disabled', true);
+ $('#repositories-grid-enable-button').prop('disabled', true);
+ };
+
+ var softwareUpdatesGridID = 'software-updates-grid';
+ var softwareUpdatesGrid = null;
+ var progressAreaID = 'software-updates-progress-textarea';
+ var reloadProgressArea = function(result) {
+ var progressArea = $('#' + progressAreaID)[0];
+ $(progressArea).text(result['message']);
+ var scrollTop = $(progressArea).prop('scrollHeight');
+ $(progressArea).prop('scrollTop', scrollTop);
+ };
+
+ var initSoftwareUpdatesGrid = function(softwareUpdates) {
+ softwareUpdatesGrid = new wok.widget.Grid({
+ container: 'software-updates-grid-container',
+ id: softwareUpdatesGridID,
+ title: i18n['KCHUPD6001M'],
+ rowSelection: 'disabled',
+ toolbarButtons: [{
+ id: softwareUpdatesGridID + '-update-button',
+ label: i18n['KCHUPD6006M'],
+ disabled: true,
+ onClick: function(event) {
+ var updateButton = $(this);
+ var progressArea = $('#' + progressAreaID)[0];
+
$('#software-updates-progress-container').removeClass('hidden');
+ $(progressArea).text('');
+ !wok.isElementInViewport(progressArea) &&
+ progressArea.scrollIntoView();
+
$(updateButton).text(i18n['KCHUPD6007M']).prop('disabled', true);
+
+ kimchi.updateSoftware(function(result) {
+ reloadProgressArea(result);
+
$(updateButton).text(i18n['KCHUPD6006M']).prop('disabled', false);
+ wok.topic('kimchi/softwareUpdated').publish({
+ result: result
+ });
+ }, function(error) {
+ var message = error && error['responseJSON']
&& error['responseJSON']['reason'];
+ wok.message.error(message || i18n['KCHUPD6009M']);
+
$(updateButton).text(i18n['KCHUPD6006M']).prop('disabled', false);
+ }, reloadProgressArea);
+ }
+ }],
+ frozenFields: [],
+ fields: [{
+ name: 'package_name',
+ label: i18n['KCHUPD6002M'],
+ 'class': 'software-update-name'
+ }, {
+ name: 'version',
+ label: i18n['KCHUPD6003M'],
+ 'class': 'software-update-version'
+ }, {
+ name: 'arch',
+ label: i18n['KCHUPD6004M'],
+ 'class': 'software-update-arch'
+ }, {
+ name: 'repository',
+ label: i18n['KCHUPD6005M'],
+ 'class': 'software-update-repos'
+ }],
+ data: listSoftwareUpdates
+ });
+ };
+
+ var listSoftwareUpdates = function(gridCallback) {
+ kimchi.listSoftwareUpdates(function(softwareUpdates) {
+ if($.isFunction(gridCallback)) {
+ gridCallback(softwareUpdates);
+ }
+ else {
+ if(softwareUpdatesGrid) {
+ softwareUpdatesGrid.setData(softwareUpdates);
+ }
+ else {
+ initSoftwareUpdatesGrid(softwareUpdates);
+ }
+ }
+
+ var updateButton = $('#' + softwareUpdatesGridID +
'-update-button');
+ $(updateButton).prop('disabled', softwareUpdates.length === 0);
+ }, function(error) {
+ var message = error && error['responseJSON'] &&
error['responseJSON']['reason'];
+ if($.isFunction(gridCallback)) {
+ gridCallback([]);
+ }
+ softwareUpdatesGrid &&
+ softwareUpdatesGrid.showMessage(message || i18n['KCHUPD6008M']);
+ });
+ };
+
+ var reportGridID = 'available-reports-grid';
+ var reportGrid = null;
+ var enableReportButtons = function(toEnable) {
+ var buttonID = '#{grid}-{btn}-button';
+ $.each(['rename', 'remove', 'download'], function(i, n)
{
+ $(wok.substitute(buttonID, {
+ grid: reportGridID,
+ btn: n
+ })).prop('disabled', !toEnable);
+ });
+ };
+ var initReportGrid = function(reports) {
+ reportGrid = new wok.widget.Grid({
+ container: 'available-reports-grid-container',
+ id: reportGridID,
+ title: i18n['KCHDR6002M'],
+ toolbarButtons: [{
+ id: reportGridID + '-generate-button',
+ label: i18n['KCHDR6006M'],
+ onClick: function(event) {
+ wok.window.open('plugins/kimchi/report-add.html');
+ }
+ }, {
+ id: reportGridID + '-rename-button',
+ label: i18n['KCHDR6008M'],
+ disabled: true,
+ onClick: function(event) {
+ var report = reportGrid.getSelected();
+ if(!report) {
+ return;
+ }
+
+ kimchi.selectedReport = report['name'];
+ wok.window.open('plugins/kimchi/report-rename.html');
+ }
+ }, {
+ id: reportGridID + '-remove-button',
+ label: i18n['KCHDR6009M'],
+ disabled: true,
+ onClick: function(event) {
+ var report = reportGrid.getSelected();
+ if(!report) {
+ return;
+ }
+
+ var settings = {
+ title : i18n['KCHAPI6004M'],
+ content : i18n['KCHDR6001M'],
+ confirm : i18n['KCHAPI6002M'],
+ cancel : i18n['KCHAPI6003M']
+ };
+
+ wok.confirm(settings, function() {
+ kimchi.deleteReport({
+ name: report['name']
+ }, function(result) {
+ listDebugReports();
+ }, function(error) {
+ wok.message.error(error.responseJSON.reason);
+ });
+ });
+ }
+ }, {
+ id: reportGridID + '-download-button',
+ label: i18n['KCHDR6010M'],
+ disabled: true,
+ onClick: function(event) {
+ var report = reportGrid.getSelected();
+ if(!report) {
+ return;
+ }
+
+ kimchi.downloadReport({
+ file: report['uri']
+ });
+ }
+ }],
+ onRowSelected: function(row) {
+ var report = reportGrid.getSelected();
+ // Only enable report buttons if the selected line is not a
+ // pending report
+ if (report['time'] == i18n['KCHDR6007M']) {
+ var gridElement = $('#'+ reportGridID);
+ var row = $('tr:contains(' + report['name'] +
')', gridElement);
+ enableReportButtons(false);
+ row.attr('class', '');
+ }
+ else {
+ enableReportButtons(true);
+ }
+ },
+ frozenFields: [],
+ fields: [{
+ name: 'name',
+ label: i18n['KCHDR6003M'],
+ 'class': 'debug-report-name'
+ }, {
+ name: 'time',
+ label: i18n['KCHDR6005M'],
+ 'class': 'debug-report-time'
+ }],
+ data: reports
+ });
+ };
+
+ var getPendingReports = function() {
+ var reports = []
+ var filter = 'status=running&target_uri=' +
encodeURIComponent('^/plugins/kimchi/debugreports/*')
+
+ kimchi.getTasksByFilter(filter, function(tasks) {
+ for(var i = 0; i < tasks.length; i++) {
+ reportName =
tasks[i].target_uri.replace(/^\/plugins\/kimchi\/debugreports\//, '') ||
i18n['KCHDR6012M'];
+ reports.push({'name': reportName, 'time':
i18n['KCHDR6007M']})
+
+ if(kimchi.trackingTasks.indexOf(tasks[i].id) >= 0) {
+ continue;
+ }
+
+ kimchi.trackTask(tasks[i].id, function(result) {
+ wok.topic('kimchi/debugReportAdded').publish();
+ }, function(result) {
+ // Error message from Async Task status
+ if (result['message']) {
+ var errText = result['message'];
+ }
+ // Error message from standard kimchi exception
+ else {
+ var errText = result['responseJSON']['reason'];
+ }
+ result && wok.message.error(errText);
+ wok.topic('kimchi/debugReportAdded').publish();
+ }, null);
+ }
+ }, null, true);
+
+ return reports;
+ };
+
+ var listDebugReports = function() {
+ kimchi.listReports(function(reports) {
+ pendingReports = getPendingReports();
+ allReports = pendingReports.concat(reports);
+ $('#debug-report-section').removeClass('hidden');
+
+ // Row selection will be cleared so disable buttons here
+ enableReportButtons(false);
+
+ if(reportGrid) {
+ reportGrid.setData(allReports);
+ }
+ else {
+ initReportGrid(allReports);
+ }
+
+ // Set id-debug-img to pending reports
+ // It will display a loading icon
+ var gridElement = $('#' + reportGridID);
+ $.each($('td:contains(' + i18n['KCHDR6007M'] +
')', gridElement), function(index, row) {
+ $(row).parent().addClass('no-hover');
+ $(row).attr('id', 'id-debug-img');
+ });
+ }, function(error) {
+ if(error['status'] == 403) {
+ $('#debug-report-section').addClass('hidden');
+ return;
+ }
+ $('#debug-report-section').removeClass('hidden');
+ });
+ };
+
+ var shutdownButtonID = '#host-button-shutdown';
+ var restartButtonID = '#host-button-restart';
+ var shutdownHost = function(params) {
+ var settings = {
+ title : i18n['KCHAPI6004M'],
+ content : i18n['KCHHOST6008M'],
+ confirm : i18n['KCHAPI6002M'],
+ cancel : i18n['KCHAPI6003M']
+ };
+
+ wok.confirm(settings, function() {
+ kimchi.shutdown(params);
+ $(shutdownButtonID).prop('disabled', true);
+ $(restartButtonID).prop('disabled', true);
+ // Check if there is any VM is running.
+ kimchi.listVMs(function(vms) {
+ for(var i = 0; i < vms.length; i++) {
+ if(vms[i]['state'] === 'running') {
+ wok.message.error.code('KCHHOST6001E');
+ $(shutdownButtonID).prop('disabled', false);
+ $(restartButtonID).prop('disabled', false);
+ return;
+ }
+ }
+
+ });
+ }, function() {
+ });
+ };
+
+ var initPage = function() {
+ $('#host-info-container .section-header').each(function(i, header) {
+ $('<span
class="arrow"></span>').prependTo(header);
+ var toExpand = $(header).attr('aria-expanded') !== 'false';
+ expand(header, toExpand);
+ });
+
+ $('#host-info-container').on('click', '.section-header',
function(event) {
+ var toExpand = $(this).attr('aria-expanded') === 'false';
+ expand(this, toExpand);
+ });
+
+ $('#host-button-shutdown').on('click', function(event) {
+ shutdownHost(null);
+ });
+
+ $('#host-button-restart').on('click', function(event) {
+ shutdownHost({
+ reboot: true
+ });
+ });
+
+ var setupUI = function() {
+ if (kimchi.capabilities == undefined) {
+ setTimeout(setupUI, 2000);
+ return;
+ }
+
+ if((kimchi.capabilities['repo_mngt_tool']) &&
(kimchi.capabilities['repo_mngt_tool']!="None")) {
+ initRepositoriesGrid(kimchi.capabilities['repo_mngt_tool']);
+ $('#repositories-section').switchClass('hidden',
kimchi.capabilities['repo_mngt_tool']);
+ wok.topic('kimchi/repositoryAdded')
+ .subscribe(listRepositories);
+ wok.topic('kimchi/repositoryUpdated')
+ .subscribe(listRepositories);
+ wok.topic('kimchi/repositoryDeleted')
+ .subscribe(listRepositories);
+ }
+
+ if(kimchi.capabilities['update_tool']) {
+ $('#software-update-section').removeClass('hidden');
+ initSoftwareUpdatesGrid();
+ wok.topic('kimchi/softwareUpdated')
+ .subscribe(listSoftwareUpdates);
+ $('#software-updates-progress-container').accordion({
+ collapsible: true
+ });
+ }
+
+ if(kimchi.capabilities['system_report_tool']) {
+ listDebugReports();
+ wok.topic('kimchi/debugReportAdded')
+ .subscribe(listDebugReports);
+ wok.topic('kimchi/debugReportRenamed')
+ .subscribe(listDebugReports);
+ }
+ };
+ setupUI();
+ };
+
+ kimchi.getHost(function(data) {
+ var htmlTmpl = $('#host-tmpl').html();
+ data['logo'] = data['logo'] || '';
+ data['memory'] = wok.formatMeasurement(data['memory'], {
+ fixed: 2
+ });
+ var templated = wok.substitute(htmlTmpl, data);
+ $('#host-content-container').html(templated);
+
+ initPage();
+ initTracker();
+ });
+
+ var StatsMgr = function() {
+ var statsArray = {
+ cpu: {
+ u: {
+ type: 'percent',
+ legend: i18n['KCHHOST6002M'],
+ points: []
+ }
+ },
+ memory: {
+ u: {
+ type: 'value',
+ base: 2,
+ fixed: 2,
+ legend: i18n['KCHHOST6003M'],
+ points: []
+ }
+ },
+ diskIO: {
+ r: {
+ type: 'value',
+ base: 2,
+ fixed: 2,
+ unit: 'B/s',
+ legend: i18n['KCHHOST6004M'],
+ points: []
+ },
+ w: {
+ type: 'value',
+ base: 2,
+ fixed: 2,
+ unit: 'B/s',
+ legend: i18n['KCHHOST6005M'],
+ 'class': 'disk-write',
+ points: []
+ }
+ },
+ networkIO: {
+ r: {
+ type: 'value',
+ base: 2,
+ fixed: 2,
+ unit: 'B/s',
+ legend: i18n['KCHHOST6006M'],
+ points: []
+ },
+ s: {
+ type: 'value',
+ base: 2,
+ fixed: 2,
+ unit: 'B/s',
+ legend: i18n['KCHHOST6007M'],
+ 'class': 'network-sent',
+ points: []
+ }
+ }
+ };
+ var SIZE = 20;
+ var cursor = SIZE;
+
+ var add = function(stats) {
+ for(var key in stats) {
+ var item = stats[key];
+ for(var metrics in item) {
+ var value = item[metrics]['v'];
+ var max = item[metrics]['max'];
+ var unifiedMetrics = statsArray[key][metrics];
+ var ps = unifiedMetrics['points'];
+ if(!Array.isArray(value)){
+ ps.push(value);
+ if(ps.length > SIZE + 1) {
+ ps.shift();
+ }
+ }
+ else{
+ ps=ps.concat(value);
+ ps.splice(0, ps.length-SIZE-1);
+ unifiedMetrics['points']=ps;
+ }
+ if(max !== undefined) {
+ unifiedMetrics['max'] = max;
+ }
+ else {
+ if(unifiedMetrics['type'] !== 'value') {
+ continue;
+ }
+ max = -Infinity;
+ $.each(ps, function(i, value) {
+ if(value > max) {
+ max = value;
+ }
+ });
+ if(max === 0) {
+ ++max;
+ }
+ max *= 1.1;
+ unifiedMetrics['max'] = max;
+ }
+ }
+ }
+ cursor++;
+ };
+
+ var get = function(which) {
+ var stats = statsArray[which];
+ var lines = [];
+ for(var k in stats) {
+ var obj = stats[k];
+ var line = {
+ type: obj['type'],
+ base: obj['base'],
+ unit: obj['unit'],
+ fixed: obj['fixed'],
+ legend: obj['legend']
+ };
+ if(obj['max']) {
+ line['max'] = obj['max'];
+ }
+ if(obj['class']) {
+ line['class'] = obj['class'];
+ }
+ var ps = obj['points'];
+ var numStats = ps.length;
+ var unifiedPoints = [];
+ $.each(ps, function(i, value) {
+ unifiedPoints.push({
+ x: cursor - numStats + i,
+ y: value
+ });
+ });
+ line['points'] = unifiedPoints;
+ lines.push(line);
+ }
+ return lines;
+ };
+
+ return {
+ add: add,
+ get: get
+ };
+ };
+
+ var Tracker = function(charts) {
+ var charts = charts;
+ var timer = null;
+ var statsPool = new StatsMgr();
+ var setCharts = function(newCharts) {
+ charts = newCharts;
+ for(var key in charts) {
+ var chart = charts[key];
+ chart.updateUI(statsPool.get(key));
+ }
+ };
+
+ var self = this;
+
+ var UnifyStats = function(stats) {
+ var result= {
+ cpu: {
+ u: {
+ v: stats['cpu_utilization']
+ }
+ },
+ memory: {
+ u: {
+ }
+ },
+ diskIO: {
+ r: {
+ v: stats['disk_read_rate']
+ },
+ w: {
+ v: stats['disk_write_rate']
+ }
+ },
+ networkIO: {
+ r: {
+ v: stats['net_recv_rate']
+ },
+ s: {
+ v: stats['net_sent_rate']
+ }
+ }
+ };
+ if(Array.isArray(stats['memory'])){
+ result.memory.u['v']=[];
+ result.memory.u['max']=-Infinity;
+ for(var i=0;i<stats['memory'].length;i++){
+
result.memory.u['v'].push(stats['memory'][i]['avail']);
+
result.memory.u['max']=Math.max(result.memory.u['max'],stats['memory'][i]['total']);
+ }
+ }
+ else {
+ result.memory.u['v']=stats['memory']['avail'],
+ result.memory.u['max']=stats['memory']['total']
+ }
+ return(result);
+ };
+
+
+ var statsCallback = function(stats) {
+ var unifiedStats = UnifyStats(stats);
+ statsPool.add(unifiedStats);
+ for(var key in charts) {
+ var chart = charts[key];
+ chart.updateUI(statsPool.get(key));
+ }
+ timer = setTimeout(function() {
+ continueTrack();
+ }, 1000);
+ };
+
+ var track = function() {
+ kimchi.getHostStatsHistory(statsCallback,
+ function() {
+ continueTrack();
+ });
+ };
+
+ var continueTrack = function() {
+ kimchi.getHostStats(statsCallback,
+ function() {
+ continueTrack();
+ });
+ };
+
+ var destroy = function() {
+ timer && clearTimeout(timer);
+ timer = null;
+ };
+
+ return {
+ setCharts: setCharts,
+ start: track,
+ stop: destroy
+ };
+ };
+
+ var initTracker = function() {
+ // TODO: Extend tabs with onUnload event to unregister timers.
+ if(kimchi.hostTimer) {
+ kimchi.hostTimer.stop();
+ delete kimchi.hostTimer;
+ }
+
+ var trackedCharts = {
+ cpu: new wok.widget.LineChart({
+ id: 'chart-cpu',
+ node: 'container-chart-cpu',
+ type: 'percent'
+ }),
+ memory: new wok.widget.LineChart({
+ id: 'chart-memory',
+ node: 'container-chart-memory',
+ type: 'value'
+ }),
+ diskIO: new wok.widget.LineChart({
+ id: 'chart-disk-io',
+ node: 'container-chart-disk-io',
+ type: 'value'
+ }),
+ networkIO: new wok.widget.LineChart({
+ id: 'chart-network-io',
+ node: 'container-chart-network-io',
+ type: 'value'
+ })
+ };
+
+ if(kimchi.hostTimer) {
+ kimchi.hostTimer.setCharts(trackedCharts);
+ }
+ else {
+ kimchi.hostTimer = new Tracker(trackedCharts);
+ kimchi.hostTimer.start();
+ }
+ };
+
+ $('#host-root-container').on('remove', function() {
+ if(kimchi.hostTimer) {
+ kimchi.hostTimer.stop();
+ delete kimchi.hostTimer;
+ }
+
+ repositoriesGrid && repositoriesGrid.destroy();
+ wok.topic('kimchi/repositoryAdded')
+ .unsubscribe(listRepositories);
+ wok.topic('kimchi/repositoryUpdated')
+ .unsubscribe(listRepositories);
+ wok.topic('kimchi/repositoryDeleted')
+ .unsubscribe(listRepositories);
+
+ softwareUpdatesGrid && softwareUpdatesGrid.destroy();
+ wok.topic('kimchi/softwareUpdated').unsubscribe(listSoftwareUpdates);
+
+ reportGrid && reportGrid.destroy();
+ wok.topic('kimchi/debugReportAdded').unsubscribe(listDebugReports);
+ wok.topic('kimchi/debugReportRenamed').unsubscribe(listDebugReports);
+ });
+};
diff --git a/src/wok/plugins/kimchi/ui/js/src/kimchi.main.js
b/src/wok/plugins/kimchi/ui/js/src/kimchi.main.js
new file mode 100644
index 0000000..2fdeb85
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/js/src/kimchi.main.js
@@ -0,0 +1,26 @@
+/*
+ * Project Kimchi
+ *
+ * Copyright IBM, Corp. 2013-2014
+ *
+ * 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.
+ */
+kimchi.capabilities = undefined;
+kimchi.getCapabilities(function(result) {
+ kimchi.capabilities = result;
+
+ if(kimchi.capabilities.federation=="on")
+ $('#peers').removeClass('hide-content');
+}, function() {
+ kimchi.capabilities = {};
+});
diff --git a/src/wok/plugins/kimchi/ui/js/src/kimchi.network.js
b/src/wok/plugins/kimchi/ui/js/src/kimchi.network.js
new file mode 100644
index 0000000..c43b59a
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/js/src/kimchi.network.js
@@ -0,0 +1,442 @@
+/*
+ * Project Kimchi
+ *
+ * Copyright IBM, Corp. 2013-2015
+ *
+ * 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.
+ */
+
+kimchi.NETWORK_TYPE_BRIDGE = "bridged";
+
+kimchi.initNetwork = function() {
+ if(wok.tabMode['network'] === 'admin') {
+ $('.tools').attr('style','display');
+ $('#network-content .header
span:last-child').attr('style','display');
+ kimchi.initNetworkCreation();
+ }
+ kimchi.initNetworkListView();
+ kimchi.initNetworkDialog();
+ kimchi.initNetworkCleanup();
+};
+
+kimchi.initNetworkListView = function() {
+ kimchi.listNetworks(function(data) {
+ for (var i = 0; i < data.length; i++) {
+ var network = {
+ name : data[i].name,
+ in_use : data[i].in_use,
+ state : data[i].state === "active" ? "up" :
"down"
+ };
+ if (data[i].connection === "bridge") {
+ network.type = kimchi.NETWORK_TYPE_BRIDGE;
+ } else {
+ network.type = data[i].connection;
+ }
+ network.interface = data[i].interface ? data[i].interface : null;
+ network.addrSpace = data[i].subnet ? data[i].subnet : null;
+ network.persistent = data[i].persistent;
+ kimchi.addNetworkItem(network);
+ }
+ $('#networkGrid').grid({enableSorting: false});
+ $('input', $('.grid-control',
'#network-content')).on('keyup', function(){
+ $('#networkGrid').grid('filter', $(this).val());
+ });
+ });
+};
+
+kimchi.addNetworkItem = function(network) {
+ var itemNode = $.parseHTML(kimchi.getNetworkItemHtml(network));
+ $("#networkBody").append(itemNode);
+ if(wok.tabMode["network"] === "admin") {
+ $(".column-action").attr("style","display");
+ } else {
+ $(".column-space").addClass('column-space-no-border-right');
+ }
+ kimchi.addNetworkActions(network);
+ return itemNode;
+};
+
+kimchi.getNetworkItemHtml = function(network) {
+ if(!network.interface) {
+ network.interface = i18n["KCHNET6001M"];
+ }
+ if(!network.addrSpace) {
+ network.addrSpace = i18n["KCHNET6001M"];
+ }
+ if(i18n["network_type_" + network.type]) {
+ network.type = i18n["network_type_" + network.type];
+ }
+
+ var disable_in_use = network.in_use ? "ui-state-disabled" : "";
+ var networkItem = wok.substitute($('#networkItem').html(), {
+ name : network.name,
+ state : network.state,
+ type : network.type,
+ interface: network.interface,
+ addrSpace : network.addrSpace,
+ startClass : network.state === "up" ? "hide-action-item" :
"",
+ stopClass : network.state === "down" ? "hide-action-item" :
disable_in_use,
+ stopDisabled : network.in_use ? "disabled" : "",
+ deleteClass : network.state === "up" || network.in_use ?
"ui-state-disabled" : "",
+ deleteDisabled: network.state === "up" || network.in_use ?
"disabled" : ""
+ });
+ return networkItem;
+};
+
+kimchi.stopNetwork = function(network,menu) {
+ $(".network-state", $("#" +
wok.escapeStr(network.name))).switchClass("up", "nw-loading");
+ $("[nwAct='stop']", menu).addClass("ui-state-disabled");
+ kimchi.toggleNetwork(network.name, false, function() {
+ $("[nwAct='start']",
menu).removeClass("hide-action-item");
+ $("[nwAct='stop']",
menu).addClass("hide-action-item");
+ $("[nwAct='stop']",
menu).removeClass("ui-state-disabled");
+ if (!network.in_use) {
+ $("[nwAct='delete']",
menu).removeClass("ui-state-disabled");
+ $(":first-child", $("[nwAct='delete']",
menu)).removeAttr("disabled");
+ }
+ $(".network-state", $("#" +
wok.escapeStr(network.name))).switchClass("nw-loading", "down");
+ }, function(err) {
+ $(".network-state", $("#" +
wok.escapeStr(network.name))).switchClass("nw-loading", "up");
+ if (!network.in_use) {
+ $("[nwAct='stop']",
menu).removeClass("ui-state-disabled");
+ }
+ wok.message.error(err.responseJSON.reason);
+ });
+}
+
+kimchi.addNetworkActions = function(network) {
+ $(".menu-container", "#" + wok.escapeStr(network.name)).menu();
+
+ $('#' + wok.escapeStr(network.name)).on('click', '.menu-container
li', function(evt) {
+ var menu = $(evt.currentTarget).parent();
+ if ($(evt.currentTarget).attr("nwAct") === "start") {
+ $(".network-state", $("#" +
wok.escapeStr(network.name))).switchClass("down", "nw-loading");
+ $("[nwAct='start']",
menu).addClass("ui-state-disabled");
+ $("[nwAct='delete']",
menu).addClass("ui-state-disabled");
+ $(":first-child", $("[nwAct='delete']",
menu)).attr("disabled", true);
+ kimchi.toggleNetwork(network.name, true, function() {
+ $("[nwAct='start']",
menu).addClass("hide-action-item");
+ $("[nwAct='start']",
menu).removeClass("ui-state-disabled");
+ $("[nwAct='stop']",
menu).removeClass("hide-action-item");
+ network.state = "up";
+ if (network.in_use) {
+ $("[nwAct='stop']",
menu).addClass("ui-state-disabled");
+ }
+ $(".network-state", $("#" +
wok.escapeStr(network.name))).switchClass("nw-loading", "up");
+ }, function(err) {
+ $(".network-state", $("#" +
wok.escapeStr(network.name))).switchClass("nw-loading","down");
+ $("[nwAct='start']",
menu).removeClass("ui-state-disabled");
+ if (!network.in_use) {
+ $("[nwAct='delete']",
menu).removeClass("ui-state-disabled");
+ }
+ $(":first-child", $("[nwAct='delete']",
menu)).removeAttr("disabled");
+ wok.message.error(err.responseJSON.reason);
+ });
+ } else if ($(evt.currentTarget).attr("nwAct") === "stop") {
+ if (network.in_use) {
+ return false;
+ }
+ if (!network.persistent) {
+ var settings = {
+ title : i18n['KCHAPI6001M'],
+ content : i18n['KCHNET6004M'],
+ confirm : i18n['KCHAPI6002M'],
+ cancel : i18n['KCHAPI6003M']
+ };
+ wok.confirm(settings, function() {
+ kimchi.stopNetwork(network, menu);
+ $('#networkGrid').grid('deleteRow',
$(evt.currentTarget).parents(".row"));
+ }, null);
+ }
+ else {
+ kimchi.stopNetwork(network, menu);
+ network.state = "down";
+ }
+ } else if ($(evt.currentTarget).attr("nwAct") === "delete")
{
+ if (network.state === "up" || network.in_use) {
+ return false;
+ }
+ wok.confirm({
+ title : i18n['KCHAPI6006M'],
+ content : i18n['KCHNET6002M'],
+ confirm : i18n['KCHAPI6002M'],
+ cancel : i18n['KCHAPI6003M']
+ }, function() {
+ kimchi.deleteNetwork(network.name, function() {
+ $('#networkGrid').grid('deleteRow',
$(evt.currentTarget).parents(".row"));
+ });
+ }, null);
+ }
+ });
+
+ $("#networkBody .column-action .popable").button({
+ icons : {
+ secondary : "action-button-icon"
+ }
+ });
+
+};
+
+kimchi.initNetworkCreation = function() {
+ $("#networkAdd").on("click", function() {
+ kimchi.openNetworkDialog(function() {
+ var errorCallback = function(){
+ $("#networkFormOk").button("enable");
+ $("#networkName").removeAttr("readonly");
+ $("#networkFormOk span").text(i18n.KCHAPI6005M);
+ };
+ var network = kimchi.getNetworkDialogValues();
+ var data = {
+ name : network.name,
+ connection: network.type
+ };
+ if (network.type === kimchi.NETWORK_TYPE_BRIDGE) {
+ data.connection = "bridge";
+ data.interface = network.interface;
+ if ($("#enableVlan").prop("checked")) {
+ data.vlan_id = network.vlan_id;
+ if (!(data.vlan_id >=1 && data.vlan_id <= 4094)) {
+ wok.message.error.code('KCHNET6001E');
+ errorCallback();
+ return;
+ }
+ }
+ }
+ kimchi.createNetwork(data, function(result) {
+ network.state = result.state === "active" ? "up" :
"down";
+ network.interface = result.interface ? result.interface :
i18n["KCHNET6001M"];
+ network.addrSpace = result.subnet ? result.subnet :
i18n["KCHNET6001M"];
+ network.persistent = result.persistent;
+ $('#networkGrid').grid('addRow',
kimchi.addNetworkItem(network));
+ $("#networkConfig").dialog("close");
+ }, function(data) {
+ wok.message.error(data.responseJSON.reason);
+ errorCallback();
+ });
+ });
+ });
+};
+
+kimchi.initNetworkDialog = function() {
+ buttonsObj= {};
+ buttonsObj['id'] = "networkFormOk";
+ buttonsObj['text'] = i18n.KCHAPI6005M;
+ buttonsObj['class'] = "btn-normal";
+ buttonsObj['disabled'] = true;
+ buttonsObj['click'] = function() { };
+ buttonsObjCancel= {};
+ buttonsObjCancel['id'] = "networkFormCancel";
+ buttonsObjCancel['text'] = i18n.KCHAPI6003M;
+ buttonsObjCancel['class'] = "btn-normal";
+ buttonsObjCancel['disabled'] = false;
+ buttonsObjCancel['click'] = function() {
+ $(this).dialog("close");
+ };
+ $("#networkConfig").dialog({
+ autoOpen : false,
+ modal : true,
+ width : 600,
+ draggable : false,
+ resizable : false,
+ closeText: "X",
+ dialogClass : "network-ui-dialog remove-when-logged-off",
+ open : function(){
+ $(".ui-dialog-titlebar-close",
$("#networkConfig").parent()).removeAttr("title");
+ $(".ui-widget-overlay").css({
+ "background": "#FFFFFF",
+ "opacity": "0.5"
+ });
+ },
+ beforeClose : function() {
+ kimchi.cleanNetworkDialog();
+ },
+ buttons : [buttonsObj, buttonsObjCancel]
+ });
+ $("#networkConfig").parent().css({
+ "background": "#FFFFFF",
+ "border-radius": 0,
+ "border": "2px solid #999999"
+ });
+ $(".ui-dialog-titlebar button",
$("#networkConfig").parent()).remove();
+ $(".ui-dialog-titlebar span",
$("#networkConfig").parent()).css({
+ "font-weight": "lighter",
+ "height": "48px",
+ "line-height": "48px",
+ "margin": "0 30px",
+ "color": "#444444",
+ "font-size": "22px"
+ });
+ $(".ui-dialog-titlebar", $("#networkConfig").parent()).css({
+ "box-shadow": "none",
+ "padding": "0",
+ });
+ $(".ui-dialog-buttonpane", $("#networkConfig").parent()).css({
+ "background": "#008ABF"
+ });
+ $(".ui-dialog .ui-dialog-buttonpane .ui-dialog-buttonset").css({
+ "padding": "0 10px",
+ "float": "left"
+ });
+ $(".ui-dialog-buttonpane .ui-dialog-buttonset
button").removeClass("ui-corner-all");
+ $(".ui-dialog-buttonpane .ui-dialog-buttonset button").css({
+ "background": "#FFFFFF",
+ "color": "#444444",
+ "font-size": "13px",
+ "border-radius": "0",
+ "opacity": "1"
+ });
+ kimchi.setupNetworkFormEvent();
+};
+
+kimchi.openNetworkDialog = function(okCallback) {
+ kimchi.getInterfaces(function(result) {
+ var options = [];
+ $('#networkDestinationID').selectMenu();
+ var nics = {};
+ for (var i = 0; i < result.length; i++) {
+ options.push({label:result[i].name,value:result[i].name});
+ nics[result[i].name] = result[i];
+ }
+ result.length>0 &&
$("#networkDestinationID").selectMenu("setData", options);
+ onChange = function() {
+ $("#networkDestinationLabel").text($("#networkDestinationID
li:first-child").text());
+ $("#networkDestinationID
li:first-child").addClass("active");
+ if (result.length>0 &&
nics[$("#networkDestinationLabel").text()].type === "bridge") {
+ $("#enableVlan").prop("checked", false);
+ $("#enableVlan").prop("disabled", true);
+ $("#networkVlanID").val("");
+ $("#networkVlanID").toggle(false);
+ $("#labelNetworkVlanID").toggle(false);
+ } else {
+ $("#enableVlan").prop("disabled",false);
+ }
+ };
+ $("#networkDestinationLabel").on("change", onChange);
+ kimchi.setDefaultNetworkType(result.length!==0);
+ onChange();
+ });
+ $("#networkConfig").dialog({
+ title : i18n.KCHNET6003M
+ });
+ $("#networkFormOk").on("click", function() {
+ $("#networkFormOk").button("disable");
+ $("#networkName").prop("readonly", "readonly");
+ $("#networkFormOk span").text(i18n.KCHAPI6008M);
+ okCallback();
+ });
+ $("#enableVlan").on("click", function() {
+ $("#networkVlanID").prop("disabled", !this.checked);
+ if (!this.checked) {
+ $("#networkVlanID").slideUp(100);
+ $("#labelNetworkVlanID").slideUp(100);
+ $("#networkVlanID").val("");
+ }
+ else {
+ $("#networkVlanID").slideDown(100);
+ $("#labelNetworkVlanID").slideDown(100);
+ }
+ });
+ $("#networkConfig").dialog("open");
+};
+
+kimchi.enableBridgeOptions = function(enable) {
+ if (!enable) {
+ $("#enableVlan").prop("checked", false);
+ $("#networkVlanID").toggle(false);
+ $("#labelNetworkVlanID").toggle(false);
+ $("#networkVlanID").val("");
+ $("#networkDestinationLabel").text("");
+ $("#bridgeOptions").slideUp(100);
+ } else if (!$("#networkDestinationLabel").text()){
+ $("#networkDestinationLabel").text($("#networkDestinationID
li:first-child").text());
+ $("#bridgeOptions").slideDown(100);
+ $("#networkVlanID").toggle(false);
+ $("#labelNetworkVlanID").toggle(false);
+ }
+};
+
+
+kimchi.setDefaultNetworkType = function(isInterfaceAvail) {
+ $("#networkTypeBri").prop("checked", isInterfaceAvail);
+ $("#networkTypeBri").prop("disabled", !isInterfaceAvail);
+ $("#networkTypeNat").prop("checked", !isInterfaceAvail);
+ if (!isInterfaceAvail) {
+ kimchi.enableBridgeOptions(false);
+ $("#networkBriDisabledLabel").show();
+ } else {
+ if (kimchi.capabilities && kimchi.capabilities.nm_running) {
+ wok.message.warn(i18n['KCHNET6001W']);
+ }
+ $("#bridgeOptions").slideDown(100);
+ $("#networkVlanID").toggle(false);
+ $("#labelNetworkVlanID").toggle(false);
+ $("#networkBriDisabledLabel").hide();
+ }
+};
+
+kimchi.getNetworkDialogValues = function() {
+ var network = {
+ name : $("#networkName").val(),
+ type : $("input:radio[name=networkType]:checked").val()
+ };
+ if (network.type === kimchi.NETWORK_TYPE_BRIDGE) {
+ network.interface = $("#networkDestinationLabel").text();
+ network.vlan_id = parseInt($("#networkVlanID").val());
+ }
+ return network;
+};
+
+kimchi.cleanNetworkDialog = function() {
+ $("input:text",
"#networkConfig").val(null).removeClass("invalid-field");
+ $("#networkTypeIso").prop("checked", false);
+ $("#networkTypeNat").prop("checked", false);
+ $("#networkTypeBri").prop("checked", false);
+ $("#networkDestinationLabel").text($("#networkDestinationID
li:first-child").text());
+ $("#networkFormOk").off("click");
+ $("#networkFormOk").button("disable");
+ $("#networkFormOk span").text(i18n.KCHAPI6005M);
+ $("#networkName").removeAttr("readonly");
+ $("#networkVlanID").toggle(false);
+ $("#labelNetworkVlanID").toggle(false);
+ $("#enableVlan").prop("checked", false);
+
+};
+kimchi.setupNetworkFormEvent = function() {
+ $("#networkName").on("keyup", function(event) {
+ $("#networkName").toggleClass("invalid-field",
!$("#networkName").val().match(/^[^\"\/]+$/));
+ kimchi.updateNetworkFormButton();
+ });
+ $("#networkTypeIso").on("click", function(event) {
+ kimchi.enableBridgeOptions(false);
+ });
+ $("#networkTypeNat").on("click", function(event) {
+ kimchi.enableBridgeOptions(false);
+ });
+ $("#networkTypeBri").on("click", function(event) {
+ kimchi.enableBridgeOptions(true);
+ });
+};
+
+kimchi.updateNetworkFormButton = function() {
+ if($("#networkName").hasClass("invalid-field")){
+ $("#networkFormOk").button("disable");
+ }else{
+ $("#networkFormOk").button("enable");
+ }
+};
+
+kimchi.initNetworkCleanup = function() {
+ $("#network-content").on("remove", function() {
+ $("#networkConfig").dialog("destroy");
+ });
+};
diff --git a/src/wok/plugins/kimchi/ui/js/src/kimchi.report_add_main.js
b/src/wok/plugins/kimchi/ui/js/src/kimchi.report_add_main.js
new file mode 100644
index 0000000..5f098d3
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/js/src/kimchi.report_add_main.js
@@ -0,0 +1,72 @@
+/*
+ * Project Kimchi
+ *
+ * Copyright IBM, Corp. 2013-2014
+ *
+ * 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.
+ */
+kimchi.report_add_main = function() {
+ var reportGridID = 'available-reports-grid';
+ var addReportForm = $('#form-report-add');
+ var submitButton = $('#button-report-add');
+ var nameTextbox = $('input[name="name"]', addReportForm);
+ nameTextbox.select();
+
+ var submitForm = function(event) {
+ if(submitButton.prop('disabled')) {
+ return false;
+ }
+ var reportName = nameTextbox.val();
+ var validator = RegExp("^[_A-Za-z0-9-]*$");
+ if (!validator.test(reportName)) {
+ wok.message.error.code('KCHDR6011M');
+ return false;
+ }
+ var formData = addReportForm.serializeObject();
+ var taskAccepted = false;
+ var onTaskAccepted = function() {
+ if(taskAccepted) {
+ return;
+ }
+ taskAccepted = true;
+ wok.window.close();
+ wok.topic('kimchi/debugReportAdded').publish();
+ };
+
+ kimchi.createReport(formData, function(result) {
+ onTaskAccepted();
+ wok.topic('kimchi/debugReportAdded').publish();
+ }, function(result) {
+ // Error message from Async Task status
+ if (result['message']) {
+ var errText = result['message'];
+ }
+ // Error message from standard kimchi exception
+ else {
+ var errText = result['responseJSON']['reason'];
+ }
+ result && wok.message.error(errText);
+
+ taskAccepted &&
+ $('.grid-body-view table tr:first-child',
+ '#' + reportGridID).remove();
+ submitButton.prop('disabled', false);
+ nameTextbox.select();
+ }, onTaskAccepted);
+
+ event.preventDefault();
+ };
+
+ addReportForm.on('submit', submitForm);
+ submitButton.on('click', submitForm);
+};
diff --git a/src/wok/plugins/kimchi/ui/js/src/kimchi.report_rename_main.js
b/src/wok/plugins/kimchi/ui/js/src/kimchi.report_rename_main.js
new file mode 100644
index 0000000..1bdb8d9
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/js/src/kimchi.report_rename_main.js
@@ -0,0 +1,66 @@
+/*
+ * Project Kimchi
+ *
+ * Copyright IBM, Corp. 2014
+ *
+ * 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.
+ */
+kimchi.report_rename_main = function() {
+ var renameReportForm = $('#form-report-rename');
+ var submitButton = $('#button-report-rename');
+ var nameTextbox = $('input[name="name"]', renameReportForm);
+ var submitForm = function(event) {
+ if(submitButton.prop('disabled')) {
+ return false;
+ }
+ var reportName = nameTextbox.val();
+
+ // if the user hasn't changed the report's name,
+ // nothing should be done.
+ if (reportName == kimchi.selectedReport) {
+ wok.message.error.code('KCHDR6013M');
+ return false;
+ }
+
+ var validator = RegExp("^[A-Za-z0-9-]*$");
+ if (!validator.test(reportName)) {
+ wok.message.error.code('KCHDR6011M');
+ return false;
+ }
+ var formData = renameReportForm.serializeObject();
+ submitButton.prop('disabled', true);
+ nameTextbox.prop('disabled', true);
+ kimchi.renameReport(kimchi.selectedReport, formData, function(result) {
+ submitButton.prop('disabled', false);
+ nameTextbox.prop('disabled', false);
+ wok.window.close();
+ wok.topic('kimchi/debugReportRenamed').publish({
+ result: result
+ });
+ }, function(result) {
+ var errText = result &&
+ result['responseJSON'] &&
+ result['responseJSON']['reason'];
+ wok.message.error(errText);
+ submitButton.prop('disabled', false);
+ nameTextbox.prop('disabled', false).focus();
+ });
+
+ event.preventDefault();
+ };
+
+ renameReportForm.on('submit', submitForm);
+ submitButton.on('click', submitForm);
+
+ nameTextbox.val(kimchi.selectedReport).select();
+};
diff --git a/src/wok/plugins/kimchi/ui/js/src/kimchi.repository_add_main.js
b/src/wok/plugins/kimchi/ui/js/src/kimchi.repository_add_main.js
new file mode 100644
index 0000000..656306b
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/js/src/kimchi.repository_add_main.js
@@ -0,0 +1,96 @@
+/*
+ * Project Kimchi
+ *
+ * Copyright IBM, Corp. 2014
+ *
+ * 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.
+ */
+kimchi.repository_add_main = function() {
+
+ var addForm = $('#form-repository-add');
+ var addButton = $('#button-repository-add');
+
+ var validateField = function(event) {
+ var valid=($(this).val()!=='');
+ $(addButton).prop('disabled', !valid);
+ return(valid);
+ };
+
+ var validateForm = function(event) {
+ var valid=false;
+ addForm.find('input.required').each( function() {
+ valid=($(this).val()!=='');
+ return(!valid);
+ });
+ return(valid);
+ }
+
+ addForm.find('input.required').on('input propertychange',
validateField);
+
+ var weedObject = function(obj) {
+ for (var key in obj) {
+ if (obj.hasOwnProperty(key)) {
+ if((typeof(obj[key])==="object") &&
!Array.isArray(obj[key])) {
+ weedObject(obj[key]);
+ }
+ else if(obj[key] == '') {
+ delete obj[key];
+ }
+ }
+ }
+ }
+
+ var addRepository = function(event) {
+ var valid = validateForm();
+ if(!valid) {
+ return false;
+ }
+
+ var formData = $(addForm).serializeObject();
+
+ if (formData && formData.isMirror!=undefined) {
+ formData.isMirror=(String(formData.isMirror).toLowerCase() ===
'true');
+ }
+ if(formData.isMirror) {
+ if(formData.config==undefined) {
+ formData.config=new Object();
+ }
+ formData.config.mirrorlist=formData.baseurl;
+ delete formData.baseurl;
+ delete formData.isMirror;
+ }
+ weedObject(formData);
+ if(formData.config && formData.config.comps) {
+ formData.config.comps=formData.config.comps.split(/[,\s]/);
+ for(var i=0; i>formData.config.comps.length; i++) {
+ formData.config.comps[i]=formData.config.comps[i].trim();
+ }
+ for (var j=formData.config.comps.indexOf(""); j!=-1;
j=formData.config.comps.indexOf("")) {
+ formData.config.comps.splice(j, 1);
+ }
+ }
+
+ kimchi.createRepository(formData, function() {
+ wok.topic('kimchi/repositoryAdded').publish();
+ wok.window.close();
+ }, function(jqXHR, textStatus, errorThrown) {
+ var reason = jqXHR &&
+ jqXHR['responseJSON'] &&
+ jqXHR['responseJSON']['reason'];
+ wok.message.error(reason);
+ });
+ return false;
+ };
+
+ $(addForm).on('submit', addRepository);
+};
diff --git a/src/wok/plugins/kimchi/ui/js/src/kimchi.repository_edit_main.js
b/src/wok/plugins/kimchi/ui/js/src/kimchi.repository_edit_main.js
new file mode 100644
index 0000000..5bfc51e
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/js/src/kimchi.repository_edit_main.js
@@ -0,0 +1,74 @@
+/*
+ * Project Kimchi
+ *
+ * Copyright IBM, Corp. 2014
+ *
+ * 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.
+ */
+kimchi.repository_edit_main = function() {
+
+ var editForm = $('#form-repository-edit');
+
+ var saveButton = $('#repository-edit-button-save');
+
+ if(kimchi.capabilities['repo_mngt_tool']=="yum") {
+ editForm.find('input.deb').prop('disabled', true);
+ }
+ else if(kimchi.capabilities['repo_mngt_tool']=="deb") {
+ editForm.find('input.yum').prop('disabled', true);
+ }
+
+ kimchi.retrieveRepository(kimchi.selectedRepository, function(repository) {
+ editForm.fillWithObject(repository);
+
+ $('input', editForm).on('input propertychange', function(event)
{
+ if($(this).val() !== '') {
+ $(saveButton).prop('disabled', false);
+ }
+ });
+ });
+
+
+ var editRepository = function(event) {
+ var formData = $(editForm).serializeObject();
+
+ if (formData && formData.config) {
+ formData.config.gpgcheck=(String(formData.config.gpgcheck).toLowerCase() ===
'true');
+ }
+
+ if(formData.config && formData.config.comps) {
+ formData.config.comps=formData.config.comps.split(/[,\s]/);
+ for(var i=0; i>formData.config.comps.length; i++) {
+ formData.config.comps[i]=formData.config.comps[i].trim();
+ }
+ for (var j=formData.config.comps.indexOf(""); j!=-1;
j=formData.config.comps.indexOf("")) {
+ formData.config.comps.splice(j, 1);
+ }
+ }
+
+ kimchi.updateRepository(kimchi.selectedRepository, formData, function() {
+ wok.topic('kimchi/repositoryUpdated').publish();
+ wok.window.close();
+ }, function(jqXHR, textStatus, errorThrown) {
+ var reason = jqXHR &&
+ jqXHR['responseJSON'] &&
+ jqXHR['responseJSON']['reason'];
+ wok.message.error(reason);
+ });
+
+ return false;
+ };
+
+ $(editForm).on('submit', editRepository);
+ $(saveButton).on('click', editRepository);
+};
diff --git a/src/wok/plugins/kimchi/ui/js/src/kimchi.storage_main.js
b/src/wok/plugins/kimchi/ui/js/src/kimchi.storage_main.js
new file mode 100644
index 0000000..40a43f6
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/js/src/kimchi.storage_main.js
@@ -0,0 +1,428 @@
+/*
+ * Project Kimchi
+ *
+ * Copyright IBM, Corp. 2013-2015
+ *
+ * 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.
+ */
+kimchi.doListStoragePools = function() {
+ kimchi.listStoragePools(function(result) {
+ var storageHtml = $('#storageTmpl').html();
+ if (result && result.length) {
+ var listHtml = '';
+ $.each(result, function(index, value) {
+ value.usage = Math.round(value.allocated / value.capacity * 100) || 0;
+ value.capacity = wok.changetoProperUnit(value.capacity,1);
+ value.allocated = wok.changetoProperUnit(value.allocated,1);
+ value.enableExt = value.type==="logical" ? "" :
"hide-content";
+ if ('kimchi-iso' !== value.type) {
+ listHtml += wok.substitute(storageHtml, value);
+ }
+ });
+ if($('#storageGrid').hasClass('grid'))
+ $('#storageGrid').grid('destroy');
+ $('#storagepoolsList').html(listHtml);
+ if(wok.tabMode['storage'] === 'admin') {
+ $('.storage-button').attr('style','display');
+ } else {
+
$('.storage-allocate').addClass('storage-allocate-padding-user');
+ }
+ $('#storageGrid').grid({enableSorting: false});
+ $('input', $('.grid-control',
'.storage')).on('keyup', function(){
+ $('#storageGrid').grid('filter', $(this).val());
+ });
+ kimchi.storageBindClick();
+ } else {
+ $('#storagepoolsList').html('');
+ }
+ }, function(err) {
+ wok.message.error(err.responseJSON.reason);
+ });
+}
+
+kimchi.storageBindClick = function() {
+
+ $('.inactive').each(function(index) {
+ if ('active' === $(this).data('state')) {
+ $(this).hide();
+ } else {
+ $(this).show();
+ }
+ });
+
+ $('.list-storage .storage-state .active').each(function(index) {
+ if ('active' === $(this).data('state')) {
+ $(this).show();
+ } else {
+ $(this).hide();
+ }
+ });
+
+ $('.pool-activate').each(function(index) {
+ if ('active' === $(this).data('stat')) {
+ $(this).hide();
+ } else {
+ $(this).show();
+ }
+ });
+
+ $('.pool-deactivate').each(function(index) {
+ if ('active' === $(this).data('stat')) {
+ $(this).show();
+ } else {
+ $(this).hide();
+ }
+ });
+
+ $('.pool-add-volume').each(function(index) {
+ var canAddVolume =
+ $(this).data('stat') === 'active' &&
+ $(this).data('type') !== 'iscsi' &&
+ $(this).data('type') !== 'scsi';
+ if(canAddVolume) {
+ $(this).show();
+ }
+ else {
+ $(this).hide();
+ }
+ });
+
+ if(wok.tabMode['storage'] === 'admin') {
+ $('.pool-delete').on('click', function(event) {
+ var $pool = $(this);
+ var settings = {
+ title : i18n['KCHAPI6001M'],
+ content : i18n['KCHPOOL6001M'],
+ confirm : i18n['KCHAPI6002M'],
+ cancel : i18n['KCHAPI6003M']
+ };
+ wok.confirm(settings, function() {
+ var poolName = $pool.data('name');
+ kimchi.deleteStoragePool(poolName, function() {
+ kimchi.doListStoragePools();
+ }, function(err) {
+ wok.message.error(err.responseJSON.reason);
+ });
+ });
+ });
+
+ $('.pool-activate').on('click', function(event) {
+ var poolName = $(this).data('name');
+ kimchi.changePoolState(poolName, 'activate', function() {
+ kimchi.doListStoragePools();
+ }, function(err) {
+ wok.message.error(err.responseJSON.reason);
+ });
+ });
+
+ $('.pool-deactivate').on('click', function(event) {
+ var poolName = $(this).data('name');
+ var settings = {
+ title : i18n['KCHAPI6001M'],
+ content : i18n['KCHPOOL6012M'],
+ confirm : i18n['KCHAPI6002M'],
+ cancel : i18n['KCHAPI6003M']
+ };
+ if (!$(this).data('persistent')) {
+ wok.confirm(settings, function() {
+ kimchi.changePoolState(poolName, 'deactivate', function() {
+ kimchi.doListStoragePools();
+ }, function(err) {
+ wok.message.error(err.responseJSON.reason);
+ });
+ }, function() {
+ return false;
+ });
+ }
+ else {
+ kimchi.changePoolState(poolName, 'deactivate', function() {
+ kimchi.doListStoragePools();
+ }, function(err) {
+ wok.message.error(err.responseJSON.reason);
+ });
+ }
+ });
+
+ $('.pool-add-volume').on('click', function(event) {
+ var poolName = $(this).data('name');
+ kimchi.selectedSP = poolName;
+ wok.window.open('plugins/kimchi/storagepool-add-volume.html');
+ });
+
+ $('.storage-action').on('click', function() {
+ var storage_action = $(this);
+ var deleteButton = storage_action.find('.pool-delete');
+ if ('active' === deleteButton.data('stat')) {
+ deleteButton.attr('disabled', 'disabled');
+ } else {
+ deleteButton.removeAttr('disabled');
+ }
+ });
+
+ $('.pool-extend').on('click', function() {
+ $("#logicalPoolExtend").dialog("option",
"poolName", $(this).data('name'));
+ $("#logicalPoolExtend").dialog("open");
+ });
+ }
+
+ $('.row').on('click', function(event) {
+ if (!$(event.target).parents().hasClass('bottom')) {
+ if ($(this).data('stat') === 'active') {
+ var that = $(this);
+ var volumeDiv = $('#volume' + that.data('name'));
+ var slide = $('.volumes', this);
+ if (that.hasClass('in')) {
+ that.css('height','auto');
+ kimchi.doListVolumes(that);
+ } else {
+ slide.slideUp('slow', function(){
+ that.css('height','');
+ });
+ that.addClass('in');
+ kimchi.changeArrow($('.arrow-up', this));
+ }
+ }
+ }
+ });
+}
+
+kimchi._generateVolumeHTML = function(volume) {
+ if(volume['type'] === 'kimchi-iso') {
+ return '';
+ }
+ var volumeHtml = $('#volumeTmpl').html();
+ volume.capacity = wok.changetoProperUnit(volume.capacity,1);
+ volume.allocation = wok.changetoProperUnit(volume.allocation,1);
+ return wok.substitute(volumeHtml, volume);
+};
+
+kimchi.doListVolumes = function(poolObj) {
+ var poolName = poolObj.data('name')
+
+ var getOngoingVolumes = function() {
+ var result = {}
+ var filter = 'status=running&target_uri=' +
encodeURIComponent('^/plugins/kimchi/storagepools/' + poolName + '/*')
+ kimchi.getTasksByFilter(filter, function(tasks) {
+ for(var i = 0; i < tasks.length; i++) {
+ var volumeName = tasks[i].target_uri.split('/').pop();
+ result[volumeName] = tasks[i];
+
+ if(kimchi.trackingTasks.indexOf(tasks[i].id) >= 0) {
+ continue;
+ }
+
+ kimchi.trackTask(tasks[i].id, function(result) {
+ wok.topic('kimchi/volumeTransferFinished').publish(result);
+ }, function(result) {
+ wok.topic('kimchi/volumeTransferError').publish(result);
+ }, function(result) {
+ wok.topic('kimchi/volumeTransferProgress').publish(result);
+ });
+ }
+ }, null, true);
+ return result;
+ };
+
+ var volumeDiv = $('#volume' + poolName);
+ $(volumeDiv).empty();
+ var slide = $('.volumes', poolObj);
+ var handleArrow = $('.arrow-down', poolObj);
+
+ kimchi.listStorageVolumes(poolName, function(result) {
+ var listHtml = '';
+ var ongoingVolumes = [];
+ var ongoingVolumesMap = getOngoingVolumes();
+ $.each(ongoingVolumesMap, function(volumeName, task) {
+ ongoingVolumes.push(volumeName)
+ var volume = {
+ poolName: poolName,
+ used_by: [],
+ capacity: 0,
+ name: volumeName,
+ format: '',
+ bootable: null,
+ os_distro: '',
+ allocation: 0,
+ os_version: '',
+ path: '',
+ type: 'file'
+ };
+ listHtml += kimchi._generateVolumeHTML(volume);
+ });
+
+ $.each(result, function(index, value) {
+ if (ongoingVolumes.indexOf(value.name) == -1) {
+ value.poolname = poolName;
+ listHtml += kimchi._generateVolumeHTML(value);
+ }
+ });
+
+ if (listHtml.length > 0) {
+ volumeDiv.html(listHtml);
+ } else {
+ volumeDiv.html("<div class='pool-empty'>" +
i18n['KCHPOOL6002M'] + "</div>");
+ }
+
+ $.each(ongoingVolumesMap, function(volumeName, task) {
+ wok.topic('kimchi/volumeTransferProgress').publish(task);
+ });
+
+ poolObj.removeClass('in');
+ kimchi.changeArrow(handleArrow);
+ slide.slideDown('slow');
+ }, function(err) {
+ wok.message.error(err.responseJSON.reason);
+ });
+}
+
+kimchi.initLogicalPoolExtend = function() {
+ $("#logicalPoolExtend").dialog({
+ autoOpen : false,
+ modal : true,
+ width : 600,
+ resizable : false,
+ closeText: "X",
+ open : function(){
+ $('#loading-info',
'#logicalPoolExtend').removeClass('hidden');
+ $(".ui-dialog-titlebar-close",
$("#logicalPoolExtend").parent()).removeAttr("title");
+ kimchi.listHostPartitions(function(data) {
+ $('#loading-info',
'#logicalPoolExtend').addClass('hidden');
+ if (data.length > 0) {
+ for(var i=0;i<data.length;i++){
+ if (data[i].type === 'part' || data[i].type ===
'disk') {
+ $('.host-partition',
'#logicalPoolExtend').append(wok.substitute($('#logicalPoolExtendTmpl').html(),
data[i]));
+ }
+ }
+ } else {
+ $('.host-partition').html(i18n['KCHPOOL6011M']);
+ $('.host-partition').addClass('text-help');
+ }
+ }, function(err) {
+ $('#loading-info',
'#logicalPoolExtend').addClass('hidden');
+ $('.host-partition').html(i18n['KCHPOOL6013M'] +
'<br/>(' + err.responseJSON.reason + ')');
+ $('.host-partition').addClass('text-help');
+ });
+ },
+ beforeClose : function() { $('.host-partition',
'#logicalPoolExtend').empty(); },
+ buttons : [{
+ class: "ui-button-primary",
+ text: i18n.KCHAPI6007M,
+ click: function(){
+ var devicePaths = [];
+ $("input[type='checkbox']:checked",
"#logicalPoolExtend").each(function(){
+ devicePaths.push($(this).prop('value'));
+ })
+
kimchi.updateStoragePool($("#logicalPoolExtend").dialog("option",
"poolName"),{disks: devicePaths},function(data){
+ var item =
$("#"+$("#logicalPoolExtend").dialog("option",
"poolName"));
+ $(".usage", $(".storage-name",
item)).text((Math.round(data.allocated/data.capacity*100)||0)+"%");
+ $(".storage-text", $(".storage-capacity",
item)).text(wok.changetoProperUnit(data.capacity,1));
+ $(".storage-text", $(".storage-allocate",
item)).text(wok.changetoProperUnit(data.allocated,1));
+ });
+ $(this).dialog("close");
+ }
+ }]
+ });
+}
+
+kimchi.storage_main = function() {
+ if(wok.tabMode['storage'] === 'admin') {
+ $('.tools').attr('style','display');
+ $('#storage-pool-add').on('click', function() {
+ wok.window.open('plugins/kimchi/storagepool-add.html');
+ });
+ $('.list-title .title-actions').attr('style','display');
+ }
+ kimchi.doListStoragePools();
+ kimchi.initLogicalPoolExtend();
+
+ wok.topic('kimchi/storageVolumeAdded').subscribe(function() {
+ pool = kimchi.selectedSP;
+ var poolNode = $('.storage-li[data-name="' + pool +
'"]');
+ kimchi.doListVolumes(poolNode);
+ });
+
+ wok.topic('kimchi/volumeTransferProgress').subscribe(function(result) {
+ var extractProgressData = function(data) {
+ var sizeArray = /(\d+)\/(\d+)/g.exec(data) || [0, 0, 0];
+ var downloaded = sizeArray[1];
+ var percent = 0;
+ if(downloaded) {
+ var total = sizeArray[2];
+ if(!isNaN(total)) {
+ percent = downloaded / total * 100;
+ }
+ }
+ var formatted = wok.formatMeasurement(downloaded);
+ var size = (1.0 * formatted['v']).toFixed(1) +
formatted['s'];
+ return {
+ size: size,
+ percent: percent
+ };
+ };
+
+ var uriElements = result.target_uri.split('/');
+ var poolName = uriElements[2];
+ var volumeName = uriElements.pop();
+ var progress = extractProgressData(result['message']);
+ var size = progress['size'];
+ var percent = progress['percent'];
+
+ volumeBox = $('#volume' + poolName + ' [data-volume-name="'
+ volumeName + '"]');
+ $('.progress-bar-inner', volumeBox).css({
+ width: percent + '%'
+ });
+ $('.progress-transferred', volumeBox).text(size);
+ $('.volume-progress', volumeBox).removeClass('hidden');
+ $('.progress-status', volumeBox).text(i18n['KCHPOOL6014M']);
+ });
+
+ wok.topic('kimchi/volumeTransferFinished').subscribe(function(result) {
+ var uriElements = result.target_uri.split('/');
+ var poolName = uriElements[2];
+ var volumeName = uriElements.pop();
+ var volumeBox = $('#volume' + poolName + '
[data-volume-name="' + volumeName + '"]');
+ $('.volume-progress', volumeBox).addClass('hidden');
+ kimchi.getStoragePoolVolume(poolName, volumeName, function(volume) {
+ var html = kimchi._generateVolumeHTML(volume);
+ $(volumeBox).replaceWith(html);
+ }, function(err) {
+ wok.message.error(err.responseJSON.reason);
+ });
+ });
+
+ wok.topic('kimchi/volumeTransferError').subscribe(function(result) {
+ // Error message from Async Task status
+ if (result['message']) {
+ var errText = result['message'];
+ }
+ // Error message from standard kimchi exception
+ else {
+ var errText = result['responseJSON']['reason'];
+ }
+ result && wok.message.error(errText);
+
+ var uriElements = result.target_uri.split('/');
+ var poolName = uriElements[2];
+ var volumeName = uriElements.pop();
+ volumeBox = $('#volume' + poolName + ' [data-volume-name="'
+ volumeName + '"]');
+ $('.progress-status', volumeBox).text(i18n['KCHPOOL6015M']);
+ });
+};
+
+kimchi.changeArrow = function(obj) {
+ if ($(obj).hasClass('arrow-down')) {
+ $(obj).removeClass('arrow-down').addClass('arrow-up');
+ } else {
+ $(obj).removeClass('arrow-up').addClass('arrow-down');
+ }
+}
diff --git a/src/wok/plugins/kimchi/ui/js/src/kimchi.storagepool_add_main.js
b/src/wok/plugins/kimchi/ui/js/src/kimchi.storagepool_add_main.js
new file mode 100644
index 0000000..8c27539
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/js/src/kimchi.storagepool_add_main.js
@@ -0,0 +1,414 @@
+/*
+ * Project Kimchi
+ *
+ * Copyright IBM, Corp. 2013-2015
+ *
+ * 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.
+ */
+
+kimchi.storagepool_add_main = function() {
+ kimchi.initStorageAddPage();
+ $('#form-pool-add').on('submit', kimchi.addPool);
+ $('#pool-doAdd').on('click', kimchi.addPool);
+ // 'pool-doAdd' button starts as disabled.
+ $("#pool-doAdd").attr("disabled", true);
+ // Make any change in the form fields enables the
+ // 'pool-doAdd' button if all the visible form
+ // fields are filled, disables it otherwise.
+ $('#form-pool-add').on('input change propertychange', function() {
+ if (!kimchi.inputsNotBlank())
+ $("#pool-doAdd").attr("disabled", true);
+ else
+ $("#pool-doAdd").attr("disabled", false);
+ });
+};
+
+kimchi.storageFilterSelect = function(id, isUpdate) {
+ var input = $('input', '#'+id);
+ var options = $(".option", '#'+id);
+ var filter = function(container, key){
+ container.children().each(function(){
+ $(this).css("display", $(this).text().indexOf(key)==-1 ?
"none" : "");
+ });
+ };
+ if(!isUpdate){
+ input.on("keyup", function(){
+ filter(options, input.val());
+ });
+ }
+ options.children().each(function(){
+ $(this).click(function(){
+ options.children().removeClass("active");
+ input.val($(this).text());
+ input.trigger("change");
+ $(this).addClass("active");
+ filter(options, "");
+ });
+ });
+};
+
+kimchi.setupISCSI = function(){
+ var loadTargets = function(server, port, callback){
+ var isUpdate = $(".option", "#iSCSITarget").children().length
> 0;
+ $(".option", "#iSCSITarget").empty();
+ $('input', "#iSCSITarget").attr("placeholder",
i18n['KCHPOOL6006M']);
+ kimchi.getISCSITargets(server, port, function(data){
+ if(data.length==0){
+ $('input',
"#iSCSITarget").attr("placeholder", i18n['KCHPOOL6007M']);
+ }else{
+ for(var i=0; i<data.length; i++){
+ var itemNode =
$.parseHTML("<li>"+data[i].target+"</li>");
+ $(".option", "#iSCSITarget").append(itemNode);
+ }
+ $('input',
"#iSCSITarget").attr("placeholder", "");
+ $(".popover",
"#iSCSITarget").css("display", "block");
+ }
+ kimchi.storageFilterSelect('iSCSITarget', isUpdate);
+ $('input', "#iSCSITarget").trigger("focus");
+ callback();
+ }, function(data){
+ $('input', "#iSCSITarget").attr("placeholder",
i18n['KCHPOOL6008M']);
+ callback();
+ wok.message.error(data.responseJSON.reason);
+ });
+ };
+ var triggerLoadTarget = function(){
+ $('input', "#iSCSITarget").val("");
+ var server = $("#iscsiserverId").val().trim();
+ var port = $("#iscsiportId").val().trim();
+ if(server!="" &&
!$("#iscsiserverId").hasClass("invalid-field") &&
!$("#iscsiportId").hasClass("invalid-field")){
+ $("#iscsiserverId").attr("disabled", true);
+ $("#iscsiportId").attr("disabled", true);
+ loadTargets(server, port, function(){
+ $("#iscsiserverId").attr("disabled", false);
+ $("#iscsiportId").attr("disabled", false);
+ });
+ }
+ };
+ $("#iscsiserverId").change(function(){
+ $('input', "#iSCSITarget").off('focus',
triggerLoadTarget);
+ $('input', "#iSCSITarget").one('focus',
triggerLoadTarget);
+ });
+ $("#iscsiportId").change(function(){
+ $('input', "#iSCSITarget").off('focus',
triggerLoadTarget);
+ $('input', "#iSCSITarget").one('focus',
triggerLoadTarget);
+ });
+ var initISCSIServers = function(){
+ kimchi.getStorageServers("iscsi", function(data){
+ for(var i=0;i<data.length;i++){
+ var itemNode =
$.parseHTML("<li>"+data[i].host+"</li>");
+ $(".option", "#iSCSIServer").append(itemNode);
+ $(itemNode).click(function(){
+ $("#iscsiportId").val($(this).prop("port"));
+ $("#iscsiserverId").val($(this).text());
+ triggerLoadTarget();
+ }).prop("port", data[i].port);
+ }
+ kimchi.storageFilterSelect('iSCSIServer', false);
+ });
+ };
+ initISCSIServers();
+};
+
+kimchi.initStorageAddPage = function() {
+ kimchi.listHostPartitions(function(data) {
+ if (data.length > 0) {
+ var deviceHtml = $('#partitionTmpl').html();
+ var listHtml = '';
+ valid_types = ['part', 'disk', 'mpath'];
+ $.each(data, function(index, value) {
+ if (valid_types.indexOf(value.type) != -1) {
+ listHtml += wok.substitute(deviceHtml, value);
+ }
+ });
+ $('.host-partition', '#form-pool-add').html(listHtml);
+ } else {
+ $('.host-partition').html(i18n['KCHPOOL6011M']);
+ $('.host-partition').addClass('text-help');
+ }
+ }, function(err) {
+ $('.host-partition').html(i18n['KCHPOOL6013M'] +
'<br/>(' + err.responseJSON.reason + ')');
+ $('.host-partition').addClass('text-help');
+ });
+
+ kimchi.getHostFCDevices(function(data){
+ if(data.length>0){
+ for(var i=0;i<data.length;i++){
+ data[i].label = data[i].name;
+ data[i].value = data[i].name;
+ }
+ $('#scsiAdapter').selectMenu();
+ $("input", "#scsiAdapter").val(data[0].name);
+ $('#scsiAdapter').selectMenu("setData", data);
+ } else {
+ $('#scsiAdapter').html(i18n['KCHPOOL6005M']);
+ $('#scsiAdapter').addClass('text-help');
+ }
+ });
+
+ $('#poolTypeId').selectMenu();
+ $('#serverComboboxId').combobox();
+ $('#targetFilterSelectId').filterselect();
+ var options = [ {
+ label : "DIR",
+ value : "dir"
+ }, {
+ label : "NFS",
+ value : "netfs"
+ }, {
+ label : "iSCSI",
+ value : "iscsi"
+ }, {
+ label : "LOGICAL",
+ value : "logical"
+ }, {
+ label : i18n.KCHPOOL6004M,
+ value : "scsi"
+ } ];
+ $('#poolTypeId').selectMenu("setData", options);
+
+ kimchi.getStorageServers('netfs', function(data) {
+ var serverContent = [];
+ if (data.length > 0) {
+ $.each(data, function(index, value) {
+ serverContent.push({
+ label : value.host,
+ value : value.host
+ });
+ });
+ }
+ $('#serverComboboxId').combobox("setData", serverContent);
+ $('input[name=nfsServerType]').change(function() {
+ if ($(this).val() === 'input') {
+ $('#nfsServerInputDiv').removeClass('tmpl-html');
+ $('#nfsServerChooseDiv').addClass('tmpl-html');
+ } else {
+ $('#nfsServerInputDiv').addClass('tmpl-html');
+ $('#nfsServerChooseDiv').removeClass('tmpl-html');
+ }
+ });
+ $('#nfsserverId').on("change keyup",function() {
+ if ($(this).val() !== '' && wok.isServer($(this).val())) {
+ $('#nfspathId').prop('disabled',false);
+ $(this).removeClass("invalid-field");
+ } else {
+ $(this).addClass("invalid-field");
+ $('#nfspathId').prop( "disabled",true);
+ }
+ $('#targetFilterSelectId').filterselect('clear');
+ });
+ $('#nfspathId').focus(function() {
+ var targetContent = [];
+ kimchi.getStorageTargets($('#nfsserverId').val(), 'netfs',
function(data) {
+ if (data.length > 0) {
+ $.each(data, function(index, value) {
+ targetContent.push({
+ label : value.target,
+ value : value.target
+ });
+ });
+ }
+ $('#targetFilterSelectId').filterselect("setData",
targetContent);
+ });
+ });
+ });
+
+ $('#poolTypeInputId').change(function() {
+ var poolObject = {'dir': ".path-section", 'netfs':
'.nfs-section',
+ 'iscsi': '.iscsi-section', 'scsi':
'.scsi-section',
+ 'logical': '.logical-section'}
+ var selectType = $(this).val();
+ $.each(poolObject, function(type, value) {
+ if(selectType == type){
+ $(value).removeClass('tmpl-html');
+ } else {
+ $(value).addClass('tmpl-html');
+ }
+ });
+ });
+ $('#authId').click(function() {
+ if ($(this).prop("checked")) {
+ $('.authenticationfield').removeClass('tmpl-html');
+ } else {
+ $('.authenticationfield').addClass('tmpl-html');
+ }
+ });
+ $('#iscsiportId').keyup(function(event) {
+ $(this).toggleClass("invalid-field",!/^[0-9]*$/.test($(this).val()));
+ });
+ $('#iscsiserverId').keyup(function(event) {
+
$(this).toggleClass("invalid-field",!wok.isServer($(this).val().trim()));
+ }).change(function(event) {
+
$(this).toggleClass("invalid-field",!wok.isServer($(this).val().trim()));
+ });
+ kimchi.setupISCSI();
+};
+
+/* Returns 'true' if all form fields were filled, 'false' if
+ * any field is left blank. The function takes into account
+ * the current poolType selected.
+ *
+ * Any 'field is blank' verification that were done in other
+ * validate functions were deleted, since we're doing it here
+ * already.
+ */
+kimchi.inputsNotBlank = function() {
+ if (!$('#poolId').val()) return false;
+ var poolType = $("#poolTypeInputId").val();
+ if (poolType === "dir") {
+ if (!$('#pathId').val()) return false;
+ } else if (poolType === "netfs") {
+ if (!$('#nfspathId').val()) return false;
+ if (!$('#nfsserverId').val()) return false;
+ } else if (poolType === "iscsi") {
+ if (!$('#iscsiserverId').val()) return false;
+ if (!$('#iscsiTargetId').val()) return false;
+ } else if (poolType === "logical") {
+ if ($("input[name=devices]:checked").length === 0)
+ return false;
+ }
+ return true;
+};
+
+kimchi.validateForm = function() {
+ var poolType = $("#poolTypeInputId").val();
+ if (poolType === "dir") {
+ return kimchi.validateDirForm();
+ } else if (poolType === "netfs") {
+ return kimchi.validateNfsForm();
+ } else if (poolType === "iscsi") {
+ return kimchi.validateIscsiForm();
+ } else if (poolType === "logical") {
+ return kimchi.validateLogicalForm();
+ } else {
+ return true;
+ }
+};
+
+kimchi.validateDirForm = function () {
+ var path = $('#pathId').val();
+ if (!/(^\/.*)$/.test(path)) {
+ wok.message.error.code('KCHAPI6003E');
+ return false;
+ }
+ return true;
+};
+
+kimchi.validateNfsForm = function () {
+ var nfspath = $('#nfspathId').val();
+ var nfsserver = $('#nfsserverId').val();
+ if (!kimchi.validateServer(nfsserver)) {
+ return false;
+ }
+ if (!/((\/([0-9a-zA-Z-_\.]+)))$/.test(nfspath)) {
+ wok.message.error.code('KCHPOOL6005E');
+ return false;
+ }
+ $('#nfs-mount-loading').removeClass('hidden');
+ return true;
+};
+
+kimchi.validateIscsiForm = function() {
+ var iscsiServer = $('#iscsiserverId').val();
+ var iscsiTarget = $('#iscsiTargetId').val();
+ if (!kimchi.validateServer(iscsiServer)) {
+ return false;
+ }
+ return true;
+};
+
+kimchi.validateServer = function(serverField) {
+ if(!wok.isServer(serverField)) {
+ wok.message.error.code('KCHPOOL6009E');
+ return false;
+ }
+ return true;
+};
+
+kimchi.validateLogicalForm = function () {
+ if ($("input[name=devices]:checked").length === 0) {
+ wok.message.error.code('KCHPOOL6006E');
+ return false;
+ } else {
+ return true;
+ }
+};
+
+kimchi.addPool = function(event) {
+ if (kimchi.validateForm()) {
+ var formData = $('#form-pool-add').serializeObject();
+ delete formData.authname;
+ var poolType = $('#poolTypeId').selectMenu('value');
+ if (poolType === 'dir') {
+ formData.path = $('#pathId').val();
+ } else if (poolType === 'logical') {
+ var source = {};
+ if (!$.isArray(formData.devices)) {
+ var deviceObj = [];
+ deviceObj[0] = formData.devices;
+ source.devices = deviceObj;
+ } else {
+ source.devices = formData.devices;
+ }
+ delete formData.devices;
+ formData.source = source;
+ } else if (poolType === 'netfs'){
+ var source = {};
+ source.path = $('#nfspathId').val();
+ source.host = $('#nfsserverId').val();
+ formData.source = source;
+ } else if (poolType === 'iscsi') {
+ var source = {};
+ source.target = $('#iscsiTargetId').val();
+ source.host = $('#iscsiserverId').val();
+ $('#iscsiportId').val() !== '' ? source.port =
parseInt($('#iscsiportId').val()): null;
+ if ($('#authId').prop("checked")) {
+ source.auth = {
+ "username" : $('#usernameId').val(),
+ "password" : $('#passwordId').val()
+ };
+ }
+ formData.source = source;
+ } else if (poolType === 'scsi'){
+ formData.source = { adapter_name:
$('#scsiAdapter').selectMenu('value') };
+ }
+ var storagePoolAddingFunc = function() {
+ $('input',
'#form-pool-add').attr('disabled','disabled');
+ $('#pool-doAdd').hide();
+ $('#pool-loading').show();
+ kimchi.createStoragePool(formData, function() {
+ kimchi.doListStoragePools();
+ wok.window.close();
+ }, function(err) {
+ wok.message.error(err.responseJSON.reason);
+ $('input',
'#form-pool-add').removeAttr('disabled');
+ $('#pool-loading').hide();
+ $('#pool-doAdd').show();
+ });
+ };
+ if (poolType === 'logical') {
+ var settings = {
+ title : i18n['KCHAPI6001M'],
+ content : i18n['KCHPOOL6003M'],
+ confirm : i18n['KCHAPI6002M'],
+ cancel : i18n['KCHAPI6003M']
+ };
+ wok.confirm(settings, function() {
+ storagePoolAddingFunc();
+ }, function() {
+ });
+ } else {
+ storagePoolAddingFunc();
+ }
+ }
+};
diff --git a/src/wok/plugins/kimchi/ui/js/src/kimchi.storagepool_add_volume_main.js
b/src/wok/plugins/kimchi/ui/js/src/kimchi.storagepool_add_volume_main.js
new file mode 100644
index 0000000..8479ab2
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/js/src/kimchi.storagepool_add_volume_main.js
@@ -0,0 +1,179 @@
+/*
+ * Project Kimchi
+ *
+ * Copyright IBM, Corp. 2014-2015
+ *
+ * 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.
+ */
+kimchi.sp_add_volume_main = function() {
+ // download from remote server or upload from local file
+ var type = 'download';
+
+ var addButton = $('#sp-add-volume-button');
+ var remoteURLBox = $('#volume-remote-url');
+ var localFileBox = $('#volume-input-file');
+ var typeRadios = $('input.volume-type');
+
+ var isValidURL = function() {
+ var url = $(remoteURLBox).val();
+ return kimchi.template_check_url(url);
+ };
+
+ var isValidFile = function() {
+ var fileName = $(localFileBox).val();
+ return fileName.length > 0;
+ };
+
+ $(typeRadios).change(function(event) {
+ $('.volume-input').prop('disabled', true);
+ $('.volume-input.' + this.value).prop('disabled', false);
+ type = this.value;
+ if(type == 'download') {
+ $(addButton).prop('disabled', !isValidURL());
+ }
+ else {
+ $(addButton).prop('disabled', !isValidFile());
+ }
+ });
+
+ $(remoteURLBox).on('input propertychange', function(event) {
+ $(addButton).prop('disabled', !isValidURL());
+ });
+
+ $(localFileBox).on('change', function(event) {
+ $(addButton).prop('disabled', !isValidFile());
+ });
+
+ var onError = function(result) {
+ $(this).prop('disabled', false);
+ $(typeRadios).prop('disabled', false);
+ if(!result) {
+ return;
+ }
+ var msg = result['message'] || (
+ result['responseJSON'] &&
result['responseJSON']['reason']
+ );
+ wok.message.error(msg);
+ };
+
+ var fetchRemoteFile = function() {
+ var volumeURL = remoteURLBox.val();
+ var volumeName = volumeURL.split(/(\\|\/)/g).pop();
+ kimchi.downloadVolumeToSP({
+ sp: kimchi.selectedSP,
+ url: volumeURL
+ }, function(result) {
+ wok.window.close();
+ wok.topic('kimchi/storageVolumeAdded').publish();
+ }, onError);
+ };
+
+ var uploadFile = function() {
+ var chunkSize = 8 * 1024 * 1024; // 8MB
+ var uploaded = 0;
+
+ var blobFile = $(localFileBox)[0].files[0];
+
+ var createUploadVol = function() {
+ kimchi.createVolumeWithCapacity(kimchi.selectedSP, {
+ name: blobFile.name,
+ format: '',
+ capacity: blobFile.size,
+ upload: true
+ }, function(result) {
+ wok.window.close();
+ trackVolCreation(result.id);
+ }, onError);
+ };
+
+ var uploadRequest = function(blob) {
+ var fd = new FormData();
+ fd.append('chunk', blob);
+ fd.append('chunk_size', blob.size);
+
+ kimchi.uploadVolumeToSP(kimchi.selectedSP, blobFile.name, {
+ formData: fd
+ }, function(result) {
+ if (uploaded < blobFile.size)
+ setTimeout(doUpload, 500);
+ }, onError);
+
+ uploaded += blob.size
+ };
+
+ // Check file exists and has read permission
+ try {
+ var blob = blobFile.slice(0, 20);
+ var reader = new FileReader();
+ reader.onloadend = function(e) {
+ if (e.loaded == 0)
+ wok.message.error.code('KCHAPI6008E');
+ else
+ createUploadVol();
+ };
+
+ reader.readAsBinaryString(blob);
+ } catch (err) {
+ wok.message.error.code('KCHAPI6008E');
+ return;
+ }
+
+ var doUpload = function() {
+ try {
+ var blob = blobFile.slice(uploaded, uploaded + chunkSize);
+ var reader = new FileReader();
+ reader.onloadend = function(e) {
+ if (e.loaded == 0)
+ wok.message.error.code('KCHAPI6009E');
+ else
+ uploadRequest(blob);
+ };
+
+ reader.readAsBinaryString(blob);
+ } catch (err) {
+ wok.message.error.code('KCHAPI6009E');
+ return;
+ }
+ }
+
+ var trackVolCreation = function(taskid) {
+ var onTaskResponse = function(result) {
+ var taskStatus = result['status'];
+ var taskMsg = result['message'];
+ if (taskStatus == 'running') {
+ if (taskMsg != 'ready for upload') {
+ setTimeout(function() {
+ trackVolCreation(taskid);
+ }, 2000);
+ } else {
+ wok.topic('kimchi/storageVolumeAdded').publish();
+ doUpload();
+ }
+ }
+ };
+ kimchi.getTask(taskid, onTaskResponse, onError);
+ };
+ };
+
+ $(addButton).on('click', function(event) {
+ $(this).prop('disabled', true);
+ $(typeRadios).prop('disabled', true);
+ if(type === 'download') {
+ fetchRemoteFile();
+ }
+ else {
+ uploadFile();
+ }
+ event.preventDefault();
+ });
+};
diff --git a/src/wok/plugins/kimchi/ui/js/src/kimchi.template_add_main.js
b/src/wok/plugins/kimchi/ui/js/src/kimchi.template_add_main.js
new file mode 100644
index 0000000..01a47c2
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/js/src/kimchi.template_add_main.js
@@ -0,0 +1,441 @@
+/*
+ * Project Kimchi
+ *
+ * Copyright IBM, Corp. 2013-2015
+ *
+ * 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.
+ */
+kimchi.switchPage = function(fromPageId, toPageId, direction) {
+ direction = direction || 'left';
+ var toLeftBegin;
+ var fromLeftEnd;
+ if('left' === direction) {
+ toLeftBegin = '100%';
+ fromLeftEnd = '-100%';
+ } else if('right' === direction) {
+ toLeftBegin = '-100%';
+ fromLeftEnd = '100%';
+ }
+ var formPage = $('#'+fromPageId);
+ var toPage = $('#'+toPageId);
+ toPage.css({
+ left: toLeftBegin
+ });
+ formPage.animate({
+ left: fromLeftEnd,
+ opacity: 0.1
+ }, 400);
+ toPage.animate({
+ left: '0',
+ opacity: 1
+ }, 400);
+};
+
+kimchi.template_add_main = function() {
+ kimchi.deepScanHandler = null;
+ // 1-1 local iso
+ $('#iso-local').click(function() {
+ kimchi.switchPage('iso-type-box', 'iso-local-box');
+ initLocalIsoField();
+ initIsoFileField();
+ kimchi.listIsos(function(isos) {
+ if (isos && isos.length) {
+ showLocalIsoField(isos);
+ $('#iso-more').show();
+ } else {
+ $('#iso-search').show();
+ }
+ }, function(err) {
+ wok.message.error(err.responseJSON.reason);
+ });
+ });
+
+ $('#iso-local-box-back').click(function() {
+ if (kimchi.deepScanHandler) {
+ kimchi.deepScanHandler.stop = true;
+ }
+ kimchi.switchPage('iso-local-box', 'iso-type-box',
'right');
+ });
+
+ $('#iso-search').click(function() {
+ var settings = {
+ content : i18n['KCHTMPL6002M']
+ };
+ wok.confirm(settings, function() {
+ $('#iso-search').hide();
+ $('#iso-search-loading').show();
+ deepScan('#iso-search');
+ });
+ });
+
+ $('#iso-more').click(function() {
+ var settings = {
+ content : i18n['KCHTMPL6002M']
+ };
+ wok.confirm(settings, function() {
+ $('#iso-more').hide();
+ $('#iso-more-loading').show();
+ deepScan('#iso-more');
+ });
+ });
+
+ $('#iso-search-loading').click(function() {
+ $('#iso-search-loading').hide();
+ $('#iso-search').show();
+ if (kimchi.deepScanHandler) {
+ kimchi.deepScanHandler.stop = true;
+ }
+ });
+
+ $('#iso-more-loading').click(function() {
+ $('#iso-more-loading').hide();
+ $('#iso-more').show();
+ if (kimchi.deepScanHandler) {
+ kimchi.deepScanHandler.stop = true;
+ }
+ });
+
+ var deepScan = function(button) {
+ kimchi.deepScanHandler = kimchi.stepListDeepScanIsos(function(isos, isFinished)
{
+ if (isos && isos.length) {
+ if(button === '#iso-search') {
+ $(button + '-loading').hide();
+ button = '#iso-more';
+ $(button + '-loading').show();
+ }
+ showLocalIsoField(isos);
+ } else {
+ if (isFinished) {
+ wok.message.warn(i18n['KCHTMPL6001W']);
+ }
+ }
+ if (isFinished) {
+ $(button + '-loading').hide();
+ $(button).show();
+ }
+ }, function(err) {
+ wok.message.error(err.responseJSON.reason);
+ $(button + '-loading').hide();
+ $(button).show();
+ });
+ };
+
+ //1-1-1 local iso list
+ var initLocalIsoField = function() {
+ kimchi.isoInfo = {};
+ $('#local-iso-field').hide();
+ $('#select-all-local-iso').prop('checked', false);
+ $('#btn-template-local-iso-create').attr('disabled',
'disabled');
+ $('#iso-search').hide();
+ $('#iso-more').hide();
+ $('#iso-search-loading').hide();
+ $('#iso-more-loading').hide();
+ $('#list-local-iso').empty();
+ };
+
+ var showLocalIsoField = function(isos) {
+ var html = '';
+ var template = $('#tmpl-list-local-iso').html();
+ $.each(isos, function(index, volume) {
+ var isoId = volume.os_distro + '*' + volume.name + '*' +
volume.os_version;
+ if (!kimchi.isoInfo[isoId]) {
+ volume.isoId = isoId;
+ volume.capacity = wok.changetoProperUnit(volume.capacity, 1);
+ kimchi.isoInfo[isoId] = volume;
+ html += wok.substitute(template, volume);
+ }
+ });
+ $('#list-local-iso').append(html);
+ $('#local-iso-field').show();
+ };
+
+ $('#select-all-local-iso').click(function() {
+ $('#list-local-iso [type="checkbox"]').prop('checked',
$(this).prop('checked'));
+ if ($(this).prop('checked')) {
+ $('#btn-template-local-iso-create').removeAttr('disabled');
+ } else {
+ $('#btn-template-local-iso-create').attr('disabled',
'disabled');
+ }
+ });
+
+ $('#list-local-iso').on('click',
'[type="checkbox"]', function() {
+ var checkedLength = $('#list-local-iso
[type="checkbox"]:checked').length;
+ if (checkedLength) {
+ $('#btn-template-local-iso-create').removeAttr('disabled');
+ var length = $('#list-local-iso
[type="checkbox"]').length;
+ $('#select-all-local-iso').prop('checked', length ==
checkedLength);
+ } else {
+ $('#select-all-local-iso').prop('checked', false);
+ $('#btn-template-local-iso-create').attr('disabled',
'disabled');
+ }
+ });
+
+ $('#btn-template-local-iso-create').click(function() {
+ submitIso('form-local-iso');
+ });
+
+ //1-1-2 local iso file
+ var initIsoFileField = function() {
+ $('#iso-file-check').prop('checked', false);
+ $('#iso-file-box').hide();
+ $('#iso-file').val('');
+ $('#btn-template-file-create').attr('disabled',
'disabled');
+ };
+
+ $('#iso-file-check').click(function() {
+ if ($(this).prop('checked')) {
+ $('#iso-file-box').slideDown();
+ } else {
+ $('#iso-file-box').slideUp();
+ }
+ });
+
+ $('#iso-file').on('input propertychange', function() {
+ if ($('#iso-file').val()) {
+ $('#btn-template-file-create').removeAttr('disabled');
+ } else {
+ $('#btn-template-file-create').attr('disabled',
'disabled');
+ }
+ });
+
+ $('#btn-template-file-create').click(function() {
+ var isoFile = $('#iso-file').val();
+ if (!kimchi.template_check_path(isoFile)) {
+ wok.message.error.code('KCHAPI6003E');
+ return;
+ }
+ var data = {
+ "cdrom" : isoFile
+ };
+ addTemplate(data);
+ });
+
+ //1-2 remote iso
+ $('#iso-remote').css('opacity', 0.3).css('cursor',
'not-allowed');
+
+ var enabledRemoteIso = function() {
+ if (kimchi.capabilities == undefined) {
+ setTimeout(enabledRemoteIso, 2000);
+ return;
+ }
+
+ if (kimchi.capabilities.qemu_stream != true) {
+ return;
+ }
+
+ $('#iso-remote').css('opacity', 1).css('cursor',
'pointer');
+ $('#iso-remote').click(function() {
+ kimchi.switchPage('iso-type-box', 'iso-remote-box');
+ initRemoteIsoField();
+ initIsoUrlField();
+ kimchi.listDistros(function(isos) {
+ showRemoteIsoField(isos);
+ }, function() {
+ });
+ });
+ };
+ enabledRemoteIso();
+
+ $('#iso-remote-box-back').click(function() {
+ kimchi.switchPage('iso-remote-box', 'iso-type-box',
'right');
+ });
+
+ //1-2-1 remote iso list
+ var initRemoteIsoField = function() {
+ $('#load-remote-iso').show();
+ $('#remote-iso-field').hide();
+ $('#iso-url-field').hide();
+ $('#select-all-remote-iso').prop('checked', false);
+ $('#btn-template-remote-iso-create').attr('disabled',
'disabled');
+ };
+
+ var showRemoteIsoField = function(isos) {
+ if (isos && isos.length) {
+ kimchi.isoInfo = {};
+ var html = '';
+ var template = $('#tmpl-list-remote-iso').html();
+ $.each(isos, function(index, volume) {
+ var isoId = volume.os_distro + '*' + volume.name + '*' +
volume.os_version;
+ if (!kimchi.isoInfo[isoId]) {
+ volume.isoId = isoId;
+ kimchi.isoInfo[isoId] = volume;
+ html += wok.substitute(template, volume);
+ }
+ });
+ $('#list-remote-iso').html(html);
+ $('#load-remote-iso').hide()
+ $('#remote-iso-field').show();
+ $('#iso-url-field').show();
+ } else {
+ $('#load-remote-iso').hide()
+ $('#iso-url-field').show();
+ wok.message.warn(i18n['KCHTMPL6001W']);
+ }
+ };
+
+ $('#select-all-remote-iso').click(function() {
+ $('#list-remote-iso [type="checkbox"]').prop('checked',
$(this).prop('checked'));
+ if ($(this).prop('checked')) {
+ $('#btn-template-remote-iso-create').removeAttr('disabled');
+ } else {
+ $('#btn-template-remote-iso-create').attr('disabled',
'disabled');
+ }
+ });
+
+ $('#list-remote-iso').on('click',
'[type="checkbox"]', function() {
+ var checkedLength = $('#list-remote-iso
[type="checkbox"]:checked').length;
+ if (checkedLength) {
+ $('#btn-template-remote-iso-create').removeAttr('disabled');
+ var length = $('#list-remote-iso
[type="checkbox"]').length;
+ $('#select-all-remote-iso').prop('checked', length ==
checkedLength);
+ } else {
+ $('#select-all-remote-iso').prop('checked', false);
+ $('#btn-template-remote-iso-create').attr('disabled',
'disabled');
+ }
+ });
+
+ $('#btn-template-remote-iso-create').click(function() {
+ submitIso('form-remote-iso');
+ });
+
+ //1-2-2 remote iso url
+ var initIsoUrlField = function() {
+ $('#iso-url-check').prop('checked', false);
+ $('#iso-url-box').hide();
+ $('#iso-url').val('');
+ $('#btn-template-url-create').attr('disabled',
'disabled');
+ }
+
+ $('#iso-url-check').click(function() {
+ if ($(this).prop('checked')) {
+ $('#iso-url-box').slideDown();
+ } else {
+ $('#iso-url-box').slideUp();
+ }
+ });
+
+ $('#iso-url').on('input propertychange', function() {
+ if ($('#iso-url').val()) {
+ $('#btn-template-url-create').removeAttr('disabled');
+ } else {
+ $('#btn-template-url-create').attr('disabled',
'disabled');
+ }
+ });
+
+ $('#vm-image-local').click(function(){
+ kimchi.switchPage('iso-type-box', 'vm-image-local-box');
+ });
+ $('#vm-image-local-box-back').click(function(){
+ kimchi.switchPage('vm-image-local-box', 'iso-type-box',
'right');
+ });
+ $('input', '#vm-image-local-box').on('keyup cut paste',
function(){
+ setTimeout(function(){
+ var isValid = kimchi.template_check_path($('input',
'#vm-image-local-box').val());
+ $('input',
'#vm-image-local-box').toggleClass('invalid-field', !isValid);
+ $('button', $('.body',
'#vm-image-local-box')).button(isValid ? "enable" :
"disable");
+ }, 0);
+ });
+ $('button', $('.body', '#vm-image-local-box')).button({
+ disabled: true
+ }).click(function(){
+ $('input', '#vm-image-local-box').prop('disabled',
true);
+ $(this).button('option', {
+ label: i18n['KCHAPI6008M'],
+ disabled: true
+ });
+ addTemplate({disks:[{base:$('input',
'#vm-image-local-box').val()}]}, function(){
+ $('input', '#vm-image-local-box').prop('disabled',
false);
+ $('button', $('.body',
'#vm-image-local-box')).button('option', {
+ label: i18n['KCHAPI6005M'],
+ disabled: false
+ });
+ });
+ });
+
+ $('#btn-template-url-create').click(function() {
+ var isoUrl = $('#iso-url').val();
+ if (!kimchi.template_check_url(isoUrl)) {
+ wok.message.error.code('KCHAPI6004E');
+ return;
+ }
+ var data = {
+ "cdrom" : isoUrl
+ };
+ addTemplate(data);
+ });
+
+ //do create
+ var addTemplate = function(data, callback) {
+ kimchi.createTemplate(data, function() {
+ if(callback) callback();
+ kimchi.doListTemplates();
+ wok.window.close();
+ wok.topic('templateCreated').publish();
+ }, function(err) {
+ if(callback) callback();
+ wok.message.error(err.responseJSON.reason);
+ });
+ };
+
+ var submitIso = function(formId) {
+ var formData = $('#' + formId).serializeObject();
+ if (formData.iso) {
+ var length = 0;
+ var successNum = 0;
+ var addTemplate = function(isoInfo) {
+ var data = {
+ "os_distro" : isoInfo.os_distro,
+ "os_version" : isoInfo.os_version,
+ "cdrom" : isoInfo.path
+ };
+ kimchi.createTemplate(data, function() {
+ successNum++;
+ $('input[value="' + isoInfo.isoId +
'"]').prop('checked', false);
+ $('.check-all>input').prop('checked', false);
+ kimchi.doListTemplates();
+ wok.topic('templateCreated').publish(data);
+ if (successNum === length) {
+ wok.window.close();
+ }
+ }, function(err) {
+ wok.message.error(err.responseJSON.reason);
+ });
+ };
+ if (formData.iso instanceof Array) {
+ length = formData.iso.length;
+ $.each(formData.iso, function(index, value) {
+ addTemplate(kimchi.isoInfo[value]);
+ });
+ } else {
+ length = 1;
+ addTemplate(kimchi.isoInfo[formData.iso]);
+ }
+ }
+ };
+};
+
+kimchi.template_check_url = function(url) {
+ var reg = /(https|http|ftp|ftps|tftp):\/\//;
+ if (url.constructor === String) {
+ return reg.test(url);
+ }
+ return false;
+};
+
+kimchi.template_check_path = function(filePath) {
+ var reg = /((\/([0-9a-zA-Z-_ \.]+))+)$/;
+ if (filePath.constructor === String) {
+ return reg.test(filePath);
+ }
+ return false;
+};
diff --git a/src/wok/plugins/kimchi/ui/js/src/kimchi.template_edit_main.js
b/src/wok/plugins/kimchi/ui/js/src/kimchi.template_edit_main.js
new file mode 100644
index 0000000..d40b6c7
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/js/src/kimchi.template_edit_main.js
@@ -0,0 +1,343 @@
+/*
+ * Project Kimchi
+ *
+ * Copyright IBM, Corp. 2013-2015
+ *
+ * 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.
+ */
+kimchi.template_edit_main = function() {
+ var templateEditMain = $('#edit-template-tabs');
+ var origDisks;
+ var origPool;
+ var origNetworks;
+ var templateDiskSize;
+ $('#template-name', templateEditMain).val(kimchi.selectedTemplate);
+ templateEditMain.tabs();
+
+ var initTemplate = function(template) {
+ origDisks = template.disks;
+ origPool = template.storagepool;
+ origNetworks = template.networks;
+ for(var i=0;i<template.disks.length;i++){
+ if(template.disks[i].base){
+ template["vm-image"] = template.disks[i].base;
+ $('.templ-edit-cdrom').addClass('hide');
+ $('.templ-edit-vm-image').removeClass('hide');
+ break;
+ }
+ }
+ for ( var prop in template) {
+ var value = template[prop];
+ if (prop == 'graphics') {
+ value = value["type"];
+ }
+ $('input[name="' + prop + '"]',
templateEditMain).val(value);
+ }
+
+ var vncOpt = [{label: 'VNC', value: 'vnc'}];
+ $('#template-edit-graphics').append('<option
selected>VNC</option>');
+
$('#template-edit-graphics').append('<option>Spice</option>');
+ wok.select('template-edit-graphics-list', vncOpt);
+ var enableSpice = function() {
+ if (kimchi.capabilities == undefined) {
+ setTimeout(enableSpice, 2000);
+ return;
+ }
+ if (kimchi.capabilities.qemu_spice == true) {
+ spiceOpt = [{label: 'Spice', value: 'spice'}]
+ wok.select('template-edit-graphics-list', spiceOpt);
+ }
+ };
+ enableSpice();
+ var initStorage = function(result) {
+ var scsipools = {};
+ var addStorageItem = function(storageData) {
+ var thisName = storageData.storageName;
+ var nodeStorage =
$.parseHTML(wok.substitute($('#template-storage-pool-tmpl').html(),
storageData));
+ $('.template-tab-body',
'#form-template-storage').append(nodeStorage);
+ var storageOptions = '';
+ var scsiOptions = '';
+ $('#selectStorageName').find('option').remove();
+ $.each(result, function(index, storageEntities) {
+ if((storageEntities.state === 'active') &&
(storageEntities.type != 'kimchi-iso')) {
+ if(storageEntities.type === 'iscsi' ||
storageEntities.type === 'scsi') {
+ kimchi.listStorageVolumes(storageEntities.name,
function(currentVolume) {
+ $.each(currentVolume, function(indexSCSI, scsiEntities)
{
+ var tmpPath = storageEntities.name + '/' +
scsiEntities.name;
+ var isSlected = tmpPath === thisName ? '
selected' : '';
+ scsiOptions += '<option' + isSlected +
'>' + tmpPath + '</option>';
+ });
+ $('#selectStorageName').append(scsiOptions);
+ }, function() {});
+ } else {
+ var isSlected = storageEntities.name === thisName ? '
selected' : '';
+ storageOptions += '<option' + isSlected +
'>' + storageEntities.name + '</option>';
+ }
+ }
+ });
+ $('#selectStorageName').append(storageOptions);
+
+ // Set disk format
+ $('#diskFormat').val(storageData.storageDiskFormat);
+ $('#diskFormat').on('change', function() {
+ $('.template-storage-disk-format').val($(this).val());
+ });
+
+ $('#selectStorageName').change(function() {
+ var selectedItem = $(this).parent().parent();
+ var tempStorageNameFull = $(this).val();
+ var tempName = tempStorageNameFull.split('/');
+ var tempStorageName = tempName[0];
+ $('.template-storage-name').val(tempStorageNameFull);
+ kimchi.getStoragePool(tempStorageName, function(info) {
+ tempType = info.type;
+
selectedItem.find('.template-storage-type').val(tempType);
+ if (tempType === 'iscsi' || tempType === 'scsi')
{
+ kimchi.getStoragePoolVolume(tempStorageName,
tempName[tempName.length-1], function(info) {
+ volSize = info.capacity / Math.pow(1024, 3);
+ $('.template-storage-disk',
selectedItem).attr('readonly', true).val(volSize);
+ $('#diskFormat').val('raw');
+ $('#diskFormat').prop('disabled',
true).change();
+ });
+ } else if (tempType === 'logical') {
+ $('.template-storage-disk',
selectedItem).attr('readonly', false);
+ $('#diskFormat').val('raw');
+ $('#diskFormat').prop('disabled',
true).change();
+ } else {
+ $('.template-storage-disk',
selectedItem).attr('readonly', false);
+ if ($('#diskFormat').prop('disabled') ==
true) {
+ $('#diskFormat').val('qcow2');
+ $('#diskFormat').prop('disabled',
false).change();
+ }
+ }
+ });
+ });
+ };
+
+ if ((origDisks && origDisks.length) && (origPool &&
origPool.length)) {
+ splitPool = origPool.split('/');
+ var defaultPool = splitPool[splitPool.length-1];
+ var defaultType;
+
+ kimchi.getStoragePool(defaultPool, function(info) {
+ defaultType = info.type;
+ $.each(origDisks, function(index, diskEntities) {
+ var storageNodeData = {
+ viewMode : '',
+ editMode : 'hide',
+ storageName : defaultPool,
+ storageType : defaultType,
+ storageDisk : diskEntities.size,
+ storageDiskFormat : diskEntities.format ? diskEntities.format
: 'qcow2'
+ }
+
+ if (diskEntities.volume) {
+ kimchi.getStoragePoolVolume(defaultPool, diskEntities.volume,
function(info) {
+ var volSize = info.capacity / Math.pow(1024, 3);
+ var nodeData = storageNodeData
+ nodeData.storageName = defaultPool + '/' +
diskEntities.volume;
+ nodeData.storageDisk = volSize;
+ addStorageItem(nodeData);
+
$('.template-storage-disk').attr('readonly', true);
+ $('#diskFormat').val('raw');
+ $('#diskFormat').prop('disabled',
true).change();
+ });
+ } else if (defaultType === 'logical') {
+ addStorageItem(storageNodeData);
+ $('#diskFormat').val('raw');
+ $('#diskFormat').prop('disabled',
true).change();
+ } else {
+ addStorageItem(storageNodeData);
+ }
+ });
+ });
+ }
+
+ $('#template-edit-storage-add-button').button({
+ icons: {
+ primary: "ui-icon-plusthick"
+ },
+ text: false,
+ disabled: true
+ }).click(function(event) {
+ event.preventDefault();
+ var storageNodeData = {
+ viewMode : 'hide',
+ editMode : '',
+ storageName : 'null',
+ storageType : 'dir',
+ storageDisk : '10'
+ }
+ addStorageItem(storageNodeData);
+ });
+ };
+ var initInterface = function(result) {
+ var networkItemNum = 0;
+ var addInterfaceItem = function(networkData) {
+ var networkName = networkData.networkV;
+ var nodeInterface =
$.parseHTML(wok.substitute($('#template-interface-tmpl').html(), networkData));
+ $('.template-tab-body',
'#form-template-interface').append(nodeInterface);
+ $('.delete', '#form-template-interface').button({
+ icons : {primary : 'ui-icon-trash'},
+ text : false
+ }).click(function(evt) {
+ evt.preventDefault();
+ $(this).parent().parent().remove();
+ });
+ var networkOptions = '';
+ for(var i=0;i<result.length;i++){
+ if(result[i].state === "active") {
+ var isSlected = networkName===result[i].name ? '
selected' : '';
+ networkOptions += '<option' + isSlected +
'>' + result[i].name + '</option>';
+ }
+ }
+ $('select', '#form-template-interface #networkID' +
networkItemNum).append(networkOptions);
+ networkItemNum += 1;
+ };
+ if(result && result.length > 0) {
+ for(var i=0;i<origNetworks.length;i++) {
+ addInterfaceItem({
+ networkID : 'networkID' + networkItemNum,
+ networkV : origNetworks[i],
+ type : 'network'
+ });
+ }
+ }
+ $('#template-edit-interface-add-button').button({
+ icons: {
+ primary: 'ui-icon-plusthick'
+ },
+ text: false
+ }).click(function(evt) {
+ evt.preventDefault();
+ addInterfaceItem({
+ networkID : 'networkID' + networkItemNum,
+ networkV : 'default',
+ type : 'network'
+ });
+ });
+ };
+ var initProcessor = function(){
+ var setCPUValue = function(){
+
if(!$('#cores').hasClass("invalid-field")&&$('#cores').val()!=""){
+
$("#cpus").val(parseInt($("#cores").val())*parseInt($("#threads").val()));
+ }else{
+ $("#cpus").val('');
+ }
+ };
+ $("input:text",
"#form-template-processor").on('keyup', function(){
+ $(this).toggleClass("invalid-field",
!$(this).val().match('^[0-9]*$'));
+ if($(this).prop('id')=='cores') setCPUValue();
+ });
+ $("input:checkbox",
"#form-template-processor").click(function(){
+ $(".topology",
"#form-template-processor").toggleClass("hide",
!$(this).prop("checked"));
+ $("#cpus").attr("disabled",
$(this).prop("checked"));
+ setCPUValue();
+ });
+ $('select', '#form-template-processor').change(function(){
+ setCPUValue();
+ });
+ kimchi.getCPUInfo(function(data){
+ var options = "";
+ for(var i=0;Math.pow(2,i)<=data.threads_per_core;i++){
+ var lastOne = Math.pow(2,i+1)>data.threads_per_core?"
selected":"";
+ options +=
"<option"+lastOne+">"+Math.pow(2,i)+"</option>";
+ }
+ $('select', '#form-template-processor').append(options);
+ if(template.cpus) $("#cpus").val(template.cpus);
+ var topo = template.cpu_info.topology;
+ if(topo&&topo.cores) $("#cores").val(topo.cores);
+ if(topo&&topo.threads){
+ $('select',
'#form-template-processor').val(topo.threads);
+ $("input:checkbox",
"#form-template-processor").trigger('click');
+ }
+ });
+ };
+ kimchi.listNetworks(initInterface);
+ kimchi.listStoragePools(initStorage);
+ initProcessor();
+ };
+ kimchi.retrieveTemplate(kimchi.selectedTemplate, initTemplate);
+
+
+ $('#tmpl-edit-button-save').on('click', function() {
+ var editableFields = [ 'name', 'memory', 'disks',
'graphics'];
+ var data = {};
+ //Fix me: Only support one storage pool now
+ var storages = $('.template-tab-body .item',
'#form-template-storage');
+ var tempName = $('.template-storage-name', storages).val();
+ var tmpItem = $('#form-template-storage .item');
+ tempName = tempName.split('/');
+ var tempNameHead = tempName[0];
+ var tempNameTail = tempNameHead;
+ if($('.template-storage-type', tmpItem).val() === 'iscsi' ||
$('.template-storage-type', tmpItem).val() == 'scsi') {
+ tempNameTail = tempName[tempName.length-1];
+ }
+ tempName = '/plugins/kimchi/storagepools/' + tempNameHead;
+ data['storagepool'] = tempName;
+ $.each(editableFields, function(i, field) {
+ /* Support only 1 disk at this moment */
+ if (field == 'disks') {
+ if($('.template-storage-type', tmpItem).val() === 'iscsi'
|| $('.template-storage-type', tmpItem).val() == 'scsi') {
+ origDisks[0]['size'] && delete
origDisks[0]['size'];
+ origDisks[0]['volume'] = tempNameTail;
+ } else {
+ origDisks[0]['volume'] && delete
origDisks[0]['volume'];
+ origDisks[0].size = Number($('.template-storage-disk',
tmpItem).val());
+ }
+ origDisks[0].format = $('.template-storage-disk-format',
tmpItem).val();
+ data[field] = origDisks;
+ }
+ else if (field == 'graphics') {
+ var type = $('#form-template-general [name="' + field +
'"]').val();
+ data[field] = {'type': type};
+ }
+ else {
+ data[field] = $('#form-template-general [name="' + field +
'"]').val();
+ }
+ });
+ data['memory'] = Number(data['memory']);
+ data['cpus'] = parseInt($('#cpus').val());
+ if($("input:checkbox",
"#form-template-processor").prop("checked")){
+ data['cpu_info'] = {
+ topology: {
+ sockets: 1,
+ cores: parseInt($("#cores").val()),
+ threads: parseInt($("#threads").val())
+ }
+ };
+ }else{
+ data['cpu_info'] = {};
+ }
+ var networks = $('.template-tab-body .item',
'#form-template-interface');
+ var networkForUpdate = new Array();
+ $.each(networks, function(index, networkEntities) {
+ var thisValue = $('select', networkEntities).val();
+ networkForUpdate.push(thisValue);
+ });
+ if (networkForUpdate instanceof Array) {
+ data.networks = networkForUpdate;
+ } else if (networkForUpdate != null) {
+ data.networks = [networkForUpdate];
+ } else {
+ data.networks = [];
+ }
+
+ kimchi.updateTemplate($('#template-name').val(), data, function() {
+ kimchi.doListTemplates();
+ wok.window.close();
+ }, function(err) {
+ wok.message.error(err.responseJSON.reason);
+ });
+ });
+};
diff --git a/src/wok/plugins/kimchi/ui/js/src/kimchi.template_main.js
b/src/wok/plugins/kimchi/ui/js/src/kimchi.template_main.js
new file mode 100644
index 0000000..b09fe12
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/js/src/kimchi.template_main.js
@@ -0,0 +1,111 @@
+/*
+ * Project Kimchi
+ *
+ * Copyright IBM, Corp. 2013-2014
+ *
+ * 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.
+ */
+kimchi.doListTemplates = function() {
+ kimchi.listTemplates(function(result) {
+ if (result && result.length) {
+ $('#noTemplates').hide();
+ var listHtml = '';
+ var templateHtml = $('#templateTmpl').html();
+ $.each(result, function(index, value) {
+ var isLocal;
+ if(value.cdrom){
+ isLocal = /^\//.test(value['cdrom']);
+ }else{
+ for(var i=0;i<value.disks.length;i++){
+ if(value.disks[i].base){
+ isLocal = /^\//.test(value.disks[i].base);
+ break;
+ }
+ }
+ }
+ if(isLocal){
+ value.location =
"plugins/kimchi/images/theme-default/icon-local.png";
+ }else{
+ value.location =
"plugins/kimchi/images/theme-default/icon-remote.png";
+ }
+ listHtml += wok.substitute(templateHtml, value);
+ });
+ $('#templateList').html(listHtml);
+ kimchi.templateBindClick();
+ } else {
+ $('#templateList').html('');
+ $('#noTemplates').show();
+ }
+ $('html').removeClass('processing');
+ }, function(err) {
+ wok.message.error(err.responseJSON.reason);
+ $('html').removeClass('processing');
+ });
+};
+
+kimchi.templateBindClick = function() {
+ $('.template-edit').on('click', function(event) {
+ var templateName = $(this).data('template');
+ kimchi.selectedTemplate = templateName;
+ wok.window.open("plugins/kimchi/template-edit.html");
+ });
+ $('.template-clone').on('click', function(event) {
+ kimchi.selectedTemplate = $(this).data('template');
+ $('html').addClass('processing');
+ kimchi.cloneTemplate(kimchi.selectedTemplate, function() {
+ kimchi.doListTemplates();
+ }, function(err) {
+ wok.message.error(err.responseJSON.reason);
+ kimchi.doListTemplates();
+ });
+ });
+ $('.template-delete').on('click', function(event) {
+ var $template = $(this);
+ var settings = {
+ title : i18n['KCHAPI6001M'],
+ content : i18n['KCHTMPL6003M'],
+ confirm : i18n['KCHAPI6002M'],
+ cancel : i18n['KCHAPI6003M']
+ };
+ wok.confirm(settings, function() {
+ var templateName = $template.data('template');
+ kimchi.deleteTemplate(templateName, function() {
+ kimchi.doListTemplates();
+ }, function(err) {
+ wok.message.error(err.responseJSON.reason);
+ });
+ }, function() {
+ });
+ });
+}
+kimchi.hideTitle = function() {
+ $('#tempTitle').hide();
+};
+
+kimchi.template_main = function() {
+ if(wok.tabMode['templates'] === 'admin') {
+ $('.tools').attr('style','display');
+ $("#template-add").on("click", function(event) {
+ wok.window.open({
+ url: 'plugins/kimchi/template-add.html',
+ close: function() {
+ if (kimchi.deepScanHandler) {
+ kimchi.deepScanHandler.stop = true;
+ }
+ }
+ });
+ });
+ }
+
+ kimchi.doListTemplates();
+};
diff --git a/src/wok/plugins/kimchi/ui/pages/Makefile.am
b/src/wok/plugins/kimchi/ui/pages/Makefile.am
new file mode 100644
index 0000000..56288e3
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/pages/Makefile.am
@@ -0,0 +1,22 @@
+#
+# Kimchi
+#
+# Copyright IBM, Corp. 2013
+#
+# 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.
+
+SUBDIRS = help
+
+htmldir = $(datadir)/wok/plugins/kimchi/ui/pages
+
+dist_html_DATA = $(wildcard *.tmpl) $(NULL)
diff --git a/src/wok/plugins/kimchi/ui/pages/guest-add.html.tmpl
b/src/wok/plugins/kimchi/ui/pages/guest-add.html.tmpl
new file mode 100644
index 0000000..3770d96
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/pages/guest-add.html.tmpl
@@ -0,0 +1,98 @@
+#*
+ * Project Kimchi
+ *
+ * Copyright IBM, Corp. 2013-2015
+ *
+ * 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.
+ *#
+#unicode UTF-8
+#import gettext
+#from wok.cachebust import href
+#silent t = gettext.translation($lang.domain, $lang.localedir, languages=$lang.lang,
fallback=True)
+#silent _ = t.gettext
+#silent _t = t.gettext
+<!DOCTYPE html>
+<html>
+<body>
+<div class="window" style="width: 900px;height: 580px;">
+ <header>
+ <h1 class="title h1 grey">$_("Create a New Virtual
Machine")</h1>
+ </header>
+ <div class="content">
+ <form id="form-vm-add">
+ <section class="form-section">
+ <h2>1. $_("Virtual Machine Name")</h2>
+ <div class="field">
+ <input type="text" class="text" style="width:
300px" name="name"><br>
+ <div class="icon-info-circled light-grey c1
help-inline"></div>
+ <p class="text-help help-inline">
+ $_("The name used to identify the virtual machine. If omitted, a
name will be chosen based on the template used.")
+ </p>
+ </div>
+ </section>
+ <section class="form-section">
+ <h2>2. $_("Template")</h2>
+ <div class="field">
+ <div class="text-help">
+ <div id="prompt-create-template"
class="hidden">
+ <div class="icon-info-circled light-grey c1
help-inline"></div>
+ <div class="text-help
help-inline">$_("Please create a template first.")</div>
+ <a id="btn-create-template"
class="btn-normal" href="templates.html">
+ <span class="text">$_("Create a
Template")</span>
+ </a>
+ </div>
+ <div id="prompt-choose-template"
class="hidden">
+ <span class="icon-info-circled light-grey
c1"></span>
+ <span class="text-help">$_("Please choose a
template.")</span>
+ </div>
+ </div>
+ <ul id="templateTile" class="tile-check
tile-template">
+ </ul>
+ <script type="html/text" id="tmpl-template"
class="tmpl-html">
+ <li>
+ <label>
+ <input type="radio" name="template"
value="/plugins/kimchi/templates/{name}">
+ <div class="info">
+ <div class="summary os-icon">
+ <img src="{icon}">
+ <span
class="title">{name}</span>
+ </div>
+ <ul class="list-info">
+
<li><label>$_("OS")</label><span>{os_distro}</span></li>
+ <li><label>$_("OS
Version")</label><span>{os_version}</span></li>
+
<li><label>$_("CPUS")</label><span>{cpus}</span></li>
+
<li><label>$_("Memory")</label><span>{memory}M</span></li>
+ </ul>
+ </div>
+ </label>
+ </li>
+ </script>
+ </div>
+ </section>
+ </form>
+ </div>
+ <footer>
+ <div class="btn-group">
+ <button id="vm-doAdd" class="btn-normal"
disabled="disabled" href="javascript:void(0);"><span
class="text">$_("Create")</span></button>
+ <button id="vm-doAdding" class="btn-normal"
disabled="disabled" style="display:none"
href="javascript:void(0);"><span
class="text">$_("Creating...")</span></button>
+ <button id="vm-add=cancel" class="btn-normal close"
type="button">
+ <span class="text">$_("Cancel")</span>
+ </button>
+ </div>
+ </footer>
+</div>
+<script>
+ kimchi.guest_add_main();
+</script>
+</body>
+</html>
diff --git a/src/wok/plugins/kimchi/ui/pages/guest-edit.html.tmpl
b/src/wok/plugins/kimchi/ui/pages/guest-edit.html.tmpl
new file mode 100644
index 0000000..c5acf04
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/pages/guest-edit.html.tmpl
@@ -0,0 +1,311 @@
+#*
+ * Project Kimchi
+ *
+ * Copyright IBM, Corp. 2013-2015
+ *
+ * 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.
+ *#
+#unicode UTF-8
+#import gettext
+#silent t = gettext.translation($lang.domain, $lang.localedir, languages=$lang.lang,
fallback=True)
+#silent _ = t.gettext
+#silent _t = t.gettext
+
+<div id="guest-edit-window" class="window">
+ <header>
+ <h1 class="title h1 grey">$_("Edit Guest")</h1>
+ </header>
+ <div class="content">
+ <div id="guest-edit-tabs">
+ <ul>
+ <li>
+ <a
href="#form-guest-edit-general">$_("General")</a>
+ </li>
+ <li>
+ <a
href="#form-guest-edit-storage">$_("Storage")</a>
+ </li>
+ <li>
+ <a
href="#form-guest-edit-interface">$_("Interface")</a>
+ </li>
+ <li>
+ <a
href="#form-guest-edit-permission">$_("Permission")</a>
+ </li>
+ <li>
+ <a href="#form-guest-edit-pci">$_("Host PCI
Device")</a>
+ </li>
+ <li>
+ <a
href="#form-guest-edit-snapshot">$_("Snapshot")</a>
+ </li>
+ </ul>
+ <form id="form-guest-edit-general">
+ <fieldset class="guest-edit-fieldset">
+ <div class="edit-general-inline">
+ <div class="guest-edit-wrapper-label">
+ <label for="guest-edit-id-textbox">
+ $_("Name")
+ </label>
+ </div>
+ <div class="guest-edit-wrapper-label">
+ <label for="guest-edit-cores-textbox">
+ $_("CPUs")
+ </label>
+ </div>
+ <div class="guest-edit-wrapper-label">
+ <label for="guest-edit-memory-textbox">
+ $_("Memory (MB)")
+ </label>
+ </div>
+ <div class="guest-edit-wrapper-label">
+ <label for="guest-edit-icon-textbox">
+ $_("Icon")
+ </label>
+ </div>
+ </div>
+ <div class="edit-general-inline">
+ <div class="guest-edit-wrapper-controls">
+ <input id="guest-edit-id-textbox"
+ name="name" type="text" />
+ </div>
+ <div class="guest-edit-wrapper-controls">
+ <input
+ id="guest-edit-cores-textbox"
+ name="cpus"
+ type="text" />
+ </div>
+ <div class="guest-edit-wrapper-controls">
+ <input id="guest-edit-memory-textbox"
+ name="memory"
+ type="text" />
+ </div>
+ <div class="guest-edit-wrapper-controls">
+ <input
+ id="guest-edit-icon-textbox"
+ name="icon"
+ type="text"
+ disabled="disabled" />
+ </div>
+ </div>
+ </fieldset>
+ </form>
+ <form id="form-guest-edit-storage">
+ <div class="header">
+ <span
class="cell">$_("Device")</span>
+ <span class="cell">$_("Path")</span>
+ <button type="button"
id="guest-edit-attach-cdrom-button" class="action-area
attach"></button>
+ </div>
+ <div class="body"></div>
+ </form>
+ <form id="form-guest-edit-interface"
class="guest-edit-interface">
+ <div class="header">
+ <span
class="cell">$_("Network")</span>
+ <span class="cell">$_("Type")</span>
+ <span class="cell">$_("MAC
Address")</span>
+ <button class="add action-area"></button>
+ </div>
+ <div class="body"></div>
+ </form>
+ <form id="form-guest-edit-permission"
class="guest-edit-permission">
+ <div class="pam">
+ <div class="column avail">
+ <div class="title">$_("Available system
users and groups")</div>
+ <input type="text"
id="permission-avail-searchBox">
+ <div class="body">
+ <div class="head">
+ <div class="column column-user"><div
class="item">Users</div></div>
+ <div class="column column-group"><div
class="item">Groups</div></div>
+ </div>
+ <div id="permission-avail-users"
class="column column-user"></div>
+ <div id="permission-avail-groups"
class="column column-group"></div>
+ </div>
+ </div>
+ <div class="column control">
+ <button id="permissionGo"> > </button>
+ <button id="permissionBack"> <
</button>
+ </div>
+ <div class="column selected">
+ <div class="title">$_("Selected system users
and groups")</div>
+ <input type="text"
id="permission-sel-searchBox">
+ <div class="body">
+ <div class="head">
+ <div class="column column-user"><div
class="item">Users</div></div>
+ <div class="column column-group"><div
class="item">Groups</div></div>
+ </div>
+ <div id="permission-sel-users"
class="column column-user"></div>
+ <div id="permission-sel-groups"
class="column column-group"></div>
+ </div>
+ </div>
+ </div>
+ <div class="ldap">
+ <div class="header">
+ <span
class="cell">$_("User")</span>
+ <button type="button"
id="guest-edit-add-user-button" class="action-area
add"></button>
+ </div>
+ <div class="body"></div>
+ </div>
+ </form>
+ <form id="form-guest-edit-pci"
class="guest-edit-pci">
+ <div class="guest-scroll-indent">
+ <div class="filter">
+ <span class="group">
+ <select class="control">
+ <option
value="all">$_("All")</option>
+ <option value="toAdd">$_("To
Add")</option>
+ <option
value="added">$_("Added")</option>
+ </select><input type="text"
class="control" placeholder="$_("filter")">
+ </span>
+ </div>
+ <div class="header">
+ <span class="cell
name">$_("Name")</span>
+ <span class="cell
product">$_("Product")</span>
+ <span class="cell
vendor">$_("Vendor")</span>
+ </div>
+ <div class="body"></div>
+ </div>
+ </form>
+ <form id="form-guest-edit-snapshot"
class="guest-edit-snapshot">
+ <div class="header">
+ <span class="cell sel"></span>
+ <span class="cell
name">$_("Name")</span>
+ <span class="cell
created">$_("Created")</span>
+ <button class="add action-area"></button>
+ </div>
+ <div class="task"></div>
+ <div class="body"></div>
+ </form>
+ </div>
+ </div>
+ <footer>
+ <div id="action-button-container" class="btn-group
hidden">
+ <button id="guest-edit-button-save"
class="btn-normal">
+ <span class="text">$_("Save")</span>
+ </button>
+ </div>
+ <button id="guest-edit-button-cancel" class="btn-normal
close">
+ <span class="text">$_("Cancel")</span>
+ </button>
+ </footer>
+</div>
+<script id="cdrom-row-tmpl" type="text/html">
+ <div class="item view" id="cdrom-{dev}">
+ <span class="cell dev">
+ <input type="text" readonly="readonly"
+ id="cdrom-dev-{dev}" name="cdrom-dev-{dev}"
value="{dev}" />
+ </span>
+ <span class="cell path">
+ <input id="cdrom-path-{dev}" name="cdrom"
type="text"
+ data-vm="{vm}" data-dev="{dev}"
+ value="{path}" readonly="readonly" />
+ </span>
+ <span class="action-area">
+ <button type="button" class="guest-edit-cdrom-button
replace"
+ data-vm="{vm}" data-dev="{dev}"
+ title='$_("Replace")'>
+ </button>
+ <button type="button" class="guest-edit-cdrom-button
detach"
+ data-vm="{vm}" data-dev="{dev}"
data-type="{type}"
+ title='$_("Detach")'>
+ </button>
+ <button type="button" class="guest-edit-cdrom-button save
hidden"
+ data-vm="{vm}" data-dev="{dev}"
+ title='$_("Save")'>
+ </button>
+ <button type="button" class="guest-edit-cdrom-button cancel
hidden"
+ data-vm="{vm}" data-dev="{dev}"
+ title='$_("Cancel")'>
+ </button>
+ </span>
+ </div>
+</script>
+<script id="interface-tmpl" type="text/html">
+ <div class="item" id="{mac}">
+ <span class="cell">
+ <label id="label-network-{id}"
class="{viewMode}">{network}</label>
+ <select class="{editMode}"></select>
+ </span>
+ <span class="cell">
+ <span>{type}</span>
+ </span>
+ <span class="cell">
+ <label id="label-mac-{id}"
class="{viewMode}">{mac}</label>
+ <input class="{editMode}" type="text"
+ id="edit-mac-{id}" name="{mac}"
value="{mac}" />
+ </span>
+ <span class="action-area {editMode}">
+ <button class="save"></button><button
class="cancel"></button>
+ </span>
+ <span class="action-area {viewMode}">
+ <button class="edit"></button><button
class="delete"></button>
+ </span>
+ <div>
+</script>
+<script id="ldap-user-tmpl" type="text/html">
+ <div class="item" id="{user}">
+ <span class="cell">
+ <label class="{viewMode}">{user}</label>
+ <input type="text" placeholder="LDAP User
ID,e.g.foo(a)foo.com" class="{editMode}"/>
+ </span>
+ <span class="action-area">
+ <button class="delete"></button>
+ </span>
+ <div>
+</script>
+<script id="disk-row-tmpl" type="text/html">
+ <div class="item" id="cdrom-{dev}">
+ <span class="cell dev">
+ <input type="text" readonly="readonly"
+ id="disk-dev-{dev}" name="disk-dev-{dev}"
value="{dev}" />
+ </span>
+ <span class="cell path">
+ <input id="disk-path-{dev}" name="path-{dev}"
type="text"
+ data-vm="{vm}" data-dev="{dev}"
+ value="{path}" readonly="readonly" />
+ </span>
+ <span class="action-area">
+ <button type="button" class="guest-edit-cdrom-button
detach"
+ data-vm="{vm}" data-dev="{dev}"
data-type="{type}"
+ title="$_("Detach")">
+ </button>
+ </span>
+ </div>
+</script>
+<script id="permission-item-pam" type="text/html">
+<div class="item">
+ <span class="icon {class}"></span>
+ <label>{val}</label>
+</div>
+</script>
+<script id="pci-tmpl" type="text/html">
+<div class="item" id="{name}">
+ <span class="cell name" title="{name}">{name}</span>
+ <span class="cell product"
title="{product}">{product}</span>
+ <span class="cell vendor"
title="{vendor}">{vendor}</span>
+ <button></button>
+</div>
+</script>
+<script id="snapshot-tmpl" type="text/html">
+ <div class="item" id="{name}">
+ <span class="cell sel">
+ <span class="icon {createMode}"></span>
+ <span class="ui-icon ui-icon-check hide"></span>
+ </span>
+ <span class="cell name">{name}</span>
+ <span class="cell created">{created}</span>
+ <span class="action-area">
+ <button class="revert {listMode}"
title="$_("revert")"></button>
+ <button class="delete {listMode}"></button>
+ </span>
+ <div>
+</script>
+<script type="text/javascript">
+ kimchi.guest_edit_main();
+</script>
diff --git a/src/wok/plugins/kimchi/ui/pages/guest-storage-add.html.tmpl
b/src/wok/plugins/kimchi/ui/pages/guest-storage-add.html.tmpl
new file mode 100644
index 0000000..a26e0f9
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/pages/guest-storage-add.html.tmpl
@@ -0,0 +1,103 @@
+#*
+ * Project Kimchi
+ *
+ * Copyright IBM, Corp. 2014
+ *
+ * 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.
+ *#
+#unicode UTF-8
+#import gettext
+#from wok.cachebust import href
+#silent t = gettext.translation($lang.domain, $lang.localedir, languages=$lang.lang,
fallback=True)
+#silent _ = t.gettext
+#silent _t = t.gettext
+<div id="guest-storage-add-window" class="window">
+ <header>
+ <h1 class="title">$_("Add a Storage Device to
VM")</h1>
+ <div class="close">X</div>
+ </header>
+ <div class="content">
+ <form id="form-guest-storage-add">
+ <section class="form-section">
+ <h2>1. $_("Device Type")</h2>
+ <div class="field">
+ <p class="text-help">
+ $_("The device type. Currently, \"cdrom\" and
\"disk\" are supported.")
+ </p>
+ <div class="btn dropdown popable">
+ <input id="guest-storage-type" name="type"
value="cdrom" type="hidden" />
+ <span class="text"
id="guest-storage-type-label"></span>
+ <span class="arrow"></span>
+ <div class="popover">
+ <ul class="select-list"
id="guest-storage-type-list" data-target="guest-storage-type"
data-label="guest-storage-type-label"></ul>
+ </div>
+ </div>
+ </div>
+ </section>
+ <div class="volume-section hidden">
+ <section class="form-section">
+ <h2>2. $_("Storage Pool")</h2>
+ <div class="field storage-field">
+ <p class="text-help">
+ $_("Storage pool which volume located in")
+ </p>
+ <div class="btn dropdown popable">
+ <input value="default"
id="guest-disk-pool" name="pool" type="hidden"/>
+ <span class="text"
id="guest-disk-pool-label">default</span><span
class="arrow"></span>
+ <div class="popover" style="width:
100%">
+ <ul class="select-list"
id="guest-add-storage-pool-list" data-target="guest-disk-pool"
data-label="guest-disk-pool-label"></ul>
+ </div>
+ </div>
+ </div>
+ </section>
+ <section class="form-section">
+ <h2>3. $_("Storage Volume")</h2>
+ <div class="field storage-field">
+ <p class="text-help">
+ $_("Storage volume to be attached")
+ </p>
+ <div class="btn dropdown popable"
id="guest-disk">
+ <input id="guest-disk-vol" name="vol"
type="hidden">
+ <span class="text"
id="guest-disk-vol-label"></span><span
class="arrow"></span>
+ <div class="popover" style="width:
100%">
+ <ul class="select-list"
id="guest-add-storage-pool-list" data-target="guest-disk-vol"
data-label="guest-disk-vol-label"></ul>
+ </div>
+ </div>
+ </div>
+ </section>
+ </div>
+ <div class="path-section">
+ <section class="form-section">
+ <h2>2. $_("File Path")</h2>
+ <div class="field">
+ <p class="text-help">
+ $_("The ISO file path in the server for CDROM.")
+ </p>
+ <input type="text" class="text"
name="path" />
+ </div>
+ </section>
+ </div>
+ </fieldset>
+ </form>
+ </div>
+ <footer>
+ <div class="btn-group">
+ <button id="guest-storage-button-add"
class="btn-normal" disabled="disabled">
+ <span class="text">$_("Attach")</span>
+ </button>
+ </div>
+ </footer>
+</div>
+<script type="text/javascript">
+ kimchi.guest_storage_add_main();
+</script>
diff --git a/src/wok/plugins/kimchi/ui/pages/guest.html.tmpl
b/src/wok/plugins/kimchi/ui/pages/guest.html.tmpl
new file mode 100644
index 0000000..78e9161
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/pages/guest.html.tmpl
@@ -0,0 +1,77 @@
+#*
+ * Project Kimchi
+ *
+ * Copyright IBM, Corp. 2013-2015
+ *
+ * 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.
+ *#
+#unicode UTF-8
+#import gettext
+#from wok.cachebust import href
+#silent t = gettext.translation($lang.domain, $lang.localedir, languages=$lang.lang,
fallback=True)
+#silent _ = t.gettext
+#silent _t = t.gettext
+ <li name="guest" class="guest">
+ <div class="sortable guest-type">
+ <div class="guest-general">
+ <h2 class="title"
title="{name}">{name}</h2>
+ </div>
+ <div class="guest-pending hide-content">
+ <span class="icon"></span><span
class="text"></span>
+ </div>
+ </div>
+ <div name="cpu_utilization" class="sortable">
+ <div class="circleGauge"></div>
+ </div>
+ <div name="io_throughput" class="sortable">
+ <div class="circleGauge"></div>
+ <div class="subtitle">KB/s</div>
+ </div>
+ <div name="net_throughput" class="sortable">
+ <div class="circleGauge"></div>
+ <div class="subtitle">KB/s</div>
+ </div>
+ <div name="guest-tile" class="sortable
guest-tile">
+ <div class="tile ">
+ <img class="imgactive" alt=""
src="">
+ <img class="imgload" alt=""
src="">
+ <img class="overlay shutoff-hidden"
alt="$_("Start")"
src="plugins/kimchi/images/theme-default/icon-power-down.png" >
+ </div>
+ </div>
+ <div class="sortable guest-actions"
name="guest-actions">
+ <div class="top">
+ <button class="btn reset-disabled"
name="vm-reset" href="javascript:void(0);"
title="$_("Reset")"><span class="icon
reset"></span></button>
+ <button class="btn pause-disabled" name="vm-pause"
href="javascript:void(0);" title="$_("Pause")"><span
class="icon pause"></span></button>
+ <button class="btn resume-hidden" name="vm-resume"
href="javascript:void(0);" title="$_("Resume")"><span
class="icon resume"></span></button>
+ <button class="btn running-hidden"
name="vm-start" href="javascript:void(0);"
title="$_("Start")"><span class="icon
power-down"></span></button>
+ <button class="btn shutoff-hidden"
name="vm-poweroff" href="javascript:void(0);"
title="$_("Power Off")"><span class="icon
power-up"></span></button>
+ </div>
+ <div class="bottom">
+ <div name="actionmenu" class="btn dropdown popable
vm-action" style="width: 126px">
+ <span
class="text">$_("Actions")</span><span
class="arrow"></span>
+ <div class="popover actionsheet right-side"
style="width: 250px">
+ <button class="button-big shutoff-disabled"
name="vm-console" ><span
class="text">$_("Connect")</span></button>
+ <button class="button-big running-disabled"
name="vm-clone"><span
class="text">$_("Clone")</span></button>
+ <button class="button-big"
name="vm-edit"><span
class="text">$_("Edit")</span></button>
+ <button class="button-big shutoff-hidden
non-persistent-disabled" name="vm-reset"><span
class="text">$_("Reset")</span></button>
+ <button class="button-big pause-hidden non-persistent-disabled"
name="vm-pause"><span
class="text">$_("Pause")</span></button>
+ <button class="button-big resume-hidden"
name="vm-resume"><span
class="text">$_("Resume")</span></button>
+ <button class="button-big shutoff-hidden"
name="vm-shutdown"><span class="text">$_("Shut
Down")</span></button>
+ <button class="button-big running-hidden"
name="vm-start"><span
class="text">$_("Start")</span></button>
+ <button class="button-big shutoff-hidden"
name="vm-poweroff"><span class="text">$_("Power
Off")</span></button>
+ <button class="button-big red
non-persistent-disabled"
name="vm-delete">$_("Delete")</button>
+ </div>
+ </div>
+ </div>
+ </div>
+ </li>
diff --git a/src/wok/plugins/kimchi/ui/pages/guests.html.tmpl
b/src/wok/plugins/kimchi/ui/pages/guests.html.tmpl
new file mode 100644
index 0000000..b8a1259
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/pages/guests.html.tmpl
@@ -0,0 +1,65 @@
+#*
+ * Project Kimchi
+ *
+ * Copyright IBM, Corp. 2013-2014
+ *
+ * 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.
+ *#
+
+#unicode UTF-8
+#import gettext
+#from Cheetah.Template import Template
+#from wok.cachebust import href
+#silent t = gettext.translation($lang.domain, $lang.localedir, languages=$lang.lang,
fallback=True)
+#silent _ = t.gettext
+#silent _t = t.gettext
+
+#silent ht = Template
+
+<!DOCTYPE html>
+<html>
+<head>
+<link rel="stylesheet"
href="plugins/kimchi/css/theme-default.min.css">
+<script src="plugins/kimchi/js/kimchi.min.js"></script>
+</head>
+<body>
+<div id="guests-root-container">
+ <div class="toolbar">
+ <div class="tools" style="display:none">
+ <a id="vm-add" class="btn-tool"
href="javascript:void(0);"><span class="icon
add">+</span></a>
+ </div>
+ </div>
+ <div id="guestListField" style="display: none">
+ <ul class="list-title">
+ <li class="guest-type">$_("Name")</li>
+ <li class="guest-cpu">$_("CPU")</li>
+ <li class="guest-storage">$_("Disk
I/O")</li>
+ <li class="guest-network">$_("Network
I/O")</li>
+ <li class="guest-tile">$_("Livetile")</li>
+ <li class="guest-actions">$_("Actions")</li>
+ </ul>
+ <ul id="guestList" class="list-vm
empty-when-logged-off">
+ </ul>
+ </div>
+ <div id="noGuests" class="list-no-result" style="display:
none;">
+ $_("No guests found.")
+ </div>
+ <script id="guest-tmpl" type="kimchi/template">
+ $ht(file=$data.ui_dir + "/pages/guest.html.tmpl", searchList=[self,
{'lang':$lang}])
+ </script>
+ <script type="text/javascript">
+ kimchi.guest_main();
+ </script>
+</div>
+</body>
+</html>
diff --git a/src/wok/plugins/kimchi/ui/pages/help/Makefile.am
b/src/wok/plugins/kimchi/ui/pages/help/Makefile.am
new file mode 100644
index 0000000..a4ee361
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/pages/help/Makefile.am
@@ -0,0 +1,34 @@
+# Copyright IBM Corp, 2014
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+SUBDIRS = zh_CN it_IT en_US zh_TW pt_BR ja_JP ru_RU ko_KR fr_FR de_DE es_ES
+
+DITA_HTML_FILES = $(patsubst %.dita,%.html,$(wildcard */*.dita))
+HTML_FILES = $(if $(DITA_HTML_FILES), $(DITA_HTML_FILES), $(wildcard */*.html))
+DITA_XSL_FILE = dita-help.xsl
+
+EXTRA_DIST = $(DITA_XSL_FILE)
+
+helpdir = $(datadir)/wok/plugins/kimchi/ui/pages/help
+
+dist_help_DATA = kimchi.css
+
+all: $(HTML_FILES) $(wildcard */*.dita)
+
+%.html: %.dita $(DITA_XSL_FILE)
+ xsltproc -o $@ $(DITA_XSL_FILE) $<
+
+CLEANFILES = $(HTML_FILES)
diff --git a/src/wok/plugins/kimchi/ui/pages/help/de_DE/Makefile.am
b/src/wok/plugins/kimchi/ui/pages/help/de_DE/Makefile.am
new file mode 100644
index 0000000..3d99aae
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/pages/help/de_DE/Makefile.am
@@ -0,0 +1,23 @@
+# Copyright IBM Corp, 2014
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+de_DE_helpdir = $(datadir)/wok/plugins/kimchi/ui/pages/help/de_DE
+
+dist_de_DE_help_DATA = $(wildcard *.html) $(NULL)
+
+EXTRA_DIST = $(wildcard *.dita)
+
+CLEANFILES = $(wildcard *.html)
diff --git a/src/wok/plugins/kimchi/ui/pages/help/de_DE/guests.dita
b/src/wok/plugins/kimchi/ui/pages/help/de_DE/guests.dita
new file mode 100644
index 0000000..1d64469
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/pages/help/de_DE/guests.dita
@@ -0,0 +1,127 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--Arbortext, Inc., 1988-2011, v.4002-->
+<!DOCTYPE cshelp PUBLIC "-//IBM//DTD DITA CSHelp//EN"
+ "..\dtd\cshelp.dtd">
+
+
+<!--This DITA specialized document type is not supported by the Authoring Tools
development team.
+For support please see:
+https://w3.opensource.ibm.com/projects/dita-cshelp/-->
+<cshelp id="kimhvirtm" xml:lang="de-de">
+<title>G��ste</title>
+<shortdesc>Auf der Seite <wintitle>G��ste</wintitle> sind die
definierten virtuellen
+Maschinen von KVM aufgelistet.</shortdesc>
+<csbody>
+<p>F��r jeden Gast werden die folgenden Informationen
angezeigt:<dl><dlentry>
+<dt>Name</dt>
+<dd>Name der virtuellen Maschine.</dd>
+</dlentry><dlentry>
+<dt>CPU</dt>
+<dd>Prozentsatz der Prozessorauslastung in der virtuellen Maschine.</dd>
+</dlentry><dlentry>
+<dt>Netz-E/A</dt>
+<dd>Netz-E/A-��bertragungsrate in KB pro Sekunde.</dd>
+</dlentry><dlentry>
+<dt>Platten-E/A</dt>
+<dd>Platten-E/A-��bertragungsrate in KB pro Sekunde.</dd>
+</dlentry><dlentry>
+<dt>Live Tile</dt>
+<dd>Status der Konsole f��r das Gastbetriebssystem oder ein Symbol, das die
+<tm tmtype="tm" trademark="Linux">Linux</tm>-Verteilung
darstellt, wenn
+der Gast nicht aktiv ist.</dd>
+</dlentry></dl></p>
+<p>Die folgenden Aktionssymbole werden f��r jeden Gast angezeigt:<dl>
+<dlentry>
+<dt>Zur��cksetzen</dt>
+<dd>Klicken Sie hier, um den Gast zur��ckzusetzen. </dd>
+</dlentry><dlentry>
+<dt>Power (Starten oder Stoppen)</dt>
+<dd>Klicken Sie hier, um den Gast ein- bzw. auszuschalten. Wenn das Symbol rot
ist,
+ist er ausgeschaltet. Wenn das Symbol gr��n ist, ist er eingeschaltet.</dd>
+</dlentry></dl> </p>
+<p>Die folgenden Aktionen k��nnen f��r jeden Gast ausgew��hlt werden:<ul>
+<li>W��hlen Sie <uicontrol>Verbinden</uicontrol> aus, um eine
Verbindung zur fernen Konsole
+f��r das Gastbetriebssystem herzustellen.</li>
+<li>W��hlen Sie <uicontrol>Medien verwalten</uicontrol> aus, um den
Pfad zu den
+Installationsmedien zu ��ndern.</li>
+<li>W��hlen Sie <uicontrol>Zur��cksetzen</uicontrol> aus, um den Gast
zur��ckzusetzen.</li>
+<li>W��hlen Sie <uicontrol>Bearbeiten</uicontrol> aus, um die
Eigenschaften eines
+bestehenden Gastes zu bearbeiten. G��ste k��nnen nur bearbeitet werden, wenn sie gestoppt
sind.</li>
+<li>W��hlen Sie <uicontrol>L��schen</uicontrol> aus, um den Gast zu
l��schen.</li>
+</ul>Um einen Gast bzw. eine virtuelle Maschine zu erstellen, klicken Sie auf das
<uicontrol>Plus (+)</uicontrol>-Symbol oben rechts auf der Seite.</p>
+</csbody>
+<cshelp id="kimhvirtmcrt" xml:lang="de-de">
+<title>Virtuelle Maschine erstellen</title>
+<shortdesc>Erstellen Sie eine virtuelle Maschine mithilfe einer bestehenden
Vorlage.</shortdesc>
+<csbody>
+<p> <ol>
+<li>Geben Sie den Namen ein, mit dem die virtuelle Maschine gekennzeichnet
wird.</li>
+<li rev="rev1">W��hlen Sie eine Vorlage aus. <ul>
+<li>Wenn Vorlagen vorhanden sind, w��hlen Sie eine aus den angezeigten Vorlagen
aus.</li>
+<li>Wenn keine Vorlagen vorhanden sind, klicken Sie auf <uicontrol>Vorlage
erstellen</uicontrol>, um eine Vorlage zu erstellen.</li>
+</ul></li>
+<li>Klicken Sie auf <uicontrol>Erstellen</uicontrol>.</li>
+</ol> </p>
+</csbody>
+</cshelp>
+<cshelp id="kimhvirtmedit" xml:lang="de-de">
+<title>Gast bearbeiten</title>
+<shortdesc>Bearbeiten Sie die Eigenschaften einer bestehenden virtuellen Maschine.
Einige Eigenschaften k��nnen nur bearbeitet werden, solange der Gast gestoppt ist. Andere
Eigenschaften treten beim n��chsten Booten in Kraft. </shortdesc>
+<csprolog><csmetadata></csmetadata></csprolog>
+<csbody>
+<p>F��r jeden Gast werden die folgenden Informationen auf der Registerkarte
<wintitle>Allgemein</wintitle> angezeigt:<dl>
+<dlentry>
+<dt>Name</dt>
+<dd>Name der virtuellen Maschine. (Kann nur bearbeitet werden, solange der Gast
gestoppt ist.)</dd>
+</dlentry><dlentry>
+<dt>CPUs</dt>
+<dd>Anzahl der Prozessoren. (Wenn der Gast aktiv ist, tritt die neue Menge beim
n��chsten Booten in Kraft.)
+</dd>
+</dlentry><dlentry>
+<dt>Speicher</dt>
+<dd>Speicherkapazit��t in MB. (Wenn der Gast aktiv ist, tritt die neue Menge beim
n��chsten Booten in Kraft.)
+</dd>
+</dlentry><dlentry>
+<dt>Symbol</dt>
+<dd>Grafikbild, das die Linux-Verteilung darstellt und anstelle des aktuellen
Status (Live Tile) angezeigt werden soll, wenn der Gast nicht aktiv ist.</dd>
+</dlentry></dl></p>
+<p>Die folgenden Informationen werden auf der Registerkarte
<wintitle>Speicher</wintitle> angezeigt.</p>
+<dl><dlentry>
+<dt>Speicher</dt>
+<dd>Zeigt die Position der ISO-Datei an, die f��r die Installation verwendet
wird.</dd>
+</dlentry></dl>
+<p> Felder, die nicht inaktiviert sind, k��nnen bearbeitet werden. Nachdem Sie ein
Feld bearbeitet haben, klicken Sie auf <uicontrol>Speichern</uicontrol>.
</p>
+</csbody>
+</cshelp>
+<cshelp id="kimstoragedevice" xml:lang="de-de">
+<title>Speichereinheit hinzuf��gen, ersetzen oder abh��ngen</title>
+<shortdesc rev="rev1">Sie k��nnen eine Speichereinheit zu Ihrer
virtuellen Maschine hinzuf��gen oder diese ersetzen oder abh��ngen. Die einzige
unterst��tzte Einheit ist CD-ROM. F��hren Sie die folgenden Schritte aus, um Ihre
Speichereinheiten zu bearbeiten:</shortdesc>
+<csbody>
+<ol>
+<li>W��hlen Sie im Fenster <wintitle>Gast bearbeiten</wintitle> die
Option <wintitle>Speicher</wintitle> aus.</li>
+<li>Um eine Speichereinheit zu ersetzen, klicken Sie auf das erste Symbol mit dem
<uicontrol>orangefarbenen Schr��gstrich (/)</uicontrol>. Geben Sie den
ISO-Dateipfad ein und klicken Sie auf
<uicontrol>Ersetzen</uicontrol>.</li>
+<li>Um eine Speichereinheit abzuh��ngen, klicken Sie auf das zweite Symbol mit dem
<uicontrol>roten Gedankenstrich (-)</uicontrol>. Best��tigen Sie den
L��schvorgang und klicken Sie auf <uicontrol>OK</uicontrol>.</li>
+<li>Um eine Speichereinheit hinzuzuf��gen, klicken Sie auf das dritte Symbol mit
dem gr��nen <uicontrol>Pluszeichen (+)</uicontrol>. Geben Sie einen
Einheitennamen und einen ISO-Dateipfad ein und klicken Sie auf
<uicontrol>Anh��ngen</uicontrol>.</li>
+</ol>
+</csbody>
+</cshelp>
+<cshelp id="kimreplacemedia" xml:lang="de-de">
+<title>CD-ROM f��r VM ersetzen</title>
+<shortdesc rev="rev1">Sie k��nnen den Inhalt der CD-ROM f��r eine
virtuelle Maschine nach Abschluss der Installation ersetzen.</shortdesc>
+<csbody>
+<ol>
+<li>Stellen Sie sicher, dass die virtuelle Maschine gestartet ist.</li>
+<li>W��hlen Sie aus dem Aktionsmen�� die Option <uicontrol>Medien
verwalten</uicontrol> aus.</li>
+<li>Um das zu ��ndern, was aktuell in der CD-ROM geladen ist, klicken Sie auf das
Symbol mit dem <uicontrol>orangefarbenen Schr��gstrich (/)</uicontrol> neben
dem hdc-Feld.</li>
+<li>Geben Sie auf der Seite <wintitle>CD-ROM f��r VM
ersetzen</wintitle> den ISO-Dateipfad ein. Die anderen beiden Felder sind
schreibgesch��tzt.</li>
+<li>Klicken Sie auf <uicontrol>Ersetzen</uicontrol>.</li>
+</ol>
+</csbody>
+</cshelp>
+<?tm 1391540919 3?>
+</cshelp>
+
+
+<!-- ENGL1SH_VERS10N 45645_6 DO NOT REMOVE OR CHANGE THIS LINE -->
+<!-- T9N_SRC_ID 231 -->
+<!-- T9N_SH1P_STR1NG KV211AAP001 1 -->
diff --git a/src/wok/plugins/kimchi/ui/pages/help/de_DE/host.dita
b/src/wok/plugins/kimchi/ui/pages/help/de_DE/host.dita
new file mode 100644
index 0000000..33a40e3
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/pages/help/de_DE/host.dita
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--Arbortext, Inc., 1988-2011, v.4002-->
+<!DOCTYPE cshelp PUBLIC "-//IBM//DTD DITA CSHelp//EN"
+ "..\dtd\cshelp.dtd">
+
+
+<!--This DITA specialized document type is not supported by the Authoring Tools
development team.
+For support please see:
+https://w3.opensource.ibm.com/projects/dita-cshelp/-->
+<cshelp id="kimhhost" xml:lang="de-de">
+<title>Host</title>
+<shortdesc>Die Seite <wintitle>Host</wintitle> zeigt Informationen zum
Hostsystem an und erm��glicht Ihnen, den Host herunterzufahren, erneut zu starten und eine
Verbindung zu ihm herzustellen.</shortdesc>
+<csbody>
+<p>Sie k��nnen die folgenden Aktionen am Host durchf��hren:<ul>
+<li>W��hlen Sie <uicontrol>Herunterfahren</uicontrol> aus, um das
Hostsystem herunterzufahren.</li>
+<li>W��hlen Sie <uicontrol>Erneut starten</uicontrol> aus, um das
Hostsystem erneut zu starten.</li>
+<li>W��hlen Sie <uicontrol>Verbinden</uicontrol> aus, um eine
VNC-Verbindung zum Hostsystem herzustellen, wenn noch keine Verbindung
besteht.</li>
+</ul></p>
+<p>Klicken Sie auf die folgenden Abschnitte, um Informationen zum Host
anzuzeigen:<dl>
+<dlentry>
+<dt>Basisinformationen</dt>
+<dd>Dieser Abschnitt zeigt die Verteilung, die Version und den Codenamen des
Hostbetriebssystems sowie den Prozessortyp und die Speicherkapazit��t in GB
an.</dd>
+</dlentry><dlentry>
+<dt>Systemstatistik</dt>
+<dd>Dieser Abschnitt zeigt mithilfe von Grafiken Statistiken f��r CPU, Speicher,
Platten-E/A und Netz-E/A f��r den Host an. W��hlen Sie <uicontrol>Daten werden nach
dem Verlassen dieser Seite gesammelt</uicontrol> aus, um mit der Sammlung von Daten
fortzufahren, wenn die Host-Registerkarte nicht angezeigt wird.</dd>
+</dlentry><dlentry>
+<dt>Software-Updates</dt>
+<dd>Dieser Abschnitt zeigt Informationen f��r alle Pakete an, bei denen
Aktualisierungen verf��gbar sind, einschlie��lich Paketname, Version, Architektur und
Repository. Sie k��nnen alle aufgelisteten Pakete aktualisieren, indem Sie
<uicontrol>Alle aktualisieren</uicontrol> ausw��hlen. Sie k��nnen nicht
einzelne Pakete zur Aktualisierung ausw��hlen.</dd>
+</dlentry><dlentry>
+<dt>Repositorys</dt>
+<dd>Dieser Abschnitt zeigt Repositorys an, die dem Hostsystem zugeordnet sind. Sie
k��nnen Repositorys hinzuf��gen, aktivieren, bearbeiten oder entfernen. Beim Hinzuf��gen
wird ein Repository dem Hostsystem zugeordnet. Das Aktivieren eines Repositorys dagegen
erm��glicht dem Host den Zugriff auf das Repository. Wenn Ihr System Red Hat Enterprise
+Linux oder Fedora ist, k��nnen Sie <filepath>yum</filepath>-Repositorys
hinzuf��gen.
+Wenn Ihr System Ubuntu oder Debian ist, f��gen Sie
<filepath>deb</filepath>-Repositorys hinzu.<p>Wenn Sie mit
yum-Repositorys arbeiten, k��nnen Sie eine GPG-Pr��fung hinzuf��gen, um sicherzustellen,
dass ein Paket aus diesem Repository nicht besch��digt wurde.
+W��hlen Sie ein Repository und dann <uicontrol>Bearbeiten</uicontrol> aus.
W��hlen Sie <uicontrol>Ja</uicontrol> aus, um die GPG-Pr��fung zu aktivieren,
und geben Sie dann ein URL zur GPG-Schl��sseldatei f��r das Repository
ein.</p></dd>
+</dlentry><dlentry>
+<dt>Debugberichte</dt>
+<dd>Dieser Abschnitt zeigt Debugberichte, einschlie��lich Name und Dateipfad, an.
+Sie haben die M��glichkeit, einen neuen Bericht zu erstellen oder einen bestehenden
Bericht umzubenennen, zu entfernen oder herunterzuladen.<p>Der Debugbericht wird
w��hrend des Befehls <cmdname>sosreport</cmdname> generiert. Er ist verf��gbar
f��r Red Hat Enterprise <tm tmtype="tm"
trademark="Linux">Linux</tm>-, Fedora-
+und Ubuntu-Verteilungen. Der Befehl generiert eine .tar-Datei, die Konfigurations- und
Diagnoseinformationen enth��lt, wie zum Beispiel Kernelversion, geladene Module sowie
System- und Servicekonfigurationdateien.
+Der Befehl f��hrt zudem externe Programme aus, um weitere Informationen zu sammeln, und
speichert diese Ausgabe im resultierenden Archiv.</p> </dd>
+</dlentry></dl></p>
+</csbody>
+<?tm 1392659967 1?>
+</cshelp>
+
+
+<!-- ENGL1SH_VERS10N 47930_4 DO NOT REMOVE OR CHANGE THIS LINE -->
+<!-- T9N_SRC_ID 232 -->
+<!-- T9N_SH1P_STR1NG KVM21AAP001 3 -->
diff --git a/src/wok/plugins/kimchi/ui/pages/help/de_DE/network.dita
b/src/wok/plugins/kimchi/ui/pages/help/de_DE/network.dita
new file mode 100644
index 0000000..49a2935
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/pages/help/de_DE/network.dita
@@ -0,0 +1,62 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--Arbortext, Inc., 1988-2011, v.4002-->
+<!DOCTYPE cshelp PUBLIC "-//IBM//DTD DITA CSHelp//EN"
+ "..\dtd\cshelp.dtd">
+
+
+<!--This DITA specialized document type is not supported by the Authoring Tools
development team.
+For support please see:
+https://w3.opensource.ibm.com/projects/dita-cshelp/-->
+<cshelp id="kimhnetw" xml:lang="de-de">
+<title>Netz</title>
+<shortdesc>Die Seite <wintitle>Netz</wintitle> zeigt Informationen zur
Netzverbindung an.</shortdesc>
+<csbody>
+<p><dl><dlentry>
+<dt>Netzname</dt>
+<dd>Name des Netzes oder <uicontrol>Standard</uicontrol>.</dd>
+</dlentry><dlentry>
+<dt>Status</dt>
+<dd>Status des Netzes, aktiv (gr��n) oder inaktiv (rot). </dd>
+</dlentry><dlentry>
+<dt>Netztyp</dt>
+<dd>Netztyp, zum Beispiel <uicontrol>NAT</uicontrol> (Network
+Address Translation, Netzadressumsetzung).</dd>
+</dlentry><dlentry>
+<dt>Schnittstelle</dt>
+<dd>Netzschnittstelle, zum Beispiel <uicontrol>virbr0</uicontrol>
(Standard).</dd>
+</dlentry><dlentry>
+<dt>Adressraum</dt>
+<dd>IP-Adresse.</dd>
+</dlentry></dl></p>
+<p>Die folgenden Aktionen k��nnen ausgew��hlt werden:<ul>
+<li rev="rev1">W��hlen Sie <uicontrol>Starten</uicontrol>
aus, um die Netzverbindung herzustellen.</li>
+<li>W��hlen Sie <uicontrol>Stoppen</uicontrol> aus, um die
Netzverbindung zu beenden.</li>
+<li>W��hlen Sie <uicontrol>L��schen</uicontrol> aus, um die
Verbindungsinformationen zu l��schen.</li>
+</ul>Um ein Netz zu erstellen, klicken Sie auf das Symbol <uicontrol>Plus
(+)</uicontrol> oben rechts in der Anzeige.</p>
+</csbody>
+<cshelp id="kimhnetwcrt" xml:lang="de-de">
+<title>Netz erstellen</title>
+<shortdesc>Erstellen Sie ein Netz.</shortdesc>
+<csbody>
+<p> <ol>
+<li>Geben Sie den Namen des Netzes ein.</li>
+<li>Klicken Sie hier, um den Netztyp auszuw��hlen. <dl
rev="rev1"><dlentry>
+<dt><uicontrol>Isoliert</uicontrol></dt>
+<dd>Isolierter Modus. G��ste k��nnen keine Kommunikation an externe Systeme senden
oder von ihnen empfangen.</dd>
+</dlentry><dlentry>
+<dt><uicontrol>NAT</uicontrol></dt>
+<dd>Network Address Translation-Modus. Bei der Kommunikation von G��sten mit
externen Systemen wird die Host-IP-Adresse verwendet. Externe Systeme k��nnen keine
Kommunikation mit G��sten initiieren.</dd>
+</dlentry><dlentry>
+<dt><uicontrol>��berbr��ckt</uicontrol></dt>
+<dd>��berbr��ckt-Modus. G��ste k��nnen mit externen Systemen kommunizieren und von
externen Systemen kontaktiert werden, als ob sie physische Systeme im Netz w��ren. F��r
den ��berbr��ckt-Modus m��ssen Sie zus��tzliche Ziel- und VLAN-Informationen
angeben.</dd>
+</dlentry></dl></li>
+<li>Klicken Sie auf <uicontrol>Erstellen</uicontrol>.</li>
+</ol> </p>
+</csbody>
+</cshelp>
+</cshelp>
+
+
+<!-- ENGL1SH_VERS10N 47050_3 DO NOT REMOVE OR CHANGE THIS LINE -->
+<!-- T9N_SRC_ID 230 -->
+<!-- T9N_SH1P_STR1NG KVM21AAP001 3 -->
diff --git a/src/wok/plugins/kimchi/ui/pages/help/de_DE/storage.dita
b/src/wok/plugins/kimchi/ui/pages/help/de_DE/storage.dita
new file mode 100644
index 0000000..7f89603
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/pages/help/de_DE/storage.dita
@@ -0,0 +1,86 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--Arbortext, Inc., 1988-2011, v.4002-->
+<!DOCTYPE cshelp PUBLIC "-//IBM//DTD DITA CSHelp//EN"
+ "..\dtd\cshelp.dtd">
+
+
+<!--This DITA specialized document type is not supported by the Authoring Tools
development team.
+For support please see:
+https://w3.opensource.ibm.com/projects/dita-cshelp/-->
+<cshelp id="kimhstor" xml:lang="de-de">
+<title>Speicher</title>
+<shortdesc>Auf der Seite <wintitle>Speicher</wintitle> werden die
verf��gbaren Speicherpools aufgelistet, einschlie��lich der sofort einsatzf��higen
Speicherpools 'default' und 'ISO'. Wenn Sie ein eigenes ISO-Image
verwenden m��chten, f��gen Sie es zum Speicherpoolpfad 'ISO'
hinzu.</shortdesc>
+<csbody>
+<p>F��r jeden Speicherpool werden die folgenden Informationen angezeigt:<dl>
+<dlentry>
+<dt>Name</dt>
+<dd>Name des Speicherpools und genutzter Prozentsatz.</dd>
+</dlentry><dlentry>
+<dt>Status</dt>
+<dd>Status des Speicherpools, aktiv (gr��n) oder inaktiv (rot). </dd>
+</dlentry><dlentry>
+<dt>Position</dt>
+<dd>Dateipfad zur Position des Speicherpools.</dd>
+</dlentry><dlentry>
+<dt>Typ</dt>
+<dd>Typ des Speicherpools, zum Beispiel
<uicontrol>dir</uicontrol>.</dd>
+</dlentry><dlentry>
+<dt>Kapazit��t</dt>
+<dd>Speicherkapazit��t im Speicherpool.</dd>
+</dlentry><dlentry>
+<dt>Zugeordnet</dt>
+<dd>Speicherplatz, der bereits im Speicherpool zugeordnet ist.</dd>
+</dlentry></dl></p>
+<p>Die folgenden Aktionen k��nnen f��r jeden Speicherpool ausgew��hlt
werden:<ul>
+<li>W��hlen Sie <uicontrol>Aktivieren</uicontrol> aus, um den
Speicherpool zu aktivieren, damit er genutzt werden kann.</li>
+<li>W��hlen Sie <uicontrol>Inaktivieren</uicontrol> aus, um einen
aktiven Speicherpool zu inaktivieren.</li>
+<li>W��hlen Sie <uicontrol>Definition aufheben</uicontrol>, um einen
inaktiven Speicherpool zu entfernen.</li>
+</ul></p>
+<p>Um Details zum Speicherdatentr��ger anzuzeigen, klicken Sie auf den Pfeil auf
der rechten Seite der Speicherpoolzeile. Zu den Details geh��ren folgende
Informationen:<dl><dlentry>
+<dt>Typ</dt>
+<dd>Typ des Datentr��gers, zum Beispiel
<uicontrol>file</uicontrol>.</dd>
+</dlentry><dlentry>
+<dt>Format</dt>
+<dd>Das Format, variiert abh��ngig vom Typ.</dd>
+</dlentry><dlentry>
+<dt>Kapazit��t</dt>
+<dd>Gr����e des Speicherdatentr��gers.</dd>
+</dlentry><dlentry>
+<dt>Zuordnung</dt>
+<dd>Speicherplatz, der bereits im Speicherpool zugeordnet ist.</dd>
+</dlentry></dl>Um einen Speicherpool zu definieren, klicken Sie auf das
Symbol <uicontrol>Plus (+)</uicontrol> oben rechts in der Anzeige.</p>
+</csbody>
+<cshelp id="kimhdefstor" xml:lang="de-de">
+<title>Speicherpool definieren</title>
+<shortdesc> Definieren Sie einen Speicherpool.</shortdesc>
+<csbody>
+<p> <ol>
+<li>Geben Sie im Feld <uicontrol>Speicherpoolname</uicontrol> den Namen
ein, mit dem der Speicherpool gekennzeichnet werden soll.</li>
+<li>W��hlen Sie aus der Liste <uicontrol>Speicherpooltyp</uicontrol>
den Typ aus: <dl><dlentry>
+<dt><uicontrol>DIR</uicontrol></dt>
+<dd>Gibt einen Verzeichnispool an. Wenn Sie <uicontrol>DIR</uicontrol>
ausw��hlen, geben Sie den <uicontrol>Speicherpfad</uicontrol> ein (Dateipfad
zum Speicherpool).</dd>
+</dlentry><dlentry>
+<dt><uicontrol>NFS</uicontrol></dt>
+<dd>Gibt einen Netzdateisystempool an. Wenn Sie
<uicontrol>NFS</uicontrol> ausw��hlen,
+geben Sie <uicontrol>NFS-Server-IP</uicontrol> und
<uicontrol>NFS-Pfad</uicontrol> an (Pfad des exportierten
Verzeichnisses).</dd>
+</dlentry><dlentry>
+<dt><uicontrol>iSCSI</uicontrol></dt>
+<dd>Gibt einen Pool an, der auf einem Ziel basiert, der auf einem iSCSI-Server
zugeordnet ist.
+Wenn Sie <uicontrol>iSCSI</uicontrol> ausw��hlen, geben Sie die IP-Adresse
vom <uicontrol>iSCSI-Server</uicontrol> und das
<uicontrol>Ziel</uicontrol> auf dem iSCSI-Server an. Sie k��nnen optional
iSCSI-Authentifizierung hinzuf��gen.</dd>
+</dlentry><dlentry>
+<dt><uicontrol>Logisch</uicontrol></dt>
+<dd>Gibt einen Speicherpool aus logischen Datentr��gern an. W��hlen Sie die
Position zur Einheit im <uicontrol>Einheitenpfad</uicontrol> aus.</dd>
+</dlentry><dlentry>
+<dt><uicontrol>SCSI-Fibre Channel</uicontrol></dt>
+<dd>Gibt einen Pool an, der auf einem SCSI-Fibre Channel basiert. W��hlen Sie aus,
welcher Adapter verwendet werden soll.</dd>
+</dlentry></dl></li>
+<li>Klicken Sie auf <uicontrol>Erstellen</uicontrol>.</li>
+</ol> </p>
+</csbody>
+</cshelp>
+</cshelp>
+
+
+<!-- ENGL1SH_VERS10N 22336_4 DO NOT REMOVE OR CHANGE THIS LINE -->
+<!-- T9N_SRC_ID 233 -->
+<!-- T9N_SH1P_STR1NG KV211AAP001 1 -->
diff --git a/src/wok/plugins/kimchi/ui/pages/help/de_DE/templates.dita
b/src/wok/plugins/kimchi/ui/pages/help/de_DE/templates.dita
new file mode 100644
index 0000000..5063930
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/pages/help/de_DE/templates.dita
@@ -0,0 +1,112 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--Arbortext, Inc., 1988-2011, v.4002-->
+<!DOCTYPE cshelp PUBLIC "-//IBM//DTD DITA CSHelp//EN"
+ "..\dtd\cshelp.dtd">
+
+
+<!--This DITA specialized document type is not supported by the Authoring Tools
development team.
+For support please see:
+https://w3.opensource.ibm.com/projects/dita-cshelp/-->
+<cshelp id="kimhtempl" xml:lang="de-de">
+<title>Vorlagen</title>
+<shortdesc>Die Seite <wintitle>Vorlagen</wintitle> zeigt die
definierten Vorlagen der virtuellen Maschine an, die zum Erstellen von KVM-G��sten
verwendet werden k��nnen.</shortdesc>
+<csbody>
+<p>F��r jede Vorlage werden die folgenden Informationen angezeigt:<dl>
+<dlentry>
+<dt>BS</dt>
+<dd>Name des Betriebssystems oder der Verteilung.</dd>
+</dlentry><dlentry>
+<dt>Version</dt>
+<dd>Version des Betriebssystems oder der Verteilung.</dd>
+</dlentry><dlentry>
+<dt>CPUs</dt>
+<dd>Anzahl der Prozessoren, die f��r die Vorlage definiert sind.</dd>
+</dlentry><dlentry>
+<dt>Speicher</dt>
+<dd>Gr����e des zuzuordnenden Arbeitsspeichers in MB.</dd>
+</dlentry></dl></p>
+<p>Die folgenden Aktionen k��nnen f��r jede Vorlage ausgew��hlt werden:<ul>
+<li>W��hlen Sie <uicontrol>Bearbeiten</uicontrol> aus, um die Vorlage
zu bearbeiten.</li>
+<li>W��hlen Sie <uicontrol>L��schen</uicontrol> aus, um die Vorlage zu
l��schen.</li>
+</ul>Um eine Vorlage hinzuzuf��gen, klicken Sie auf das Symbol
<uicontrol>Plus (+)</uicontrol> oben rechts in der Anzeige.</p>
+</csbody>
+<cshelp id="kimhedittempl" xml:lang="de-de">
+<title>Vorlage bearbeiten</title>
+<shortdesc>Bearbeiten Sie eine bestehende Vorlage.</shortdesc>
+<csbody>
+<p>F��r jede Vorlage werden die folgenden Informationen angezeigt: <dl>
+<dlentry>
+<dt>Name</dt>
+<dd>Name der Vorlage.</dd>
+</dlentry><dlentry>
+<dt>Anbieter</dt>
+<dd>Der Name des Unternehmens, das das Betriebssystem oder die Verteilung erstellt
hat, f��r die die Vorlage konfiguriert ist.</dd>
+</dlentry><dlentry>
+<dt>Version</dt>
+<dd>Die Version des Betriebssystems oder der Verteilung, f��r die die Vorlage
konfiguriert ist.</dd>
+</dlentry><dlentry>
+<dt>CPU-Anzahl</dt>
+<dd>Anzahl der Prozessoren, die f��r die Vorlage definiert sind.</dd>
+</dlentry><dlentry>
+<dt>Speicher</dt>
+<dd>Speicherkapazit��t in MB, die der virtuellen Maschine zugeordnet werden
soll.</dd>
+</dlentry><dlentry>
+<dt>Platte</dt>
+<dd>Plattengr����e in GB.</dd>
+</dlentry><dlentry>
+<dt>CD-ROM</dt>
+<dd>Dateipfad zur Position der ISO-Datei an, die f��r die Installation des
KVM-Gastes verwendet wird.</dd>
+</dlentry><dlentry>
+<dt>Speicherpool</dt>
+<dd>Bestimmter Speicherpool oder der Standardspeicherpool.</dd>
+</dlentry><dlentry>
+<dt>Netz</dt>
+<dd>Standardnetzschnittstelle, die f��r den KVM-Gast verf��gbar ist. Sie k��nnen
mehrere Netze ausw��hlen.</dd>
+</dlentry></dl> Felder, die nicht inaktiviert sind, k��nnen bearbeitet
werden. Nachdem Sie ein Feld bearbeitet haben, klicken Sie auf
<uicontrol>Speichern</uicontrol>. </p>
+</csbody>
+</cshelp>
+<cshelp id="kimhaddtempl">
+<title>Vorlage hinzuf��gen</title>
+<shortdesc>F��gen Sie eine Vorlage vom Quellendatentr��ger hinzu. Sie k��nnen f��r
eine nachfolgende Erkennung Ihr eigenes ISO-Image zum Speicherpool 'ISO'
hinzuf��gen.</shortdesc>
+<csbody>
+<p>W��hlen Sie die Position des Quellendatentr��gers aus den folgenden Optionen
aus:<dl>
+<dlentry>
+<dt>Lokales ISO-Image</dt>
+<dd>W��hlen Sie diese Option aus, um Speicherpools nach Installations-ISO-Images zu
durchsuchen, die im System verf��gbar sind.</dd>
+</dlentry><dlentry>
+<dt>Fernes ISO-Image</dt>
+<dd>W��hlen Sie diese Option aus, um eine ferne Position f��r ein
Installations-ISO-Image anzugeben.</dd>
+</dlentry></dl></p>
+</csbody>
+</cshelp>
+<cshelp id="kimhaddloct">
+<title>Vorlage hinzuf��gen - lokales ISO-Image</title>
+<shortdesc>F��gen Sie eine Vorlage aus einem lokalen ISO-Image
hinzu.</shortdesc>
+<csbody>
+<p>Die im System verf��gbaren ISO-Images werden
angezeigt.<dl><dlentry>
+<dt>BS</dt>
+<dd>Name des Betriebssystems oder der Verteilung.</dd>
+</dlentry><dlentry>
+<dt>Version</dt>
+<dd>Version des Betriebssystems oder der Verteilung.</dd>
+</dlentry><dlentry>
+<dt>Gr����e</dt>
+<dd>Gr����e des ISO-Image.</dd>
+</dlentry></dl></p>
+<p>Um eine Vorlage aus einem ISO-Image zu erstellen, w��hlen Sie aus den folgenden
+Optionen aus:<ul>
+<li>W��hlen Sie ein ISO-Image aus, aus dem Sie eine Vorlage erstellen m��chten, und
klicken Sie dann auf <uicontrol>Vorlagen aus ausgew��hltem ISO
erstellen</uicontrol>.</li>
+<li>W��hlen Sie <uicontrol>Alle</uicontrol> aus, um eine Vorlage aus
jedem aufgelisteten ISO-Image zu erstellen, und klicken Sie dann auf
<uicontrol>Vorlagen aus ausgew��hltem ISO erstellen</uicontrol>.</li>
+<li>Wenn das ISO-Image, das Sie verwenden m��chten, nicht in den Suchergebnissen
angezeigt wird, k��nnen Sie aus den folgenden Optionen ausw��hlen:<ul>
+<li>W��hlen Sie <uicontrol>Ich m��chte eine bestimmte ISO-Datei
verwenden</uicontrol> aus, um einen Pfad zum ISO-Image anzugeben.</li>
+<li>Klicken Sie auf <uicontrol>Weitere ISOs suchen</uicontrol>, um
weitere ISO-Images zu suchen.</li>
+</ul></li>
+</ul></p>
+</csbody>
+</cshelp>
+</cshelp>
+
+
+<!-- ENGL1SH_VERS10N 61085_5 DO NOT REMOVE OR CHANGE THIS LINE -->
+<!-- T9N_SRC_ID 229 -->
+<!-- T9N_SH1P_STR1NG KV211AAP001 1 -->
diff --git a/src/wok/plugins/kimchi/ui/pages/help/dita-help.xsl
b/src/wok/plugins/kimchi/ui/pages/help/dita-help.xsl
new file mode 100644
index 0000000..45f0a3b
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/pages/help/dita-help.xsl
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<xsl:stylesheet version="1.0"
+
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+
xmlns="http://www.w3.org/1999/xhtml">
+ <xsl:output method="xml" indent="yes"
encoding="UTF-8" />
+
+ <xsl:template match="/">
+ <html>
+ <head>
+ <title><xsl:value-of select="/cshelp/title"
/></title>
+ <meta charset="UTF-8" />
+ <link rel="shortcut icon" href="images/logo.ico"
/>
+ <link rel="stylesheet" type="text/css"
href="../kimchi.css" />
+ </head>
+ <body>
+ <xsl:apply-templates select="//cshelp" />
+ </body>
+ </html>
+ </xsl:template>
+
+ <xsl:template match="cshelp">
+ <h1><xsl:value-of select="title" /></h1>
+ <p class="shortdesc"><xsl:value-of
select="shortdesc" /></p>
+ <p class="csbody"><xsl:copy-of
select="csbody/node()" /></p>
+ </xsl:template>
+</xsl:stylesheet>
diff --git a/src/wok/plugins/kimchi/ui/pages/help/en_US/Makefile.am
b/src/wok/plugins/kimchi/ui/pages/help/en_US/Makefile.am
new file mode 100644
index 0000000..d37f03a
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/pages/help/en_US/Makefile.am
@@ -0,0 +1,23 @@
+# Copyright IBM Corp, 2014
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+en_US_helpdir = $(datadir)/wok/plugins/kimchi/ui/pages/help/en_US
+
+dist_en_US_help_DATA = $(wildcard *.html) $(NULL)
+
+EXTRA_DIST = $(wildcard *.dita)
+
+CLEANFILES = $(wildcard *.html)
diff --git a/src/wok/plugins/kimchi/ui/pages/help/en_US/guests.dita
b/src/wok/plugins/kimchi/ui/pages/help/en_US/guests.dita
new file mode 100644
index 0000000..1bb437a
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/pages/help/en_US/guests.dita
@@ -0,0 +1,136 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--Arbortext, Inc., 1988-2011, v.4002-->
+<!DOCTYPE cshelp PUBLIC "-//IBM//DTD DITA CSHelp//EN"
+ "..\dtd\cshelp.dtd">
+<?Pub Sty _display FontColor="red"?>
+<?Pub Inc?>
+<!--This DITA specialized document type is not supported by the Authoring Tools
development team.
+For support please see:
+https://w3.opensource.ibm.com/projects/dita-cshelp/-->
+<cshelp id="kimhvirtm" xml:lang="en-us">
+<title>Guests</title>
+<shortdesc>The <wintitle>Guests</wintitle> page lists the defined
+KVM virtual machines.</shortdesc>
+<csbody>
+<p>For each guest, the following information is
displayed:<dl><dlentry>
+<dt>Name</dt>
+<dd>Name of the virtual machine.</dd>
+</dlentry><dlentry>
+<dt>CPU</dt>
+<dd>Percentage of processor utilization in the virtual machine.</dd>
+</dlentry><dlentry>
+<dt>Network I/O</dt>
+<dd>Network input/output transmission rate in KB per seconds.</dd>
+</dlentry><dlentry>
+<dt>Disk I/O</dt>
+<dd>Disk input/output transmission rate in KB per seconds.</dd>
+</dlentry><dlentry>
+<dt>Livetile</dt>
+<dd>State of guest operating system console, or an icon that represents
+the <tm tmtype="tm" trademark="Linux">Linux</tm>
distribution if the
+guest is not active.</dd>
+</dlentry></dl></p>
+<p>The following actions icons are displayed for each guest:<dl>
+<dlentry>
+<dt>Reset</dt>
+<dd>Click to reset the guest. </dd>
+</dlentry><dlentry>
+<dt>Power (Start or Stop)</dt>
+<dd>Click to power on or power off the guest. If the icon is red,
+the power is off; if the icon is green, the power is on.</dd>
+</dlentry></dl> </p>
+<p>The following actions can be selected for each guest:<ul>
+<li>Select <uicontrol>Connect</uicontrol> to connect to the remote
+console for the guest operating system.</li>
+<li>Select <uicontrol>Manage media</uicontrol> to change the path
+to the installation media.</li>
+<li>Select <uicontrol>Reset</uicontrol> to reset the guest.</li>
+<li>Select <uicontrol>Edit</uicontrol> to edit the properties of an
+existing guest. Guests can be edited only while stopped.</li>
+<li>Select <uicontrol>Delete</uicontrol> to delete the
guest.</li>
+</ul>To create a guest, or virtual machine, click the <uicontrol>plus
+(+)</uicontrol> icon in the upper right of the page.</p>
+</csbody>
+<cshelp id="kimhvirtmcrt" xml:lang="en-us">
+<title>Create virtual machine</title>
+<shortdesc>Create a virtual machine by using an existing
template.</shortdesc>
+<csbody>
+<p> <ol>
+<li>Type the name to be used to identify the virtual machine.</li>
+<li rev="rev1">Select a template. <ul>
+<li>If templates exist, select from displayed templates.</li>
+<li>If no templates exist, click <uicontrol>Create a
template</uicontrol> to
+create a template.</li>
+</ul></li>
+<li>Click <uicontrol>Create</uicontrol>.</li>
+</ol> </p>
+</csbody>
+</cshelp>
+<cshelp id="kimhvirtmedit" xml:lang="en-us">
+<title>Edit guest</title>
+<shortdesc>Edit the properties of an existing virtual machine. Some properties
+can be edited only while guest is stopped. Others will take effect in next
boot.</shortdesc>
+<csprolog><csmetadata></csmetadata></csprolog>
+<csbody>
+<p>For each guest, the following information is displayed on the
<wintitle>General</wintitle> tab:<dl>
+<dlentry>
+<dt>Name</dt>
+<dd>Name of the virtual machine. (can only be edited while guest is
stopped)</dd>
+</dlentry><dlentry>
+<dt>CPUs</dt>
+<dd>Number of processors. (if guest is running, new amount will take effect
+in next boot)</dd>
+</dlentry><dlentry>
+<dt>Memory</dt>
+<dd>Amount of memory in MB. (if guest is running, new amount will take effect
+in next boot)</dd>
+</dlentry><dlentry>
+<dt>Icon</dt>
+<dd>Graphic image representing the Linux distribution to be displayed
+in place of current status (Livetile) when the guest is not active.</dd>
+</dlentry></dl></p>
+<p>The following information is displayed on the
<wintitle>Storage</wintitle> tab.</p>
+<dl><dlentry>
+<dt>Storage</dt>
+<dd>Displays the location of the ISO file used for installation.</dd>
+</dlentry></dl><?Pub Caret -2?>
+<p> Fields that are not disabled can be edited. After you edit a field,
+click <uicontrol>Save</uicontrol>. </p>
+</csbody>
+</cshelp>
+<cshelp id="kimstoragedevice" xml:lang="en-us">
+<title>Add, replace, or detach a storage device</title>
+<shortdesc rev="rev1">You can add, replace, or detach a storage device
+to your virtual machine. The only supported device is CDROM. To edit
+your storage devices, follow these steps:</shortdesc>
+<csbody>
+<ol>
+<li>On the <wintitle>Edit Guest</wintitle> window, select
<wintitle>Storage</wintitle>.</li>
+<li>To replace a storage device, click the first icon with the
<uicontrol>orange
+slash (/)</uicontrol>. Enter the ISO file path and click
<uicontrol>Replace</uicontrol>.</li>
+<li>To detach a storage device, click the second icon with the
<uicontrol>red
+dash (-)</uicontrol>. Confirm the deletion and click
<uicontrol>OK</uicontrol>.</li>
+<li>To add a storage device, click the third icon with the green
<uicontrol>plus
+sign (+)</uicontrol>. Enter a device name and ISO file path and click
<uicontrol>Attach</uicontrol>.</li>
+</ol>
+</csbody>
+</cshelp>
+<cshelp id="kimreplacemedia" xml:lang="en-us">
+<title>Replace a CDROM of VM</title>
+<shortdesc rev="rev1">You can replace the contents of the CDROM for
+a virtual machine after the installation is complete.</shortdesc>
+<csbody>
+<ol>
+<li>Ensure that the virtual machine is started.</li>
+<li>From the Actions menu, select <uicontrol>Manage
Media</uicontrol>.</li>
+<li>To change what is currently loaded in the CDROM, click the
<uicontrol>orange
+slash (/)</uicontrol> icon next to the hdc field.</li>
+<li>On the <wintitle>Replace a CDROM of VM</wintitle> page, enter
+the ISO file path. The other two fields are read-only.</li>
+<li>Click <uicontrol>Replace</uicontrol>.</li>
+</ol>
+</csbody>
+</cshelp>
+<?tm 1391540919 3?>
+</cshelp>
+<?Pub *0000005541?>
diff --git a/src/wok/plugins/kimchi/ui/pages/help/en_US/host.dita
b/src/wok/plugins/kimchi/ui/pages/help/en_US/host.dita
new file mode 100644
index 0000000..0dcb670
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/pages/help/en_US/host.dita
@@ -0,0 +1,70 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--Arbortext, Inc., 1988-2011, v.4002-->
+<!DOCTYPE cshelp PUBLIC "-//IBM//DTD DITA CSHelp//EN"
+ "..\dtd\cshelp.dtd">
+<?Pub Sty _display FontColor="red"?>
+<?Pub Inc?>
+<!--This DITA specialized document type is not supported by the Authoring Tools
development team.
+For support please see:
+https://w3.opensource.ibm.com/projects/dita-cshelp/-->
+<cshelp id="kimhhost" xml:lang="en-us">
+<title>Host</title>
+<shortdesc>The <wintitle>Host</wintitle> page shows information about
+the host system, and allows you to shut down, restart, and connect
+to the host.</shortdesc>
+<csbody>
+<p>You can perform the following actions on the host:<ul>
+<li>Select <uicontrol>Shut down</uicontrol> to shut down the host
+system.</li>
+<li>Select <uicontrol>Restart</uicontrol> to restart the host
system.</li>
+<li>Select <uicontrol>Connect</uicontrol> to open a VNC connection
+to the host system, if it is not already connected.</li>
+</ul></p>
+<p>Click the following sections to display information about the host:<dl>
+<dlentry>
+<dt>Basic information</dt>
+<dd>This section displays the host operating system distribution,
+version, and code name, as well as the processor type, the number of
+online CPUs and amount of memory in GB.</dd>
+</dlentry><dlentry>
+<dt>System statistics</dt>
+<dd>This section displays graphs to show statistics for CPU, memory,
+disk I/O, and network I/O for the host. Select <uicontrol>Collecting
+data after leaving this page</uicontrol> to continue collecting data
+when the host tab is out of view.</dd>
+</dlentry><dlentry>
+<dt>Software Updates</dt>
+<dd>This section displays information for all of the packages that
+have updates available, including package name, version, architecture,
+and repository. You can update all of the packages listed by selecting
<uicontrol>Update
+All</uicontrol>. You cannot select individual packages for updates.</dd>
+</dlentry><dlentry>
+<dt>Repositories</dt>
+<dd>This section displays repositories that are associated with the
+host system. You can add, enable, edit, or remove repositories. Adding
+a repository associates it with the host system while enabling a repository
+allows the host to access it. If your system is Red Hat Enterprise
+Linux or Fedora, you can add <filepath>yum</filepath> repositories.
+If your system is Ubuntu or Debian, then add <filepath>deb</filepath>
repositories.<p>If
+you are working with yum repositories, you can add a GPG check to
+verify that a package from this repository have not been corrupted.
+Select a repository and then <uicontrol>Edit</uicontrol>. Select
<uicontrol>Yes</uicontrol> to
+enable GPG Check and then enter a URL to the GPG key file for the
+repository.</p><?Pub Caret 156?></dd>
+</dlentry><dlentry>
+<dt>Debug reports</dt>
+<dd>This section displays debug reports, including name and file path.
+You can select from options to generate a new report, or rename, remove,
+or download an existing report.<p>The debug report is generated using
+the <cmdname>sosreport</cmdname> command. It is available for Red
+Hat Enterprise <tm tmtype="tm"
trademark="Linux">Linux</tm>, Fedora,
+and Ubuntu distributions. The command generates a .tar file that contains
+configuration and diagnostic information, such as the running kernel
+version, loaded modules, and system and service configuration files.
+The command also runs external programs to collect further information
+and stores this output in the resulting archive.</p> </dd>
+</dlentry></dl></p>
+</csbody>
+<?tm 1392659967 1?>
+</cshelp>
+<?Pub *0000003492?>
diff --git a/src/wok/plugins/kimchi/ui/pages/help/en_US/network.dita
b/src/wok/plugins/kimchi/ui/pages/help/en_US/network.dita
new file mode 100644
index 0000000..25c05ff
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/pages/help/en_US/network.dita
@@ -0,0 +1,68 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--Arbortext, Inc., 1988-2011, v.4002-->
+<!DOCTYPE cshelp PUBLIC "-//IBM//DTD DITA CSHelp//EN"
+ "..\dtd\cshelp.dtd">
+<?Pub Sty _display FontColor="red"?>
+<?Pub Inc?>
+<!--This DITA specialized document type is not supported by the Authoring Tools
development team.
+For support please see:
+https://w3.opensource.ibm.com/projects/dita-cshelp/-->
+<cshelp id="kimhnetw" xml:lang="en-us">
+<title>Network</title>
+<shortdesc>The <wintitle>Network</wintitle> page displays information
+about the network connection.</shortdesc>
+<csbody>
+<p><dl><dlentry>
+<dt>Network Name</dt>
+<dd>Name of the network, or <uicontrol>default</uicontrol>.</dd>
+</dlentry><dlentry>
+<dt>State</dt>
+<dd>State of the network, active (green) or inactive (red). </dd>
+</dlentry><dlentry>
+<dt>Network type</dt>
+<dd>Network type, for example, <uicontrol>NAT</uicontrol> (network
+address translation).</dd>
+</dlentry><dlentry>
+<dt>Interface</dt>
+<dd>Network interface, for example, <uicontrol>virbr0</uicontrol>
(default).</dd>
+</dlentry><dlentry>
+<dt>Address space</dt>
+<dd>IP address.</dd>
+</dlentry></dl></p>
+<p>The following actions can be selected:<ul>
+<li rev="rev1">Select <uicontrol>Start</uicontrol> to begin
the network
+connection.</li>
+<li>Select <uicontrol>Stop</uicontrol> to end the network
connection.</li>
+<li>Select <uicontrol>Delete</uicontrol> to delete the connection
+information.</li>
+</ul>To create a network, click the <uicontrol>plus (+)</uicontrol>
icon
+in the upper right of the display.</p>
+</csbody>
+<cshelp id="kimhnetwcrt" xml:lang="en-us">
+<title>Create a network</title>
+<shortdesc>Create a network.</shortdesc>
+<csbody>
+<p> <ol>
+<li>Type the name of the network.</li>
+<li>Click to select the network type. <dl
rev="rev1"><dlentry>
+<dt><uicontrol>Isolated</uicontrol></dt>
+<dd>Isolated mode. Guests cannot send or receive communication to
+or from external systems.</dd>
+</dlentry><dlentry>
+<dt><uicontrol>NAT</uicontrol></dt>
+<dd>Network Address Translation mode. Communication from guests to
+external systems uses the host IP address. External systems cannot
+initiate communication to guests.</dd>
+</dlentry><dlentry>
+<dt><uicontrol>Bridged</uicontrol></dt>
+<dd>Bridged mode. Guests can communicate with external systems and
+be contacted by external systems as if they were physical systems
+on the network. For bridged mode, you must specify additional destination
+and VLAN information.</dd>
+</dlentry></dl><?Pub Caret 224?></li>
+<li>Click <uicontrol>Create</uicontrol>.</li>
+</ol> </p>
+</csbody>
+</cshelp>
+</cshelp>
+<?Pub *0000002571?>
diff --git a/src/wok/plugins/kimchi/ui/pages/help/en_US/storage.dita
b/src/wok/plugins/kimchi/ui/pages/help/en_US/storage.dita
new file mode 100644
index 0000000..d9a32f9
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/pages/help/en_US/storage.dita
@@ -0,0 +1,99 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--Arbortext, Inc., 1988-2011, v.4002-->
+<!DOCTYPE cshelp PUBLIC "-//IBM//DTD DITA CSHelp//EN"
+ "..\dtd\cshelp.dtd">
+<?Pub Sty _display FontColor="red"?>
+<?Pub Inc?>
+<!--This DITA specialized document type is not supported by the Authoring Tools
development team.
+For support please see:
+https://w3.opensource.ibm.com/projects/dita-cshelp/-->
+<cshelp id="kimhstor" xml:lang="en-us">
+<title>Storage</title>
+<shortdesc>The <wintitle>Storage</wintitle> page lists the available
+storage pools, including the out of box 'default' and 'ISO' storage
pool.
+If you want to use your own ISO, please add it to 'ISO' storage pool
path.</shortdesc>
+<csbody>
+<p>For each storage pool, the following information is displayed:<dl>
+<dlentry>
+<dt>Name</dt>
+<dd>Name of the storage pool and percentage used.</dd>
+</dlentry><dlentry>
+<dt>State</dt>
+<dd>State of the storage pool, active (green) or inactive (red). </dd>
+</dlentry><dlentry>
+<dt>Location</dt>
+<dd>File path to the location of the storage pool.</dd>
+</dlentry><dlentry>
+<dt>Type</dt>
+<dd>Type of storage pool, for example,
<uicontrol>dir</uicontrol>.</dd>
+</dlentry><dlentry>
+<dt>Capacity</dt>
+<dd>Amount of space in the storage pool.</dd>
+</dlentry><dlentry>
+<dt>Allocated</dt>
+<dd>Amount of space that is already allocated in the storage pool.</dd>
+</dlentry></dl></p>
+<p>The following actions can be selected for each storage pool:<ul>
+<li>Select <uicontrol>Activate</uicontrol> to activate the storage
+pool so that it can be used.</li>
+<li>Select <uicontrol>Deactivate</uicontrol> to deactivate an active
+storage pool.</li>
+<li>Select <uicontrol>Undefine</uicontrol> to remove an inactive
storage
+pool.</li>
+</ul></p>
+<p>To display storage volume details for a storage pool, click the
+arrow on the right side of the storage pool row. Details include
+the following:<dl><dlentry>
+<dt>Type</dt>
+<dd>The type of volume, for example,
<uicontrol>file</uicontrol>.</dd>
+</dlentry><dlentry>
+<dt>Format</dt>
+<dd>The format, varying dependent on the type.</dd>
+</dlentry><dlentry>
+<dt>Capacity</dt>
+<dd>Size of the storage volume.</dd>
+</dlentry><dlentry>
+<dt>Allocation</dt>
+<dd>Amount of space that is already allocated in the storage pool.</dd>
+</dlentry></dl>To define a storage pool, click the <uicontrol>plus
+(+)</uicontrol> icon in the upper right of the display.</p>
+</csbody>
+<cshelp id="kimhdefstor" xml:lang="en-us">
+<title>Define a storage pool</title>
+<shortdesc> Define a storage pool.</shortdesc>
+<csbody>
+<p> <ol>
+<li>In the <uicontrol>Storage pool name</uicontrol> field, type the
+name to be used to identify the storage pool.</li>
+<li>In the <uicontrol>Storage pool type</uicontrol> list, select the
+type: <dl><dlentry>
+<dt><uicontrol>DIR</uicontrol></dt>
+<dd>Specifies a directory pool. When selecting
<uicontrol>DIR</uicontrol>,
+type the <uicontrol>Storage path</uicontrol> (file path to the storage
+pool).</dd>
+</dlentry><dlentry>
+<dt><uicontrol>NFS</uicontrol></dt>
+<dd>Specifies a network filesystem pool. When selecting
<uicontrol>NFS</uicontrol>,
+type the <uicontrol>NFS server IP</uicontrol> address and
<uicontrol>NFS
+path</uicontrol> (path of the exported directory).</dd>
+</dlentry><dlentry>
+<dt><uicontrol>iSCSI</uicontrol></dt>
+<dd>Specifies a pool based on a target allocated on an iSCSI server.
+When selecting <uicontrol>iSCSI</uicontrol>, type the <uicontrol>iSCSI
+server</uicontrol> IP address and <uicontrol>Target</uicontrol> on
+the iSCSI server. You can optionally select to add iSCSI authentication.</dd>
+</dlentry><dlentry>
+<dt><uicontrol>Logical</uicontrol></dt>
+<dd>Specifies a logical volume storage pool. Select the location to
+the device in <uicontrol>Device path</uicontrol>.</dd>
+</dlentry><dlentry>
+<dt><uicontrol>SCSI Fibre Channel</uicontrol></dt>
+<dd>Specifies a pool based on an SCSI Fibre Channel. Select which
+SCSI adapter to use.</dd>
+</dlentry></dl><?Pub Caret 0?></li>
+<li>Click <uicontrol>Create</uicontrol>.</li>
+</ol> </p>
+</csbody>
+</cshelp>
+</cshelp>
+<?Pub *0000003914?>
diff --git a/src/wok/plugins/kimchi/ui/pages/help/en_US/templates.dita
b/src/wok/plugins/kimchi/ui/pages/help/en_US/templates.dita
new file mode 100644
index 0000000..57ee9b5
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/pages/help/en_US/templates.dita
@@ -0,0 +1,123 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--Arbortext, Inc., 1988-2011, v.4002-->
+<!DOCTYPE cshelp PUBLIC "-//IBM//DTD DITA CSHelp//EN"
+ "..\dtd\cshelp.dtd">
+<?Pub Sty _display FontColor="red"?>
+<?Pub Inc?>
+<!--This DITA specialized document type is not supported by the Authoring Tools
development team.
+For support please see:
+https://w3.opensource.ibm.com/projects/dita-cshelp/-->
+<cshelp id="kimhtempl" xml:lang="en-us">
+<title>Templates</title>
+<shortdesc>The <wintitle>Templates</wintitle> page shows the defined
+virtual machine templates that can be used to create KVM guests.</shortdesc>
+<csbody>
+<p>For each template, the following information is displayed:<dl>
+<dlentry>
+<dt>OS</dt>
+<dd>Name of the operating system or distribution.</dd>
+</dlentry><dlentry>
+<dt>Version</dt>
+<dd>Version of the operating system or distribution.</dd>
+</dlentry><dlentry>
+<dt>CPUs</dt>
+<dd>Number of processors that are defined for the template.</dd>
+</dlentry><dlentry>
+<dt>Memory</dt>
+<dd>Amount of random access memory to be allocated, in MB.</dd>
+</dlentry></dl></p>
+<p>The following actions can be selected for each template:<ul>
+<li>Select <uicontrol>Edit</uicontrol> to edit the
template.</li>
+<li>Select <uicontrol>Delete</uicontrol> to delete the
template.</li>
+</ul>To add a template, click the <uicontrol>plus (+)</uicontrol> icon
+in the upper right of the display.</p>
+</csbody>
+<cshelp id="kimhedittempl" xml:lang="en-us">
+<title>Edit template</title>
+<shortdesc>Edit an existing template.</shortdesc>
+<csbody>
+<p>For each template, the following information is displayed: <dl>
+<dlentry>
+<dt>Name</dt>
+<dd>Name of the template.</dd>
+</dlentry><dlentry>
+<dt>Vendor</dt>
+<dd>The name of the company that created the operating system or distribution
+that the template is configured to use.</dd>
+</dlentry><dlentry>
+<dt>Version</dt>
+<dd>The version of the operating system or distribution that the template
+is configured to use.</dd>
+</dlentry><dlentry>
+<dt>CPU number</dt>
+<dd>Number of processors that are defined for the template.</dd>
+</dlentry><dlentry>
+<dt>Memory</dt>
+<dd>Amount of memory in MB to be allocated to the virtual machine.</dd>
+</dlentry><dlentry>
+<dt>Disk</dt>
+<dd>Disk size in GB.</dd>
+</dlentry><dlentry>
+<dt>CDROM</dt>
+<dd>File path to the location of the ISO file used to install the
+KVM guest.</dd>
+</dlentry><dlentry>
+<dt>Storage pool</dt>
+<dd>Specific storage pool or the default storage pool.</dd>
+</dlentry><dlentry>
+<dt>Network</dt>
+<dd>Default network interfaces available to the KVM guest. You can
+select multiple networks.</dd>
+</dlentry></dl> Fields that are not disabled can be edited. After
+you edit a field, click <uicontrol>Save</uicontrol>. </p>
+</csbody>
+</cshelp>
+<cshelp id="kimhaddtempl">
+<title>Add template</title>
+<shortdesc>Add a template from source media.
+You can add your own ISO image to 'ISO' storage pool for following
discovery.</shortdesc>
+<csbody>
+<p>Select the location of the source media from the following options:<dl>
+<dlentry>
+<dt>Local ISO image</dt>
+<dd>Select to scan storage pools for installation ISO images available
+on the system.</dd>
+</dlentry><dlentry>
+<dt>Remote ISO image</dt>
+<dd>Select to specify a remote location for an installation ISO image.</dd>
+</dlentry></dl></p>
+</csbody>
+</cshelp>
+<cshelp id="kimhaddloct">
+<title>Add template - local ISO image</title>
+<shortdesc>Add a template from a local ISO image.</shortdesc>
+<csbody>
+<p>The ISO images available on the system are displayed.<dl><dlentry>
+<dt>OS</dt>
+<dd>Name of the operating system or distribution.</dd>
+</dlentry><dlentry>
+<dt>Version</dt>
+<dd>Version of the operating system or distribution.</dd>
+</dlentry><dlentry>
+<dt>Size</dt>
+<dd>Size of the ISO image.</dd>
+</dlentry></dl></p>
+<p>To create a template from an ISO image, choose from the following
+options:<ul>
+<li>Select an ISO image from which to create a template, then click
<uicontrol>Create
+Templates from Selected ISO</uicontrol>.</li>
+<li>Select <uicontrol>All</uicontrol> to create a template from each
+ listed ISO image, then click <uicontrol>Create Templates from Selected
+ISO</uicontrol>.</li>
+<li>If the ISO image that you want to use does not appear in the scan
+results, you can select from the following options:<ul>
+<li>Select <uicontrol>I want to use a specific ISO file</uicontrol> to
+specify a path to the ISO image.</li>
+<li>Click <uicontrol>Search more ISOs</uicontrol> to search for more
+ISO images.</li>
+</ul></li><?Pub Caret 0?>
+</ul></p>
+</csbody>
+</cshelp>
+</cshelp>
+<?Pub *0000004433?>
diff --git a/src/wok/plugins/kimchi/ui/pages/help/es_ES/Makefile.am
b/src/wok/plugins/kimchi/ui/pages/help/es_ES/Makefile.am
new file mode 100644
index 0000000..29c596f
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/pages/help/es_ES/Makefile.am
@@ -0,0 +1,23 @@
+# Copyright IBM Corp, 2014
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+es_ES_helpdir = $(datadir)/wok/plugins/kimchi/ui/pages/help/es_ES
+
+dist_es_ES_help_DATA = $(wildcard *.html) $(NULL)
+
+EXTRA_DIST = $(wildcard *.dita)
+
+CLEANFILES = $(wildcard *.html)
diff --git a/src/wok/plugins/kimchi/ui/pages/help/es_ES/guests.dita
b/src/wok/plugins/kimchi/ui/pages/help/es_ES/guests.dita
new file mode 100644
index 0000000..88e77e0
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/pages/help/es_ES/guests.dita
@@ -0,0 +1,120 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--Arbortext, Inc., 1988-2011, v.4002-->
+<!DOCTYPE cshelp PUBLIC "-//IBM//DTD DITA CSHelp//EN"
+ "..\dtd\cshelp.dtd">
+
+
+<!--This DITA specialized document type is not supported by the Authoring Tools
development team.
+For support please see:
+https://w3.opensource.ibm.com/projects/dita-cshelp/-->
+<cshelp id="kimhvirtm" xml:lang="es-es">
+<title>Invitados</title>
+<shortdesc>La p��gina <wintitle>Invitados</wintitle> lista las
m��quinas virtuales KVM definidas.</shortdesc>
+<csbody>
+<p>Se visualiza la siguiente informaci��n para cada
invitado:<dl><dlentry>
+<dt>Nombre</dt>
+<dd>Nombre de la m��quina virtual.</dd>
+</dlentry><dlentry>
+<dt>CPU</dt>
+<dd>Porcentaje de utilizaci��n de procesador en la m��quina virtual.</dd>
+</dlentry><dlentry>
+<dt>E/S de red</dt>
+<dd>Velocidad de transmisi��n de entrada/salida de red en KB por
segundos.</dd>
+</dlentry><dlentry>
+<dt>E/S de disco</dt>
+<dd>Velocidad de transmisi��n de entrada/salida de disco en KB por
segundos.</dd>
+</dlentry><dlentry>
+<dt>Livetile</dt>
+<dd>Estado de la consola del sistema operativo invitado, o un icono que representa
la distribuci��n de <tm tmtype="tm"
trademark="Linux">Linux</tm> si el invitado no est��
activo.</dd>
+</dlentry></dl></p>
+<p>Se visualizan los siguientes iconos de acciones para cada invitado:<dl>
+<dlentry>
+<dt>Restablecer</dt>
+<dd>Pulse aqu�� para restablecer el invitado. </dd>
+</dlentry><dlentry>
+<dt>Alimentaci��n (Iniciar o Detener)</dt>
+<dd>Pulse aqu�� para encender o apagar el invitado. Si el icono es de color rojo,
la alimentaci��n est�� apagada; si el icono es de color verde, la alimentaci��n est��
encendida.</dd>
+</dlentry></dl> </p>
+<p>Se pueden seleccionar las siguientes acciones para cada invitado:<ul>
+<li>Seleccione <uicontrol>Conectar</uicontrol> para conectarse a la
consola remota para el sistema operativo invitado.</li>
+<li>Seleccione <uicontrol>Gestionar soporte</uicontrol> para cambiar la
v��a de acceso al soporte de instalaci��n.</li>
+<li>Seleccione <uicontrol>Restablecer</uicontrol> para restablecer el
invitado.</li>
+<li>Seleccione <uicontrol>Editar</uicontrol> para editar las
propiedades de un invitado existente. Los invitados s��lo pueden editarse mientras est��n
detenidos.</li>
+<li>Seleccione <uicontrol>Suprimir</uicontrol> para suprimir el
invitado.</li>
+</ul>Para crear un invitado o m��quina virtual, pulse el icono
<uicontrol>m��s (+)</uicontrol> en la esquina superior derecha de la
p��gina.</p>
+</csbody>
+<cshelp id="kimhvirtmcrt" xml:lang="es-es">
+<title>Crear m��quina virtual</title>
+<shortdesc>Crear una m��quina virtual utilizando una plantilla
existente.</shortdesc>
+<csbody>
+<p> <ol>
+<li>Escriba el nombre a utilizar para identificar la m��quina virtual.</li>
+<li rev="rev1">Seleccione una plantilla. <ul>
+<li>Si existen plantillas, seleccione entre las plantillas mostradas.</li>
+<li>Si no existen plantillas, pulse <uicontrol>Crear una
plantilla</uicontrol> para crear una plantilla.</li>
+</ul></li>
+<li>Pulse <uicontrol>Crear</uicontrol>.</li>
+</ol> </p>
+</csbody>
+</cshelp>
+<cshelp id="kimhvirtmedit" xml:lang="es-es">
+<title>Editar invitado</title>
+<shortdesc>Editar las propiedades de una m��quina virtual existente. Algunas
propiedades pueden editarse s��lo cuando el invitado se ha detenido. Otras surtir��n
efecto en el arranque siguiente.</shortdesc>
+<csprolog><csmetadata></csmetadata></csprolog>
+<csbody>
+<p>Se visualiza la siguiente informaci��n para cada invitado en la pesta��a
<wintitle>General</wintitle>:<dl>
+<dlentry>
+<dt>Nombre</dt>
+<dd>Nombre de la m��quina virtual.(s��lo puede editarse cuando el invitado se ha
detenido)</dd>
+</dlentry><dlentry>
+<dt>CPUs</dt>
+<dd>N��mero de procesadores.(si el invitado est�� en ejecuci��n, la nueva cantidad
surtir�� efecto en el siguiente arranque)
+</dd>
+</dlentry><dlentry>
+<dt>Memoria</dt>
+<dd>Cantidad de memoria en MB.(si el invitado est�� en ejecuci��n, la nueva
cantidad surtir�� efecto en el siguiente arranque)
+</dd>
+</dlentry><dlentry>
+<dt>Icono</dt>
+<dd>Imagen gr��fica que representa la distribuci��n de Linux a visualizar en lugar
del estado actual (Livetile) cuando el invitado no est�� activo.</dd>
+</dlentry></dl></p>
+<p>Se visualiza la siguiente informaci��n en la pesta��a
<wintitle>Almacenamiento</wintitle>.</p>
+<dl><dlentry>
+<dt>Almacenamiento</dt>
+<dd>Muestra la ubicaci��n del archivo ISO utilizado para la
instalaci��n.</dd>
+</dlentry></dl>
+<p> Los campos que no est��n inhabilitados pueden editarse. Despu��s de editar un
campo, pulse <uicontrol>Guardar</uicontrol>. </p>
+</csbody>
+</cshelp>
+<cshelp id="kimstoragedevice" xml:lang="es-es">
+<title>A��adir, sustituir o desconectar un dispositivo de
almacenamiento</title>
+<shortdesc rev="rev1">Puede a��adir, sustituir o desconectar un
dispositivo de almacenamiento a la m��quina virtual. El ��nico dispositivo soportado es
CDROM. Para editar los dispositivos de almacenamiento, siga estos
pasos:</shortdesc>
+<csbody>
+<ol>
+<li>En la ventana <wintitle>Editar invitado</wintitle>, seleccione
<wintitle>Almacenamiento</wintitle>.</li>
+<li>Para sustituir un dispositivo de almacenamiento, pulse el primer icono con la
<uicontrol>barra inclinada naranja (/)</uicontrol>. Especifique la v��a de
acceso del archivo ISO y pulse <uicontrol>Sustituir</uicontrol>.</li>
+<li>Para desconectar un dispositivo de almacenamiento, pulse el segundo icono con
el <uicontrol>gui��n rojo (-)</uicontrol>. Confirme la supresi��n y pulse
<uicontrol>Aceptar</uicontrol>.</li>
+<li>Para a��adir un dispositivo de almacenamiento, pulse el tercer icono con el
<uicontrol>signo m��s (+)</uicontrol> verde. Especifique un nombre de
dispositivo y la v��a de acceso del archivo ISO y pulse
<uicontrol>Conectar</uicontrol>.</li>
+</ol>
+</csbody>
+</cshelp>
+<cshelp id="kimreplacemedia" xml:lang="es-es">
+<title>Sustituir un CDROM de m��quina virtual</title>
+<shortdesc rev="rev1">Puede sustituir el contenido del CDROM para una
m��quina virtual despu��s de completarse la instalaci��n.</shortdesc>
+<csbody>
+<ol>
+<li>Aseg��rese de que la m��quina virtual se ha iniciado.</li>
+<li>En el men�� Acciones, seleccione <uicontrol>Gestionar
soporte</uicontrol>.</li>
+<li>Para cambiar lo que est�� cargado actualmente en el CDROM, pulse el icono
<uicontrol>barra inclinada naranja (/)</uicontrol> junto al campo
hdc.</li>
+<li>En la p��gina <wintitle>Sustituir un CDROM de m��quina
virtual</wintitle>, especifique la v��a de acceso del archivo ISO. Los otros dos
campos son de s��lo lectura.</li>
+<li>Pulse <uicontrol>Sustituir</uicontrol>.</li>
+</ol>
+</csbody>
+</cshelp>
+<?tm 1391540919 3?>
+</cshelp>
+
+
+<!-- ENGL1SH_VERS10N 45645_6 DO NOT REMOVE OR CHANGE THIS LINE -->
+<!-- T9N_SRC_ID 231 -->
+<!-- T9N_SH1P_STR1NG KV211AAP001 1 -->
diff --git a/src/wok/plugins/kimchi/ui/pages/help/es_ES/host.dita
b/src/wok/plugins/kimchi/ui/pages/help/es_ES/host.dita
new file mode 100644
index 0000000..7734244
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/pages/help/es_ES/host.dita
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--Arbortext, Inc., 1988-2011, v.4002-->
+<!DOCTYPE cshelp PUBLIC "-//IBM//DTD DITA CSHelp//EN"
+ "..\dtd\cshelp.dtd">
+
+
+<!--This DITA specialized document type is not supported by the Authoring Tools
development team.
+For support please see:
+https://w3.opensource.ibm.com/projects/dita-cshelp/-->
+<cshelp id="kimhhost" xml:lang="es-es">
+<title>Host</title>
+<shortdesc>La p��gina <wintitle>Host</wintitle> muestra informaci��n
sobre el sistema host y le permite concluir, reiniciar y conectar con el sistema
principal.</shortdesc>
+<csbody>
+<p>Puede realizar las acciones siguientes en el host:<ul>
+<li>Seleccione <uicontrol>Concluir</uicontrol> para concluir el sistema
host.</li>
+<li>Seleccione <uicontrol>Reiniciar</uicontrol> para reiniciar el
sistema host.</li>
+<li>Seleccione <uicontrol>Conectar</uicontrol> para abrir una conexi��n
VNC al sistema host, si no est�� conectado a��n.</li>
+</ul></p>
+<p>Pulse en las secciones siguientes para visualizar informaci��n acerca del
host:<dl>
+<dlentry>
+<dt>Informaci��n b��sica</dt>
+<dd>Esta secci��n muestra la distribuci��n del sistema operativo de host, la
versi��n y el nombre de c��digo, as�� como el tipo de procesador y la cantidad de memoria
en GB.</dd>
+</dlentry><dlentry>
+<dt>Estad��sticas del sistema</dt>
+<dd>Esta secci��n muestra gr��ficos para mostrar estad��sticas para CPU, memoria,
E/S de disco y E/S de red para el host. Seleccione <uicontrol>Recoger datos despu��s
de salir de esta p��gina</uicontrol> para continuar la recogida de datos cuando la
pesta��a principal ya no est�� a la vista.</dd>
+</dlentry><dlentry>
+<dt>Actualizaciones de software</dt>
+<dd>En esta secci��n se muestra informaci��n para todos los paquetes que tienen
actualizaciones disponibles, incluido el nombre de paquete, versi��n, arquitectura y
repositorio. Puede actualizar todos los paquetes listados seleccionando
<uicontrol>Actualizar todo</uicontrol>. No puede seleccionar paquetes
individuales para las actualizaciones.</dd>
+</dlentry><dlentry>
+<dt>Repositorios</dt>
+<dd>En esta secci��n se muestran los repositorios que est��n asociados con el
sistema host. Puede a��adir, habilitar, editar o eliminar repositorios. A��adir un
repositorio lo asocia con el sistema host mientras que habilitar un repositorio permite
que el host acceda a ��l. Si el sistema es Red Hat Enterprise
+Linux o Fedora, puede a��adir repositorios <filepath>yum</filepath>.
+Si el sistema es Ubuntu o Debian, a��ada repositorios
<filepath>deb</filepath>.<p>Si est�� trabajando con repositorios yum,
puede a��adir una comprobaci��n GPG para verificar que un paquete de este repositorio no
ha resultado da��ado.
+Seleccione un repositorio y, a continuaci��n, <uicontrol>Editar</uicontrol>.
Seleccione <uicontrol>S��</uicontrol> para habilitar la comprobaci��n GPG y, a
continuaci��n, especifique un URL al archivo de claves GPG para el
repositorio.</p></dd>
+</dlentry><dlentry>
+<dt>Informes de depuraci��n</dt>
+<dd>En esta secci��n se muestran informes de depuraci��n, incluido el nombre y la
ruta de archivo.
+Puede seleccionar entre opciones para generar un informe nuevo, o bien redenominar,
eliminar o descargar un informe existente.<p>El informe de depuraci��n se genera
utilizando el mandato <cmdname>sosreport</cmdname>. Est�� disponible para
distribuciones de Red
+Hat Enterprise <tm tmtype="tm"
trademark="Linux">Linux</tm>, Fedora y Ubuntu. El mandato genera un
archivo .tar que contiene la informaci��n de configuraci��n y de diagn��stico, como la
versi��n de kernel en ejecuci��n, los m��dulos de carga y los archivos de configuraci��n
del sistema y servicio.
+El mandato tambi��n ejecuta programas externos para recopilar informaci��n adicional y
almacena esta salida en el archivo resultante.</p> </dd>
+</dlentry></dl></p>
+</csbody>
+<?tm 1392659967 1?>
+</cshelp>
+
+
+<!-- ENGL1SH_VERS10N 47930_4 DO NOT REMOVE OR CHANGE THIS LINE -->
+<!-- T9N_SRC_ID 232 -->
+<!-- T9N_SH1P_STR1NG KVM21AAP001 3 -->
diff --git a/src/wok/plugins/kimchi/ui/pages/help/es_ES/network.dita
b/src/wok/plugins/kimchi/ui/pages/help/es_ES/network.dita
new file mode 100644
index 0000000..3654531
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/pages/help/es_ES/network.dita
@@ -0,0 +1,61 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--Arbortext, Inc., 1988-2011, v.4002-->
+<!DOCTYPE cshelp PUBLIC "-//IBM//DTD DITA CSHelp//EN"
+ "..\dtd\cshelp.dtd">
+
+
+<!--This DITA specialized document type is not supported by the Authoring Tools
development team.
+For support please see:
+https://w3.opensource.ibm.com/projects/dita-cshelp/-->
+<cshelp id="kimhnetw" xml:lang="es-es">
+<title>Red</title>
+<shortdesc>La p��gina <wintitle>Red</wintitle> muestra informaci��n
sobre la conexi��n de red.</shortdesc>
+<csbody>
+<p><dl><dlentry>
+<dt>Nombre de red</dt>
+<dd>Nombre de la red, o
<uicontrol>predeterminado</uicontrol>.</dd>
+</dlentry><dlentry>
+<dt>Estado</dt>
+<dd>Estado de la red, activa (verde) o inactiva (rojo). </dd>
+</dlentry><dlentry>
+<dt>Tipo de red</dt>
+<dd>Tipo de red, por ejemplo, <uicontrol>NAT</uicontrol> (conversi��n
de direcciones de red).</dd>
+</dlentry><dlentry>
+<dt>Interfaz</dt>
+<dd>La interfaz de red, por ejemplo, <uicontrol>virbr0</uicontrol>
(predeterminada).</dd>
+</dlentry><dlentry>
+<dt>Espacio de direcciones</dt>
+<dd>Direcci��n IP.</dd>
+</dlentry></dl></p>
+<p>Se pueden seleccionar las siguientes acciones:<ul>
+<li rev="rev1">Seleccione <uicontrol>Iniciar</uicontrol> para
iniciar la conexi��n de red.</li>
+<li>Seleccione <uicontrol>Detener</uicontrol> para finalizar la
conexi��n de red.</li>
+<li>Seleccione <uicontrol>Suprimir</uicontrol> para suprimir la
informaci��n de conexi��n.</li>
+</ul>Para crear una red, pulse en el icono <uicontrol>m��s
(+)</uicontrol> en la esquina superior derecha de la pantalla.</p>
+</csbody>
+<cshelp id="kimhnetwcrt" xml:lang="es-es">
+<title>Crear una red</title>
+<shortdesc>Crear una red.</shortdesc>
+<csbody>
+<p> <ol>
+<li>Escriba el nombre de la red.</li>
+<li>Pulse para seleccionar el tipo de red. <dl
rev="rev1"><dlentry>
+<dt><uicontrol>Aislada</uicontrol></dt>
+<dd>Modalidad aislada. Los invitados no pueden enviar ni recibir comunicaci��n a
sistemas externos o desde ellos.</dd>
+</dlentry><dlentry>
+<dt><uicontrol>NAT</uicontrol></dt>
+<dd>Modalidad de Conversi��n de direcciones de red. La comunicaci��n de invitados a
sistemas externos utiliza la direcci��n IP del host. Los sistemas externos no pueden
iniciar la comunicaci��n con los invitados.</dd>
+</dlentry><dlentry>
+<dt><uicontrol>Puenteada</uicontrol></dt>
+<dd>Modalidad puenteada. Los invitados pueden comunicarse con sistemas externos y
ser contactados por sistemas externos como si fueran sistemas f��sicos en la red. Para la
modalidad puenteada, debe especificar informaci��n de destino y VLAN
adicional.</dd>
+</dlentry></dl></li>
+<li>Pulse <uicontrol>Crear</uicontrol>.</li>
+</ol> </p>
+</csbody>
+</cshelp>
+</cshelp>
+
+
+<!-- ENGL1SH_VERS10N 47050_3 DO NOT REMOVE OR CHANGE THIS LINE -->
+<!-- T9N_SRC_ID 230 -->
+<!-- T9N_SH1P_STR1NG KVM21AAP001 3 -->
diff --git a/src/wok/plugins/kimchi/ui/pages/help/es_ES/storage.dita
b/src/wok/plugins/kimchi/ui/pages/help/es_ES/storage.dita
new file mode 100644
index 0000000..0c68951
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/pages/help/es_ES/storage.dita
@@ -0,0 +1,86 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--Arbortext, Inc., 1988-2011, v.4002-->
+<!DOCTYPE cshelp PUBLIC "-//IBM//DTD DITA CSHelp//EN"
+ "..\dtd\cshelp.dtd">
+
+
+<!--This DITA specialized document type is not supported by the Authoring Tools
development team.
+For support please see:
+https://w3.opensource.ibm.com/projects/dita-cshelp/-->
+<cshelp id="kimhstor" xml:lang="es-es">
+<title>Almacenamiento</title>
+<shortdesc>La p��gina <wintitle>Almacenamiento</wintitle> lista las
agrupaciones de almacenamiento disponibles, incluyendo la agrupaci��n de almacenamiento
predefinida 'default' e 'ISO'.
+Si desea utilizar su propia ISO, a����dala a la v��a de acceso de la agrupaci��n de
almacenamiento 'ISO'.</shortdesc>
+<csbody>
+<p>Se visualiza la siguiente informaci��n para cada agrupaci��n de
almacenamiento:<dl>
+<dlentry>
+<dt>Nombre</dt>
+<dd>Nombre de la agrupaci��n de almacenamiento y el porcentaje
utilizado.</dd>
+</dlentry><dlentry>
+<dt>Estado</dt>
+<dd>Estado de la agrupaci��n de almacenamiento, activa (verde) o inactiva (rojo).
</dd>
+</dlentry><dlentry>
+<dt>Ubicaci��n</dt>
+<dd>V��a de acceso de archivo a la ubicaci��n de la agrupaci��n de
almacenamiento.</dd>
+</dlentry><dlentry>
+<dt>Tipo</dt>
+<dd>Tipo de agrupaci��n de almacenamiento, por ejemplo,
<uicontrol>dir</uicontrol>.</dd>
+</dlentry><dlentry>
+<dt>Capacidad</dt>
+<dd>Cantidad de espacio en la agrupaci��n de almacenamiento.</dd>
+</dlentry><dlentry>
+<dt>Asignado</dt>
+<dd>Cantidad de espacio que ya est�� asignado en la agrupaci��n de
almacenamiento.</dd>
+</dlentry></dl></p>
+<p>Se pueden seleccionar las siguientes acciones para cada agrupaci��n de
almacenamiento:<ul>
+<li>Seleccione <uicontrol>Activar</uicontrol> para activar la
agrupaci��n de almacenamiento para que pueda utilizarse.</li>
+<li>Seleccione <uicontrol>Desactivar</uicontrol> para desactivar una
agrupaci��n de almacenamiento activa.</li>
+<li>Seleccione <uicontrol>No definir</uicontrol> para eliminar una
agrupaci��n de almacenamiento inactiva.</li>
+</ul></p>
+<p>Para visualizar detalles de volumen de almacenamiento para una agrupaci��n de
almacenamiento, pulse la flecha situada en el lado derecho de la fila de agrupaci��n de
almacenamiento. Los detalles incluyen lo siguiente:<dl><dlentry>
+<dt>Tipo</dt>
+<dd>El tipo de volumen, por ejemplo,
<uicontrol>archivo</uicontrol>.</dd>
+</dlentry><dlentry>
+<dt>Formato</dt>
+<dd>El formato, variable dependiendo del tipo.</dd>
+</dlentry><dlentry>
+<dt>Capacidad</dt>
+<dd>Tama��o del volumen de almacenamiento.</dd>
+</dlentry><dlentry>
+<dt>Asignaci��n</dt>
+<dd>Cantidad de espacio que ya est�� asignado en la agrupaci��n de
almacenamiento.</dd>
+</dlentry></dl>Para definir una agrupaci��n de almacenamiento, pulse en el
icono <uicontrol>m��s (+)</uicontrol> en la esquina superior derecha de la
pantalla.</p>
+</csbody>
+<cshelp id="kimhdefstor" xml:lang="es-es">
+<title>Definir una agrupaci��n de almacenamiento</title>
+<shortdesc> Definir una agrupaci��n de almacenamiento.</shortdesc>
+<csbody>
+<p> <ol>
+<li>En el campo <uicontrol>Nombre de agrupaci��n de
almacenamiento</uicontrol>, escriba el nombre que se utilizar�� para identificar la
agrupaci��n de almacenamiento.</li>
+<li>En la lista <uicontrol>Tipo de agrupaci��n
almacenamiento</uicontrol>, seleccione el tipo: <dl><dlentry>
+<dt><uicontrol>DIR</uicontrol></dt>
+<dd>Especifica una agrupaci��n de directorio. Al seleccionar
<uicontrol>DIR</uicontrol>, escriba la <uicontrol>V��a de acceso de
almacenamiento</uicontrol> (v��a de acceso de archivo a la agrupaci��n de
almacenamiento).</dd>
+</dlentry><dlentry>
+<dt><uicontrol>NFS</uicontrol></dt>
+<dd>Especifica una agrupaci��n de sistema de archivos de red. Al seleccionar
<uicontrol>NFS</uicontrol>, escriba la direcci��n <uicontrol>IP de
servidor NFS</uicontrol> y <uicontrol>v��a de acceso de NFS</uicontrol>
(v��a de acceso del directorio exportado).</dd>
+</dlentry><dlentry>
+<dt><uicontrol>iSCSI</uicontrol></dt>
+<dd>Especifica una agrupaci��n basada en un destino asignado en un servidor iSCSI.
+Al seleccionar <uicontrol>iSCSI</uicontrol>, escriba la direcci��n IP del
<uicontrol>Servidor iSCSI</uicontrol> y el
<uicontrol>Destino</uicontrol> en el servidor iSCSI. Opcionalmente puede
seleccionar a��adir autenticaci��n iSCSI.</dd>
+</dlentry><dlentry>
+<dt><uicontrol>L��gico</uicontrol></dt>
+<dd>Especifica una agrupaci��n de almacenamiento de volumen l��gico. Seleccione la
ubicaci��n al dispositivo en <uicontrol>V��a de acceso de
dispositivo</uicontrol>.</dd>
+</dlentry><dlentry>
+<dt><uicontrol>Canal de fibra de SCSI</uicontrol></dt>
+<dd>Especifica una agrupaci��n basada en un Canal de fibra SCSI. Seleccione qu��
adaptador SCSI se utilizar��.</dd>
+</dlentry></dl></li>
+<li>Pulse <uicontrol>Crear</uicontrol>.</li>
+</ol> </p>
+</csbody>
+</cshelp>
+</cshelp>
+
+
+<!-- ENGL1SH_VERS10N 22336_4 DO NOT REMOVE OR CHANGE THIS LINE -->
+<!-- T9N_SRC_ID 233 -->
+<!-- T9N_SH1P_STR1NG KV211AAP001 1 -->
diff --git a/src/wok/plugins/kimchi/ui/pages/help/es_ES/templates.dita
b/src/wok/plugins/kimchi/ui/pages/help/es_ES/templates.dita
new file mode 100644
index 0000000..8cceee7
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/pages/help/es_ES/templates.dita
@@ -0,0 +1,111 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--Arbortext, Inc., 1988-2011, v.4002-->
+<!DOCTYPE cshelp PUBLIC "-//IBM//DTD DITA CSHelp//EN"
+ "..\dtd\cshelp.dtd">
+
+
+<!--This DITA specialized document type is not supported by the Authoring Tools
development team.
+For support please see:
+https://w3.opensource.ibm.com/projects/dita-cshelp/-->
+<cshelp id="kimhtempl" xml:lang="es-es">
+<title>Plantillas</title>
+<shortdesc>La p��gina <wintitle>Plantillas</wintitle> muestra las
plantillas de m��quina virtual definidas que se pueden utilizar para crear invitados
KVM.</shortdesc>
+<csbody>
+<p>Se visualiza la siguiente informaci��n para cada plantilla:<dl>
+<dlentry>
+<dt>SO</dt>
+<dd>Nombre del sistema operativo o distribuci��n.</dd>
+</dlentry><dlentry>
+<dt>Versi��n</dt>
+<dd>Versi��n del sistema operativo o distribuci��n.</dd>
+</dlentry><dlentry>
+<dt>CPUs</dt>
+<dd>N��mero de procesadores que est��n definidos para la plantilla.</dd>
+</dlentry><dlentry>
+<dt>Memoria</dt>
+<dd>Cantidad de memoria de acceso aleatorio a asignar, en MB.</dd>
+</dlentry></dl></p>
+<p>Se pueden seleccionar las siguientes acciones para cada plantilla:<ul>
+<li>Seleccione <uicontrol>Editar</uicontrol> para editar la
plantilla.</li>
+<li>Seleccione <uicontrol>Suprimir</uicontrol> para suprimir la
plantilla.</li>
+</ul>Para a��adir una plantilla, pulse en el icono <uicontrol>m��s
(+)</uicontrol> en la esquina superior derecha de la pantalla.</p>
+</csbody>
+<cshelp id="kimhedittempl" xml:lang="es-es">
+<title>Editar plantilla</title>
+<shortdesc>Editar una plantilla existente.</shortdesc>
+<csbody>
+<p>Se visualiza la siguiente informaci��n para cada plantilla: <dl>
+<dlentry>
+<dt>Nombre</dt>
+<dd>Nombre de la plantilla.</dd>
+</dlentry><dlentry>
+<dt>Proveedor</dt>
+<dd>El nombre de la empresa que cre�� el sistema operativo o distribuci��n que la
plantilla est�� configurada para utilizar.</dd>
+</dlentry><dlentry>
+<dt>Versi��n</dt>
+<dd>La versi��n del sistema operativo o distribuci��n que la plantilla est��
configurada para utilizar.</dd>
+</dlentry><dlentry>
+<dt>N��mero de CPU</dt>
+<dd>N��mero de procesadores que est��n definidos para la plantilla.</dd>
+</dlentry><dlentry>
+<dt>Memoria</dt>
+<dd>Cantidad de memoria en MB a asignar a la m��quina virtual.</dd>
+</dlentry><dlentry>
+<dt>Disco</dt>
+<dd>Tama��o de disco en GB.</dd>
+</dlentry><dlentry>
+<dt>CDROM</dt>
+<dd>V��a de acceso de archivo a la ubicaci��n del archivo ISO utilizado para
instalar el invitado KVM.</dd>
+</dlentry><dlentry>
+<dt>Agrupaci��n de almacenamiento</dt>
+<dd>Agrupaci��n de almacenamiento espec��fica o la agrupaci��n de almacenamiento
predeterminada.</dd>
+</dlentry><dlentry>
+<dt>Red</dt>
+<dd>Interfaces de red predeterminadas disponibles para el invitado KVM. Puede
seleccionar varias redes.</dd>
+</dlentry></dl> Los campos que no est��n inhabilitados pueden editarse.
Despu��s de editar un campo, pulse <uicontrol>Guardar</uicontrol>. </p>
+</csbody>
+</cshelp>
+<cshelp id="kimhaddtempl">
+<title>A��adir plantilla</title>
+<shortdesc>A��adir una plantilla desde el soporte de origen. Puede a��adir su
propia imagen ISO a la agrupaci��n de almacenamiento 'ISO' para el siguiente
descubrimiento.</shortdesc>
+<csbody>
+<p>Seleccione la ubicaci��n del soporte de origen entre una de las opciones
siguientes:<dl>
+<dlentry>
+<dt>Imagen ISO local</dt>
+<dd>Seleccione esta opci��n para explorar las agrupaciones de almacenamiento en
busca de im��genes ISO de instalaci��n disponibles en el sistema.</dd>
+</dlentry><dlentry>
+<dt>Imagen ISO remota</dt>
+<dd>Seleccione esta opci��n para especificar una ubicaci��n remota para una imagen
ISO de instalaci��n.</dd>
+</dlentry></dl></p>
+</csbody>
+</cshelp>
+<cshelp id="kimhaddloct">
+<title>A��adir plantilla ��� imagen ISO local</title>
+<shortdesc>A��adir una plantilla desde una imagen ISO local.</shortdesc>
+<csbody>
+<p>Se visualizan las im��genes ISO disponibles en el
sistema.<dl><dlentry>
+<dt>SO</dt>
+<dd>Nombre del sistema operativo o distribuci��n.</dd>
+</dlentry><dlentry>
+<dt>Versi��n</dt>
+<dd>Versi��n del sistema operativo o distribuci��n.</dd>
+</dlentry><dlentry>
+<dt>Tama��o</dt>
+<dd>Tama��o de la imagen ISO.</dd>
+</dlentry></dl></p>
+<p>Para crear una plantilla a partir de una imagen ISO, elija entre las opciones
siguientes:<ul>
+<li>Seleccione una imagen ISO desde la que desea crear una plantilla y, a
continuaci��n, pulse <uicontrol>Crear plantillas desde ISO
seleccionada</uicontrol>.</li>
+<li>Seleccione <uicontrol>Todo</uicontrol> para crear una plantilla
desde cada imagen ISO en la lista y, a continuaci��n, pulse <uicontrol>Crear
plantillas desde ISO seleccionada</uicontrol>.</li>
+<li>Si la imagen ISO que desea utilizar no aparece en los resultados de la
exploraci��n, puede seleccionar entre las opciones siguientes:<ul>
+<li>Seleccione <uicontrol>Deseo utilizar un archivo ISO
espec��fico</uicontrol> para especificar una v��a de acceso a la imagen
ISO.</li>
+<li>Pulse <uicontrol>Buscar m��s ISO</uicontrol> para buscar m��s
im��genes ISO.</li>
+</ul></li>
+</ul></p>
+</csbody>
+</cshelp>
+</cshelp>
+
+
+<!-- ENGL1SH_VERS10N 61085_5 DO NOT REMOVE OR CHANGE THIS LINE -->
+<!-- T9N_SRC_ID 229 -->
+<!-- T9N_SH1P_STR1NG KV211AAP001 1 -->
diff --git a/src/wok/plugins/kimchi/ui/pages/help/fr_FR/Makefile.am
b/src/wok/plugins/kimchi/ui/pages/help/fr_FR/Makefile.am
new file mode 100644
index 0000000..11ce394
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/pages/help/fr_FR/Makefile.am
@@ -0,0 +1,23 @@
+# Copyright IBM Corp, 2014
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+fr_FR_helpdir = $(datadir)/wok/plugins/kimchi/ui/pages/help/fr_FR
+
+dist_fr_FR_help_DATA = $(wildcard *.html) $(NULL)
+
+EXTRA_DIST = $(wildcard *.dita)
+
+CLEANFILES = $(wildcard *.html)
diff --git a/src/wok/plugins/kimchi/ui/pages/help/fr_FR/guests.dita
b/src/wok/plugins/kimchi/ui/pages/help/fr_FR/guests.dita
new file mode 100644
index 0000000..ad5b4e4
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/pages/help/fr_FR/guests.dita
@@ -0,0 +1,130 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--Arbortext, Inc., 1988-2011, v.4002-->
+<!DOCTYPE cshelp PUBLIC "-//IBM//DTD DITA CSHelp//EN"
+ "..\dtd\cshelp.dtd">
+
+
+<!--This DITA specialized document type is not supported by the Authoring Tools
development team.
+For support please see:
+https://w3.opensource.ibm.com/projects/dita-cshelp/-->
+<cshelp id="kimhvirtm" xml:lang="fr-fr">
+<title>Invit��s</title>
+<shortdesc>La page <wintitle>Invit��s</wintitle> r��pertorie les
machines virtuelles KVM d��finies.</shortdesc>
+<csbody>
+<p>Pour chaque invit��, les informations suivantes sont affich��es
:<dl><dlentry>
+<dt>Nom</dt>
+<dd>Nom de la machine virtuelle.</dd>
+</dlentry><dlentry>
+<dt>UC</dt>
+<dd>Pourcentage d'utilisation du processeur sur la machine
virtuelle.</dd>
+</dlentry><dlentry>
+<dt>E-S r��seau</dt>
+<dd>Vitesse de transmission d'entr��e-sortie du r��seau, exprim��e en ko par
seconde.</dd>
+</dlentry><dlentry>
+<dt>E-S disque</dt>
+<dd>Vitesse de transmission d'entr��e-sortie du disque, exprim��e en ko par
seconde.</dd>
+</dlentry><dlentry>
+<dt>Livetile</dt>
+<dd>Etat de la console du syst��me d'exploitation de l'h��te, ou
+ic��ne repr��sentant la distribution <tm tmtype="tm"
trademark="Linux">Linux</tm>
+si l'invit�� n'est pas actif.</dd>
+</dlentry></dl></p>
+<p>Les ic��nes d'action suivantes sont affich��es pour chaque invit��
:<dl>
+<dlentry>
+<dt>R��initialiser</dt>
+<dd>Cliquez pour r��initialiser l'invit��. </dd>
+</dlentry><dlentry>
+<dt>Alimentation (D��marrer ou Arr��ter)</dt>
+<dd>Cliquez pour mettre sous ou hors tension l'invit��. Si l'ic��ne est
rouge,
+l'alimentation est d��marr��e ; si l'ic��ne est verte, l'alimentation est
arr��t��e.</dd>
+</dlentry></dl> </p>
+<p>Les actions suivantes peuvent ��tre s��lectionn��es pour chaque invit��
:<ul>
+<li>S��lectionnez <uicontrol>Connexion</uicontrol> pour vous connecter
�� la console
+distante du syst��me d'exploitation invit��.</li>
+<li>S��lectionnez <uicontrol>G��rer le support</uicontrol> pour
modifier le chemin
+d'acc��s au support d'installation.</li>
+<li>S��lectionnez <uicontrol>R��initialiser</uicontrol> pour
r��initialiser l'invit��.</li>
+<li>S��lectionnez <uicontrol>Editer</uicontrol> pour ��diter les
propri��t��s d'un invit�� existant. Les invit��s peuvent ��tre ��dit��s uniquement
lorsqu'ils sont �� l'arr��t.</li>
+<li>S��lectionnez <uicontrol>Supprimer</uicontrol> pour supprimer
l'invit��.</li>
+</ul>Pour cr��er un invit��, cliquez sur l'ic��ne <uicontrol>plus
(+)</uicontrol>
+dans le coin sup��rieur droit de la page.</p>
+</csbody>
+<cshelp id="kimhvirtmcrt" xml:lang="fr-fr">
+<title>Cr��er une machine virtuelle</title>
+<shortdesc>Cr��ez une machine virtuelle en utilisant un mod��le
existant.</shortdesc>
+<csbody>
+<p> <ol>
+<li>Entrez le nom �� utiliser pour identifier la machine virtuelle.</li>
+<li rev="rev1">S��lectionnez un mod��le. <ul>
+<li>Si des mod��les existent, faites un choix parmi les mod��les
affich��s.</li>
+<li>Si aucun mod��le n'existe, cliquez sur <uicontrol>Cr��er un
mod��le</uicontrol> pour cr��er un mod��le.</li>
+</ul></li>
+<li>Cliquez sur <uicontrol>Cr��er</uicontrol>.</li>
+</ol> </p>
+</csbody>
+</cshelp>
+<cshelp id="kimhvirtmedit" xml:lang="fr-fr">
+<title>Editer l'invit��</title>
+<shortdesc>Editez les propri��t��s d'une machine virtuelle existante. Certaines
propri��t��s
+peuvent ��tre ��dit��es uniquement lorsque l'invit�� est arr��t��. D'autres
seront appliqu��es �� l'amor��age suivant.</shortdesc>
+<csprolog><csmetadata></csmetadata></csprolog>
+<csbody>
+<p>Pour chaque invit��, les informations suivantes sont affich��es dans
l'onglet <wintitle>G��n��ral</wintitle> :<dl>
+<dlentry>
+<dt>Nom</dt>
+<dd>Nom de la machine virtuelle. (Ne peut ��tre ��dit�� que lorsque l'invit��
est arr��t��)</dd>
+</dlentry><dlentry>
+<dt>UC</dt>
+<dd>Nombre de processeurs. (Si l'invit�� est en cours d'ex��cution, la
nouvelle quantit�� sera appliqu��e �� l'amor��age suivant)</dd>
+</dlentry><dlentry>
+<dt>M��moire</dt>
+<dd>Quantit�� de m��moire en Mo. (Si l'invit�� est en cours d'ex��cution,
la nouvelle quantit�� sera appliqu��e �� l'amor��age suivant)</dd>
+</dlentry><dlentry>
+<dt>Ic��ne</dt>
+<dd>Image graphique repr��sentant la distribution Linux �� afficher �� la place
+du statut en cours (Livetile) lorsque l'invit�� n'est pas actif.</dd>
+</dlentry></dl></p>
+<p>Les informations suivantes sont affich��es dans l'onglet
<wintitle>Stockage</wintitle>.</p>
+<dl><dlentry>
+<dt>Stockage</dt>
+<dd>Affiche l'emplacement du fichier ISO utilis�� pour
l'installation.</dd>
+</dlentry></dl>
+<p> Les zones qui ne sont pas d��sactiv��es peuvent ��tre ��dit��es. Apr��s que
vous avez ��dit�� une zone, cliquez sur <uicontrol>Sauvegarder</uicontrol>.
</p>
+</csbody>
+</cshelp>
+<cshelp id="kimstoragedevice" xml:lang="fr-fr">
+<title>Ajoutez, remplacez ou d��tachez une unit�� de stockage</title>
+<shortdesc rev="rev1">Vous pouvez ajouter, remplacer ou d��tacher une
unit�� de stockage
+pour votre machine virtuelle. Seule une unit�� CD-ROM est prise en charge. Pour ��diter
vos unit��s de stockage, proc��dez comme suit :</shortdesc>
+<csbody>
+<ol>
+<li>Dans la fen��tre <wintitle>Editer l'invit��</wintitle>,
s��lectionnez <wintitle>Stockage</wintitle>.</li>
+<li>Pour remplacer une unit�� de stockage, cliquez sur la premi��re ic��ne avec la
<uicontrol>barre oblique (/) orange</uicontrol>. Entrez le chemin d'acc��s
au fichier ISO et cliquez sur <uicontrol>Remplacer</uicontrol>.</li>
+<li>Pour d��tacher une unit�� de stockage, cliquez sur la deuxi��me ic��ne avec le
<uicontrol>tiret (-) rouge</uicontrol>. Confirmer la suppression et cliquez
sur <uicontrol>OK</uicontrol>.</li>
+<li>Pour ajouter une unit�� de stockage, cliquez sur la troisi��me ic��ne avec le
<uicontrol>signe plus (+) vert</uicontrol>. Entrez un nom d'unit�� et un
chemin d'acc��s au fichier ISO puis cliquez sur
<uicontrol>Attacher</uicontrol>.</li>
+</ol>
+</csbody>
+</cshelp>
+<cshelp id="kimreplacemedia" xml:lang="fr-fr">
+<title>Remplacer l'unit�� CD-ROM d'une machine virtuelle</title>
+<shortdesc rev="rev1">Vous pouvez remplacer le contenu du CD-ROM pour
+une machine virtuelle une fois l'installation termin��e.</shortdesc>
+<csbody>
+<ol>
+<li>V��rifiez que la machine virtuelle est d��marr��e.</li>
+<li>Dans le menu Actions, s��lectionnez <uicontrol>G��rer le
support</uicontrol>.</li>
+<li>Pour modifier les donn��es actuellement charg��es dans l'unit�� de CD-ROM,
cliquez sur l'ic��ne
+<uicontrol>barre oblique (/) orange</uicontrol> en regard de la zone
hdc.</li>
+<li>Sur la page <wintitle>Remplacer une unit�� CD-ROM d'une machine
virtuelle</wintitle>,
+entrez le chemin d'acc��s au fichier ISO. Les deux autres zones sont en lecture
seule.</li>
+<li>Cliquez sur <uicontrol>Remplacer</uicontrol>.</li>
+</ol>
+</csbody>
+</cshelp>
+<?tm 1391540919 3?>
+</cshelp>
+
+
+<!-- ENGL1SH_VERS10N 45645_6 DO NOT REMOVE OR CHANGE THIS LINE -->
+<!-- T9N_SRC_ID 231 -->
+<!-- T9N_SH1P_STR1NG KV211AAP001 1 -->
diff --git a/src/wok/plugins/kimchi/ui/pages/help/fr_FR/host.dita
b/src/wok/plugins/kimchi/ui/pages/help/fr_FR/host.dita
new file mode 100644
index 0000000..f4c330b
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/pages/help/fr_FR/host.dita
@@ -0,0 +1,68 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--Arbortext, Inc., 1988-2011, v.4002-->
+<!DOCTYPE cshelp PUBLIC "-//IBM//DTD DITA CSHelp//EN"
+ "..\dtd\cshelp.dtd">
+
+
+<!--This DITA specialized document type is not supported by the Authoring Tools
development team.
+For support please see:
+https://w3.opensource.ibm.com/projects/dita-cshelp/-->
+<cshelp id="kimhhost" xml:lang="fr-fr">
+<title>H��te</title>
+<shortdesc>La page <wintitle>H��te</wintitle> affiche des informations
+sur le syst��me h��te et vous permet d'arr��ter, de red��marrer et de vous
+connecter �� l'h��te.</shortdesc>
+<csbody>
+<p>Vous pouvez effectuer les actions suivantes sur l'h��te :<ul>
+<li>S��lectionnez <uicontrol>Arr��ter</uicontrol> pour arr��ter le
syst��me h��te.</li>
+<li>S��lectionnez <uicontrol>Red��marrer</uicontrol> pour red��marrer
le syst��me h��te.</li>
+<li>S��lectionnez <uicontrol>Connexion</uicontrol> pour ouvrir une
connexion VNC
+au syst��me h��te, si celui-ci n'est pas d��j�� connect��.</li>
+</ul></p>
+<p>Cliquez sur les sections suivantes pour afficher des informations sur
l'h��te :<dl>
+<dlentry>
+<dt>Informations de base</dt>
+<dd>Cette section affiche la distribution, la version et le nom de code
+du syst��me d'exploitation h��te, ainsi que le type de processeur et la quantit��
+de m��moire en Go.</dd>
+</dlentry><dlentry>
+<dt>Statistiques syst��me</dt>
+<dd>Cette section affiche les graphiques des statistiques pour l'UC, m��moire,
ainsi que
+les E-S disque et E-S r��seau pour l'h��te. S��lectionnez <uicontrol>Collecte
des donn��es une fois la page quitt��e</uicontrol>
+pour continuer la collecte de donn��es lorsque l'onglet h��te n'est plus
visible.</dd>
+</dlentry><dlentry>
+<dt>Mises �� jour logicielles</dt>
+<dd>Cette section affiche des informations pour tous les modules qui
+disposent de mises �� jour disponibles, y compris le nom de module, la version,
l'architecture
+et le r��f��rentiel. Vous pouvez mettre �� jour toutes les modules r��pertori��s en
s��lectionnant <uicontrol>Tout
+mettre �� jour</uicontrol>. Vous ne pouvez pas s��lectionner des modules
individuels pour les mises �� jour.</dd>
+</dlentry><dlentry>
+<dt>R��f��rentiels</dt>
+<dd>Cette section affiche les r��f��rentiels associ��s au syst��me h��te. Vous
pouvez ajouter, activer, ��diter ou retirer des r��f��rentiels. L'ajout d'un
r��f��rentiel associe celui-ci au syst��me h��te,
+tandis que l'activation d'un r��f��rentiel permet �� l'h��te d'y
acc��der. Si votre syst��me est Red Hat Enterprise Linux ou Fedora,
+vous pouvez ajouter des r��f��rentiels <filepath>yum</filepath>.
+Si votre syst��me est de type Ubuntu ou Debian, ajoutez des r��f��rentiels
+<filepath>deb</filepath>.<p>Si vous travaillez avec des r��f��rentiels
yum, vous pouvez ajouter un contr��le GPG
+afin de v��rifier qu'un module provenant de ce r��f��rentiel n'a pas ��t��
endommag��.
+S��lectionnez un r��f��rentiel puis cliquez sur
<uicontrol>Editer</uicontrol>. S��lectionnez
<uicontrol>Oui</uicontrol> pour activer le contr��le GPG,
+puis entrez une URL pour le fichier de cl��s GPG du r��f��rentiel.</p></dd>
+</dlentry><dlentry>
+<dt>Rapports de d��bogage</dt>
+<dd>Cette section affiche les rapports de d��bogage, y compris le nom et le chemin
du fichier.
+Vous pouvez faire un choix parmi les options afin de g��n��rer un nouveau rapport, ou
renommer, supprimer,
+ou t��l��charger un rapport existant.<p>Le rapport de d��bogage est g��n��r�� ��
+l'aide de la commande <cmdname>sosreport</cmdname>. Cette option est
disponible pour les distributions
+Red Hat Enterprise <tm tmtype="tm"
trademark="Linux">Linux</tm>, Fedora et Ubuntu. La commande g��n��re un
fichier .tar contenant la configuration et des informations de diagnostic,
+telles que la version du noyau d'ex��cution, les modules charg��s, ainsi que les
fichiers de configuration
+du syst��me et de la maintenance.
+La commande ex��cute ��galement des programmes externes pour collecter des informations
+suppl��mentaires et stocke cette sortie dans l'archive r��sultante.</p>
</dd>
+</dlentry></dl></p>
+</csbody>
+<?tm 1392659967 1?>
+</cshelp>
+
+
+<!-- ENGL1SH_VERS10N 47930_4 DO NOT REMOVE OR CHANGE THIS LINE -->
+<!-- T9N_SRC_ID 232 -->
+<!-- T9N_SH1P_STR1NG KVM21AAP001 3 -->
diff --git a/src/wok/plugins/kimchi/ui/pages/help/fr_FR/network.dita
b/src/wok/plugins/kimchi/ui/pages/help/fr_FR/network.dita
new file mode 100644
index 0000000..5c2e9dd
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/pages/help/fr_FR/network.dita
@@ -0,0 +1,67 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--Arbortext, Inc., 1988-2011, v.4002-->
+<!DOCTYPE cshelp PUBLIC "-//IBM//DTD DITA CSHelp//EN"
+ "..\dtd\cshelp.dtd">
+
+
+<!--This DITA specialized document type is not supported by the Authoring Tools
development team.
+For support please see:
+https://w3.opensource.ibm.com/projects/dita-cshelp/-->
+<cshelp id="kimhnetw" xml:lang="fr-fr">
+<title>R��seau</title>
+<shortdesc>La page <wintitle>R��seau</wintitle> affiche des
informations sur la connexion r��seau.</shortdesc>
+<csbody>
+<p><dl><dlentry>
+<dt>Nom du r��seau</dt>
+<dd>Nom du r��seau, ou <uicontrol>par d��faut</uicontrol>.</dd>
+</dlentry><dlentry>
+<dt>Etat</dt>
+<dd>Etat du r��seau, actif (vert) ou inactif (rouge). </dd>
+</dlentry><dlentry>
+<dt>Type de r��seau</dt>
+<dd>Type du r��seau, par exemple <uicontrol>NAT</uicontrol> (conversion
d'adresses r��seau).</dd>
+</dlentry><dlentry>
+<dt>Interface</dt>
+<dd>Interface r��seau, par exemple <uicontrol>virbr0</uicontrol> (par
d��faut).</dd>
+</dlentry><dlentry>
+<dt>Espace adresse</dt>
+<dd>Adresse IP.</dd>
+</dlentry></dl></p>
+<p>Les actions suivantes peuvent ��tre s��lectionn��es :<ul>
+<li rev="rev1">S��lectionnez <uicontrol>D��marrer</uicontrol>
pour d��marrer la connexion au r��seau.</li>
+<li>S��lectionnez <uicontrol>Arr��ter</uicontrol> pour mettre fin �� la
connexion au r��seau.</li>
+<li>S��lectionnez <uicontrol>Supprimer</uicontrol> pour supprimer les
informations de connexion.</li>
+</ul>Pour cr��er un r��seau, cliquez sur l'ic��ne <uicontrol>plus
(+)</uicontrol>
+dans le coin sup��rieur droit de l'��cran.</p>
+</csbody>
+<cshelp id="kimhnetwcrt" xml:lang="fr-fr">
+<title>Cr��er un r��seau</title>
+<shortdesc>Cr��ez un r��seau.</shortdesc>
+<csbody>
+<p> <ol>
+<li>Entrez le nom du r��seau.</li>
+<li>Cliquez pour s��lectionner le type de r��seau. <dl
rev="rev1"><dlentry>
+<dt><uicontrol>Isol��</uicontrol></dt>
+<dd>Mode isol��. Les invit��s ne peuvent pas envoyer ni recevoir de communication
avec des syst��mes externes.</dd>
+</dlentry><dlentry>
+<dt><uicontrol>NAT</uicontrol></dt>
+<dd>Mode de conversion d'adresses r��seau. La communication �� partir
d'invit��s
+vers des syst��mes externes utilise l'adresse IP h��te. Les syst��mes externes ne
+peuvent pas initier de communication vers les invit��s.</dd>
+</dlentry><dlentry>
+<dt><uicontrol>Rout��</uicontrol></dt>
+<dd>Mode rout��. Les invit��s peuvent communiquer avec des syst��mes externes et
+��tre contact��s par des syst��mes externes comme s'il s'agissait de syst��mes
physiques
+sur le r��seau. Pour le mode rout��, vous devez sp��cifier des informations
suppl��mentaires
+sur la destination et le r��seau local virtuel.</dd>
+</dlentry></dl></li>
+<li>Cliquez sur <uicontrol>Cr��er</uicontrol>.</li>
+</ol> </p>
+</csbody>
+</cshelp>
+</cshelp>
+
+
+<!-- ENGL1SH_VERS10N 47050_3 DO NOT REMOVE OR CHANGE THIS LINE -->
+<!-- T9N_SRC_ID 230 -->
+<!-- T9N_SH1P_STR1NG KVM21AAP001 3 -->
diff --git a/src/wok/plugins/kimchi/ui/pages/help/fr_FR/storage.dita
b/src/wok/plugins/kimchi/ui/pages/help/fr_FR/storage.dita
new file mode 100644
index 0000000..eebf2bb
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/pages/help/fr_FR/storage.dita
@@ -0,0 +1,93 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--Arbortext, Inc., 1988-2011, v.4002-->
+<!DOCTYPE cshelp PUBLIC "-//IBM//DTD DITA CSHelp//EN"
+ "..\dtd\cshelp.dtd">
+
+
+<!--This DITA specialized document type is not supported by the Authoring Tools
development team.
+For support please see:
+https://w3.opensource.ibm.com/projects/dita-cshelp/-->
+<cshelp id="kimhstor" xml:lang="fr-fr">
+<title>Stockage</title>
+<shortdesc>La page <wintitle>Stockage</wintitle> r��pertorie les pools
de stockage disponibles,
+y compris les pools de stockage 'default' et 'ISO' pr��ts ��
l'emploi.
+Si vous souhaitez utiliser votre propre pool de stockage ISO, ajoutez-le dans le chemin
du pool de stockage 'ISO'.</shortdesc>
+<csbody>
+<p>Pour chaque pool de stockage, les informations suivantes sont affich��es
:<dl>
+<dlentry>
+<dt>Nom</dt>
+<dd>Nom du pool de stockage et pourcentage d'utilisation.</dd>
+</dlentry><dlentry>
+<dt>Etat</dt>
+<dd>Etat du pool de stockage, actif (vert) ou inactif (rouge). </dd>
+</dlentry><dlentry>
+<dt>Emplacement</dt>
+<dd>chemin d'acc��s au fichier pour l'emplacement du pool de
stockage.</dd>
+</dlentry><dlentry>
+<dt>Type</dt>
+<dd>Type de pool de stockage, par exemple
<uicontrol>dir</uicontrol>.</dd>
+</dlentry><dlentry>
+<dt>Capacit��</dt>
+<dd>Quantit�� d'espace dans le pool de stockage.</dd>
+</dlentry><dlentry>
+<dt>Allou��</dt>
+<dd>Quantit�� d'espace d��j�� allou��e dans le pool de stockage.</dd>
+</dlentry></dl></p>
+<p>Les actions suivantes peuvent ��tre s��lectionn��es pour chaque pool de
stockage :<ul>
+<li>S��lectionnez <uicontrol>Activer</uicontrol> pour activer le pool
de stockage pour utilisation.</li>
+<li>S��lectionnez <uicontrol>D��sactiver</uicontrol> pour d��sactiver
un pool de stockage actif.</li>
+<li>S��lectionnez <uicontrol>Annuler d��finition</uicontrol> pour
retirer un pool de stockage inactif.</li>
+</ul></p>
+<p>Pour afficher les d��tails de volume de stockage pour un pool de stockage,
cliquez sur la
+fl��che situ��e �� droite de la ligne du pool de stockage. D��tails inclus
:<dl><dlentry>
+<dt>Type</dt>
+<dd>Type de volume, par exemple
<uicontrol>file</uicontrol>.</dd>
+</dlentry><dlentry>
+<dt>Format</dt>
+<dd>Format, variable selon le type.</dd>
+</dlentry><dlentry>
+<dt>Capacit��</dt>
+<dd>Taille du volume de stockage.</dd>
+</dlentry><dlentry>
+<dt>Allocation</dt>
+<dd>Quantit�� d'espace d��j�� allou��e dans le pool de stockage.</dd>
+</dlentry></dl>Pour d��finir un pool de stockage, cliquez sur l'ic��ne
<uicontrol>plus (+)</uicontrol>
+dans le coin sup��rieur droit de l'��cran.</p>
+</csbody>
+<cshelp id="kimhdefstor" xml:lang="fr-fr">
+<title>D��finir un pool de stockage</title>
+<shortdesc> D��finissez un pool de stockage.</shortdesc>
+<csbody>
+<p> <ol>
+<li>Dans la zone <uicontrol>Nom du pool de stockage</uicontrol>, entrez
le nom �� utiliser pour identifier le pool de stockage.</li>
+<li>Dans la zone <uicontrol>Type de pool de stockage</uicontrol>,
s��lectionnez le type : <dl><dlentry>
+<dt><uicontrol>DIR</uicontrol></dt>
+<dd>Indique un pool de r��pertoires. Lorsque vous s��lectionnez
<uicontrol>DIR</uicontrol>,
+indiquez le <uicontrol>Chemin de stockage</uicontrol> (chemin d'acc��s au
fichier
+du pool de stockage).</dd>
+</dlentry><dlentry>
+<dt><uicontrol>NFS</uicontrol></dt>
+<dd>indique un pool de syst��mes de fichiers r��seau. Lorsque vous s��lectionnez
<uicontrol>NFS</uicontrol>,
+indiquez l'adresse <uicontrol>IP du serveur NFS</uicontrol> et le
<uicontrol>Chemin NFS</uicontrol> (chemin d'acc��s au r��pertoire
d'exportation).</dd>
+</dlentry><dlentry>
+<dt><uicontrol>iSCSI</uicontrol></dt>
+<dd>Indique un pool bas�� sur une cible allou��e sur un serveur iSCSI.
+Lorsque vous s��lectionnez <uicontrol>iSCSI</uicontrol>, indiquez
l'adresse IP du <uicontrol>Serveur iSCSI</uicontrol>
+et la <uicontrol>Cible</uicontrol> sur le serveur iSCSI. Vous avez la
possibilit�� d'ajouter l'authentification iSCSI.</dd>
+</dlentry><dlentry>
+<dt><uicontrol>Logique</uicontrol></dt>
+<dd>Indique un pool de stockage de volumes logiques. S��lectionnez
l'emplacement de l'unit�� dans <uicontrol>Chemin
d'unit��</uicontrol>.</dd>
+</dlentry><dlentry>
+<dt><uicontrol>Fibre Channel SCSI</uicontrol></dt>
+<dd>Indique un pool bas��e sur une connexion Fibre Channel SCSI. S��lectionnez
l'adaptateur SCSI �� utiliser.</dd>
+</dlentry></dl></li>
+<li>Cliquez sur <uicontrol>Cr��er</uicontrol>.</li>
+</ol> </p>
+</csbody>
+</cshelp>
+</cshelp>
+
+
+<!-- ENGL1SH_VERS10N 22336_4 DO NOT REMOVE OR CHANGE THIS LINE -->
+<!-- T9N_SRC_ID 233 -->
+<!-- T9N_SH1P_STR1NG KV211AAP001 1 -->
diff --git a/src/wok/plugins/kimchi/ui/pages/help/fr_FR/templates.dita
b/src/wok/plugins/kimchi/ui/pages/help/fr_FR/templates.dita
new file mode 100644
index 0000000..a517e33
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/pages/help/fr_FR/templates.dita
@@ -0,0 +1,120 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--Arbortext, Inc., 1988-2011, v.4002-->
+<!DOCTYPE cshelp PUBLIC "-//IBM//DTD DITA CSHelp//EN"
+ "..\dtd\cshelp.dtd">
+
+
+<!--This DITA specialized document type is not supported by the Authoring Tools
development team.
+For support please see:
+https://w3.opensource.ibm.com/projects/dita-cshelp/-->
+<cshelp id="kimhtempl" xml:lang="fr-fr">
+<title>Mod��les</title>
+<shortdesc>La page <wintitle>Mod��les</wintitle> affiche les mod��les
de machine virtuelle d��finis
+pouvant ��tre utilis��s pour cr��er des h��tes KVM.</shortdesc>
+<csbody>
+<p>Pour chaque mod��le, les informations suivantes sont affich��es :<dl>
+<dlentry>
+<dt>SE</dt>
+<dd>Nom du syst��me d'exploitation ou de la distribution.</dd>
+</dlentry><dlentry>
+<dt>Version</dt>
+<dd>Version du syst��me d'exploitation ou de la distribution.</dd>
+</dlentry><dlentry>
+<dt>UC</dt>
+<dd>Nombre de processeurs d��finis pour le mod��le.</dd>
+</dlentry><dlentry>
+<dt>M��moire</dt>
+<dd>Quantit�� de m��moire vive �� allouer, en Mo.</dd>
+</dlentry></dl></p>
+<p>Les actions suivantes peuvent ��tre s��lectionn��es pour chaque mod��le
:<ul>
+<li>S��lectionnez <uicontrol>Editer</uicontrol> pour ��diter le
mod��le.</li>
+<li>S��lectionnez <uicontrol>Supprimer</uicontrol> pour supprimer le
mod��le.</li>
+</ul>Pour ajouter un mod��le, cliquez sur l'ic��ne <uicontrol>plus
(+)</uicontrol>
+dans le coin sup��rieur droit de l'��cran.</p>
+</csbody>
+<cshelp id="kimhedittempl" xml:lang="fr-fr">
+<title>Editer un mod��le</title>
+<shortdesc>Editez un mod��le existant.</shortdesc>
+<csbody>
+<p>Pour chaque mod��le, les informations suivantes sont affich��es : <dl>
+<dlentry>
+<dt>Nom</dt>
+<dd>Nom du mod��le.</dd>
+</dlentry><dlentry>
+<dt>Fournisseur</dt>
+<dd>Nom de la soci��t�� qui a cr���� le syst��me d'exploitation ou la
distribution
+pour lequel/laquelle le mod��le est configur��.</dd>
+</dlentry><dlentry>
+<dt>Version</dt>
+<dd>Version du syst��me d'exploitation ou de la distribution
+pour lequel/laquelle le mod��le est configur��.</dd>
+</dlentry><dlentry>
+<dt>Nombre d'UC</dt>
+<dd>Nombre de processeurs d��finis pour le mod��le.</dd>
+</dlentry><dlentry>
+<dt>M��moire</dt>
+<dd>Quantit�� de m��moire en Mo �� allouer �� la machine virtuelle.</dd>
+</dlentry><dlentry>
+<dt>Disque</dt>
+<dd>Taille du disque en Go.</dd>
+</dlentry><dlentry>
+<dt>CD-ROM</dt>
+<dd>chemin d'acc��s au fichier pour l'emplacement du fichier ISO utilis��
pour l'installation de l'invit�� KVM.</dd>
+</dlentry><dlentry>
+<dt>Pool de stockage</dt>
+<dd>Pool de stockage sp��cifique ou pool de stockage par d��faut.</dd>
+</dlentry><dlentry>
+<dt>R��seau</dt>
+<dd>Interfaces r��seau par d��faut disponibles pour l'invit�� KVM. Vous pouvez
+s��lectionner plusieurs r��seaux.</dd>
+</dlentry></dl> Les zones qui ne sont pas d��sactiv��es peuvent ��tre
��dit��es. Apr��s que vous avez ��dit�� une zone, cliquez sur
<uicontrol>Sauvegarder</uicontrol>. </p>
+</csbody>
+</cshelp>
+<cshelp id="kimhaddtempl">
+<title>Ajouter un mod��le</title>
+<shortdesc>Ajoutez un mod��le �� partir du support source.
+Vous pouvez ajouter votre propre image ISO au pool de stockage 'ISO' pour la
reconnaissance suivante.</shortdesc>
+<csbody>
+<p>S��lectionnez l'emplacement du support source �� partir des options
suivantes :<dl>
+<dlentry>
+<dt>Image ISO locale</dt>
+<dd>S��lectionnez cette option pour rechercher dans les pools de stockage
l'image d'installation ISO disponible sur le syst��me.</dd>
+</dlentry><dlentry>
+<dt>Image ISO distante</dt>
+<dd>S��lectionnez cette option pour indiquer un emplacement distant pour une image
d'installation ISO.</dd>
+</dlentry></dl></p>
+</csbody>
+</cshelp>
+<cshelp id="kimhaddloct">
+<title>Ajouter un mod��le - Image ISO locale</title>
+<shortdesc>Ajoutez un mod��le �� partir d'une image ISO
locale.</shortdesc>
+<csbody>
+<p>Les images ISO disponibles sur le syst��me sont
affich��es.<dl><dlentry>
+<dt>SE</dt>
+<dd>Nom du syst��me d'exploitation ou de la distribution.</dd>
+</dlentry><dlentry>
+<dt>Version</dt>
+<dd>Version du syst��me d'exploitation ou de la distribution.</dd>
+</dlentry><dlentry>
+<dt>Taille</dt>
+<dd>Taille de l'image ISO.</dd>
+</dlentry></dl></p>
+<p>Pour cr��er un mod��le �� partir d'une image ISO, choisissez parmi les
options suivantes :<ul>
+<li>S��lectionnez une image ISO �� partir de laquelle cr��er un mod��le, puis
cliquez sur <uicontrol>Cr��er des mod��les �� partir de l'ISO s��lectionn��
</uicontrol>.</li>
+<li>S��lectionnez <uicontrol>Tout</uicontrol> pour cr��er un mod��le ��
partir de chaque
+image ISO r��pertori��e, puis cliquez sur <uicontrol>Cr��er des mod��les �� partir
de l'ISO s��lectionn��</uicontrol>.</li>
+<li>Si l'image ISO que vous souhaitez utiliser ne figure pas dans les
r��sultats
+d'analyse, vous pouvez faire un choix parmi les options suivantes :<ul>
+<li>S��lectionnez <uicontrol>Je souhaite utiliser un fichier ISO
sp��cifique</uicontrol> pour
+sp��cifier un chemin d'acc��s �� l'image ISO.</li>
+<li>Cliquez sur <uicontrol>Rechercher d'autres images
ISO</uicontrol> pour rechercher des images ISO suppl��mentaires.</li>
+</ul></li>
+</ul></p>
+</csbody>
+</cshelp>
+</cshelp>
+
+
+<!-- ENGL1SH_VERS10N 61085_5 DO NOT REMOVE OR CHANGE THIS LINE -->
+<!-- T9N_SRC_ID 229 -->
+<!-- T9N_SH1P_STR1NG KV211AAP001 1 -->
diff --git a/src/wok/plugins/kimchi/ui/pages/help/it_IT/Makefile.am
b/src/wok/plugins/kimchi/ui/pages/help/it_IT/Makefile.am
new file mode 100644
index 0000000..62e2f29
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/pages/help/it_IT/Makefile.am
@@ -0,0 +1,23 @@
+# Copyright IBM Corp, 2014
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+it_IT_helpdir = $(datadir)/wok/plugins/kimchi/ui/pages/help/it_IT
+
+dist_it_IT_help_DATA = $(wildcard *.html) $(NULL)
+
+EXTRA_DIST = $(wildcard *.dita)
+
+CLEANFILES = $(wildcard *.html)
diff --git a/src/wok/plugins/kimchi/ui/pages/help/it_IT/guests.dita
b/src/wok/plugins/kimchi/ui/pages/help/it_IT/guests.dita
new file mode 100644
index 0000000..e05db7e
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/pages/help/it_IT/guests.dita
@@ -0,0 +1,123 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--Arbortext, Inc., 1988-2011, v.4002-->
+<!DOCTYPE cshelp PUBLIC "-//IBM//DTD DITA CSHelp//EN"
+ "..\dtd\cshelp.dtd">
+
+
+<!--This DITA specialized document type is not supported by the Authoring Tools
development team.
+For support please see:
+https://w3.opensource.ibm.com/projects/dita-cshelp/-->
+<cshelp id="kimhvirtm" xml:lang="it-it">
+<title>Guest</title>
+<shortdesc>La pagina <wintitle>Guest</wintitle> elenca le macchine
virtuali
+KVM definite.</shortdesc>
+<csbody>
+<p>Per ciascuna macchina guest vengono visualizzate le seguenti
informazioni:<dl><dlentry>
+<dt>Nome</dt>
+<dd>Il nome della macchina virtuale.</dd>
+</dlentry><dlentry>
+<dt>CPU</dt>
+<dd>La percentuale di utilizzo del processore nella macchina virtuale.</dd>
+</dlentry><dlentry>
+<dt>I/O di rete</dt>
+<dd>La velocit�� di trasmissione dell'input/output di rete in KB al
secondo.</dd>
+</dlentry><dlentry>
+<dt>I/O disco</dt>
+<dd>La velocit�� di trasmissione dell'input/output disco in KB al
secondo.</dd>
+</dlentry><dlentry>
+<dt>Riquadro animato</dt>
+<dd>Lo stato della console del sistema operativo della macchina guest o
un'icona che rappresenta la distribuzione <tm tmtype="tm"
trademark="Linux">Linux</tm> se la macchina guest non ��
attiva.</dd>
+</dlentry></dl></p>
+<p>Per ciascuna macchina guest vengono visualizzate le icone di azioni indicate di
seguito:<dl>
+<dlentry>
+<dt>Reimposta</dt>
+<dd>Fare clic qui per reimpostare la macchina guest. </dd>
+</dlentry><dlentry>
+<dt>Alimentazione (Avvia o Arresta)</dt>
+<dd>Fare clic qui per accendere o spegnere la macchina guest. Se l'icona ��
rossa, la macchina �� spenta, se �� verde �� accesa.</dd>
+</dlentry></dl> </p>
+<p>Per ciascuna macchina guest �� possibile selezionare le azioni indicate di
seguito:<ul>
+<li>Selezionare <uicontrol>Connetti</uicontrol> per effettuare la
connessione alla console remota per il sistema operativo della macchina guest.</li>
+<li>Selezionare <uicontrol>Gestisci supporti</uicontrol> per modificare
il percorso al supporto di installazione.</li>
+<li>Selezionare <uicontrol>Reimposta</uicontrol> per reimpostare la
macchina guest.</li>
+<li>Selezionare <uicontrol>Modifica</uicontrol> per modificare le
propriet����di una macchina guest esistente. �� possibile modificare le macchine guest
solo se sono arrestate.</li>
+<li>Selezionare <uicontrol>Elimina</uicontrol> per eliminare la
macchina guest.</li>
+</ul>Per creare una macchina guest, o macchina virtuale, fare clic sull'icona
<uicontrol>pi��
+(+)</uicontrol> nella parte in alto a destra della pagina.</p>
+</csbody>
+<cshelp id="kimhvirtmcrt" xml:lang="it-it">
+<title>Creare una macchina virtuale</title>
+<shortdesc>Creare una macchina virtuale utilizzando un modello
esistente.</shortdesc>
+<csbody>
+<p> <ol>
+<li>Immettere il nome da utilizzare per identificare la macchina
virtuale.</li>
+<li rev="rev1">Selezionare un modello. <ul>
+<li>Se il modello esiste, selezionarlo dai modelli visualizzati.</li>
+<li>Se non esiste alcun modello, fare clic su <uicontrol>Crea un
modello</uicontrol> per crearne uno.</li>
+</ul></li>
+<li>Fare clic su <uicontrol>Crea</uicontrol>.</li>
+</ol> </p>
+</csbody>
+</cshelp>
+<cshelp id="kimhvirtmedit" xml:lang="it-it">
+<title>Modifica macchina guest</title>
+<shortdesc>Modificare le propriet�� di una macchina virtuale esistente. Alcune
propriet�� possono essere
+modificate solo mentre la macchina guest �� arrestata. Altre diventeranno effettive al
prossimo avvio.</shortdesc>
+<csprolog><csmetadata></csmetadata></csprolog>
+<csbody>
+<p>Per ciascuna macchina guest vengono visualizzate le seguenti informazioni sulla
scheda <wintitle>Generale</wintitle>:<dl>
+<dlentry>
+<dt>Nome</dt>
+<dd>Il nome della macchina virtuale. (Pu�� essere modificato solo mentre la
macchina guest �� arrestata)</dd>
+</dlentry><dlentry>
+<dt>CPU</dt>
+<dd>Il numero di processori. (Se la macchina guest �� in esecuzione, la nuova
quantit�� diventer�� effettiva
+al prossimo avvio)</dd>
+</dlentry><dlentry>
+<dt>Memoria</dt>
+<dd>La quantit�� di memoria in MB. (Se la macchina guest �� in esecuzione, la nuova
quantit�� diventer�� effettiva
+al prossimo avvio)</dd>
+</dlentry><dlentry>
+<dt>Icona</dt>
+<dd>L'immagine grafica che rappresenta la distribuzione Linux da visualizzare
al posto dello stato corrente (Riquadro animato) quando la macchina guest non ��
attiva.</dd>
+</dlentry></dl></p>
+<p>Sulla scheda <wintitle>Memoria</wintitle> vengono visualizzate le
seguenti informazioni.</p>
+<dl><dlentry>
+<dt>Memoria</dt>
+<dd>Visualizza l'ubicazione del file ISO utilizzato per
l'installazione.</dd>
+</dlentry></dl>
+<p> I campi non disabilitati possono essere modificati. Dopo aver modificato un
campo, fare clic su <uicontrol>Salva</uicontrol>. </p>
+</csbody>
+</cshelp>
+<cshelp id="kimstoragedevice" xml:lang="it-it">
+<title>Aggiungere, sostituire o scollegare un dispositivo di
memoria.</title>
+<shortdesc rev="rev1">�� possibile aggiungere, sostituire o scollegare un
dispositivo di memoria per la macchina virtuale. L'unico dispositivo supportato ��
CDROM. Per modificare i dispositivi di memoria, attenersi alla seguente
procedura:</shortdesc>
+<csbody>
+<ol>
+<li>Nella finestra <wintitle>Modifica macchina guest</wintitle>,
selezionare <wintitle>Memoria</wintitle>.</li>
+<li>Per sostituire un dispositivo di memoria, fare clic sulla prima icona con la
<uicontrol>barra (/) arancione</uicontrol>. Immettere il percorso del file ISO
e fare clic su <uicontrol>Sostituisci</uicontrol>.</li>
+<li>Per scollegare un dispositivo di memoria, fare clic sulla seconda icona con il
<uicontrol>trattino (-) rosso</uicontrol>. Confermare l'eliminazione
facendo clic su <uicontrol>OK</uicontrol>.</li>
+<li>Per aggiungere un dispositivo di memoria, fare clic sulla terza icona con il
<uicontrol>segno pi�� (+)</uicontrol> verde. Immettere un nome dispositivo e
percorso file ISO e fare clic su <uicontrol>Collega</uicontrol>.</li>
+</ol>
+</csbody>
+</cshelp>
+<cshelp id="kimreplacemedia" xml:lang="it-it">
+<title>Sostituisci un CDROM della macchina virtuale</title>
+<shortdesc rev="rev1">�� possibile sostituire il contenuto del CDROM per
una macchina virtuale dopo il completamento dell'installazione.</shortdesc>
+<csbody>
+<ol>
+<li>Assicurarsi che la macchina virtuale sia avviata.</li>
+<li>Dal menu Azioni, selezionare <uicontrol>Gestisci
supporti</uicontrol>.</li>
+<li>Per modificare il contenuto correntemente caricato sul CDROM, fare clic
sull'icona della <uicontrol>barra (/) arancione</uicontrol> accanto al
campo hdc.</li>
+<li>Sulla pagina <wintitle>Sostituisci un CDROM della macchina
virtuale</wintitle>, immettere il percorso del file ISO. Gli altri due campi sono di
sola lettura.</li>
+<li>Fare clic su <uicontrol>Sostituisci</uicontrol>.</li>
+</ol>
+</csbody>
+</cshelp>
+<?tm 1391540919 3?>
+</cshelp>
+
+
+<!-- ENGL1SH_VERS10N 45645_6 DO NOT REMOVE OR CHANGE THIS LINE -->
+<!-- T9N_SRC_ID 231 -->
+<!-- T9N_SH1P_STR1NG KV211AAP001 1 -->
diff --git a/src/wok/plugins/kimchi/ui/pages/help/it_IT/host.dita
b/src/wok/plugins/kimchi/ui/pages/help/it_IT/host.dita
new file mode 100644
index 0000000..63d3367
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/pages/help/it_IT/host.dita
@@ -0,0 +1,51 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--Arbortext, Inc., 1988-2011, v.4002-->
+<!DOCTYPE cshelp PUBLIC "-//IBM//DTD DITA CSHelp//EN"
+ "..\dtd\cshelp.dtd">
+
+
+<!--This DITA specialized document type is not supported by the Authoring Tools
development team.
+For support please see:
+https://w3.opensource.ibm.com/projects/dita-cshelp/-->
+<cshelp id="kimhhost" xml:lang="it-it">
+<title>Host</title>
+<shortdesc>La pagina <wintitle>Host</wintitle> visualizza le
informazioni sul sistema host e consente di arrestarlo, riavviarlo e connettersi ad
esso.</shortdesc>
+<csbody>
+<p>�� possibile effettuare le seguenti operazioni sull'host:<ul>
+<li>Selezionare <uicontrol>Arresta</uicontrol> per arrestare il sistema
host.</li>
+<li>Selezionare <uicontrol>Riavvia</uicontrol> per riavviare il sistema
host.</li>
+<li>Selezionare <uicontrol>Connetti</uicontrol> per aprire una
connessione VNC al sistema host, se non �� gi�� connesso.</li>
+</ul></p>
+<p>Fare clic sulle seguenti sezioni per visualizzare le informazioni
sull'host:<dl>
+<dlentry>
+<dt>Informazioni di base</dt>
+<dd>Questa sezione visualizza il nome codice, la versione e la distribuzione del
sistema operativo, come pure il tipo di processore e la quantit�� di memoria in
GB.</dd>
+</dlentry><dlentry>
+<dt>Statistiche di sistema</dt>
+<dd>Questa sezione visualizza i grafici che mostrano le statistiche per la CPU, la
memoria, l'I/O disco e di rete per l'host. Selezionare <uicontrol>Raccolta
dati all'uscita dalla pagina</uicontrol> per continuare la raccolta dei dati
quando la scheda host non �� pi�� visibile.</dd>
+</dlentry><dlentry>
+<dt>Aggiornamenti del software</dt>
+<dd>Questa sezione visualizza le informazioni per tutti i pacchetti per cui sono
disponibili gli aggiornamenti, incluso il nome, la versione, l'architettura e il
repository del pacchetto. �� possibile aggiornare tutti i pacchetti elencati, selezionando
<uicontrol>Aggiorna tutto</uicontrol>. Non �� possibile selezionare singoli
pacchetti per gli aggiornamenti.</dd>
+</dlentry><dlentry>
+<dt>Repository</dt>
+<dd>Questa sezione visualizza i repository associati al sistema host. �� possibile
aggiungere, abilitare, modificare o rimuovere i repository. L'aggiunta di un
repository lo associa al sistema host, mentre l'abilitazione di un repository
+consente all'host di accedervi. Se il sistema �� Red Hat Enterprise
+Linux o Fedora, �� possibile aggiungere i repository
<filepath>yum</filepath>.
+Se il sistema �� Ubuntu o Debian, aggiungere i repository
<filepath>deb</filepath>.<p>Se si stanno utilizzando i repository yum,
�� possibile aggiungere un controllo GPG per verificare che un pacchetto da questo
repository non sia stato corrotto.
+Selezionare un repository, quindi <uicontrol>Modifica</uicontrol>.
Selezionare <uicontrol>S��</uicontrol> per abilitare il controllo GPG, quindi
immettere un URL al file di chiavi GPG per il
+repository.</p></dd>
+</dlentry><dlentry>
+<dt>Report di debug</dt>
+<dd>Questa sezione visualizza i report di debug, incluso il nome e il percorso
file.
+Le opzioni disponibili consentono di generare un nuovo report oppure ridenominare,
rimuovere o scaricare un report esistente.<p>Il report di debug viene generato
utilizzando il comando <cmdname>sosreport</cmdname>. �� disponibile per le
distribuzioni Red
+Hat Enterprise <tm tmtype="tm"
trademark="Linux">Linux</tm>, Fedora e Ubuntu. Il comando genera un
file .tar che contiene informazioni di diagnostica e configurazione, come la versione del
kernel in esecuzione, i moduli caricati e i file di configurazione del servizio e del
sistema.
+Il comando esegue anche programmi esterni per raccogliere ulteriori informazioni e
memorizza l'output nell'archivio risultante.</p> </dd>
+</dlentry></dl></p>
+</csbody>
+<?tm 1392659967 1?>
+</cshelp>
+
+
+<!-- ENGL1SH_VERS10N 47930_4 DO NOT REMOVE OR CHANGE THIS LINE -->
+<!-- T9N_SRC_ID 232 -->
+<!-- T9N_SH1P_STR1NG KVM21AAP001 3 -->
diff --git a/src/wok/plugins/kimchi/ui/pages/help/it_IT/network.dita
b/src/wok/plugins/kimchi/ui/pages/help/it_IT/network.dita
new file mode 100644
index 0000000..a396d58
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/pages/help/it_IT/network.dita
@@ -0,0 +1,63 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--Arbortext, Inc., 1988-2011, v.4002-->
+<!DOCTYPE cshelp PUBLIC "-//IBM//DTD DITA CSHelp//EN"
+ "..\dtd\cshelp.dtd">
+
+
+<!--This DITA specialized document type is not supported by the Authoring Tools
development team.
+For support please see:
+https://w3.opensource.ibm.com/projects/dita-cshelp/-->
+<cshelp id="kimhnetw" xml:lang="it-it">
+<title>Rete</title>
+<shortdesc>La pagina <wintitle>Rete</wintitle> visualizza le
informazioni sulla connessione di rete.</shortdesc>
+<csbody>
+<p><dl><dlentry>
+<dt>Nome rete</dt>
+<dd>Il nome della rete o il <uicontrol>valore
predefinito</uicontrol>.</dd>
+</dlentry><dlentry>
+<dt>Stato</dt>
+<dd>Lo stato della rete, attivo (verde) o non attivo (rosso). </dd>
+</dlentry><dlentry>
+<dt>Tipo di rete</dt>
+<dd>I tipo di rete, ad esempio, <uicontrol>NAT</uicontrol> (network
+address translation).</dd>
+</dlentry><dlentry>
+<dt>Interfaccia</dt>
+<dd>L'interfaccia di rete, ad esempio,
<uicontrol>virbr0</uicontrol> (valore predefinito).</dd>
+</dlentry><dlentry>
+<dt>Spazio indirizzo</dt>
+<dd>L'indirizzo IP.</dd>
+</dlentry></dl></p>
+<p>�� possibile selezionare le seguenti azioni:<ul>
+<li rev="rev1">Selezionare <uicontrol>Avvia</uicontrol> per
iniziare la connessione di rete.</li>
+<li>Selezionare <uicontrol>Arresta</uicontrol> per terminare la
connessione di rete.</li>
+<li>Selezionare <uicontrol>Elimina</uicontrol> per eliminare le
informazioni di connessione.</li>
+</ul>Per creare una rete fare clic sull'icona <uicontrol>pi��
+(+)</uicontrol> nella parte in alto a destra del pannello.</p>
+</csbody>
+<cshelp id="kimhnetwcrt" xml:lang="it-it">
+<title>Crea una rete</title>
+<shortdesc>Creare una rete.</shortdesc>
+<csbody>
+<p> <ol>
+<li>Immettere il nome della rete.</li>
+<li>Fare clic per selezionare il tipo di rete. <dl
rev="rev1"><dlentry>
+<dt><uicontrol>Isolata</uicontrol></dt>
+<dd>La modalit�� isolata. Le macchine guest non possono inviare o ricevere
comunicazioni verso o da i sistemi esterni.</dd>
+</dlentry><dlentry>
+<dt><uicontrol>NAT</uicontrol></dt>
+<dd>La modalit�� NAT (Network Address Translation). La comunicazione dalle macchine
guest ai sistemi esterni utilizza l'indirizzo IP host. I sistemi esterni non possono
iniziare la comunicazione con le macchine guest.</dd>
+</dlentry><dlentry>
+<dt><uicontrol>Con bridge</uicontrol></dt>
+<dd>La modalit�� con bridge. Le macchine guest possono comunicare con i sistemi
esterni ed essere contattate dai sistemi esterni come se fossero sistemi fisici sulla
rete. Per la modalit�� con bridge, �� necessario specificare informazioni aggiuntive su
destinazione e VLAN.</dd>
+</dlentry></dl></li>
+<li>Fare clic su <uicontrol>Crea</uicontrol>.</li>
+</ol> </p>
+</csbody>
+</cshelp>
+</cshelp>
+
+
+<!-- ENGL1SH_VERS10N 47050_3 DO NOT REMOVE OR CHANGE THIS LINE -->
+<!-- T9N_SRC_ID 230 -->
+<!-- T9N_SH1P_STR1NG KVM21AAP001 3 -->
diff --git a/src/wok/plugins/kimchi/ui/pages/help/it_IT/storage.dita
b/src/wok/plugins/kimchi/ui/pages/help/it_IT/storage.dita
new file mode 100644
index 0000000..5a9bc25
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/pages/help/it_IT/storage.dita
@@ -0,0 +1,91 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--Arbortext, Inc., 1988-2011, v.4002-->
+<!DOCTYPE cshelp PUBLIC "-//IBM//DTD DITA CSHelp//EN"
+ "..\dtd\cshelp.dtd">
+
+
+<!--This DITA specialized document type is not supported by the Authoring Tools
development team.
+For support please see:
+https://w3.opensource.ibm.com/projects/dita-cshelp/-->
+<cshelp id="kimhstor" xml:lang="it-it">
+<title>Memoria</title>
+<shortdesc>La pagina <wintitle>Memoria</wintitle> elenca i pool di
memoria
+disponibili, compresi i pool di memoria pronti per l'uso 'default' e
'ISO'.
+Se si desidera utilizzare un proprio ISO, aggiungerlo al percorso del pool di memoria
'ISO'.</shortdesc>
+<csbody>
+<p>Per ciascun pool di memoria vengono visualizzate le seguenti
informazioni:<dl>
+<dlentry>
+<dt>Nome</dt>
+<dd>Il nome del pool di memoria e la percentuale utilizzata.</dd>
+</dlentry><dlentry>
+<dt>Stato</dt>
+<dd>Lo stato del pool di memoria, attivo (verde) o non attivo (rosso). </dd>
+</dlentry><dlentry>
+<dt>Ubicazione</dt>
+<dd>Il percorso file all'ubicazione del pool di memoria.</dd>
+</dlentry><dlentry>
+<dt>Tipo</dt>
+<dd>Il tipo di pool di memoria, ad esempio,
<uicontrol>dir</uicontrol>.</dd>
+</dlentry><dlentry>
+<dt>Capacit��</dt>
+<dd>La quantit�� di spazio nel pool di memoria.</dd>
+</dlentry><dlentry>
+<dt>Assegnato</dt>
+<dd>La quantit�� di spazio gi�� assegnato nel pool di memoria.</dd>
+</dlentry></dl></p>
+<p>Per ciascun pool di memoria �� possibile selezionare le azioni indicate di
seguito:<ul>
+<li>Selezionare <uicontrol>Attiva</uicontrol> per attivare il pool di
memoria in modo da poterlo utilizzare.</li>
+<li>Selezionare <uicontrol>Disattiva</uicontrol> per disattivare un
pool di memoria attivo.</li>
+<li>Selezionare <uicontrol>Rimuovi definizione</uicontrol> per
rimuovere un pool di memoria non attivo.</li>
+</ul></p>
+<p>Per visualizzare i dettagli del volume di memoria per un pool di memoria, fare
clic sulla freccia sul lato destro della riga del pool di memoria. I dettagli
includono:<dl><dlentry>
+<dt>Tipo</dt>
+<dd>Il tipo di volume, ad esempio,
<uicontrol>file</uicontrol>.</dd>
+</dlentry><dlentry>
+<dt>Formato</dt>
+<dd>Il formato, che varia in base al tipo.</dd>
+</dlentry><dlentry>
+<dt>Capacit��</dt>
+<dd>La dimensione del volume di memoria.</dd>
+</dlentry><dlentry>
+<dt>Assegnazione</dt>
+<dd>La quantit�� di spazio gi�� assegnato nel pool di memoria.</dd>
+</dlentry></dl>Per definire un pool di memoria fare clic sull'icona
<uicontrol>pi��
+(+)</uicontrol> nella parte in alto a destra del pannello.</p>
+</csbody>
+<cshelp id="kimhdefstor" xml:lang="it-it">
+<title>Definire un pool di memoria</title>
+<shortdesc> Definire un pool di memoria.</shortdesc>
+<csbody>
+<p> <ol>
+<li>Nel campo <uicontrol>Nome pool di memoria</uicontrol>, immettere i
l nome da utilizzare per definire il pool di memoria.</li>
+<li>Nell'elenco <uicontrol>Tipo pool di memoria</uicontrol>,
selezionare il tipo: <dl><dlentry>
+<dt><uicontrol>DIR</uicontrol></dt>
+<dd>Specifica un pool directory. Quando si seleziona
<uicontrol>DIR</uicontrol>,
+immettere il <uicontrol>Percorso di memoria</uicontrol> (percorso file al
pool di memoria).</dd>
+</dlentry><dlentry>
+<dt><uicontrol>NFS</uicontrol></dt>
+<dd>Specifica un pool NFS (Network File System). Quando si seleziona
<uicontrol>NFS</uicontrol>,
+immettere l'indirizzo <uicontrol>IP del server NFS</uicontrol> e il
<uicontrol>Percorso NFS</uicontrol> (percorso alla directory
esportata).</dd>
+</dlentry><dlentry>
+<dt><uicontrol>iSCSI</uicontrol></dt>
+<dd>Specifica un pool basato su una destinazione assegnata su un server iSCSI.
+Quando si seleziona <uicontrol>iSCSI</uicontrol>, immettere l'indirizzo
IP del <uicontrol>Server iSCSI</uicontrol> e la
<uicontrol>Destinazione</uicontrol> sul server iSCSI. �� possibile,
facoltativamente, selezionare di aggiungere l'autenticazione iSCSI.</dd>
+</dlentry><dlentry>
+<dt><uicontrol>Logico</uicontrol></dt>
+<dd>Specifica un pool di memoria di tipo volume logico. Selezionare
l'ubicazione del dispositivo in <uicontrol>Percorso
dispositivo</uicontrol>.</dd>
+</dlentry><dlentry>
+<dt><uicontrol>Canale a fibre ottiche SCSI</uicontrol></dt>
+<dd>Specifica un pool basato su un canale a fibre ottiche SCSI. Selezionare quale
adattatore
+SCSI utilizzare.</dd>
+</dlentry></dl></li>
+<li>Fare clic su <uicontrol>Crea</uicontrol>.</li>
+</ol> </p>
+</csbody>
+</cshelp>
+</cshelp>
+
+
+<!-- ENGL1SH_VERS10N 22336_4 DO NOT REMOVE OR CHANGE THIS LINE -->
+<!-- T9N_SRC_ID 233 -->
+<!-- T9N_SH1P_STR1NG KV211AAP001 1 -->
diff --git a/src/wok/plugins/kimchi/ui/pages/help/it_IT/templates.dita
b/src/wok/plugins/kimchi/ui/pages/help/it_IT/templates.dita
new file mode 100644
index 0000000..9b84b16
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/pages/help/it_IT/templates.dita
@@ -0,0 +1,115 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--Arbortext, Inc., 1988-2011, v.4002-->
+<!DOCTYPE cshelp PUBLIC "-//IBM//DTD DITA CSHelp//EN"
+ "..\dtd\cshelp.dtd">
+
+
+<!--This DITA specialized document type is not supported by the Authoring Tools
development team.
+For support please see:
+https://w3.opensource.ibm.com/projects/dita-cshelp/-->
+<cshelp id="kimhtempl" xml:lang="it-it">
+<title>Modelli</title>
+<shortdesc>La pagina <wintitle>Modelli</wintitle> visualizza i modelli
di macchina virtuale definiti che �� possibile utilizzare per creare macchine guest
KVM.</shortdesc>
+<csbody>
+<p>Per ciascun modello vengono visualizzate le seguenti informazioni:<dl>
+<dlentry>
+<dt>SO</dt>
+<dd>Il nome del sistema operativo o della distribuzione.</dd>
+</dlentry><dlentry>
+<dt>Versione</dt>
+<dd>La versione del sistema operativo o della distribuzione.</dd>
+</dlentry><dlentry>
+<dt>CPU</dt>
+<dd>Il numero di processori definiti per il modello.</dd>
+</dlentry><dlentry>
+<dt>Memoria</dt>
+<dd>La quantit�� di memoria ad accesso casuale da assegnare, in MB.</dd>
+</dlentry></dl></p>
+<p>Per ciascun modello �� possibile selezionare le azioni indicate di
seguito:<ul>
+<li>Selezionare <uicontrol>Modifica</uicontrol> per modificare il
modello.</li>
+<li>Selezionare <uicontrol>Elimina</uicontrol> per eliminare il
modello.</li>
+</ul>Per aggiungere un modello fare clic sull'icona <uicontrol>pi��
+(+)</uicontrol> nella parte in alto a destra del pannello.</p>
+</csbody>
+<cshelp id="kimhedittempl" xml:lang="it-it">
+<title>Modifica modello</title>
+<shortdesc>Modificare un modello esistente.</shortdesc>
+<csbody>
+<p>Per ciascun modello vengono visualizzate le seguenti informazioni: <dl>
+<dlentry>
+<dt>Nome</dt>
+<dd>Il nome del modello.</dd>
+</dlentry><dlentry>
+<dt>Fornitore</dt>
+<dd>Il nome della societ�� che ha creato il sistema operativo o la distribuzione
per il cui utilizzo �� configurato il modello.</dd>
+</dlentry><dlentry>
+<dt>Versione</dt>
+<dd>La versione del sistema operativo o della distribuzione per il cui utilizzo ��
configurato il modello.</dd>
+</dlentry><dlentry>
+<dt>Numero CPU</dt>
+<dd>Il numero di processori definiti per il modello.</dd>
+</dlentry><dlentry>
+<dt>Memoria</dt>
+<dd>La quantit�� di memoria in MB da assegnare alla macchina virtuale.</dd>
+</dlentry><dlentry>
+<dt>Disco</dt>
+<dd>La dimensione del disco in GB.</dd>
+</dlentry><dlentry>
+<dt>CDROM</dt>
+<dd>Il percorso file all'ubicazione del file ISO utilizzato per installare la
macchina guest
+KVM.</dd>
+</dlentry><dlentry>
+<dt>Pool di memoria</dt>
+<dd>Un pool di memoria specifico o quello predefinito.</dd>
+</dlentry><dlentry>
+<dt>Rete</dt>
+<dd>Le interfacce di rete predefinite disponibili per la macchina guest KVM. ��
possibile selezionare pi�� reti.</dd>
+</dlentry></dl> I campi non disabilitati possono essere modificati. Dopo aver
modificato un campo, fare clic su <uicontrol>Salva</uicontrol>. </p>
+</csbody>
+</cshelp>
+<cshelp id="kimhaddtempl">
+<title>Aggiungi modello</title>
+<shortdesc>Aggiungere un modello dal supporto di origine.
+�� possibile aggiungere una propria immagine ISO al pool di memoria 'ISO' per la
seguente individuazione.</shortdesc>
+<csbody>
+<p>Selezionare l'ubicazione del supporto di origine dalle seguenti
opzioni:<dl>
+<dlentry>
+<dt>Immagine ISO locale</dt>
+<dd>Selezionare questa opzione per eseguire la scansione dei pool di memoria alla
ricerca di immagini ISO di installazione disponibili sul sistema.</dd>
+</dlentry><dlentry>
+<dt>Immagine ISO remota</dt>
+<dd>Selezionare questa opzione per specificare un'ubicazione remota per
un'immagine ISO di installazione.</dd>
+</dlentry></dl></p>
+</csbody>
+</cshelp>
+<cshelp id="kimhaddloct">
+<title>Aggiungi modello - Immagine ISO locale</title>
+<shortdesc>Aggiungere un modello da un'immagine ISO locale.</shortdesc>
+<csbody>
+<p>Vengono visualizzate le immagini ISO disponibili sul
sistema.<dl><dlentry>
+<dt>SO</dt>
+<dd>Il nome del sistema operativo o della distribuzione.</dd>
+</dlentry><dlentry>
+<dt>Versione</dt>
+<dd>La versione del sistema operativo o della distribuzione.</dd>
+</dlentry><dlentry>
+<dt>Dimensione</dt>
+<dd>La dimensione dell'immagine ISO.</dd>
+</dlentry></dl></p>
+<p>Per creare un modello da un'immagine ISO scegliere tra le seguenti
opzioni:<ul>
+<li>Selezionare un'immagine ISO da cui creare un modello, quindi fare clic su
<uicontrol>Crea modelli da ISO selezionato</uicontrol>.</li>
+<li>Selezionare <uicontrol>Tutti</uicontrol> per creare un modello da
ciascuna immagine ISO elencata, quindi fare clic su <uicontrol>Crea modelli da ISO
selezionato</uicontrol>.</li>
+<li>Se nei risultati della scansione non viene visualizzata l'immagine ISO che
si desidera utilizzare, �� possibile selezionare dalle seguenti opzioni:<ul>
+<li>Selezionare <uicontrol>Utilizzare un file ISO specifico</uicontrol>
per specificare un percorso all'immagine ISO.</li>
+<li>Fare clic su <uicontrol>Ricerca pi�� ISO</uicontrol> per ricercare
pi�� immagini
+ISO.</li>
+</ul></li>
+</ul></p>
+</csbody>
+</cshelp>
+</cshelp>
+
+
+<!-- ENGL1SH_VERS10N 61085_5 DO NOT REMOVE OR CHANGE THIS LINE -->
+<!-- T9N_SRC_ID 229 -->
+<!-- T9N_SH1P_STR1NG KV211AAP001 1 -->
diff --git a/src/wok/plugins/kimchi/ui/pages/help/ja_JP/Makefile.am
b/src/wok/plugins/kimchi/ui/pages/help/ja_JP/Makefile.am
new file mode 100644
index 0000000..f9c2f33
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/pages/help/ja_JP/Makefile.am
@@ -0,0 +1,23 @@
+# Copyright IBM Corp, 2014
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+ja_JP_helpdir = $(datadir)/wok/plugins/kimchi/ui/pages/help/ja_JP
+
+dist_ja_JP_help_DATA = $(wildcard *.html) $(NULL)
+
+EXTRA_DIST = $(wildcard *.dita)
+
+CLEANFILES = $(wildcard *.html)
diff --git a/src/wok/plugins/kimchi/ui/pages/help/ja_JP/guests.dita
b/src/wok/plugins/kimchi/ui/pages/help/ja_JP/guests.dita
new file mode 100644
index 0000000..5dade49
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/pages/help/ja_JP/guests.dita
@@ -0,0 +1,172 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--Arbortext, Inc., 1988-2011, v.4002-->
+<!DOCTYPE cshelp PUBLIC "-//IBM//DTD DITA CSHelp//EN"
+ "..\dtd\cshelp.dtd">
+
+
+<!--This DITA specialized document type is not supported by the Authoring Tools
development team.
+For support please see:
+https://w3.opensource.ibm.com/projects/dita-cshelp/-->
+<cshelp id="kimhvirtm" xml:lang="ja-jp">
+<title>���������</title>
+<shortdesc><wintitle>���������������</wintitle>������������������������������
KVM ������������������������������������������
+</shortdesc>
+<csbody>
+<p>������������������������������������������������������������
+<dl><dlentry>
+<dt>������</dt>
+<dd>���������������������������
+</dd>
+</dlentry><dlentry>
+<dt>CPU</dt>
+<dd>���������������������������������������������������������
+</dd>
+</dlentry><dlentry>
+<dt>���������������������������</dt>
+<dd>������������������������������������ (KB/���)���
+</dd>
+</dlentry><dlentry>
+<dt>���������������������</dt>
+<dd>������������������������������ (KB/���)���
+</dd>
+</dlentry><dlentry>
+<dt>������������������</dt>
+<dd>������������������������������������������������������������������������������������������������������������������������������������������<tm
tmtype="tm" trademark="Linux">Linux</tm>
+���������������������������������������������������������
+</dd>
+</dlentry></dl></p>
+<p>������������������������������������������������������������������������������������
+<dl>
+<dlentry>
+<dt>������������</dt>
+<dd>������������������������������������������������������
+</dd>
+</dlentry><dlentry>
+<dt>������ (���������������������)</dt>
+<dd>���������������������������������������������������������������������������
+������������������������������������������������������������������������������������������������������������������������
+</dd>
+</dlentry></dl> </p>
+<p>���������������������������������������������������������������������
+<ul>
+<li>������������������������������������������������������������������������������������������������������������<uicontrol>������������</uicontrol>���������������������
+</li>
+<li>������������������������������������������������������������������<uicontrol>���������������������������</uicontrol>���������������������
+</li>
+<li>������������������������������������<uicontrol>������������������</uicontrol>���������������������
+</li>
+<li>���������������������������������������������������������������<uicontrol>������������</uicontrol>���������������������
+���������������������������������������������������������������
+</li>
+<li>������������������������������<uicontrol>������������</uicontrol>���������������������
+</li>
+</ul>��������� (���������������)
���������������������������������������������������<uicontrol>���������
(+)</uicontrol> ������������������������������������������������
+</p>
+</csbody>
+<cshelp id="kimhvirtmcrt" xml:lang="ja-jp">
+<title>������������������������</title>
+<shortdesc>���������������������������������������������������������������������������������������������������
+</shortdesc>
+<csbody>
+<p> <ol>
+<li>������������������������������������������������������������������
+</li>
+<li rev="rev1">���������������������������������������
+<ul>
+<li>������������������������������������������������������������������������������������������������������������
+</li>
+<li>������������������������������������������������<uicontrol>���������������������������������</uicontrol>������������������������������������������������������������
+</li>
+</ul></li>
+<li><uicontrol>������������</uicontrol>������������������������������������
+</li>
+</ol> </p>
+</csbody>
+</cshelp>
+<cshelp id="kimhvirtmedit" xml:lang="ja-jp">
+<title>������������������</title>
+<shortdesc>������������������������������������������������������������������
+������������������������������������������������������������������������������������������������
+������������������������������������������������������������������������������������������</shortdesc>
+<csprolog><csmetadata></csmetadata></csprolog>
+<csbody>
+<p>���������������������������������������<wintitle>������������</wintitle>������������������������������
+<dl>
+<dlentry>
+<dt>������</dt>
+<dd>���������������������������
+(������������������������������������������������������)</dd>
+</dlentry><dlentry>
+<dt>CPU</dt>
+<dd>���������������������������
+(���������������������������������������������������������������������������������������)</dd>
+</dlentry><dlentry>
+<dt>������������</dt>
+<dd>������������������ (MB ������)���
+(���������������������������������������������������������������������������������������)</dd>
+</dlentry><dlentry>
+<dt>������������</dt>
+<dd>���������������������������������������������������������������
(������������������) ���������������������������Linux
������������������������������������������������������������������������������
+</dd>
+</dlentry></dl></p>
+<p>���������������<wintitle>���������������������</wintitle>������������������������������
+</p>
+<dl><dlentry>
+<dt>���������������</dt>
+<dd>������������������������������������ ISO
������������������������������������������������������
+</dd>
+</dlentry></dl>
+<p> ������������������������������������������������������������������������
+������������������������������������<uicontrol>������������</uicontrol>������������������������������������
+</p>
+</csbody>
+</cshelp>
+<cshelp id="kimstoragedevice" xml:lang="ja-jp">
+<title>������������������������������������������������������������������������</title>
+<shortdesc
rev="rev1">������������������������������������������������������������������������������������������������������������������������������������������������������
+������������������������������������������ CDROM ���������������
+������������������������������������������������������������������������������������������������
+</shortdesc>
+<csbody>
+<ol>
+<li><wintitle>������������������������</wintitle>������������������<wintitle>���������������������</wintitle>���������������������
+</li>
+<li>������������������������������������������������������<uicontrol>������������������������������
(/)</uicontrol>
���������������������������������������������������������������������
+ISO
������������������������������������<uicontrol>������������</uicontrol>���������������������������
+</li>
+<li>������������������������������������������������������<uicontrol>������������������
(-)</uicontrol> ������������ 2
���������������������������������������������������������
+���������������������<uicontrol>���OK���</uicontrol>���������������������������
+</li>
+<li>������������������������������������������������������<uicontrol>���������������
(+)</uicontrol> ������������ 3
���������������������������������������������������������
+������������������ ISO
������������������������������������<uicontrol>������������</uicontrol>���������������������������
+</li>
+</ol>
+</csbody>
+</cshelp>
+<cshelp id="kimreplacemedia" xml:lang="ja-jp">
+<title>VM ��� CDROM ���������</title>
+<shortdesc
rev="rev1">������������������������������������������������������������ CDROM
������������������������������������������������
+</shortdesc>
+<csbody>
+<ol>
+<li>���������������������������������������������������������������
+</li>
+<li>���������������������������������������<uicontrol>���������������������������</uicontrol>���������������������
+</li>
+<li>CDROM ���������������������������������������������������������hdc
������������������������������<uicontrol>������������������������������
(/)</uicontrol> ���������������������������������������
+</li>
+<li><wintitle>���VM ��� CDROM ������������</wintitle>���������������ISO
������������������������������������������
+��������������� 2 ���������������������������������������������������
+</li>
+<li><uicontrol>������������</uicontrol>������������������������������������
+</li>
+</ol>
+</csbody>
+</cshelp>
+<?tm 1391540919 3?>
+</cshelp>
+
+
+<!-- ENGL1SH_VERS10N 45645_6 DO NOT REMOVE OR CHANGE THIS LINE -->
+<!-- T9N_SRC_ID 231 -->
+<!-- T9N_SH1P_STR1NG KV211AAP001 1 -->
diff --git a/src/wok/plugins/kimchi/ui/pages/help/ja_JP/host.dita
b/src/wok/plugins/kimchi/ui/pages/help/ja_JP/host.dita
new file mode 100644
index 0000000..3a0141c
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/pages/help/ja_JP/host.dita
@@ -0,0 +1,70 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--Arbortext, Inc., 1988-2011, v.4002-->
+<!DOCTYPE cshelp PUBLIC "-//IBM//DTD DITA CSHelp//EN"
+ "..\dtd\cshelp.dtd">
+
+
+<!--This DITA specialized document type is not supported by the Authoring Tools
development team.
+For support please see:
+https://w3.opensource.ibm.com/projects/dita-cshelp/-->
+<cshelp id="kimhhost" xml:lang="ja-jp">
+<title>���������</title>
+<shortdesc><wintitle>���������������</wintitle>������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������
+</shortdesc>
+<csbody>
+<p>���������������������������������������������������������������������
+<ul>
+<li>������������������������������������������������������������<uicontrol>���������������������������</uicontrol>���������������������
+</li>
+<li>������������������������������������������������<uicontrol>���������������</uicontrol>���������������������
+</li>
+<li>������������������������������ VNC ���������
(���������������������������������������)
���������������������������<uicontrol>������������</uicontrol>���������������������
+</li>
+</ul></p>
+<p>������������������������������������������������������������������������������������������������������������
+<dl>
+<dlentry>
+<dt>������������</dt>
+<dd>������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������
(GB ������) ������������������������
+</dd>
+</dlentry><dlentry>
+<dt>������������������������</dt>
+<dd>������������������������������������������
CPU���������������������������������������������������������������������������������������������������������������������������������������
+���������������������������������������������������������������������������������<uicontrol>���������������������������������������������������������������</uicontrol>������������������������������
+</dd>
+</dlentry><dlentry>
+<dt>������������������������</dt>
+<dd>���������������������������������������������������������������������������������������������
+(������������������������������������������������������������������������������������������)
������������������������
+<uicontrol>���������������������</uicontrol>���������������������������������������������������������������������������������������������
+���������������������������������������������������������������������������������������������
+</dd>
+</dlentry><dlentry>
+<dt>������������������</dt>
+<dd>������������������������������������������������������������������������������������������������������������������������������
+������������������������������������������������������������������������������������������������������������������
+������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������
+��������������� Red Hat Enterprise Linux ��������� Fedora
���������������<filepath>yum</filepath>
������������������������������������������
+��������������� Ubuntu ��������� Debian
���������������<filepath>deb</filepath>
������������������������������������������������
+<p>yum
������������������������������������������������������������������������������������������������������������������������������������������������������������GPG
������������������������������������
+���������������������������������<uicontrol>������������</uicontrol>������������������������������������
+<uicontrol>������������</uicontrol>��������������� GPG
������������������������������������������������������������������ GPG ������������������
URL ������������������������������
+</p></dd>
+</dlentry><dlentry>
+<dt>���������������������������</dt>
+<dd>���������������������������������������������������������
(������������������������������������) ������������������������
+������������������������������������������������������������������������������������������������������������������������������������������������������������������
+<p>���������������������������������<cmdname>sosreport</cmdname>
������������������������������������
+������������Red Hat Enterprise <tm tmtype="tm"
trademark="Linux">Linux</tm>���Fedora������������ Ubuntu
���������������������������������������������������������������
+���������������������������������������������������
(������������������������������������������������������������������������������������������������������������������������������������������������)
������������ .tar ���������������������������������
+������������������������������������������������������������������������������������������������������������������������������������������������������������
+</p> </dd>
+</dlentry></dl></p>
+</csbody>
+<?tm 1392659967 1?>
+</cshelp>
+
+
+<!-- ENGL1SH_VERS10N 47930_4 DO NOT REMOVE OR CHANGE THIS LINE -->
+<!-- T9N_SRC_ID 227 -->
+<!-- T9N_SH1P_STR1NG KVM21AAP001 1 -->
diff --git a/src/wok/plugins/kimchi/ui/pages/help/ja_JP/network.dita
b/src/wok/plugins/kimchi/ui/pages/help/ja_JP/network.dita
new file mode 100644
index 0000000..5d9ce05
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/pages/help/ja_JP/network.dita
@@ -0,0 +1,83 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--Arbortext, Inc., 1988-2011, v.4002-->
+<!DOCTYPE cshelp PUBLIC "-//IBM//DTD DITA CSHelp//EN"
+ "..\dtd\cshelp.dtd">
+
+
+<!--This DITA specialized document type is not supported by the Authoring Tools
development team.
+For support please see:
+https://w3.opensource.ibm.com/projects/dita-cshelp/-->
+<cshelp id="kimhnetw" xml:lang="ja-jp">
+<title> ������������������</title>
+<shortdesc><wintitle>������������������������</wintitle>������������������������������������������������������������������������������������
+</shortdesc>
+<csbody>
+<p><dl><dlentry>
+<dt>���������������������</dt>
+<dd>��������������������������� (���������
<uicontrol>default</uicontrol>) ���������
+</dd>
+</dlentry><dlentry>
+<dt>������</dt>
+<dd>������������������������������������������������ (���)
��������������������������� (���) ���������
+</dd>
+</dlentry><dlentry>
+<dt>������������������������������</dt>
+<dd>���������������������������������������������
<uicontrol>NAT</uicontrol> (���������������������������������������)
���������
+</dd>
+</dlentry><dlentry>
+<dt>������������������������</dt>
+<dd>������������������������������������������������������������
<uicontrol>virbr0</uicontrol> (���������������) ���������
+</dd>
+</dlentry><dlentry>
+<dt>���������������������������</dt>
+<dd>IP ���������������</dd>
+</dlentry></dl></p>
+<p>������������������������������������������������
+<ul>
+<li
rev="rev1">���������������������������������������������<uicontrol>������������</uicontrol>���������������������
+</li>
+<li>���������������������������������������������<uicontrol>������������</uicontrol>���������������������
+</li>
+<li>���������������������������������<uicontrol>������������</uicontrol>���������������������
+</li>
+</ul>������������������������������������������������������������������<uicontrol>���������
(+)</uicontrol> ������������������������������������������������
+</p>
+</csbody>
+<cshelp id="kimhnetwcrt" xml:lang="ja-jp">
+<title>���������������������������</title>
+<shortdesc>���������������������������������������
+</shortdesc>
+<csbody>
+<p> <ol>
+<li>������������������������������������������������
+</li>
+<li>���������������������������������������������������������������������
+<dl rev="rev1"><dlentry>
+<dt><uicontrol>������</uicontrol></dt>
+<dd>������������������
+���������������������������������������������������������������������������������������
+</dd>
+</dlentry><dlentry>
+<dt><uicontrol>NAT</uicontrol></dt>
+<dd>���������������������������������������������������
+������������������������������������������������������������ IP
������������������������������������
+������������������������������������������������������������������������
+</dd>
+</dlentry><dlentry>
+<dt><uicontrol>������������</uicontrol></dt>
+<dd>���������������������������
+������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������
+������������������������������������������������ VLAN
������������������������������������������������������
+</dd>
+</dlentry></dl></li>
+<li><uicontrol>������������</uicontrol>������������������������������������
+</li>
+</ol> </p>
+</csbody>
+</cshelp>
+</cshelp>
+
+
+<!-- ENGL1SH_VERS10N 47050_3 DO NOT REMOVE OR CHANGE THIS LINE -->
+<!-- T9N_SRC_ID 230 -->
+<!-- T9N_SH1P_STR1NG KVM21AAP001 3 -->
diff --git a/src/wok/plugins/kimchi/ui/pages/help/ja_JP/storage.dita
b/src/wok/plugins/kimchi/ui/pages/help/ja_JP/storage.dita
new file mode 100644
index 0000000..f975e7a
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/pages/help/ja_JP/storage.dita
@@ -0,0 +1,120 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--Arbortext, Inc., 1988-2011, v.4002-->
+<!DOCTYPE cshelp PUBLIC "-//IBM//DTD DITA CSHelp//EN"
+ "..\dtd\cshelp.dtd">
+
+
+<!--This DITA specialized document type is not supported by the Authoring Tools
development team.
+For support please see:
+https://w3.opensource.ibm.com/projects/dita-cshelp/-->
+<cshelp id="kimhstor" xml:lang="ja-jp">
+<title>���������������</title>
+<shortdesc><wintitle>���������������������</wintitle>���������������������������������
+���������������������������
(������������������������default������������������������������������ISO���������������������������������������)
���������������������������
+��������� ISO
���������������������������������������ISO���������������������������������������������������������������������</shortdesc>
+<csbody>
+<p>������������������������������������������������������������������������������
+<dl>
+<dlentry>
+<dt>������</dt>
+<dd>���������������������������������������������������������
+</dd>
+</dlentry><dlentry>
+<dt>������</dt>
+<dd>��������������������������������������������������������� (���)
��������������������������� (���) ���������
+</dd>
+</dlentry><dlentry>
+<dt>������������������</dt>
+<dd>���������������������������������������������������������������������������
+</dd>
+</dlentry><dlentry>
+<dt>���������</dt>
+<dd>������������������������������������������������������
<uicontrol>dir</uicontrol> ���������
+</dd>
+</dlentry><dlentry>
+<dt>������</dt>
+<dd>������������������������������������������������������������
+</dd>
+</dlentry><dlentry>
+<dt>������������������</dt>
+<dd>������������������������������������������������������������������������������������
+</dd>
+</dlentry></dl></p>
+<p>���������������������������������������������������������������������������������������
+<ul>
+<li>������������������������������������������������������������������������������������<uicontrol>������������������������������</uicontrol>���������������������
+</li>
+<li>������������������������������������������������������������������������������������<uicontrol>���������������������������������</uicontrol>���������������������
+</li>
+<li>������������������������������������������������������������������������<uicontrol>���������������������������</uicontrol>���������������������
+</li>
+</ul></p>
+<p>���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������
+������������������������������������
+<dl><dlentry>
+<dt>���������</dt>
+<dd>������������������������������������������
<uicontrol>file</uicontrol> ���������
+</dd>
+</dlentry><dlentry>
+<dt>������������������</dt>
+<dd>���������������������������������������������������
+</dd>
+</dlentry><dlentry>
+<dt>������</dt>
+<dd>������������������������������������������������
+</dd>
+</dlentry><dlentry>
+<dt>������������</dt>
+<dd>������������������������������������������������������������������������������������
+</dd>
+</dlentry></dl>���������������������������������������������������������������������������<uicontrol>���������
(+)</uicontrol> ������������������������������������������������
+</p>
+</csbody>
+<cshelp id="kimhdefstor" xml:lang="ja-jp">
+<title>������������������������������������</title>
+<shortdesc> ������������������������������������������������
+</shortdesc>
+<csbody>
+<p> <ol>
+<li><uicontrol>������������������������������������</uicontrol>���������������������������������������������������������������������������������������������������
+</li>
+<li><uicontrol>���������������������������������������������</uicontrol>���������������������������������������������������������
+<dl><dlentry>
+<dt><uicontrol>DIR</uicontrol></dt>
+<dd>������������������������������������������������������
+<uicontrol>DIR</uicontrol>
������������������������<uicontrol>������������������������</uicontrol>
(���������������������������������������������������) ������������������������������
+</dd>
+</dlentry><dlentry>
+<dt><uicontrol>NFS</uicontrol></dt>
+<dd>������������������������������������������������������������������������������
+<uicontrol>NFS</uicontrol> ������������������������<uicontrol>NFS
������������ IP</uicontrol> ��������������������� <uicontrol>NFS
������</uicontrol>
+(���������������������������������������������������������)
������������������������������
+</dd>
+</dlentry><dlentry>
+<dt><uicontrol>iSCSI</uicontrol></dt>
+<dd>iSCSI
���������������������������������������������������������������������������������������������������������
+<uicontrol>iSCSI</uicontrol> ������������������������<uicontrol>iSCSI
������������</uicontrol> IP ������������������������ iSCSI
������������������<uicontrol>���������������</uicontrol>������������������������������
+���������������������iSCSI ������������������������������������������������
+</dd>
+</dlentry><dlentry>
+<dt><uicontrol>������</uicontrol></dt>
+<dd>������������������������������������������������������������������������
+������������������������������������<uicontrol>���������������������������</uicontrol>������������������������������
+</dd>
+</dlentry><dlentry>
+<dt><uicontrol>SCSI
������������������������������</uicontrol></dt>
+<dd>SCSI
���������������������������������������������������������������������������
+������������ SCSI ���������������������������������������������
+</dd>
+</dlentry></dl></li>
+<li><uicontrol>������������</uicontrol>������������������������������������
+</li>
+</ol> </p>
+</csbody>
+</cshelp>
+</cshelp>
+
+
+<!-- ENGL1SH_VERS10N 22336_4 DO NOT REMOVE OR CHANGE THIS LINE -->
+<!-- T9N_SRC_ID 233 -->
+<!-- T9N_SH1P_STR1NG KV211AAP001 1 -->
diff --git a/src/wok/plugins/kimchi/ui/pages/help/ja_JP/templates.dita
b/src/wok/plugins/kimchi/ui/pages/help/ja_JP/templates.dita
new file mode 100644
index 0000000..24dc2ab
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/pages/help/ja_JP/templates.dita
@@ -0,0 +1,150 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--Arbortext, Inc., 1988-2011, v.4002-->
+<!DOCTYPE cshelp PUBLIC "-//IBM//DTD DITA CSHelp//EN"
+ "..\dtd\cshelp.dtd">
+
+
+<!--This DITA specialized document type is not supported by the Authoring Tools
development team.
+For support please see:
+https://w3.opensource.ibm.com/projects/dita-cshelp/-->
+<cshelp id="kimhtempl" xml:lang="ja-jp">
+<title>������������������</title>
+<shortdesc><wintitle>������������������������</wintitle>������������������KVM
���������������������������������������������������������������������������������������������������������������������������
+</shortdesc>
+<csbody>
+<p>���������������������������������������������������������������������
+<dl>
+<dlentry>
+<dt>OS</dt>
+<dd>���������������������������������������������������������������������������������������������
+</dd>
+</dlentry><dlentry>
+<dt>���������������</dt>
+<dd>������������������������������������������������������������������������������������������������������
+</dd>
+</dlentry><dlentry>
+<dt>CPU</dt>
+<dd>���������������������������������������������������������������������
+</dd>
+</dlentry><dlentry>
+<dt>������������</dt>
+<dd>��������������������������������������������������������������������� (MB
������)���
+</dd>
+</dlentry></dl></p>
+<p>������������������������������������������������������������������������������
+<ul>
+<li>���������������������������������������<uicontrol>������������</uicontrol>���������������������
+</li>
+<li>���������������������������������������<uicontrol>������������</uicontrol>���������������������
+</li>
+</ul>������������������������������������������������������������������<uicontrol>���������
(+)</uicontrol> ������������������������������������������������
+</p>
+</csbody>
+<cshelp id="kimhedittempl" xml:lang="ja-jp">
+<title>���������������������������</title>
+<shortdesc>������������������������������������������������
+</shortdesc>
+<csbody>
+<p>���������������������������������������������������������������������
+<dl>
+<dlentry>
+<dt>������</dt>
+<dd>������������������������������
+</dd>
+</dlentry><dlentry>
+<dt>������������</dt>
+<dd>������������������������������������������������������������������������������������������������������������������������������������������������������������������������������
+</dd>
+</dlentry><dlentry>
+<dt>���������������</dt>
+<dd>������������������������������������������������������������������������������������������������������������������������������������������������������������������
+</dd>
+</dlentry><dlentry>
+<dt>CPU ���</dt>
+<dd>���������������������������������������������������������������������
+</dd>
+</dlentry><dlentry>
+<dt>������������</dt>
+<dd>��������������������������������������������������������� (MB ������)���
+</dd>
+</dlentry><dlentry>
+<dt>������������</dt>
+<dd>������������������������ (GB ������)���
+</dd>
+</dlentry><dlentry>
+<dt>CDROM</dt>
+<dd>KVM ������������������������������������������������������������ ISO
������������������������������������������������������������
+</dd>
+</dlentry><dlentry>
+<dt>���������������������������</dt>
+<dd>������������������������������������������������������������������������������������������������
+</dd>
+</dlentry><dlentry>
+<dt> ������������������</dt>
+<dd>KVM
���������������������������������������������������������������������������������������������
+������������������������������������������������������������������
+</dd>
+</dlentry></dl>
������������������������������������������������������������������������
+������������������������������������<uicontrol>������������</uicontrol>������������������������������������
+</p>
+</csbody>
+</cshelp>
+<cshelp id="kimhaddtempl">
+<title>���������������������������</title>
+<shortdesc>���������������������������������������������������������������������
+������������������������������������������������������ ISO
������������������ISO������������������������������������������������������</shortdesc>
+<csbody>
+<p>���������������������������������������������������������������������������������������������������������
+<dl>
+<dlentry>
+<dt>������������ ISO ������������</dt>
+<dd>������������������������������������������������������������������������ ISO
������������������������������������������������������������������������
+</dd>
+</dlentry><dlentry>
+<dt>������������ ISO ������������</dt>
+<dd>������������������������������������������ ISO
���������������������������������������������������������������������
+</dd>
+</dlentry></dl></p>
+</csbody>
+</cshelp>
+<cshelp id="kimhaddloct">
+<title>��������������������������� - ������������ ISO ������������</title>
+<shortdesc>��������������������������������� ISO
������������������������������������
+</shortdesc>
+<csbody>
+<p>������������������������������ ISO ������������������������������������
+<dl><dlentry>
+<dt>OS</dt>
+<dd>���������������������������������������������������������������������������������������������
+</dd>
+</dlentry><dlentry>
+<dt>���������������</dt>
+<dd>������������������������������������������������������������������������������������������������������
+</dd>
+</dlentry><dlentry>
+<dt>���������</dt>
+<dd>ISO ���������������������������
+</dd>
+</dlentry></dl></p>
+<p>��������������������� ISO
���������������������������������������������������������������������������������������������
+<ul>
+<li>��������������������������������������������� ISO
������������������������������<uicontrol>��������������� ISO
������������������������������������</uicontrol>���������������������������
+</li>
+<li>������������������������ ISO
������������������������������������������������������������������������<uicontrol>���������������</uicontrol>���������������������<uicontrol>���������������
ISO ������������������������������������</uicontrol>���������������������������
+</li>
+<li>��������������� ISO
���������������������������������������������������������������������������������������������������������������
+<ul>
+<li>ISO ���������������������������������������������<uicontrol>������������
ISO ������������������������������</uicontrol>���������������������
+</li>
+<li>��������������� ISO ������������������������������������<uicontrol>���ISO
���������������������</uicontrol>���������������������������
+</li>
+</ul></li>
+</ul></p>
+</csbody>
+</cshelp>
+</cshelp>
+
+
+<!-- ENGL1SH_VERS10N 61085_5 DO NOT REMOVE OR CHANGE THIS LINE -->
+<!-- T9N_SRC_ID 229 -->
+<!-- T9N_SH1P_STR1NG KV211AAP001 1 -->
diff --git a/src/wok/plugins/kimchi/ui/pages/help/kimchi.css
b/src/wok/plugins/kimchi/ui/pages/help/kimchi.css
new file mode 100644
index 0000000..32fae4a
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/pages/help/kimchi.css
@@ -0,0 +1,208 @@
+/*
+ * Project Kimchi
+ *
+ * Copyright IBM, Corp. 2014
+ *
+ * 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.
+ */
+BODY {
+ background: #FFFFFF;
+ margin-bottom: 1em;
+ margin-left: .5em;
+}
+
+bold {
+ font-weight: bold;
+}
+
+boldItalic {
+ font-weight: bold;
+ font-style: italic;
+}
+
+italic {
+ font-style: italic;
+}
+
+underlined {
+ text-decoration: underline;
+}
+
+uicontrol {
+ font-weight: bold;
+}
+
+filepath {
+ font-family: monospace, monospace;
+}.option {
+ font-family: monospace, monospace;
+}
+
+cmdname {
+ font-weight: bold;
+ font-family: monospace, monospace;
+}
+
+.defparmname {
+ font-weight: bold;
+ text-decoration: underline;
+ font-family: monospace, monospace;
+}
+
+.kwd {
+ font-weight: bold;
+}
+
+.defkwd {
+ font-weight: bold;
+ text-decoration: underline;
+}
+
+var {
+ font-style : italic;
+}
+
+strongwintitle {
+ font-weight : bold;
+}
+
+parmname {
+ font-weight: bold;
+ font-family: monospace, monospace;
+ white-space: nowrap;
+}
+
+code {
+ font-family: monospace, monospace;
+}
+
+pre {
+ font-family: monospace, monospace;
+}
+
+CITE {
+ font-style: italic;
+}
+
+EM {
+ font-style: italic;
+}
+
+STRONG {
+ font-weight: bold;
+}
+
+VAR {
+ font-style: italic;
+}
+
+dt {
+ font-weight: bold;
+}
+
+/***********************************************************
+ * Basic fonts
+ ***********************************************************/
+body,
+td,
+th,
+caption {
+ font-family: Verdana, Arial, Helvetica, sans-serif;
+ font-size: 10pt;
+}
+
+pre, code {
+ font-family: MS Courier New, Courier, monospace;
+}
+
+h1, h2, h3 {
+ font-size: 12pt;
+ font-weight: bold;
+ color: #336699;
+}
+
+h4 {
+ font-size: 10pt;
+ font-weight: bold;
+ color: #336699;
+}
+
+/***********************************************************
+ * Basic indents, padding, and margin
+ ***********************************************************/
+body {
+ color: black;
+ background-color: white;
+ margin: 0;
+ padding-top: 0.2em;
+ padding-left: 0.6em;
+ padding-right: 0.2em;
+ padding-bottom: 1em;
+}
+
+h1,
+h2,
+h3,
+h4,
+h5,
+h6 {
+ padding: 0;
+ margin-top: 1em;
+ margin-bottom: 0.75em;
+ margin-left: 0;
+ margin-right: 0;
+}
+
+address,
+dl,
+li,
+p {
+ padding: 0;
+ margin-top: 0.75em;
+ margin-bottom: 0.75em;
+ margin-left: 0;
+ margin-right: 0;
+ line-height: 125%;
+}
+
+td dl {
+ margin-left: 2em;
+}
+
+pre {
+ padding: 0;
+ margin-top: 0.75em;
+ margin-bottom: 0.75em;
+ margin-left: 2em;
+ margin-right: 0;
+}
+
+ol,
+ul {
+ padding: 0;
+ margin-top: 0.75em;
+ margin-bottom: 0.75em;
+ margin-left: 2.00em;
+ margin-right: 0;
+}
+
+dd {
+ margin-left: 3.00em;
+ margin-top: 0.75em;
+ margin-bottom: 0.75em;
+}
+
+dt {
+ margin-left: 1.00em;
+ margin-top: 0.75em;
+}
diff --git a/src/wok/plugins/kimchi/ui/pages/help/ko_KR/Makefile.am
b/src/wok/plugins/kimchi/ui/pages/help/ko_KR/Makefile.am
new file mode 100644
index 0000000..e441955
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/pages/help/ko_KR/Makefile.am
@@ -0,0 +1,23 @@
+# Copyright IBM Corp, 2014
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+ko_KR_helpdir = $(datadir)/wok/plugins/kimchi/ui/pages/help/ko_KR
+
+dist_ko_KR_help_DATA = $(wildcard *.html) $(NULL)
+
+EXTRA_DIST = $(wildcard *.dita)
+
+CLEANFILES = $(wildcard *.html)
diff --git a/src/wok/plugins/kimchi/ui/pages/help/ko_KR/guests.dita
b/src/wok/plugins/kimchi/ui/pages/help/ko_KR/guests.dita
new file mode 100644
index 0000000..2d9f32b
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/pages/help/ko_KR/guests.dita
@@ -0,0 +1,119 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--Arbortext, Inc., 1988-2011, v.4002-->
+<!DOCTYPE cshelp PUBLIC "-//IBM//DTD DITA CSHelp//EN"
+ "..\dtd\cshelp.dtd">
+
+
+<!--This DITA specialized document type is not supported by the Authoring Tools
development team.
+For support please see:
+https://w3.opensource.ibm.com/projects/dita-cshelp/-->
+<cshelp id="kimhvirtm" xml:lang="ko-kr">
+<title>���������</title>
+<shortdesc><wintitle>���������</wintitle> ��������������� ��������� KVM
������ ��������� ���������������.</shortdesc>
+<csbody>
+<p>��� ������������ ������ ������ ���������
���������������.<dl><dlentry>
+<dt>������</dt>
+<dd>������ ��������� ���������������.</dd>
+</dlentry><dlentry>
+<dt>CPU</dt>
+<dd>������ ��������� ������������ ������������������.</dd>
+</dlentry><dlentry>
+<dt>������������ I/O</dt>
+<dd>������ ������������ ���/������(I/O) ������ ������(KB)���������.</dd>
+</dlentry><dlentry>
+<dt>��������� I/O</dt>
+<dd>������ ��������� ���/������(I/O) ������ ������(KB)���������.</dd>
+</dlentry><dlentry>
+<dt>���������������</dt>
+<dd>��������� ������ ��������� ���������������, ������������ ��������� ������
������ <tm tmtype="tm" trademark="Linux">Linux</tm>
��������� ������������ ������������������.</dd>
+</dlentry></dl></p>
+<p>������ ������ ������������ ��� ��������������� ���������������.<dl>
+<dlentry>
+<dt>������ ������</dt>
+<dd>������������ ������ ��������������� ���������������. </dd>
+</dlentry><dlentry>
+<dt>������(������ ������ ������)</dt>
+<dd>������������ ��������� ��������� ��������� ���������������. ������������
��������������� ��������� ������ ��������� ������������ ������������ ��������� ������
������������.</dd>
+</dlentry></dl> </p>
+<p>��� ��������������� ������ ��������� ��������� ��� ������������.<ul>
+<li>��������� ������ ��������� ������ ��������� ���������������
<uicontrol>������</uicontrol>��� ���������������.</li>
+<li>��������� ������ ��������� ��������������� <uicontrol>������
������</uicontrol>��� ���������������.</li>
+<li>������������ ������ ��������������� <uicontrol>������
������</uicontrol>��� ���������������.</li>
+<li>������ ������������ ��������� ���������������
<uicontrol>������</uicontrol>��� ���������������. ������������ ������
��������� ������ ��������� ��� ������������.</li>
+<li>������������ ��������������� <uicontrol>������</uicontrol>���
���������������.</li>
+</ul>��������� ������ ������ ��������� ��������������� ��������� ���������
��������� ������ <uicontrol>���������(+)</uicontrol> ������������
���������������.</p>
+</csbody>
+<cshelp id="kimhvirtmcrt" xml:lang="ko-kr">
+<title>������ ������ ������</title>
+<shortdesc>������ ��������������� ������������ ������ ���������
���������������.</shortdesc>
+<csbody>
+<p> <ol>
+<li>������ ��������� ������������ ��� ��������� ���������
������������������.</li>
+<li rev="rev1">��������������� ������������������. <ul>
+<li>��������������� ������������ ������, ��������� ������������ ���������
������������������.</li>
+<li>��������������� ������ ������, <uicontrol>������������
������</uicontrol>��� ������������ ��������������� ������������������.</li>
+</ul></li>
+<li><uicontrol>������</uicontrol>��� ������������������.</li>
+</ol> </p>
+</csbody>
+</cshelp>
+<cshelp id="kimhvirtmedit" xml:lang="ko-kr">
+<title>��������� ������</title>
+<shortdesc>������ ������ ��������� ��������� ���������������. ������ ���������
������������ ��������� ������������ ��������� ��� ������������.
+������ ��������� ������ ������������ ���������������. </shortdesc>
+<csprolog><csmetadata></csmetadata></csprolog>
+<csbody>
+<p>��� ������������ ������ ������ ��������� <wintitle>������</wintitle>
������ ���������������.<dl>
+<dlentry>
+<dt>������</dt>
+<dd>������ ��������� ���������������(������������ ��������� ������������ ���������
��� ������).</dd>
+</dlentry><dlentry>
+<dt>CPU</dt>
+<dd>������������ ������������(������������ ������ ������ ������ ��� ���������
������ ������������ ���������).</dd>
+</dlentry><dlentry>
+<dt>���������</dt>
+<dd>��������� ������(MB)���������(������������ ������ ������ ������ ��� ���������
������ ������������ ���������).</dd>
+</dlentry><dlentry>
+<dt>���������</dt>
+<dd>������������ ��������� ������ ��� ������ ������(���������������) ���������
��������� Linux ��������� ������������ ��������� ������������������.</dd>
+</dlentry></dl></p>
+<p>������ ��������� <wintitle>������������</wintitle> ������
���������������.</p>
+<dl><dlentry>
+<dt>������������</dt>
+<dd>��������� ��������� ISO ��������� ��������� ���������������.</dd>
+</dlentry></dl>
+<p> ������ ������������ ������������ ������ ��������� ��������� ��� ������������.
��������� ��������� ������ <uicontrol>������</uicontrol>��� ���������������.
</p>
+</csbody>
+</cshelp>
+<cshelp id="kimstoragedevice" xml:lang="ko-kr">
+<title>������������ ������ ������, ������ ������ ������</title>
+<shortdesc rev="rev1">������ ��������� ������ ������������ ���������
������, ������ ������ ��������� ��� ������������. ������������ ���������
CDROM������������. ������������ ��������� ��������������� ������ ���������
������������������.</shortdesc>
+<csbody>
+<ol>
+<li><wintitle>��������� ������</wintitle> ���������
<wintitle>������������</wintitle>��� ������������������.</li>
+<li>������������ ��������� ��������������� <uicontrol>���������
���������(/)</uicontrol>��� ������ ��� ������ ������������ ������������������. ISO
������ ��������� ������������ <uicontrol>������</uicontrol>���
������������������.</li>
+<li>������������ ��������� ��������������� <uicontrol>���������
������(-)</uicontrol>��� ������ ��� ������ ������������ ������������������. ������
��������� ������������ <uicontrol>������</uicontrol>���
������������������.</li>
+<li>������������ ��������� ��������������� ������ <uicontrol>���������
������(+)</uicontrol>��� ������ ��� ������ ������������ ������������������. ������
������ ��� ISO ������ ��������� ������������ <uicontrol>������</uicontrol>���
������������������.</li>
+</ol>
+</csbody>
+</cshelp>
+<cshelp id="kimreplacemedia" xml:lang="ko-kr">
+<title>VM��� CDROM ������</title>
+<shortdesc rev="rev1">��������� ��������� ������ ������ ��������� ������
CDROM��� ������������ ������ ��� ������������.</shortdesc>
+<csbody>
+<ol>
+<li>������ ��������� ������������������ ������������������.</li>
+<li>������ ������������ <uicontrol>������ ������</uicontrol>���
������������������.</li>
+<li>CDROM��� ������ ��������� ��������� ������������ ������ hdc ������ ������
������ <uicontrol>��������� ���������(/)</uicontrol> ������������
������������������.</li>
+<li><wintitle>VM��� CDROM ������</wintitle> ��������������� ISO ������
��������� ������������������. ������ ��� ��������� ������ ���������������.</li>
+<li><uicontrol>������</uicontrol>��� ������������������.</li>
+</ol>
+</csbody>
+</cshelp>
+<?tm 1391540919 3?>
+</cshelp>
+
+
+<!-- ENGL1SH_VERS10N 45645_6 DO NOT REMOVE OR CHANGE THIS LINE -->
+<!-- T9N_SRC_ID 231 -->
+<!-- T9N_SH1P_STR1NG KV211AAP001 1 -->
diff --git a/src/wok/plugins/kimchi/ui/pages/help/ko_KR/host.dita
b/src/wok/plugins/kimchi/ui/pages/help/ko_KR/host.dita
new file mode 100644
index 0000000..ee4a9c3
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/pages/help/ko_KR/host.dita
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--Arbortext, Inc., 1988-2011, v.4002-->
+<!DOCTYPE cshelp PUBLIC "-//IBM//DTD DITA CSHelp//EN"
+ "..\dtd\cshelp.dtd">
+
+
+<!--This DITA specialized document type is not supported by the Authoring Tools
development team.
+For support please see:
+https://w3.opensource.ibm.com/projects/dita-cshelp/-->
+<cshelp id="kimhhost" xml:lang="ko-kr">
+<title>���������</title>
+<shortdesc><wintitle>���������</wintitle> ��������������� ���������
������������ ������ ��������� ������������ ��� ������������ ������������ ������������
������ ��� ������ ��������������� ������������ ��������� ���
������������.</shortdesc>
+<csbody>
+<p>������������ ������ ������ ��������� ��������� ��� ������������.<ul>
+<li>��������� ������������ ��������������� <uicontrol>���������
������</uicontrol>��� ���������������.</li>
+<li>��������� ������������ ������ ��������������� <uicontrol>������
������</uicontrol>��� ���������������.</li>
+<li>������ ������������ ������ ������ ������, ��������� ������������ ������ VNC
��������� ��������������� <uicontrol>������</uicontrol>���
���������������.</li>
+</ul></p>
+<p>������������ ������ ��������� ��������������� ������ ���������
������������������.<dl>
+<dlentry>
+<dt>������ ������</dt>
+<dd>��� ������������ ��������� ������ ������ ������, ������, ������ ������,
������������ ������, ��������� ������(GB) ������ ���������������.</dd>
+</dlentry><dlentry>
+<dt>��������� ������</dt>
+<dd>��� ������������ ������������ CPU, ���������, ��������� I/O, ������������
I/O��� ������ ��������� ������������ ������������ ���������������. ��������� ������
��������� ��� ��������� ��������� ��������������� <uicontrol>��� ������������ ������
������ ��������� ������</uicontrol>��� ���������������.</dd>
+</dlentry><dlentry>
+<dt>��������������� ������������</dt>
+<dd>��� ������������ ��������� ������, ������, ������������, ������������
������������ ������ ��������� ��������������� ������ ������ ������������ ������ ���������
���������������. <uicontrol>������ ������������</uicontrol>��� ������������
��������� ������ ������������ ��������������� ��� ������������. ��������������� ������
������ ������������ ��������� ������ ������������.</dd>
+</dlentry><dlentry>
+<dt>���������</dt>
+<dd>��� ������������ ��������� ������������ ��������� ������������ ���������������.
������������ ���������������, ������������ ���������������, ���������������, ��������� ���
������������. ������������ ������������ ������������ ��������� ������������ ������������,
������������ ������������ ������������ ������������ ������������ ������������ ���
������������. ������ ������������ Red Hat Enterprise Linux ������ Fedora��� ������,
<filepath>yum</filepath> ������������ ��������� ��� ������������.
+������ ������������ Ubuntu ������ Debian��� ������, <filepath>deb</filepath>
������������ ������������������.<p>yum ������������ ������������ ������, GPG
��������� ������������ ��� ������������ ������������ ������������ ������������ ���������
��� ������������.
+������������ ��������� ��� <uicontrol>������</uicontrol>���
������������������. <uicontrol>���</uicontrol>��� ������������ GPG ���������
������������ ��������� ��� ������������ ������ GPG ��� ��������� URL���
������������������.</p></dd>
+</dlentry><dlentry>
+<dt>��������� ���������</dt>
+<dd>��� ������������ ������ ��� ������ ��������� ��������� ��������� ������������
���������������.
+��� ��������� ������, ������ ��������� ������ ���������, ������, ������������ ������
������ ��������� ��������� ��� ������������.<p>��������� ������������
<cmdname>sosreport</cmdname> ��������� ������������ ���������������. ������
Red Hat Enterprise <tm tmtype="tm"
trademark="Linux">Linux</tm>, Fedora ��� Ubuntu ������������ ������
���������������. ��� ��������� ������ ��� ������ ������(���: ������ ������ ������ ������,
��������� ������, ��������� ��� ��������� ������ ������)��� ������������ .tar ���������
���������������.
+������ ��� ��������� ������ ��������������� ������������ ������ ��������� ������������
������ ��������������� ��� ��������� ���������������.</p> </dd>
+</dlentry></dl></p>
+</csbody>
+<?tm 1392659967 1?>
+</cshelp>
+
+
+<!-- ENGL1SH_VERS10N 47930_4 DO NOT REMOVE OR CHANGE THIS LINE -->
+<!-- T9N_SRC_ID 232 -->
+<!-- T9N_SH1P_STR1NG KVM21AAP001 3 -->
diff --git a/src/wok/plugins/kimchi/ui/pages/help/ko_KR/network.dita
b/src/wok/plugins/kimchi/ui/pages/help/ko_KR/network.dita
new file mode 100644
index 0000000..451510f
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/pages/help/ko_KR/network.dita
@@ -0,0 +1,61 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--Arbortext, Inc., 1988-2011, v.4002-->
+<!DOCTYPE cshelp PUBLIC "-//IBM//DTD DITA CSHelp//EN"
+ "..\dtd\cshelp.dtd">
+
+
+<!--This DITA specialized document type is not supported by the Authoring Tools
development team.
+For support please see:
+https://w3.opensource.ibm.com/projects/dita-cshelp/-->
+<cshelp id="kimhnetw" xml:lang="ko-kr">
+<title>������������</title>
+<shortdesc><wintitle>������������</wintitle> ���������������
������������ ��������� ������ ��������� ���������������.</shortdesc>
+<csbody>
+<p><dl><dlentry>
+<dt>������������ ������</dt>
+<dd>��������������� ������ ������
<uicontrol>���������</uicontrol>���������.</dd>
+</dlentry><dlentry>
+<dt>������</dt>
+<dd>��������������� ������(��������� ������ ������, ������������ ������
���������)���������. </dd>
+</dlentry><dlentry>
+<dt>������������ ������</dt>
+<dd>������������ ���������������. ���:
<uicontrol>NAT</uicontrol>(Network Address Translation)</dd>
+</dlentry><dlentry>
+<dt>���������������</dt>
+<dd>������������ ������������������������. ���:
<uicontrol>virbr0</uicontrol>(���������)</dd>
+</dlentry><dlentry>
+<dt>������ ������</dt>
+<dd>IP ���������������.</dd>
+</dlentry></dl></p>
+<p>������ ��������� ��������� ��� ������������.<ul>
+<li rev="rev1">������������ ��������� ���������������
<uicontrol>������</uicontrol>��� ���������������.</li>
+<li>������������ ��������� ���������������
<uicontrol>������</uicontrol>��� ���������������.</li>
+<li>������ ��������� ��������������� <uicontrol>������</uicontrol>���
���������������.</li>
+</ul>��������������� ��������������� ������ ��������� ��������� ������
<uicontrol>���������(+)</uicontrol> ������������ ���������������.</p>
+</csbody>
+<cshelp id="kimhnetwcrt" xml:lang="ko-kr">
+<title>������������ ������</title>
+<shortdesc>��������������� ���������������.</shortdesc>
+<csbody>
+<p> <ol>
+<li>��������������� ��������� ������������������.</li>
+<li>������������ ��������� ��������������� ������������������. <dl
rev="rev1"><dlentry>
+<dt><uicontrol>���������</uicontrol></dt>
+<dd>������ ���������������. ������������ ������ ������������ ������ ���������
������������ ������ ��� ������������.</dd>
+</dlentry><dlentry>
+<dt><uicontrol>NAT</uicontrol></dt>
+<dd>Network Address Translation ���������������. ������������ ������
��������������� ��������� ������������ ��������� IP ��������� ���������������. ������
������������ ��������������� ��������� ��������� ��� ������������.</dd>
+</dlentry><dlentry>
+<dt><uicontrol>������������</uicontrol></dt>
+<dd>��������� ���������������. ������������ ������ ������������ ��������� ���
������ ������ ������������ ������������������ ��������� ��������������� ������������
��������� ��� ������������. ��������� ��������� ������, ������ ��������� ��� VLAN
��������� ������������ ���������.</dd>
+</dlentry></dl></li>
+<li><uicontrol>������</uicontrol>��� ������������������.</li>
+</ol> </p>
+</csbody>
+</cshelp>
+</cshelp>
+
+
+<!-- ENGL1SH_VERS10N 47050_3 DO NOT REMOVE OR CHANGE THIS LINE -->
+<!-- T9N_SRC_ID 230 -->
+<!-- T9N_SH1P_STR1NG KVM21AAP001 3 -->
diff --git a/src/wok/plugins/kimchi/ui/pages/help/ko_KR/storage.dita
b/src/wok/plugins/kimchi/ui/pages/help/ko_KR/storage.dita
new file mode 100644
index 0000000..2e6f5e8
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/pages/help/ko_KR/storage.dita
@@ -0,0 +1,86 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--Arbortext, Inc., 1988-2011, v.4002-->
+<!DOCTYPE cshelp PUBLIC "-//IBM//DTD DITA CSHelp//EN"
+ "..\dtd\cshelp.dtd">
+
+
+<!--This DITA specialized document type is not supported by the Authoring Tools
development team.
+For support please see:
+https://w3.opensource.ibm.com/projects/dita-cshelp/-->
+<cshelp id="kimhstor" xml:lang="ko-kr">
+<title>������������</title>
+<shortdesc><wintitle>������������</wintitle> ��������������� ������
��������� ��� ������ '������' ��� 'ISO' ������������ ������ ������������
������ ��������� ������������ ������ ���������������.
+��������� ������ ISO��� ��������������� ������ 'ISO' ������������ ��� ���������
������������������.</shortdesc>
+<csbody>
+<p>��� ������������ ������ ������ ������ ��������� ���������������.<dl>
+<dlentry>
+<dt>������</dt>
+<dd>������������ ������ ������ ��� ������������������.</dd>
+</dlentry><dlentry>
+<dt>������</dt>
+<dd>������������ ������ ������(��������� ������ ������, ������������ ������
���������)���������. </dd>
+</dlentry><dlentry>
+<dt>������</dt>
+<dd>������������ ������ ��������� ������ ������ ���������������.</dd>
+</dlentry><dlentry>
+<dt>������</dt>
+<dd>������������ ������ ���������������. ���:
<uicontrol>dir</uicontrol></dd>
+</dlentry><dlentry>
+<dt>������</dt>
+<dd>������������ ��������� ��������� ������������.</dd>
+</dlentry><dlentry>
+<dt>���������</dt>
+<dd>������������ ������ ������ ��������� ��������� ������������.</dd>
+</dlentry></dl></p>
+<p>��� ������������ ��������� ������ ��������� ��������� ���
������������.<ul>
+<li>������ ��������������� ������������ ������ ������������������
<uicontrol>���������</uicontrol>��� ���������������.</li>
+<li>������������ ������ ���������������������
<uicontrol>������������</uicontrol>��� ���������������.</li>
+<li>��������� ������������ ������ ��������������� <uicontrol>������
������</uicontrol>��� ���������������.</li>
+</ul></p>
+<p>������������ ������ ������ ������������ ������ ��������������� ���������������
������������ ��� ������ ������������ ������ ������������ ������������������.
������������������ ��������� ���������������.<dl><dlentry>
+<dt>������</dt>
+<dd>��������� ���������������. ���:
<uicontrol>������</uicontrol></dd>
+</dlentry><dlentry>
+<dt>������</dt>
+<dd>��������� ��������� ������ ���������������.</dd>
+</dlentry><dlentry>
+<dt>������</dt>
+<dd>������������ ��������� ���������������.</dd>
+</dlentry><dlentry>
+<dt>������</dt>
+<dd>������������ ������ ������ ��������� ��������� ������������.</dd>
+</dlentry></dl>������������ ������ ��������������� ������ ��������� ���������
������ <uicontrol>���������(+)</uicontrol> ������������
���������������.</p>
+</csbody>
+<cshelp id="kimhdefstor" xml:lang="ko-kr">
+<title>������������ ��� ������</title>
+<shortdesc> ������������ ������ ���������������.</shortdesc>
+<csbody>
+<p> <ol>
+<li><uicontrol>������������ ��� ������</uicontrol> ������������,
������������ ������ ������������ ��� ��������� ��������� ������������������.</li>
+<li><uicontrol>������������ ��� ������</uicontrol> ������������ ������
��������� ������������������. <dl><dlentry>
+<dt><uicontrol>DIR</uicontrol></dt>
+<dd>������������ ������ ���������������. <uicontrol>DIR</uicontrol>
��������� ��������� ������, <uicontrol>������������
������</uicontrol>(������������ ������ ������ ������)���
���������������.</dd>
+</dlentry><dlentry>
+<dt><uicontrol>NFS</uicontrol></dt>
+<dd>������������ ������ ��������� ������ ���������������.
<uicontrol>NFS</uicontrol>��� ��������� ������, <uicontrol>NFS ������ IP
������</uicontrol> ��� <uicontrol>NFS ������</uicontrol>(������
��������������� ������)��� ���������������.</dd>
+</dlentry><dlentry>
+<dt><uicontrol>iSCSI</uicontrol></dt>
+<dd>iSCSI ��������� ��������� ��������� ������������ ������ ���������������.
+<uicontrol>iSCSI</uicontrol>��� ��������� ������, iSCSI ��������� ������
<uicontrol>iSCSI ������ IP ������</uicontrol> ���
<uicontrol>������</uicontrol>��� ���������������. ���������������, iSCSI
��������� ��������������� ��������� ��� ������������.</dd>
+</dlentry><dlentry>
+<dt><uicontrol>���������</uicontrol></dt>
+<dd>��������� ������ ������������ ������ ���������������. <uicontrol>������
������</uicontrol>������ ��������� ������ ��������� ���������������.</dd>
+</dlentry><dlentry>
+<dt><uicontrol>SCSI ��������� ������</uicontrol></dt>
+<dd>SCSI ��������� ��������� ������������ ������ ���������������. ��������� SCSI
������������ ���������������.</dd>
+</dlentry></dl></li>
+<li><uicontrol>������</uicontrol>��� ������������������.</li>
+</ol> </p>
+</csbody>
+</cshelp>
+</cshelp>
+
+
+<!-- ENGL1SH_VERS10N 22336_4 DO NOT REMOVE OR CHANGE THIS LINE -->
+<!-- T9N_SRC_ID 233 -->
+<!-- T9N_SH1P_STR1NG KV211AAP001 1 -->
diff --git a/src/wok/plugins/kimchi/ui/pages/help/ko_KR/templates.dita
b/src/wok/plugins/kimchi/ui/pages/help/ko_KR/templates.dita
new file mode 100644
index 0000000..de16d6e
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/pages/help/ko_KR/templates.dita
@@ -0,0 +1,111 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--Arbortext, Inc., 1988-2011, v.4002-->
+<!DOCTYPE cshelp PUBLIC "-//IBM//DTD DITA CSHelp//EN"
+ "..\dtd\cshelp.dtd">
+
+
+<!--This DITA specialized document type is not supported by the Authoring Tools
development team.
+For support please see:
+https://w3.opensource.ibm.com/projects/dita-cshelp/-->
+<cshelp id="kimhtempl" xml:lang="ko-kr">
+<title>������������</title>
+<shortdesc><wintitle>������������</wintitle> ��������������� KVM
������������ ������������ ��� ��������� ��� ������ ��������� ������ ������ ���������������
���������������.</shortdesc>
+<csbody>
+<p>��� ��������������� ������ ������ ��������� ���������������.<dl>
+<dlentry>
+<dt>OS</dt>
+<dd>������ ������ ������ ��������� ���������������.</dd>
+</dlentry><dlentry>
+<dt>������</dt>
+<dd>������ ������ ������ ��������� ���������������.</dd>
+</dlentry><dlentry>
+<dt>CPU</dt>
+<dd>��������������� ������ ��������� ��������������� ������������.</dd>
+</dlentry><dlentry>
+<dt>���������</dt>
+<dd>��������� RAM(Random Access Memory)��� ���(MB)���������.</dd>
+</dlentry></dl></p>
+<p>��� ������������������ ������ ��������� ��������� ��� ������������.<ul>
+<li>��������������� ��������������� <uicontrol>������</uicontrol>���
���������������.</li>
+<li>��������������� ��������������� <uicontrol>������</uicontrol>���
���������������.</li>
+</ul>��������������� ��������������� ������ ��������� ��������� ������
<uicontrol>���������(+)</uicontrol> ������������ ���������������.</p>
+</csbody>
+<cshelp id="kimhedittempl" xml:lang="ko-kr">
+<title>������������ ������</title>
+<shortdesc>������ ��������������� ���������������.</shortdesc>
+<csbody>
+<p>��� ��������������� ������ ������ ��������� ���������������. <dl>
+<dlentry>
+<dt>������</dt>
+<dd>��������������� ���������������.</dd>
+</dlentry><dlentry>
+<dt>������������</dt>
+<dd>��������������� ��������������� ��������� ������ ������ ������ ���������
��������� ��������� ���������������.</dd>
+</dlentry><dlentry>
+<dt>������</dt>
+<dd>��������������� ��������������� ��������� ������ ������ ������ ���������
���������������.</dd>
+</dlentry><dlentry>
+<dt>CPU ���</dt>
+<dd>��������������� ������ ��������� ��������������� ������������.</dd>
+</dlentry><dlentry>
+<dt>���������</dt>
+<dd>������ ��������� ��������� ��������� ������(MB)���������.</dd>
+</dlentry><dlentry>
+<dt>���������</dt>
+<dd>��������� ������(GB)���������.</dd>
+</dlentry><dlentry>
+<dt>CDROM</dt>
+<dd>KVM ������������ ������������ ��� ��������� ISO ��������� ��������� ������
������ ���������������.</dd>
+</dlentry><dlentry>
+<dt>������������ ���</dt>
+<dd>������ ������������ ��� ������ ������ ������������ ������������.</dd>
+</dlentry><dlentry>
+<dt>������������</dt>
+<dd>KVM ������������ ������ ��������� ������ ������������ ������������������������.
������ ��������������� ��������� ��� ������������.</dd>
+</dlentry></dl> ������ ������������ ������������ ������ ��������� ���������
��� ������������. ��������� ��������� ������ <uicontrol>������</uicontrol>���
���������������. </p>
+</csbody>
+</cshelp>
+<cshelp id="kimhaddtempl">
+<title>������������ ������</title>
+<shortdesc>������ ��������������� ��������������� ���������������. ������ ���������
������ 'ISO' ������������ ������ ��������� ������ ISO ������������ ��������� ���
������������. </shortdesc>
+<csbody>
+<p>������ ������ ��������� ������ ��������� ���������
������������������.<dl>
+<dlentry>
+<dt>������ ISO ���������</dt>
+<dd>��������������� ������ ��������� ������ ISO ������������ ������������ ������
��������������� ���������������.</dd>
+</dlentry><dlentry>
+<dt>������ ISO ���������</dt>
+<dd>������ ISO ������������ ������ ��������� ���������������
���������������.</dd>
+</dlentry></dl></p>
+</csbody>
+</cshelp>
+<cshelp id="kimhaddloct">
+<title>������������ ������ - ������ ISO ���������</title>
+<shortdesc>������ ISO ������������������ ���������������
���������������.</shortdesc>
+<csbody>
+<p>��������������� ������ ��������� ISO ������������
���������������.<dl><dlentry>
+<dt>OS</dt>
+<dd>������ ������ ������ ��������� ���������������.</dd>
+</dlentry><dlentry>
+<dt>������</dt>
+<dd>������ ������ ������ ��������� ���������������.</dd>
+</dlentry><dlentry>
+<dt>������</dt>
+<dd>ISO ������������ ���������������.</dd>
+</dlentry></dl></p>
+<p>ISO ������������������ ��������������� ��������������� ������ ������ ���������
������������������.<ul>
+<li>��������������� ������������ ������ ISO ������������ ��������� ���
<uicontrol>��������� ISO��������� ������������ ������</uicontrol>���
���������������.</li>
+<li>��������� ��� ISO ������������������ ��������������� ���������������
<uicontrol>������</uicontrol>��� ��������� ��� <uicontrol>���������
ISO��������� ������������ ������</uicontrol>��� ���������������.</li>
+<li>��������������� ISO ������������ ������ ��������� ������������ ������ ������,
������ ������ ��������� ��������� ��� ������������.<ul>
+<li>ISO ������������ ��������� ��������������� <uicontrol>������ ISO
��������� ��������������� ���������.</uicontrol>��� ���������������.</li>
+<li>������ ISO ������������ ��������������� <uicontrol>������ ISO
������</uicontrol>��� ���������������.</li>
+</ul></li>
+</ul></p>
+</csbody>
+</cshelp>
+</cshelp>
+
+
+<!-- ENGL1SH_VERS10N 61085_5 DO NOT REMOVE OR CHANGE THIS LINE -->
+<!-- T9N_SRC_ID 229 -->
+<!-- T9N_SH1P_STR1NG KV211AAP001 1 -->
diff --git a/src/wok/plugins/kimchi/ui/pages/help/pt_BR/Makefile.am
b/src/wok/plugins/kimchi/ui/pages/help/pt_BR/Makefile.am
new file mode 100644
index 0000000..7fc2cb0
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/pages/help/pt_BR/Makefile.am
@@ -0,0 +1,23 @@
+# Copyright IBM Corp, 2014
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+pt_BR_helpdir = $(datadir)/wok/plugins/kimchi/ui/pages/help/pt_BR
+
+dist_pt_BR_help_DATA = $(wildcard *.html) $(NULL)
+
+EXTRA_DIST = $(wildcard *.dita)
+
+CLEANFILES = $(wildcard *.html)
diff --git a/src/wok/plugins/kimchi/ui/pages/help/pt_BR/guests.dita
b/src/wok/plugins/kimchi/ui/pages/help/pt_BR/guests.dita
new file mode 100644
index 0000000..ac58d5c
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/pages/help/pt_BR/guests.dita
@@ -0,0 +1,137 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--Arbortext, Inc., 1988-2011, v.4002-->
+<!DOCTYPE cshelp PUBLIC "-//IBM//DTD DITA CSHelp//EN"
+ "..\dtd\cshelp.dtd">
+
+
+<!--This DITA specialized document type is not supported by the Authoring Tools
development team.
+For support please see:
+https://w3.opensource.ibm.com/projects/dita-cshelp/-->
+<cshelp id="kimhvirtm" xml:lang="pt-br">
+<title>M��quinas Virtuais</title>
+<shortdesc>A p��gina <wintitle>M��quinas Virtuais</wintitle> lista as
m��quinas virtuais
+KVM definidas.</shortdesc>
+<csbody>
+<p>Para cada convidado, as informa����es a seguir s��o
exibidas:<dl><dlentry>
+<dt>Nome</dt>
+<dd>Nome da m��quina virtual.</dd>
+</dlentry><dlentry>
+<dt>CPU</dt>
+<dd>Porcentagem de utiliza����o do processador na m��quina virtual.</dd>
+</dlentry><dlentry>
+<dt>E/S de rede</dt>
+<dd>Taxa de transmiss��o de entrada/sa��da de rede em KB por segundo.</dd>
+</dlentry><dlentry>
+<dt>E/S de disco</dt>
+<dd>Taxa de transmiss��o de entrada/sa��da de disco em KB por segundo.</dd>
+</dlentry><dlentry>
+<dt>Livetile</dt>
+<dd>Estado do console do sistema operacional guest ou um ��cone que representa
+a distribui����o <tm tmtype="tm"
trademark="Linux">Linux</tm> se o
+convidado n��o estiver ativo.</dd>
+</dlentry></dl></p>
+<p>Os ��cones de a����es a seguir s��o exibidos para cada convidado:<dl>
+<dlentry>
+<dt>Reiniciar</dt>
+<dd>Clique para Reiniciar o convidado. </dd>
+</dlentry><dlentry>
+<dt>Energia (iniciar ou parar)</dt>
+<dd>Clique para ligar ou desligar o convidado. Se o ��cone estiver vermelho,
+a energia est�� desligada; se o ��cone estiver verde, a energia est�� ligada.</dd>
+</dlentry></dl> </p>
+<p>As a����es a seguir podem ser selecionadas para cada convidado:<ul>
+<li>Selecione <uicontrol>Conectar</uicontrol> para conectar-se ao
console
+remoto para o sistema operacional guest.</li>
+<li>Selecione <uicontrol>Gerenciar m��dia</uicontrol> para alterar o
caminho
+para a m��dia de instala����o.</li>
+<li>Selecione <uicontrol>Reiniciar</uicontrol> para Reiniciar o
convidado.</li>
+<li>Selecione <uicontrol>Editar</uicontrol> para editar as propriedades
de um
+convidado existente. Os M��quinas Virtuais podem ser editados somente quando
interrompidos.</li>
+<li>Selecione <uicontrol>Excluir</uicontrol> para excluir o
convidado.</li>
+</ul>Para criar um convidado, ou m��quina virtual, clique no ��cone
<uicontrol>mais
+(+)</uicontrol> na parte superior direita da p��gina.</p>
+</csbody>
+<cshelp id="kimhvirtmcrt" xml:lang="en-us">
+<title>Criar m��quina virtual</title>
+<shortdesc>Crie uma m��quina virtual usando um modelo existente.</shortdesc>
+<csbody>
+<p> <ol>
+<li>Digite o nome a ser usado para identificar a m��quina virtual.</li>
+<li rev="rev1">Selecione um modelo. <ul>
+<li>Se existirem modelos, selecione a partir dos modelos exibidos.</li>
+<li>Se n��o existir nenhum modelo, clique em <uicontrol>Criar um
modelo</uicontrol> para
+criar um modelo.</li>
+</ul></li>
+<li>Clique em <uicontrol>Criar</uicontrol>.</li>
+</ol> </p>
+</csbody>
+</cshelp>
+<cshelp id="kimhvirtmedit" xml:lang="en-us">
+<title>Editar convidado</title>
+<shortdesc>Edite as propriedades de uma m��quina virtual existente. Algumas
propriedades podem ser editadas enquanto o convidado est�� interrompido. Outras entrar��o
em vigor na pr��xima inicializa����o.</shortdesc>
+<csprolog><csmetadata></csmetadata></csprolog>
+<csbody>
+<p>Para cada convidado, as informa����es a seguir s��o exibidas na guia
<wintitle>Geral</wintitle>:<dl>
+<dlentry>
+<dt>Nome</dt>
+<dd>Nome da m��quina virtual. (somente pode ser editado enquanto o convidado est��
interrompido)</dd>
+</dlentry><dlentry>
+<dt>CPUs</dt>
+<dd>N��mero de processadores. (se o convidado estiver em execu����o, uma nova
quantia entrar�� em vigor na pr��xima inicializa����o)</dd>
+</dlentry><dlentry>
+<dt>Mem��ria</dt>
+<dd>Quantia de mem��ria em MB. (se o convidado estiver em execu����o, uma nova
quantia entrar�� em vigor na pr��xima inicializa����o)</dd>
+</dlentry><dlentry>
+<dt>��cone</dt>
+<dd>Imagem gr��fica representando a distribui����o Linux a ser exibida
+no lugar do status atual (Livetile) quando o convidado n��o est�� ativo.</dd>
+</dlentry></dl></p>
+<p>As informa����es a seguir s��o exibidas na guia
<wintitle>Armazenamento</wintitle>.</p>
+<dl><dlentry>
+<dt>Armazenamento</dt>
+<dd>Exibe o local do arquivo ISO usado para instala����o.</dd>
+</dlentry></dl>
+<p> Os campos que n��o est��o desativados podem ser editados. Depois de editar um
campo,
+clique em <uicontrol>Salvar</uicontrol>. </p>
+</csbody>
+</cshelp>
+<cshelp id="kimstoragedevice" xml:lang="en-us">
+<title>Incluir, substituir ou remover um dispositivo de
armazenamento</title>
+<shortdesc rev="rev1">�� poss��vel incluir, substituir ou remover um
dispositivo de armazenamento
+para sua m��quina virtual. O ��nico dispositivo suportado �� CD-ROM. Para editar
+seus dispositivos de armazenamento, siga estas etapas:</shortdesc>
+<csbody>
+<ol>
+<li>Na janela <wintitle>Editar convidado</wintitle>, selecione
<wintitle>Armazenamento</wintitle>.</li>
+<li>Para substituir um dispositivo de armazenamento, clique no primeiro ��cone com
a <uicontrol>barra
+laranja (/)</uicontrol>. Insira o caminho do arquivo ISO e clique em
<uicontrol>Substituir</uicontrol>.</li>
+<li>Para remover um dispositivo de armazenamento, clique no segundo ��cone com o
<uicontrol>tra��o
+vermelho (-)</uicontrol>. Confirme a exclus��o e clique em
<uicontrol>OK</uicontrol>.</li>
+<li>Para incluir um dispositivo de armazenamento, clique no terceiro ��cone com o
<uicontrol>sinal de
+mais (+)</uicontrol> verde. Insira um nome de dispositivo e um caminho de arquivo
ISO e clique em <uicontrol>Conectar</uicontrol>.</li>
+</ol>
+</csbody>
+</cshelp>
+<cshelp id="kimreplacemedia" xml:lang="en-us">
+<title>Substituir um CD-ROM da VM</title>
+<shortdesc rev="rev1">�� poss��vel substituir o conte��do do CD-ROM para
+uma m��quina virtual ap��s a instala����o ser conclu��da.</shortdesc>
+<csbody>
+<ol>
+<li>Assegure-se de que a m��quina virtual esteja iniciada.</li>
+<li>No menu A����es, selecione <uicontrol>Gerenciar
m��dia</uicontrol>.</li>
+<li>Para alterar o que est�� atualmente carregado no CD-ROM, clique no ��cone
<uicontrol>barra
+laranja (/)</uicontrol> pr��ximo ao campo hdc.</li>
+<li>Na p��gina <wintitle>Substituir um CD-ROM da VM</wintitle>, insira
+o caminho do arquivo ISO. Os outros dois campos s��o somente leitura.</li>
+<li>Clique em <uicontrol>Substituir</uicontrol>.</li>
+</ol>
+</csbody>
+</cshelp>
+<?tm 1391540919 3?>
+</cshelp>
+
+
+<!-- ENGL1SH_VERS10N 45645_6 DO NOT REMOVE OR CHANGE THIS LINE -->
+<!-- T9N_SRC_ID 231 -->
+<!-- T9N_SH1P_STR1NG KV211AAP001 1 -->
diff --git a/src/wok/plugins/kimchi/ui/pages/help/pt_BR/host.dita
b/src/wok/plugins/kimchi/ui/pages/help/pt_BR/host.dita
new file mode 100644
index 0000000..88f7eb2
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/pages/help/pt_BR/host.dita
@@ -0,0 +1,74 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--Arbortext, Inc., 1988-2011, v.4002-->
+<!DOCTYPE cshelp PUBLIC "-//IBM//DTD DITA CSHelp//EN"
+ "..\dtd\cshelp.dtd">
+
+
+<!--This DITA specialized document type is not supported by the Authoring Tools
development team.
+For support please see:
+https://w3.opensource.ibm.com/projects/dita-cshelp/-->
+<cshelp id="kimhhost" xml:lang="pt-br">
+<title>Host</title>
+<shortdesc>A p��gina <wintitle>Host</wintitle> mostra informa����es
sobre
+o sistema host e permite encerrar, reiniciar e conectar
+ao host.</shortdesc>
+<csbody>
+<p>�� poss��vel executar as a����es a segur no host:<ul>
+<li>Selecione <uicontrol>Encerrar</uicontrol> para encerrar o sistema
+host.</li>
+<li>Selecione <uicontrol>Reiniciar</uicontrol> para reiniciar o sistema
host.</li>
+<li>Selecione <uicontrol>Conectar</uicontrol> para abrir uma conex��o
VNC
+para o sistema host, se ele j�� n��o estiver conectado.</li>
+</ul></p>
+<p>Clique nas se����es a seguir para exibir informa����es sobre o host:<dl>
+<dlentry>
+<dt>Informa����es b��sicas</dt>
+<dd>Esta se����o exibe a distribui����o do sistema operacional do host,
+a vers��o e o nome do c��digo, bem como o tipo de processador e quantia de
+mem��ria em GB.</dd>
+</dlentry><dlentry>
+<dt>Estat��sticas do sistema</dt>
+<dd>Esta se����o exibe gr��ficos para mostrar estat��sticas para CPU, mem��ria,
+E/S de disco e E/S de rede para o host. Selecione <uicontrol>Coletando
+dados depois de sair desta p��gina</uicontrol> para continuar a coletar dados
+quando a guia do host estiver fora de visualiza����o.</dd>
+</dlentry><dlentry>
+<dt>Atualiza����es de software</dt>
+<dd>Esta se����o exibe informa����es de todos os pacotes que
+possuem atualiza����es dispon��veis, incluindo nome do pacote, vers��o, arquitetura
+e reposit��rio. �� poss��vel atualizar todos os pacotes listados selecionando
<uicontrol>Atualizar
+todos</uicontrol>. N��o �� poss��vel selecionar pacotes individuais para
atualiza����es.</dd>
+</dlentry><dlentry>
+<dt>Reposit��rios</dt>
+<dd>Esta se����o exibe reposit��rios que est��o associados ao
+sistema host. �� poss��vel incluir, ativar, editar ou remover reposit��rios. Incluir
+um reposit��rio o associa com o sistema host enquanto ativar um reposit��rio
+permite que o host o acesse. Se o seu sistema for Red Hat Enterprise
+Linux ou Fedora, ser�� poss��vel incluir reposit��rios
<filepath>yum</filepath>.
+Se o seu sistema for Ubuntu ou Debian, inclua reposit��rios
<filepath>deb</filepath>.<p>Se
+voc�� estiver trabalhando com reposit��rios yum, ser�� poss��vel incluir uma
verifica����o de GPG para
+verificar se um pacote desse reposit��rio n��o foi corrompido.
+Selecione um reposit��rio e, em seguida, <uicontrol>Editar</uicontrol>.
Selecione <uicontrol>Sim</uicontrol> para
+ativar a Verifica����o de GPG e, em seguida, insira uma URL no arquivo-chave de GPG para
o
+reposit��rio.</p></dd>
+</dlentry><dlentry>
+<dt>Relat��rios de depura����o</dt>
+<dd>Esta se����o exibe relat��rios de depura����o, incluindo nome e caminho do
arquivo.
+�� poss��vel selecionar a partir das op����es para gerar um novo relat��rio ou renomear,
remover
+ou fazer o download de um relat��rio existente.<p>O relat��rio de depura����o ��
gerado usando
+o comando <cmdname>sosreport</cmdname>. Ele est�� dispon��vel para
distribui����es
+Red Hat Enterprise <tm tmtype="tm"
trademark="Linux">Linux</tm>, Fedora
+e Ubuntu. O comando gera um arquivo .tar que cont��m
+informa����es de configura����o e de diagn��stico, como vers��o do kernel
+em execu����o, m��dulos carregados e arquivos de configura����o de sistema e de
servi��o.
+O comando tamb��m executa programas externos para coletar informa����es adicionais
+e armazena essa sa��da no archive resultante.</p> </dd>
+</dlentry></dl></p>
+</csbody>
+<?tm 1392659967 1?>
+</cshelp>
+
+
+<!-- ENGL1SH_VERS10N 47930_4 DO NOT REMOVE OR CHANGE THIS LINE -->
+<!-- T9N_SRC_ID 232 -->
+<!-- T9N_SH1P_STR1NG KVM21AAP001 3 -->
diff --git a/src/wok/plugins/kimchi/ui/pages/help/pt_BR/network.dita
b/src/wok/plugins/kimchi/ui/pages/help/pt_BR/network.dita
new file mode 100644
index 0000000..1585298
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/pages/help/pt_BR/network.dita
@@ -0,0 +1,72 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--Arbortext, Inc., 1988-2011, v.4002-->
+<!DOCTYPE cshelp PUBLIC "-//IBM//DTD DITA CSHelp//EN"
+ "..\dtd\cshelp.dtd">
+
+
+<!--This DITA specialized document type is not supported by the Authoring Tools
development team.
+For support please see:
+https://w3.opensource.ibm.com/projects/dita-cshelp/-->
+<cshelp id="kimhnetw" xml:lang="pt-br">
+<title>Rede</title>
+<shortdesc>A p��gina <wintitle>Rede</wintitle> exibe informa����es
+sobre a conex��o de rede.</shortdesc>
+<csbody>
+<p><dl><dlentry>
+<dt>Nome da rede</dt>
+<dd>Nome da rede ou <uicontrol>padr��o</uicontrol>.</dd>
+</dlentry><dlentry>
+<dt>Estado</dt>
+<dd>Estado da rede, ativo (verde) ou inativo (vermelho). </dd>
+</dlentry><dlentry>
+<dt>Tipo de rede</dt>
+<dd>Tipo de rede, por exemplo, <uicontrol>NAT</uicontrol> (convers��o
+de endere��o de rede).</dd>
+</dlentry><dlentry>
+<dt>Interface</dt>
+<dd>Interface de rede, por exemplo, <uicontrol>virbr0</uicontrol>
(padr��o).</dd>
+</dlentry><dlentry>
+<dt>Espa��o de endere��o</dt>
+<dd>Endere��o IP.</dd>
+</dlentry></dl></p>
+<p>As a����es a seguir podem ser selecionadas:<ul>
+<li rev="rev1">Selecione <uicontrol>Iniciar</uicontrol> para
iniciar a conex��o
+de rede.</li>
+<li>Selecione <uicontrol>Parar</uicontrol> para terminar a conex��o de
rede.</li>
+<li>Selecione <uicontrol>Excluir</uicontrol> para excluir as
informa����es
+de conex��o.</li>
+</ul>Para criar uma rede, clique no ��cone <uicontrol>mais
(+)</uicontrol> na
+parte superior direita da exibi����o.</p>
+</csbody>
+<cshelp id="kimhnetwcrt" xml:lang="en-us">
+<title>Criar uma rede</title>
+<shortdesc>Crie uma rede.</shortdesc>
+<csbody>
+<p> <ol>
+<li>Digite o nome da rede.</li>
+<li>Clique para selecionar o tipo de rede. <dl
rev="rev1"><dlentry>
+<dt><uicontrol>Isolado</uicontrol></dt>
+<dd>Modo isolado. Os M��quinas Virtuais n��o podem enviar ou receber comunica����o
para
+ou de sistemas externos.</dd>
+</dlentry><dlentry>
+<dt><uicontrol>NAT</uicontrol></dt>
+<dd>Modo de Convers��o de Endere��o de Rede. A comunica����o de M��quinas Virtuais
com
+sistemas externos usa o endere��o IP do host. Os sistemas externos n��o podem
+iniciar a comunica����o com os M��quinas Virtuais.</dd>
+</dlentry><dlentry>
+<dt><uicontrol>bridged</uicontrol></dt>
+<dd>Modo bridged. Os M��quinas Virtuais podem se comunicar com os sistemas externos
e
+ser contatados por sistemas externos como se fossem sistemas f��sicos
+na rede. Para o modo bridged, devem-se especificar informa����es adicionais
+de destino e de VLAN.</dd>
+</dlentry></dl></li>
+<li>Clique em <uicontrol>Criar</uicontrol>.</li>
+</ol> </p>
+</csbody>
+</cshelp>
+</cshelp>
+
+
+<!-- ENGL1SH_VERS10N 47050_3 DO NOT REMOVE OR CHANGE THIS LINE -->
+<!-- T9N_SRC_ID 230 -->
+<!-- T9N_SH1P_STR1NG KVM21AAP001 3 -->
diff --git a/src/wok/plugins/kimchi/ui/pages/help/pt_BR/storage.dita
b/src/wok/plugins/kimchi/ui/pages/help/pt_BR/storage.dita
new file mode 100644
index 0000000..03c8cab
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/pages/help/pt_BR/storage.dita
@@ -0,0 +1,102 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--Arbortext, Inc., 1988-2011, v.4002-->
+<!DOCTYPE cshelp PUBLIC "-//IBM//DTD DITA CSHelp//EN"
+ "..\dtd\cshelp.dtd">
+
+
+<!--This DITA specialized document type is not supported by the Authoring Tools
development team.
+For support please see:
+https://w3.opensource.ibm.com/projects/dita-cshelp/-->
+<cshelp id="kimhstor" xml:lang="pt-br">
+<title>Armazenamento</title>
+<shortdesc>A p��gina <wintitle>Armazenamento</wintitle> lista os
conjuntos de armazenamentos dispon��veis, inclusive o conjunto de armazenamentos
'padr��o' e 'ISO' integrado.
+Se desejar usar seu pr��prio ISO, inclua-o em seu caminho do conjunto de armazenamentos
'ISO'.</shortdesc>
+<csbody>
+<p>Para cada storage pool, as informa����es a seguir s��o exibidas:<dl>
+<dlentry>
+<dt>Nome</dt>
+<dd>Nome do storage pool e porcentagem usada.</dd>
+</dlentry><dlentry>
+<dt>Estado</dt>
+<dd>Estado do storage pool, ativo (verde) ou inativo (vermelho). </dd>
+</dlentry><dlentry>
+<dt>Local</dt>
+<dd>Caminho do arquivo para o local do storage pool.</dd>
+</dlentry><dlentry>
+<dt>Tipo</dt>
+<dd>Tipo de storage pool, por exemplo,
<uicontrol>dir</uicontrol>.</dd>
+</dlentry><dlentry>
+<dt>Capacidade</dt>
+<dd>Quantia de espa��o no storage pool.</dd>
+</dlentry><dlentry>
+<dt>Alocado</dt>
+<dd>Quantia de espa��o j�� alocado no storage pool.</dd>
+</dlentry></dl></p>
+<p>As a����es a seguir podem ser selecionadas para cada storage pool:<ul>
+<li>Selecione <uicontrol>Ativar</uicontrol> para ativar o storage pool
+para que ele possa ser usado.</li>
+<li>Selecione <uicontrol>Desativar</uicontrol> para desativar um
storage pool
+ativo.</li>
+<li>Selecione <uicontrol>Indefinir</uicontrol> para remover um storage
pool
+inativo.</li>
+</ul></p>
+<p>Para exibir detalhes do volume de armazenamento para um storage pool, clique na
+seta no lado direito da linha do storage pool. Os detalhes incluem
+os seguintes:<dl><dlentry>
+<dt>Tipo</dt>
+<dd>O tipo de volume, por exemplo,
<uicontrol>arquivo</uicontrol>.</dd>
+</dlentry><dlentry>
+<dt>Formato</dt>
+<dd>O formato, que varia dependendo do tipo.</dd>
+</dlentry><dlentry>
+<dt>Capacidade</dt>
+<dd>Tamanho do volume de armazenamento.</dd>
+</dlentry><dlentry>
+<dt>Aloca����o</dt>
+<dd>Quantia de espa��o j�� alocado no storage pool.</dd>
+</dlentry></dl>Para definir um storage pool, clique no ��cone
<uicontrol>mais
+(+)</uicontrol> na parte superior direita da exibi����o.</p>
+</csbody>
+<cshelp id="kimhdefstor" xml:lang="en-us">
+<title>Definir um storage pool</title>
+<shortdesc> Defina um storage pool.</shortdesc>
+<csbody>
+<p> <ol>
+<li>No campo <uicontrol>Nome do storage pool</uicontrol>, digite o
+nome a ser usado para identificar o storage pool.</li>
+<li>Na lista <uicontrol>Tipo de storage pool</uicontrol>, selecione o
+tipo: <dl><dlentry>
+<dt><uicontrol>DIR</uicontrol></dt>
+<dd>Especifica um conjunto de diret��rios. Ao selecionar
<uicontrol>DIR</uicontrol>,
+digite o <uicontrol>Caminho do armazenamento</uicontrol> (caminho do arquivo
para o
+storage pool).</dd>
+</dlentry><dlentry>
+<dt><uicontrol>NFS</uicontrol></dt>
+<dd>Especifica um conjunto de sistema de arquivos de rede. Ao selecionar
<uicontrol>NFS</uicontrol>,
+digite o endere��o <uicontrol>IP do servidor NFS</uicontrol> e o
<uicontrol>Caminho
+do NFS</uicontrol> (caminho do diret��rio exportado).</dd>
+</dlentry><dlentry>
+<dt><uicontrol>iSCSI</uicontrol></dt>
+<dd>Especifica um conjunto com base em um destino alocado em um servidor iSCSI.
+Ao selecionar <uicontrol>iSCSI</uicontrol>, digite o endere��o IP do
<uicontrol>Servidor
+iSCSI</uicontrol> e o <uicontrol>Destino</uicontrol> no
+servidor iSCSI. Opcionalmente, �� poss��vel selecionar para incluir a autentica����o
iSCSI.</dd>
+</dlentry><dlentry>
+<dt><uicontrol>L��gico</uicontrol></dt>
+<dd>Especifica um storage pool do volume l��gico. Selecione o local para
+o dispositivo em <uicontrol>Caminho do dispositivo</uicontrol>.</dd>
+</dlentry><dlentry>
+<dt><uicontrol>Fibre Channel SCSI</uicontrol></dt>
+<dd>Especifica um conjunto com base em um Fibre Channel SCSI. Selecione qual
+adaptador SCSI deve ser usado.</dd>
+</dlentry></dl></li>
+<li>Clique em <uicontrol>Criar</uicontrol>.</li>
+</ol> </p>
+</csbody>
+</cshelp>
+</cshelp>
+
+
+<!-- ENGL1SH_VERS10N 22336_4 DO NOT REMOVE OR CHANGE THIS LINE -->
+<!-- T9N_SRC_ID 233 -->
+<!-- T9N_SH1P_STR1NG KV211AAP001 1 -->
diff --git a/src/wok/plugins/kimchi/ui/pages/help/pt_BR/templates.dita
b/src/wok/plugins/kimchi/ui/pages/help/pt_BR/templates.dita
new file mode 100644
index 0000000..f3c6515
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/pages/help/pt_BR/templates.dita
@@ -0,0 +1,127 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--Arbortext, Inc., 1988-2011, v.4002-->
+<!DOCTYPE cshelp PUBLIC "-//IBM//DTD DITA CSHelp//EN"
+ "..\dtd\cshelp.dtd">
+
+
+<!--This DITA specialized document type is not supported by the Authoring Tools
development team.
+For support please see:
+https://w3.opensource.ibm.com/projects/dita-cshelp/-->
+<cshelp id="kimhtempl" xml:lang="pt-br">
+<title>Modelos</title>
+<shortdesc>A p��gina <wintitle>Modelos</wintitle> mostra os modelos de
+m��quina virtual definidos que podem ser usados para criar M��quinas Virtuais do
KVM.</shortdesc>
+<csbody>
+<p>Para cada modelo, as informa����es a seguir s��o exibidas:<dl>
+<dlentry>
+<dt>S.O.</dt>
+<dd>Nome do sistema operacional ou distribui����o.</dd>
+</dlentry><dlentry>
+<dt>Vers��o</dt>
+<dd>Vers��o do sistema operacional ou distribui����o.</dd>
+</dlentry><dlentry>
+<dt>CPUs</dt>
+<dd>N��mero de processadores que est��o definidos para o modelo.</dd>
+</dlentry><dlentry>
+<dt>Mem��ria</dt>
+<dd>Quantia de mem��ria de acesso aleat��rio a ser alocada, em MB.</dd>
+</dlentry></dl></p>
+<p>As a����es a seguir podem ser selecionadas para cada modelo:<ul>
+<li>Selecione <uicontrol>Editar</uicontrol> para editar o
modelo.</li>
+<li>Selecione <uicontrol>Excluir</uicontrol> para excluir o
modelo.</li>
+</ul>Para incluir um modelo, clique no ��cone <uicontrol>mais
(+)</uicontrol> na
+parte superior direita da exibi����o.</p>
+</csbody>
+<cshelp id="kimhedittempl" xml:lang="en-us">
+<title>Editar modelo</title>
+<shortdesc>Edite um modelo existente.</shortdesc>
+<csbody>
+<p>Para cada modelo, as informa����es a seguir s��o exibidas: <dl>
+<dlentry>
+<dt>Nome</dt>
+<dd>Nome do modelo.</dd>
+</dlentry><dlentry>
+<dt>Fornecedor</dt>
+<dd>O nome da empresa que criou o sistema operacional ou a distribui����o
+que o modelo est�� configurado para usar.</dd>
+</dlentry><dlentry>
+<dt>Vers��o</dt>
+<dd>A vers��o do sistema operacional ou distribui����o que o modelo
+est�� configurado para usar.</dd>
+</dlentry><dlentry>
+<dt>N��mero de CPU</dt>
+<dd>N��mero de processadores que est��o definidos para o modelo.</dd>
+</dlentry><dlentry>
+<dt>Mem��ria</dt>
+<dd>Quantia de mem��ria em MB a ser alocada para a m��quina virtual.</dd>
+</dlentry><dlentry>
+<dt>Disco</dt>
+<dd>O tamanho do disco em GB.</dd>
+</dlentry><dlentry>
+<dt>CD-ROM</dt>
+<dd>O caminho do arquivo para o local do arquivo ISO usado para instalar o
+convidado do KVM.</dd>
+</dlentry><dlentry>
+<dt>storage pool</dt>
+<dd>storage pool espec��fico ou storage pool padr��o.</dd>
+</dlentry><dlentry>
+<dt>Rede</dt>
+<dd>As interfaces de rede padr��o dispon��veis para o convidado do KVM. ��
poss��vel
+selecionar diversas redes.</dd>
+</dlentry></dl> Os campos que n��o est��o desativados podem ser editados.
Depois
+de editar um campo, clique em <uicontrol>Salvar</uicontrol>. </p>
+</csbody>
+</cshelp>
+<cshelp id="kimhaddtempl">
+<title>Incluir modelo</title>
+<shortdesc>Inclua um modelo a partir da m��dia de origem.
+�� poss��vel incluir sua pr��pria imagem ISO em seu conjunto de armazenamentos
'ISO' para a descoberta a seguir.</shortdesc>
+<csbody>
+<p>Selecione o local da m��dia de origem a partir das op����es a seguir:<dl>
+<dlentry>
+<dt>Imagem ISO local</dt>
+<dd>Selecione para varrer conjuntos de armazenamentos para imagens ISO de
instala����o dispon��veis
+no sistema.</dd>
+</dlentry><dlentry>
+<dt>Imagem ISO remota</dt>
+<dd>Selecione para especificar um local remoto para uma imagem ISO de
instala����o.</dd>
+</dlentry></dl></p>
+</csbody>
+</cshelp>
+<cshelp id="kimhaddloct">
+<title>Incluir modelo - imagem ISO local</title>
+<shortdesc>Inclua um modelo a partir de uma imagem ISO local.</shortdesc>
+<csbody>
+<p>As imagens ISO dispon��veis no sistema s��o exibidas.<dl><dlentry>
+<dt>S.O.</dt>
+<dd>Nome do sistema operacional ou distribui����o.</dd>
+</dlentry><dlentry>
+<dt>Vers��o</dt>
+<dd>Vers��o do sistema operacional ou distribui����o.</dd>
+</dlentry><dlentry>
+<dt>Tamanho</dt>
+<dd>Tamanho da imagem ISO.</dd>
+</dlentry></dl></p>
+<p>Para criar um modelo a partir de uma imagem ISO, escolha a partir das op����es
+a seguir:<ul>
+<li>Selecione uma imagem ISO para criar um modelo a partir dela, em seguida, clique
em <uicontrol>Criar
+modelos a partir do ISO selecionado</uicontrol>.</li>
+<li>Selecione <uicontrol>Todos</uicontrol> para criar um modelo a
partir de cada
+imagem ISO listada, em seguida, clique em <uicontrol>Criar modelos a partir do
+ISO selecionado</uicontrol>.</li>
+<li>Se a imagem ISO que voc�� deseja usar n��o aparecer nos resultados de
+varredura, ser�� poss��vel selecionar a partir das op����es a seguir:<ul>
+<li>Selecione <uicontrol>Eu desejo usar um arquivo ISO
espec��fico</uicontrol> para
+especificar um caminho para a imagem ISO.</li>
+<li>Clique em <uicontrol>Procurar mais ISOs</uicontrol> para procurar
mais
+imagens ISO.</li>
+</ul></li>
+</ul></p>
+</csbody>
+</cshelp>
+</cshelp>
+
+
+<!-- ENGL1SH_VERS10N 61085_5 DO NOT REMOVE OR CHANGE THIS LINE -->
+<!-- T9N_SRC_ID 229 -->
+<!-- T9N_SH1P_STR1NG KV211AAP001 1 -->
diff --git a/src/wok/plugins/kimchi/ui/pages/help/ru_RU/Makefile.am
b/src/wok/plugins/kimchi/ui/pages/help/ru_RU/Makefile.am
new file mode 100644
index 0000000..85ca27a
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/pages/help/ru_RU/Makefile.am
@@ -0,0 +1,23 @@
+# Copyright IBM Corp, 2014
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+ru_RU_helpdir = $(datadir)/wok/plugins/kimchi/ui/pages/help/ru_RU
+
+dist_ru_RU_help_DATA = $(wildcard *.html) $(NULL)
+
+EXTRA_DIST = $(wildcard *.dita)
+
+CLEANFILES = $(wildcard *.html)
diff --git a/src/wok/plugins/kimchi/ui/pages/help/ru_RU/guests.dita
b/src/wok/plugins/kimchi/ui/pages/help/ru_RU/guests.dita
new file mode 100644
index 0000000..701dd7e
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/pages/help/ru_RU/guests.dita
@@ -0,0 +1,122 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--Arbortext, Inc., 1988-2011, v.4002-->
+<!DOCTYPE cshelp PUBLIC "-//IBM//DTD DITA CSHelp//EN"
+ "..\dtd\cshelp.dtd">
+
+
+<!--This DITA specialized document type is not supported by the Authoring Tools
development team.
+For support please see:
+https://w3.opensource.ibm.com/projects/dita-cshelp/-->
+<cshelp id="kimhvirtm" xml:lang="ru-ru">
+<title>���������������� ��������������</title>
+<shortdesc>���� ���������������� <wintitle>����������������
��������������</wintitle> ������������������������ ������������ ������������������
���������������������� ���������� KVM.</shortdesc>
+<csbody>
+<p>������ ������������ ���������������� �������������� ������������������������
������������������ ��������������������:<dl><dlentry>
+<dt>������</dt>
+<dd>������ ���������������������� ������������.</dd>
+</dlentry><dlentry>
+<dt>������������������</dt>
+<dd>�������������� �������������������������� �������������������� ��
���������������������� ������������.</dd>
+</dlentry><dlentry>
+<dt>�������������� ��������-����������</dt>
+<dd>���������������� ���������������� ����������-������������ ��
����/��.</dd>
+</dlentry><dlentry>
+<dt>���������������� ��������-����������</dt>
+<dd>���������������� ������������������ ����������-������������ ��
����/��.</dd>
+</dlentry><dlentry>
+<dt>Livetile</dt>
+<dd>������������������ �������������� ���������������� ������������������������
�������������� ������ ������������, ���������������������������� �������������� ����
<tm tmtype="tm" trademark="Linux">Linux</tm>, ��������
���������������� �������������� ���� ��������������.</dd>
+</dlentry></dl></p>
+<p>������ ������������ ���������������� �������������� ������������������������
������������������ ������������ ����������������:<dl>
+<dlentry>
+<dt>����������</dt>
+<dd>���������� ���������������� ��������������. </dd>
+</dlentry><dlentry>
+<dt>�������������� (������������/������������������)</dt>
+<dd>������������������/�������������������� �������������� ����������������
��������������. �������� ������������ ��������������, �������������� ������������������.
�������� ������������ ��������������, �������������� ����������������.</dd>
+</dlentry></dl> </p>
+<p>������ ������������ ���������������� �������������� ����������������
������������������ ����������������:<ul>
+<li><uicontrol>������������������������</uicontrol> -
������������������������ �� ������������������ �������������� ����������������
������������������������ ��������������.</li>
+<li><uicontrol>�������������������� ��������������������</uicontrol> -
������������������ �������� �� �������������������������� ����������������.</li>
+<li><uicontrol>����������</uicontrol> - ���������� ����������������
��������������.</li>
+<li><uicontrol>����������������</uicontrol> - ������������������
�������������� ���������������� ��������������. ���������������� ����������������
�������������� ���������� ����������������, ������������ ���������� ��������������
����������������������.</li>
+<li><uicontrol>��������������</uicontrol> - ��������������
���������������� ��������������.</li>
+</ul>������ ���������������� ���������������� ��������������
(���������������������� ������������) ���������������� ���� ������������
<uicontrol>��������
+(+)</uicontrol> �� ������������ �������������� ��������
����������������.</p>
+</csbody>
+<cshelp id="kimhvirtmcrt" xml:lang="ru-ru">
+<title>���������������� ���������������������� ������������</title>
+<shortdesc>���������������� ���������������������� ������������ �� ��������������
��������������.</shortdesc>
+<csbody>
+<p> <ol>
+<li>�������������� ������ ������ �������������������������� ����������������������
������������.</li>
+<li rev="rev1">���������������� ������������. <ul>
+<li>�������� �������� ��������������, ���������������� ������������ ��
������������.</li>
+<li>�������� ���������������� ������, ���������������� ����
<uicontrol>�������������� ������������</uicontrol>, ���������� ��������������
������������.</li>
+</ul></li>
+<li>���������������� ����
<uicontrol>��������������</uicontrol>.</li>
+</ol> </p>
+</csbody>
+</cshelp>
+<cshelp id="kimhvirtmedit" xml:lang="ru-ru">
+<title>������������������ ���������������� ��������������</title>
+<shortdesc>������������������ �������������� ������������������������
���������������������� ������������. ������������������ ���������������� ����������
���������������� ������������ �������� ���������������������� ���������������� ����������.
������������ ���������������� �� �������� ���������� ������������������
������������������������.</shortdesc>
+<csprolog><csmetadata></csmetadata></csprolog>
+<csbody>
+<p>������ ������������ ���������������� �������������� ������������������������
������������������ �������������������� ���� ��������������
<wintitle>����������</wintitle>:<dl>
+<dlentry>
+<dt>������</dt>
+<dd>������ ���������������������� ������������. (����������
�������������������������� �������� ���������������������� ����������������
����������)</dd>
+</dlentry><dlentry>
+<dt>��������������������</dt>
+<dd>���������� ����������������������. (�������� ���������������� ����������
����������������, ���������� ���������� �������������� �� �������� ����������
������������������������)</dd>
+</dlentry><dlentry>
+<dt>������������</dt>
+<dd>���������� ������������ �� ����. (�������� ���������������� ����������
����������������, ���������� ���������� �������������� �� �������� ����������
������������������������)</dd>
+</dlentry><dlentry>
+<dt>������������</dt>
+<dd>���������������������� ����������������������, ����������������������������
�������������� ���� Linux. ������ ������������������������ ������������ ����������������
������������������
+(Livetile), ���������� ���������������� �������������� ���� ��������������.</dd>
+</dlentry></dl></p>
+<p>���� �������������� <wintitle>����������������
������������</wintitle> ������������������������ ������������������
��������������������.</p>
+<dl><dlentry>
+<dt>���������������� ������������</dt>
+<dd>�������������������� ������������������������ ���������� ISO ������
������������������.</dd>
+</dlentry></dl>
+<p> ���������������� �������� ���������� ����������������. ����������
������������������ �������� ���������������� ����
<uicontrol>������������������</uicontrol>. </p>
+</csbody>
+</cshelp>
+<cshelp id="kimstoragedevice" xml:lang="ru-ru">
+<title>��������������������, ������������ �� ��������������������
������������������ ����������������</title>
+<shortdesc rev="rev1">�� ���������������������� ������������ ����������
������������������, ���������������� �� ������������������ ��������������������
����������������. ������������������������ ����������������������������
�������������������� - CDROM. ������ ������������������ ������������������
���������������� ������������������ ������������������
����������������:</shortdesc>
+<csbody>
+<ol>
+<li>�� �������� <wintitle>���������������� ����������������
��������������</wintitle> ���������������� <wintitle>����������������
������������</wintitle>.</li>
+<li>������ ������������ �������������������� ���������������� ���������������� ����
������������ ������������ �� <uicontrol>������������������ ���������� ������������
(/)</uicontrol>. �������������� �������� �� ���������� ISO �� ���������������� ����
<uicontrol>����������������</uicontrol>.</li>
+<li>������ �������������������� �������������������� ����������������
���������������� ���� ������������ ������������ �� <uicontrol>��������������
���������������������������� ������������ (-)</uicontrol>. ����������������������
���������������� �� �������������� ������������
<uicontrol>OK</uicontrol>.</li>
+<li>������ �������������������� �������������������� ����������������
���������������� ���� �������������� ������������ �� <uicontrol>��������������
������������
+(+)</uicontrol>. �������������� ������ �������������������� �� �������� ��
���������� ISO �� ���������������� ����
<uicontrol>��������������������</uicontrol>.</li>
+</ol>
+</csbody>
+</cshelp>
+<cshelp id="kimreplacemedia" xml:lang="ru-ru">
+<title>������������ CDROM ���������������������� ������������</title>
+<shortdesc rev="rev1">���� ������������������ ������������������
���������� ���������������� �������������������� CDROM ������ ����������������������
������������.</shortdesc>
+<csbody>
+<ol>
+<li>������������������ ���������������������� ������������.</li>
+<li>�� �������� ���������������� ����������������
<uicontrol>�������������������� ��������������������</uicontrol>.</li>
+<li>������ ������������ ����������������, ������������������������ �� CDROM,
���������������� ���� ������������ �� <uicontrol>������������������ ����������
������������
+(/)</uicontrol> ���������� �� ���������� hdc.</li>
+<li>���� ���������������� <wintitle>������������ CDROM ����������������������
������������</wintitle> �������������� �������� �� ���������� ISO. ������
������������ �������� ���������������� ������������ ������ ������������.</li>
+<li>���������������� ����������
<uicontrol>����������������</uicontrol>.</li>
+</ol>
+</csbody>
+</cshelp>
+<?tm 1391540919 3?>
+</cshelp>
+
+
+<!-- ENGL1SH_VERS10N 45645_6 DO NOT REMOVE OR CHANGE THIS LINE -->
+<!-- T9N_SRC_ID 231 -->
+<!-- T9N_SH1P_STR1NG KV211AAP001 1 -->
diff --git a/src/wok/plugins/kimchi/ui/pages/help/ru_RU/host.dita
b/src/wok/plugins/kimchi/ui/pages/help/ru_RU/host.dita
new file mode 100644
index 0000000..fb72c21
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/pages/help/ru_RU/host.dita
@@ -0,0 +1,48 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--Arbortext, Inc., 1988-2011, v.4002-->
+<!DOCTYPE cshelp PUBLIC "-//IBM//DTD DITA CSHelp//EN"
+ "..\dtd\cshelp.dtd">
+
+
+<!--This DITA specialized document type is not supported by the Authoring Tools
development team.
+For support please see:
+https://w3.opensource.ibm.com/projects/dita-cshelp/-->
+<cshelp id="kimhhost" xml:lang="ru-ru">
+<title>��������</title>
+<shortdesc>���������������� <wintitle>��������</wintitle>
�������������������� �������������������� �� �������������� ���������� ��
������������������ �������������������������� ��������, ��������������������������
�������� �� ������������������������ �� ��������.</shortdesc>
+<csbody>
+<p>���� ���������� ���������� ������������������ ������������������
����������������:<ul>
+<li><uicontrol>������������������ ������������</uicontrol> -
�������������������� �������������� ����������.</li>
+<li><uicontrol>��������������������������</uicontrol> -
�������������������������� �������������� ����������.</li>
+<li><uicontrol>������������������������</uicontrol> - ��������������
�������������������� VNC �� ���������������� ����������, �������� ������ ������ ����
����������������������.</li>
+</ul></p>
+<p>���������������� ���� ������������������ ���������������� ������
������������������ �������������������� �� ����������:<dl>
+<dlentry>
+<dt>�������������� ��������������������</dt>
+<dd>�� �������� �������������� ������������������������ ��������������
������������������������ ��������������, ������ ������������ �� �������������� ������, ��
���������� ������ �������������������� �� ���������� ������������ �� ����.</dd>
+</dlentry><dlentry>
+<dt>������������������ ��������������������</dt>
+<dd>�� �������� �������������� ������������������������ ��������������,
�������������������� ���������������������������� �������������������� ��
��������������������, ������������, ���������������� ����������-������������ ��
�������������� ����������-������������ ������ ����������. ����������������
<uicontrol>�������� ������������ ���������� ���������������� ��������
����������������</uicontrol>, ���������� �������� ������������
���������������������� ���������� ���������������� �������������� ��������.</dd>
+</dlentry><dlentry>
+<dt>�������������������� ������������������������
����������������������</dt>
+<dd>�� �������� �������������� ������������������������ �������������������� ������
�������� ��������������, ������ �������������� ���������������� ��������������������,
�������������� ������ ������������, ������������, ���������������������� ��
������������������. ���������� ���������������� ������ ������������ �� ������������
�������������� ���� <uicontrol>���������������� ������</uicontrol>.
������������������ ������������ ������ �������������������� ��������������
������������.</dd>
+</dlentry><dlentry>
+<dt>������������������</dt>
+<dd>�� �������� �������������� ������������������������ ������������������,
������������������ �� ���������������� ����������. ������������������ ����������
������������������, ������������������������, ���������������� �� ��������������. ������
�������������������� ������������������ ���������������������� �� ����������������
����������, ������ ������������������ ������������������ ��������������������
������������������ ������ ����������. �������� �������������� - Red Hat Enterprise Linux
������ Fedora, ���������� ���������������� ������������������
<filepath>yum</filepath>.
+�������� �������������� - Ubuntu ������ Debian, ���������������� ������������������
<filepath>deb</filepath>.<p>������ ������������ ��
���������������������� yum ���������� ���������������� ���������������� GPG ������
���������������� ���������������������� �������������� ���� ��������������
������������������.
+���������������� ������������������ �� ���������������� ����
<uicontrol>����������������</uicontrol>. ����������������
<uicontrol>����</uicontrol>, ���������� ���������������� ���������������� GPG,
�� �������������� URL ���������� ������������ GPG ������
������������������.</p></dd>
+</dlentry><dlentry>
+<dt>�������������������� ������������</dt>
+<dd>�� �������� �������������� ������������������������ ��������������������
������������, �������������� ������ �� ��������.
+���������������� �������������� ������ ����������������, ����������������������������,
���������������� �� ���������������� ��������������.<p>��������������������
���������� ������������������ ���������������� <cmdname>sosreport</cmdname>.
���� ���������������� ������ Red
+Hat Enterprise <tm tmtype="tm"
trademark="Linux">Linux</tm>, Fedora �� Ubuntu. ��������������
�������������� �������� .tar �� �������������������������������� ��
������������������������������ ����������������������, ���������� ������ ������������
��������, ���������������������� ������������ �� ���������� ������������������������
�������������� �� ����������.
+�������������� ���������� ������������������ �������������� ������������������ ������
���������� ���������������������������� �������������������� �� ������������������ ����
���������� �� ���������������������������� ������������.</p> </dd>
+</dlentry></dl></p>
+</csbody>
+<?tm 1392659967 1?>
+</cshelp>
+
+
+<!-- ENGL1SH_VERS10N 47930_4 DO NOT REMOVE OR CHANGE THIS LINE -->
+<!-- T9N_SRC_ID 232 -->
+<!-- T9N_SH1P_STR1NG KVM21AAP001 3 -->
diff --git a/src/wok/plugins/kimchi/ui/pages/help/ru_RU/network.dita
b/src/wok/plugins/kimchi/ui/pages/help/ru_RU/network.dita
new file mode 100644
index 0000000..9cdcdd1
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/pages/help/ru_RU/network.dita
@@ -0,0 +1,61 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--Arbortext, Inc., 1988-2011, v.4002-->
+<!DOCTYPE cshelp PUBLIC "-//IBM//DTD DITA CSHelp//EN"
+ "..\dtd\cshelp.dtd">
+
+
+<!--This DITA specialized document type is not supported by the Authoring Tools
development team.
+For support please see:
+https://w3.opensource.ibm.com/projects/dita-cshelp/-->
+<cshelp id="kimhnetw" xml:lang="ru-ru">
+<title>��������</title>
+<shortdesc>���� ���������������� <wintitle>��������</wintitle>
������������������������ �������������������� �� ��������������
��������������������.</shortdesc>
+<csbody>
+<p><dl><dlentry>
+<dt>������ ��������</dt>
+<dd>������ �������� ������ <uicontrol>����
������������������</uicontrol>.</dd>
+</dlentry><dlentry>
+<dt>������������������</dt>
+<dd>������������������ �������� - ���������������� (��������������) ������
�������������������� (��������������). </dd>
+</dlentry><dlentry>
+<dt>������ ��������</dt>
+<dd>������ ��������, ���������������� <uicontrol>NAT</uicontrol>
(���������������������������� �������������� ��������������).</dd>
+</dlentry><dlentry>
+<dt>������������������</dt>
+<dd>�������������� ������������������, ����������������
<uicontrol>virbr0</uicontrol> (���� ������������������).</dd>
+</dlentry><dlentry>
+<dt>���������������� ������������������������</dt>
+<dd>IP-����������.</dd>
+</dlentry></dl></p>
+<p>���������������� ������������������ ����������������:<ul>
+<li rev="rev1"><uicontrol>������������������</uicontrol> -
�������������� �������������� ��������������������.</li>
+<li><uicontrol>��������������������</uicontrol> - ��������������
�������������� ��������������������.</li>
+<li><uicontrol>��������������</uicontrol> - ��������������
�������������������� �� ��������������������.</li>
+</ul>������ ���������������� �������� ���������������� ���� ������������
<uicontrol>���������� (+)</uicontrol> �� ������������ �������������� ��������
����������������.</p>
+</csbody>
+<cshelp id="kimhnetwcrt" xml:lang="ru-ru">
+<title>���������������� ��������</title>
+<shortdesc>���������������� ��������.</shortdesc>
+<csbody>
+<p> <ol>
+<li>�������������� ������ ��������.</li>
+<li>���������������� ������ ��������. <dl
rev="rev1"><dlentry>
+<dt><uicontrol>��������������������������</uicontrol></dt>
+<dd>�������������������������� ����������. ���������������� �������������� ����
���������� ������������������������ �������������� �� ����������������
������������������.</dd>
+</dlentry><dlentry>
+<dt><uicontrol>NAT</uicontrol></dt>
+<dd>���������� ���������������������������� �������������� ��������������.
���������� �������������� ���������� ������������������ �� ����������������
������������������ ���������������������������� ���������� IP-���������� ����������.
�������������� �������������� ���� ���������� ������������������������ ��
����������������.</dd>
+</dlentry><dlentry>
+<dt><uicontrol>���������� ��������</uicontrol></dt>
+<dd>���������� ������������ ���������� ��������. ���������������� ��������������
���������� ������������������������ �������������� �� ���������������� ������������������,
�� �������������� �������������� ���������� ������������������������ �� ����������������,
������ �������� ���� ���� �������� ���������������������� ������������������ �� ��������.
�� ������������ ������������ ���������� �������� �������������������� ��������������
���������������������������� �������������������� �� ��������������
������������������������ �� VLAN.</dd>
+</dlentry></dl></li>
+<li>���������������� ����
<uicontrol>��������������</uicontrol>.</li>
+</ol> </p>
+</csbody>
+</cshelp>
+</cshelp>
+
+
+<!-- ENGL1SH_VERS10N 47050_3 DO NOT REMOVE OR CHANGE THIS LINE -->
+<!-- T9N_SRC_ID 230 -->
+<!-- T9N_SH1P_STR1NG KVM21AAP001 3 -->
diff --git a/src/wok/plugins/kimchi/ui/pages/help/ru_RU/storage.dita
b/src/wok/plugins/kimchi/ui/pages/help/ru_RU/storage.dita
new file mode 100644
index 0000000..fa37edc
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/pages/help/ru_RU/storage.dita
@@ -0,0 +1,88 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--Arbortext, Inc., 1988-2011, v.4002-->
+<!DOCTYPE cshelp PUBLIC "-//IBM//DTD DITA CSHelp//EN"
+ "..\dtd\cshelp.dtd">
+
+
+<!--This DITA specialized document type is not supported by the Authoring Tools
development team.
+For support please see:
+https://w3.opensource.ibm.com/projects/dita-cshelp/-->
+<cshelp id="kimhstor" xml:lang="ru-ru">
+<title>���������������� ������������</title>
+<shortdesc>���� ���������������� <wintitle>����������������
������������</wintitle> ������������������������ ������������ ������������������
���������� ������������, �������������� �������� ������������ '����
������������������' �� 'ISO'.
+�������� ���� ������������ ������������������������ ���������������������� ISO,
���������������� ������ �� �������� ���������������� ������������
'ISO'.</shortdesc>
+<csbody>
+<p>������ �������������� �������� ������������ ������������������������
������������������ ��������������������:<dl>
+<dlentry>
+<dt>������</dt>
+<dd>������ �������� ������������ �� ��������������
��������������������������.</dd>
+</dlentry><dlentry>
+<dt>������������������</dt>
+<dd>������������������ �������� ������������ - ���������������� (��������������)
������ �������������������� (��������������). </dd>
+</dlentry><dlentry>
+<dt>������������������������</dt>
+<dd>�������� �� ������������������������ �������� ������������.</dd>
+</dlentry><dlentry>
+<dt>������</dt>
+<dd>������ �������� ������������, ����������������
<uicontrol>��������������</uicontrol>.</dd>
+</dlentry><dlentry>
+<dt>��������������</dt>
+<dd>���������� �������� ������������.</dd>
+</dlentry><dlentry>
+<dt>����������������</dt>
+<dd>���������� �������������������� ������������ �� ��������.</dd>
+</dlentry></dl></p>
+<p>������ �������������� �������� ������������ ���������� ����������������
������������������ ����������������:<ul>
+<li><uicontrol>������������������������</uicontrol> -
������������������������ ������ ������������, ���������� ������ ���������� ��������
������������������������.</li>
+<li><uicontrol>����������������������������</uicontrol> -
���������������������������� ���������������� ������ ������������.</li>
+<li><uicontrol>��������������</uicontrol> - ��������������
�������������������� ������ ������������.</li>
+</ul></p>
+<p>������ ������������������ ���������������� �� ���������� �������� ������������
���������������� ���� �������������� �� ������������ ���������� ������������ ��������
������������. ���������������� ����������������:<dl><dlentry>
+<dt>������</dt>
+<dd>������ ��������, ����������������
<uicontrol>��������</uicontrol>.</dd>
+</dlentry><dlentry>
+<dt>������������</dt>
+<dd>������������ (�������������� ���� ��������).</dd>
+</dlentry><dlentry>
+<dt>��������������</dt>
+<dd>������������ ��������.</dd>
+</dlentry><dlentry>
+<dt>������������������</dt>
+<dd>���������� �������������������� ������������ �� ��������.</dd>
+</dlentry></dl>������ ���������������� �������� ������������ ����������������
���� ������������ <uicontrol>���������� (+)</uicontrol> �� ������������
�������������� �������� ����������������.</p>
+</csbody>
+<cshelp id="kimhdefstor" xml:lang="ru-ru">
+<title>���������������� �������� ������������</title>
+<shortdesc> ���������������� �������� ������������.</shortdesc>
+<csbody>
+<p> <ol>
+<li>�� �������� <uicontrol>������ �������� ������������</uicontrol>
�������������� ������ ������ �������������������������� �������� ������������.</li>
+<li>�� ������������ <uicontrol>������ �������� ������������</uicontrol>
���������������� ������: <dl><dlentry>
+<dt><uicontrol>��������������</uicontrol></dt>
+<dd>������������ ������-��������������. ������ ������������ ��������
<uicontrol>��������������</uicontrol> ������������������ ��������
+<uicontrol>�������� �� �������� ������������</uicontrol> (�������� ��
�������� ������������ �� ���������������� ��������������).</dd>
+</dlentry><dlentry>
+<dt><uicontrol>NFS</uicontrol></dt>
+<dd>������������ ������ ���� ������������ �������������� ����������������
��������������. ������ ������������ <uicontrol>NFS</uicontrol> ��������������
���������� ��
+�������� <uicontrol>IP-���������� �������������� NFS</uicontrol> �� ��������
�� ���������������������������������� ���������������� �� ��������
<uicontrol>�������� NFS</uicontrol>.</dd>
+</dlentry><dlentry>
+<dt><uicontrol>iSCSI</uicontrol></dt>
+<dd>������������ ������ ���� ������������ ���������������� ��������������,
���������������������� ���� �������������� iSCSI.
+������ ������������ �������� <uicontrol>iSCSI</uicontrol> ��������������
IP-���������� �� �������� <uicontrol>������������ iSCSI</uicontrol> ��
�������������� ������������ ���� �������������� iSCSI �� ��������
<uicontrol>�������������� ������������</uicontrol>. ���������� ����������
���������������� �������������������������� iSCSI.</dd>
+</dlentry><dlentry>
+<dt><uicontrol>��������������������</uicontrol></dt>
+<dd>������������ ������ ������������ ���� ������������ ����������������������
��������. ���������������� ������������������������ �������������������� �� ��������
<uicontrol>�������� �� ��������������������</uicontrol>.</dd>
+</dlentry><dlentry>
+<dt><uicontrol>SCSI Fibre Channel</uicontrol></dt>
+<dd>������������ ������ ���� ������������ SCSI Fibre Channel. ����������������
�������������� SCSI.</dd>
+</dlentry></dl></li>
+<li>���������������� ����
<uicontrol>��������������</uicontrol>.</li>
+</ol> </p>
+</csbody>
+</cshelp>
+</cshelp>
+
+
+<!-- ENGL1SH_VERS10N 22336_4 DO NOT REMOVE OR CHANGE THIS LINE -->
+<!-- T9N_SRC_ID 233 -->
+<!-- T9N_SH1P_STR1NG KV211AAP001 1 -->
diff --git a/src/wok/plugins/kimchi/ui/pages/help/ru_RU/templates.dita
b/src/wok/plugins/kimchi/ui/pages/help/ru_RU/templates.dita
new file mode 100644
index 0000000..27ce4ae
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/pages/help/ru_RU/templates.dita
@@ -0,0 +1,111 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--Arbortext, Inc., 1988-2011, v.4002-->
+<!DOCTYPE cshelp PUBLIC "-//IBM//DTD DITA CSHelp//EN"
+ "..\dtd\cshelp.dtd">
+
+
+<!--This DITA specialized document type is not supported by the Authoring Tools
development team.
+For support please see:
+https://w3.opensource.ibm.com/projects/dita-cshelp/-->
+<cshelp id="kimhtempl" xml:lang="ru-ru">
+<title>��������������</title>
+<shortdesc>���� ���������������� <wintitle>��������������</wintitle>
������������������������ ������������������ �������������� ����������������������
����������, �������������� ���������� ������������������������ ������ ����������������
���������������� ������������ KVM.</shortdesc>
+<csbody>
+<p>������ �������������� �������������� ������������������������ ������������������
��������������������:<dl>
+<dlentry>
+<dt>����</dt>
+<dd>������ ������������������������ �������������� ������ ����������������
������������������������ ��������������.</dd>
+</dlentry><dlentry>
+<dt>������������</dt>
+<dd>������������ ������������������������ �������������� ������ ����������������
������������������������ ��������������.</dd>
+</dlentry><dlentry>
+<dt>��������������������</dt>
+<dd>�������������������� ���������������������� ������ ��������������.</dd>
+</dlentry><dlentry>
+<dt>������������</dt>
+<dd>�������������������� ���������� ���������������������� ������������ ��
����.</dd>
+</dlentry></dl></p>
+<p>������ �������������� �������������� ���������� ����������������
������������������ ����������������:<ul>
+<li><uicontrol>����������������</uicontrol> - ����������������
������������.</li>
+<li><uicontrol>��������������</uicontrol> - ��������������
������������.</li>
+</ul>������ �������������������� �������������� ���������������� ���� ������������
<uicontrol>���������� (+)</uicontrol> �� ������������ �������������� ��������
����������������.</p>
+</csbody>
+<cshelp id="kimhedittempl" xml:lang="ru-ru">
+<title>���������������� ������������</title>
+<shortdesc>���������������� ������������������������
������������.</shortdesc>
+<csbody>
+<p>������ �������������� �������������� ������������������������ ������������������
��������������������: <dl>
+<dlentry>
+<dt>������</dt>
+<dd>������ ��������������.</dd>
+</dlentry><dlentry>
+<dt>������������</dt>
+<dd>������ ����������������, ������������������ ������������������������
�������������� ������ �������������� ������������������������ ��������������, ������
�������������������������� �������������� ��������������������������
������������.</dd>
+</dlentry><dlentry>
+<dt>������������</dt>
+<dd>������������ ������������������������ �������������� ������ ����������������
������������������������ ��������������, ������ �������������������������� ��������������
�������������������������� ������������.</dd>
+</dlentry><dlentry>
+<dt>�������������������� ����������������������</dt>
+<dd>�������������������� ���������������������� ������ ��������������.</dd>
+</dlentry><dlentry>
+<dt>������������</dt>
+<dd>���������� ������������ �� ����, �������������������� ����������������������
������������.</dd>
+</dlentry><dlentry>
+<dt>��������</dt>
+<dd>������������ ���������� �� ����.</dd>
+</dlentry><dlentry>
+<dt>CDROM</dt>
+<dd>�������� �� ���������� ISO ������ ������������������ ����������������
�������������� KVM.</dd>
+</dlentry><dlentry>
+<dt>������ ������������</dt>
+<dd>������������������������ ������ ������������ ������ ������ ������������ ����
������������������.</dd>
+</dlentry><dlentry>
+<dt>��������</dt>
+<dd>�������������� �������������������� ���� ������������������, ������������������
������ ���������������� �������������� KVM. ���������� �������������� ������������������
����������.</dd>
+</dlentry></dl> ���������������� �������� ���������� ����������������.
���������� ������������������ �������� ���������������� ����
<uicontrol>������������������</uicontrol>. </p>
+</csbody>
+</cshelp>
+<cshelp id="kimhaddtempl">
+<title>�������������������� ��������������</title>
+<shortdesc>�������������������� �������������� �� ������������������
����������������. ���������������� ���������������������� ���������� ISO ��
���������������� ������������ ISO ������ ����������������������
������������.</shortdesc>
+<csbody>
+<p>���������������� �������� ���� ������������������ ������������������
������������������������ ������������������ ����������������:<dl>
+<dlentry>
+<dt>������������������ ���������� ISO</dt>
+<dd>���������������� �������� �������������� ������ ������������
������������������������ �������������� ISO �� ������������������ ���������� ������������
��������������.</dd>
+</dlentry><dlentry>
+<dt>������������������ ���������� ISO</dt>
+<dd>���������������� �������� ��������������, ���������� ��������������
������������������ ������������������������ �������������������������� ������������
ISO.</dd>
+</dlentry></dl></p>
+</csbody>
+</cshelp>
+<cshelp id="kimhaddloct">
+<title>�������������������� �������������� (������������������ ����������
ISO)</title>
+<shortdesc>�������������������� �������������� ���� ��������������������
������������ ISO.</shortdesc>
+<csbody>
+<p>���������� ���������������� ������������ ISO, ������������������ ��
��������������.<dl><dlentry>
+<dt>����</dt>
+<dd>������ ������������������������ �������������� ������ ����������������
������������������������ ��������������.</dd>
+</dlentry><dlentry>
+<dt>������������</dt>
+<dd>������������ ������������������������ �������������� ������ ����������������
������������������������ ��������������.</dd>
+</dlentry><dlentry>
+<dt>������������</dt>
+<dd>������������ ������������ ISO.</dd>
+</dlentry></dl></p>
+<p>������ ���������������� �������������� ���� ������������ ISO ����������������
�������� ���� ������������������ ������������������:<ul>
+<li>���������������� ���������� ISO, ���� ���������������� ����������
�������������� ������������, ���������� ���������������� ����
<uicontrol>�������������� �������������� ���� ������������������ ��������������
ISO</uicontrol>.</li>
+<li>���������������� <uicontrol>������</uicontrol>, ����������
�������������� ������������ ���� �������������� ������������ ISO �� ������������,
���������� ���������������� ���� <uicontrol>�������������� �������������� ����
������������������ �������������� ISO</uicontrol>.</li>
+<li>�������� ������������������ ���������� ISO ���������������������� ��
���������������������� ������������, ���������������� �������� ���� ������������������
������������������:<ul>
+<li>���������������� <uicontrol>������������������������ ��������������������
�������� ISO</uicontrol>, ���������� �������������� �������� �� ������������
ISO.</li>
+<li>���������������� ���� <uicontrol>���������� ����������������������������
�������������� ISO</uicontrol> ������ ������������ ����������������������������
�������������� ISO.</li>
+</ul></li>
+</ul></p>
+</csbody>
+</cshelp>
+</cshelp>
+
+
+<!-- ENGL1SH_VERS10N 61085_5 DO NOT REMOVE OR CHANGE THIS LINE -->
+<!-- T9N_SRC_ID 229 -->
+<!-- T9N_SH1P_STR1NG KV211AAP001 1 -->
diff --git a/src/wok/plugins/kimchi/ui/pages/help/zh_CN/Makefile.am
b/src/wok/plugins/kimchi/ui/pages/help/zh_CN/Makefile.am
new file mode 100644
index 0000000..e785048
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/pages/help/zh_CN/Makefile.am
@@ -0,0 +1,23 @@
+# Copyright IBM Corp, 2014
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+zh_CN_helpdir = $(datadir)/wok/plugins/kimchi/ui/pages/help/zh_CN
+
+dist_zh_CN_help_DATA = $(wildcard *.html) $(NULL)
+
+EXTRA_DIST = $(wildcard *.dita)
+
+CLEANFILES = $(wildcard *.html)
diff --git a/src/wok/plugins/kimchi/ui/pages/help/zh_CN/guests.dita
b/src/wok/plugins/kimchi/ui/pages/help/zh_CN/guests.dita
new file mode 100644
index 0000000..d684af2
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/pages/help/zh_CN/guests.dita
@@ -0,0 +1,118 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--Arbortext, Inc., 1988-2011, v.4002-->
+<!DOCTYPE cshelp PUBLIC "-//IBM//DTD DITA CSHelp//EN"
+ "..\dtd\cshelp.dtd">
+
+
+<!--This DITA specialized document type is not supported by the Authoring Tools
development team.
+For support please see:
+https://w3.opensource.ibm.com/projects/dita-cshelp/-->
+<cshelp id="kimhvirtm" xml:lang="zh-cn">
+<title>������</title>
+<shortdesc>���<wintitle>������</wintitle>���������������������������
KVM ������������</shortdesc>
+<csbody>
+<p>���������������������������������������������<dl><dlentry>
+<dt>������</dt>
+<dd>���������������������</dd>
+</dlentry><dlentry>
+<dt>CPU</dt>
+<dd>���������������������������������������</dd>
+</dlentry><dlentry>
+<dt>������ I/O</dt>
+<dd>������������/������������������������ KB/������������</dd>
+</dlentry><dlentry>
+<dt>������ I/O</dt>
+<dd>������������/������������������������ KB/������������</dd>
+</dlentry><dlentry>
+<dt>Livetile</dt>
+<dd>������������������������������������������������������������������������������������
<tm tmtype="tm" trademark="Linux">Linux</tm>
���������������������</dd>
+</dlentry></dl></p>
+<p>���������������������������������������������<dl>
+<dlentry>
+<dt>������</dt>
+<dd>������������������������������</dd>
+</dlentry><dlentry>
+<dt>���������������������������</dt>
+<dd>������������������������������������������������������������������������������������������������������������������������������������������������������</dd>
+</dlentry></dl> </p>
+<p>���������������������������������������<ul>
+<li>������<uicontrol>������</uicontrol>���������������������������������������������������</li>
+<li>������<uicontrol>������������</uicontrol>���������������������������������</li>
+<li>������<uicontrol>������</uicontrol>������������������</li>
+<li>������<uicontrol>������</uicontrol>���������������������������������������������������������������������</li>
+<li>������<uicontrol>������</uicontrol>������������������</li>
+</ul>���������������������������������������������������������<uicontrol>���������
(+) </uicontrol> ���������</p>
+</csbody>
+<cshelp id="kimhvirtmcrt" xml:lang="zh-cn">
+<title>���������������</title>
+<shortdesc>������������������������������������������</shortdesc>
+<csbody>
+<p> <ol>
+<li>���������������������������������������</li>
+<li rev="rev1">���������������<ul>
+<li>���������������������������������������������������������������</li>
+<li>���������������������������������������<uicontrol>������������</uicontrol>������������������</li>
+</ul></li>
+<li>������<uicontrol>������</uicontrol>���</li>
+</ol> </p>
+</csbody>
+</cshelp>
+<cshelp id="kimhvirtmedit" xml:lang="zh-cn">
+<title>������������</title>
+<shortdesc>���������������������������������������������������������������������������������������������������������������������������������������</shortdesc>
+<csprolog><csmetadata></csmetadata></csprolog>
+<csbody>
+<p>������������������������������<wintitle>������</wintitle>������������������������������������<dl>
+<dlentry>
+<dt>������</dt>
+<dd>���������������������������������������������������������������������</dd>
+</dlentry><dlentry>
+<dt>CPU ���</dt>
+<dd>���������������������������������������������������������������������������������������������</dd>
+</dlentry><dlentry>
+<dt>������</dt>
+<dd>��������������� MB
���������������������������������������������������������������������������������</dd>
+</dlentry><dlentry>
+<dt>������</dt>
+<dd>��������������������������������������������������� Linux
������������������������������ (Livetile) ������������������</dd>
+</dlentry></dl></p>
+<p>���������<wintitle>���������</wintitle>������������������������������������</p>
+<dl><dlentry>
+<dt>���������</dt>
+<dd>��������������������� ISO ������������������������</dd>
+</dlentry></dl>
+<p>
���������������������������������������������������������������������<uicontrol>������</uicontrol>���</p>
+</csbody>
+</cshelp>
+<cshelp id="kimstoragedevice" xml:lang="zh-cn">
+<title>������������������������������������</title>
+<shortdesc
rev="rev1">���������������������������������������������������������������������������������������
CDROM���������������������������������������������������</shortdesc>
+<csbody>
+<ol>
+<li>������<wintitle>������������</wintitle>������������������������<wintitle>���������</wintitle>������</li>
+<li>���������������������������������������������������������<uicontrol>������������
(/)</uicontrol>��������� ISO
���������������������<uicontrol>������</uicontrol>���</li>
+<li>���������������������������������������������������������<uicontrol>���������������
(-)</uicontrol>������������������������������������<uicontrol>������</uicontrol>���</li>
+<li>���������������������������������������������������������<uicontrol>���������������
(+)</uicontrol>��������������������� ISO
���������������������<uicontrol>������</uicontrol>���</li>
+</ol>
+</csbody>
+</cshelp>
+<cshelp id="kimreplacemedia" xml:lang="zh-cn">
+<title>������ VM ��� CDROM</title>
+<shortdesc rev="rev1">������������������������������������������������
CDROM ������������</shortdesc>
+<csbody>
+<ol>
+<li>������������������������������</li>
+<li>���������������������������������<uicontrol>������������</uicontrol>���</li>
+<li>������������������������ CDROM ������������������������ hdc
���������������<uicontrol>������������ (/)</uicontrol> ���������</li>
+<li>������<wintitle>������ VM ��� CDROM</wintitle>���������������������
ISO ���������������������������������������������</li>
+<li>������<uicontrol>������</uicontrol>���</li>
+</ol>
+</csbody>
+</cshelp>
+<?tm 1391540919 3?>
+</cshelp>
+
+
+<!-- ENGL1SH_VERS10N 45645_6 DO NOT REMOVE OR CHANGE THIS LINE -->
+<!-- T9N_SRC_ID 231 -->
+<!-- T9N_SH1P_STR1NG KV211AAP001 1 -->
diff --git a/src/wok/plugins/kimchi/ui/pages/help/zh_CN/host.dita
b/src/wok/plugins/kimchi/ui/pages/help/zh_CN/host.dita
new file mode 100644
index 0000000..78a89c3
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/pages/help/zh_CN/host.dita
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--Arbortext, Inc., 1988-2011, v.4002-->
+<!DOCTYPE cshelp PUBLIC "-//IBM//DTD DITA CSHelp//EN"
+ "..\dtd\cshelp.dtd">
+
+
+<!--This DITA specialized document type is not supported by the Authoring Tools
development team.
+For support please see:
+https://w3.opensource.ibm.com/projects/dita-cshelp/-->
+<cshelp id="kimhhost" xml:lang="zh-cn">
+<title>������</title>
+<shortdesc>���<wintitle>������</wintitle>������������������������������������������������������������������������������������������������������</shortdesc>
+<csbody>
+<p>���������������������������������<ul>
+<li>������<uicontrol>������</uicontrol>������������������������</li>
+<li>������<uicontrol>������������</uicontrol>������������������������������</li>
+<li>������<uicontrol>������</uicontrol>��������������������������� VNC
���������������������������������</li>
+</ul></p>
+<p>���������������������������������������������������<dl>
+<dlentry>
+<dt>������������</dt>
+<dd>���������������������������������������������������������������������������������������������������������
GB ���������</dd>
+</dlentry><dlentry>
+<dt>������������������</dt>
+<dd>��������������������������������������������� CPU������������������ I/O
��������� I/O
������������������������<uicontrol>���������������������������������</uicontrol>������������������������������������������������������������</dd>
+</dlentry><dlentry>
+<dt>������������</dt>
+<dd>���������������������������������������������������������������������������������������������������������������������������������������������<uicontrol>������������</uicontrol>���������������������������������������������������������������������������������</dd>
+</dlentry><dlentry>
+<dt>���������</dt>
+<dd>���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������
Red Hat Enterprise Linux ��� Fedora������������������ <filepath>yum</filepath>
��������������������������������� Ubuntu ��� Debian������������������
<filepath>deb</filepath> ������������<p>��������������� Yum
��������������������������� GPG
������������������������������������������������������������������������������������������������<uicontrol>������</uicontrol>���������<uicontrol>���</uicontrol>���������
GPG ��������������������������������� GPG ��������������� URL���</p></dd>
+</dlentry><dlentry>
+<dt>������������</dt>
+<dd>���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������<p>���������������������
+<cmdname>sosreport</cmdname> ��������������������������������� Red
+Hat Enterprise <tm tmtype="tm"
trademark="Linux">Linux</tm>���Fedora ��� Ubuntu
������������������������������������������������������������ .tar
���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������</p>
</dd>
+</dlentry></dl></p>
+</csbody>
+<?tm 1392659967 1?>
+</cshelp>
+
+
+<!-- ENGL1SH_VERS10N 47930_4 DO NOT REMOVE OR CHANGE THIS LINE -->
+<!-- T9N_SRC_ID 232 -->
+<!-- T9N_SH1P_STR1NG KVM21AAP001 3 -->
diff --git a/src/wok/plugins/kimchi/ui/pages/help/zh_CN/network.dita
b/src/wok/plugins/kimchi/ui/pages/help/zh_CN/network.dita
new file mode 100644
index 0000000..f6aa532
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/pages/help/zh_CN/network.dita
@@ -0,0 +1,61 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--Arbortext, Inc., 1988-2011, v.4002-->
+<!DOCTYPE cshelp PUBLIC "-//IBM//DTD DITA CSHelp//EN"
+ "..\dtd\cshelp.dtd">
+
+
+<!--This DITA specialized document type is not supported by the Authoring Tools
development team.
+For support please see:
+https://w3.opensource.ibm.com/projects/dita-cshelp/-->
+<cshelp id="kimhnetw" xml:lang="zh-cn">
+<title>������</title>
+<shortdesc>���<wintitle>������</wintitle>���������������������������������������������</shortdesc>
+<csbody>
+<p><dl><dlentry>
+<dt>���������</dt>
+<dd>������������������<uicontrol>���������</uicontrol>���</dd>
+</dlentry><dlentry>
+<dt>������</dt>
+<dd>���������������������������������������������������������������</dd>
+</dlentry><dlentry>
+<dt>������������</dt>
+<dd>������������������������<uicontrol>NAT</uicontrol>���������������������������</dd>
+</dlentry><dlentry>
+<dt>������</dt>
+<dd>������������������������<uicontrol>virbr0</uicontrol>������������������</dd>
+</dlentry><dlentry>
+<dt>������������</dt>
+<dd>IP ���������</dd>
+</dlentry></dl></p>
+<p>���������������������������<ul>
+<li
rev="rev1">������<uicontrol>������</uicontrol>������������������������</li>
+<li>������<uicontrol>������</uicontrol>������������������������</li>
+<li>������<uicontrol>������</uicontrol>������������������������</li>
+</ul>������������������������������������������������<uicontrol>���������
(+)</uicontrol> ���������</p>
+</csbody>
+<cshelp id="kimhnetwcrt" xml:lang="zh-cn">
+<title>������������</title>
+<shortdesc>���������������</shortdesc>
+<csbody>
+<p> <ol>
+<li>������������������������</li>
+<li>������������������������������������<dl
rev="rev1"><dlentry>
+<dt><uicontrol>������</uicontrol></dt>
+<dd>������������������������������������������������������������������������������</dd>
+</dlentry><dlentry>
+<dt><uicontrol>NAT</uicontrol></dt>
+<dd>��������������������������������������������������������������������������� IP
������������������������������������������������������</dd>
+</dlentry><dlentry>
+<dt><uicontrol>������</uicontrol></dt>
+<dd>������������������������������������������������������������������������������������������������������������������������������������������������������������������
VLAN ���������</dd>
+</dlentry></dl></li>
+<li>������<uicontrol>������</uicontrol>���</li>
+</ol> </p>
+</csbody>
+</cshelp>
+</cshelp>
+
+
+<!-- ENGL1SH_VERS10N 47050_3 DO NOT REMOVE OR CHANGE THIS LINE -->
+<!-- T9N_SRC_ID 230 -->
+<!-- T9N_SH1P_STR1NG KVM21AAP001 3 -->
diff --git a/src/wok/plugins/kimchi/ui/pages/help/zh_CN/storage.dita
b/src/wok/plugins/kimchi/ui/pages/help/zh_CN/storage.dita
new file mode 100644
index 0000000..cfb09f5
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/pages/help/zh_CN/storage.dita
@@ -0,0 +1,84 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--Arbortext, Inc., 1988-2011, v.4002-->
+<!DOCTYPE cshelp PUBLIC "-//IBM//DTD DITA CSHelp//EN"
+ "..\dtd\cshelp.dtd">
+
+
+<!--This DITA specialized document type is not supported by the Authoring Tools
development team.
+For support please see:
+https://w3.opensource.ibm.com/projects/dita-cshelp/-->
+<cshelp id="kimhstor" xml:lang="zh-cn">
+<title>���������</title>
+<shortdesc>���<wintitle>���������</wintitle>���������������������������������������������������������������������ISO���������������������������������������������
ISO������������������������ISO���������������������</shortdesc>
+<csbody>
+<p>������������������������������������������������<dl>
+<dlentry>
+<dt>������</dt>
+<dd>������������������������������������������</dd>
+</dlentry><dlentry>
+<dt>������</dt>
+<dd>������������������������������������������������������������������</dd>
+</dlentry><dlentry>
+<dt>������ </dt>
+<dd>���������������������������������������</dd>
+</dlentry><dlentry>
+<dt>������</dt>
+<dd>������������������������������<uicontrol>dir</uicontrol>���</dd>
+</dlentry><dlentry>
+<dt>������</dt>
+<dd>���������������������������</dd>
+</dlentry><dlentry>
+<dt>���������</dt>
+<dd>������������������������������������</dd>
+</dlentry></dl></p>
+<p>������������������������������������������<ul>
+<li>������<uicontrol>������</uicontrol>���������������������������������������</li>
+<li>������<uicontrol>������������</uicontrol>���������������������������������</li>
+<li>������<uicontrol>������������</uicontrol>������������������������������</li>
+</ul></p>
+<p>���������������������������������������������������������������������������������������������������������������������<dl><dlentry>
+<dt>������</dt>
+<dd>������������������������<uicontrol>������</uicontrol>���</dd>
+</dlentry><dlentry>
+<dt>������</dt>
+<dd>���������������������������������</dd>
+</dlentry><dlentry>
+<dt>������</dt>
+<dd>���������������������</dd>
+</dlentry><dlentry>
+<dt>������</dt>
+<dd>������������������������������������</dd>
+</dlentry></dl>���������������������������������������������������<uicontrol>���������
(+)</uicontrol> ���������</p>
+</csbody>
+<cshelp id="kimhdefstor" xml:lang="zh-cn">
+<title>���������������</title>
+<shortdesc> ������������������</shortdesc>
+<csbody>
+<p> <ol>
+<li>���<uicontrol>���������������</uicontrol>���������������������������������������������������</li>
+<li>���<uicontrol>���������������</uicontrol>���������������������������<dl><dlentry>
+<dt><uicontrol>DIR</uicontrol></dt>
+<dd>��������������������������� <uicontrol>DIR</uicontrol>
������������<uicontrol>������������</uicontrol>���������������������������������</dd>
+</dlentry><dlentry>
+<dt><uicontrol>NFS</uicontrol></dt>
+<dd>��������������������������������������� <uicontrol>NFS</uicontrol>
������������ <uicontrol>NFS ��������� IP ������</uicontrol>���
<uicontrol>NFS ������</uicontrol>���������������������������������</dd>
+</dlentry><dlentry>
+<dt><uicontrol>iSCSI</uicontrol></dt>
+<dd>������ iSCSI ������������������������������������������������
<uicontrol>iSCSI</uicontrol> ��������� iSCSI ������������������
<uicontrol>iSCSI ��������� IP
������</uicontrol>���<uicontrol>������</uicontrol>������������������������������������
iSCSI ���������</dd>
+</dlentry><dlentry>
+<dt><uicontrol>������</uicontrol></dt>
+<dd>������������������������������<uicontrol>������������</uicontrol>���������������������������</dd>
+</dlentry><dlentry>
+<dt><uicontrol>SCSI ������������</uicontrol></dt>
+<dd>������ SCSI ������������������������������������������ SCSI
������������</dd>
+</dlentry></dl></li>
+<li>������<uicontrol>������</uicontrol>���</li>
+</ol> </p>
+</csbody>
+</cshelp>
+</cshelp>
+
+
+<!-- ENGL1SH_VERS10N 22336_4 DO NOT REMOVE OR CHANGE THIS LINE -->
+<!-- T9N_SRC_ID 233 -->
+<!-- T9N_SH1P_STR1NG KV211AAP001 1 -->
diff --git a/src/wok/plugins/kimchi/ui/pages/help/zh_CN/templates.dita
b/src/wok/plugins/kimchi/ui/pages/help/zh_CN/templates.dita
new file mode 100644
index 0000000..ca50119
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/pages/help/zh_CN/templates.dita
@@ -0,0 +1,111 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--Arbortext, Inc., 1988-2011, v.4002-->
+<!DOCTYPE cshelp PUBLIC "-//IBM//DTD DITA CSHelp//EN"
+ "..\dtd\cshelp.dtd">
+
+
+<!--This DITA specialized document type is not supported by the Authoring Tools
development team.
+For support please see:
+https://w3.opensource.ibm.com/projects/dita-cshelp/-->
+<cshelp id="kimhtempl" xml:lang="zh-cn">
+<title>������</title>
+<shortdesc>���<wintitle>������</wintitle>������������������������������
KVM ������������������������������������</shortdesc>
+<csbody>
+<p>���������������������������������������������<dl>
+<dlentry>
+<dt>������������</dt>
+<dd>������������������������������������</dd>
+</dlentry><dlentry>
+<dt>������</dt>
+<dd>������������������������������������</dd>
+</dlentry><dlentry>
+<dt>CPU ���</dt>
+<dd>���������������������������������</dd>
+</dlentry><dlentry>
+<dt>������</dt>
+<dd>��������������������������������������� MB ���������</dd>
+</dlentry></dl></p>
+<p>���������������������������������������<ul>
+<li>������<uicontrol>������</uicontrol>������������������</li>
+<li>������<uicontrol>������</uicontrol>������������������</li>
+</ul>������������������������������������������������<uicontrol>���������
(+)</uicontrol> ���������</p>
+</csbody>
+<cshelp id="kimhedittempl" xml:lang="zh-cn">
+<title>������������</title>
+<shortdesc>���������������������</shortdesc>
+<csbody>
+<p>���������������������������������������������<dl>
+<dlentry>
+<dt>������</dt>
+<dd>������������������</dd>
+</dlentry><dlentry>
+<dt>���������</dt>
+<dd>������������������������������������������������������������������������������������</dd>
+</dlentry><dlentry>
+<dt>������</dt>
+<dd>������������������������������������������������������������</dd>
+</dlentry><dlentry>
+<dt>CPU ������</dt>
+<dd>���������������������������������</dd>
+</dlentry><dlentry>
+<dt>������</dt>
+<dd>��������������������������������������� MB ���������</dd>
+</dlentry><dlentry>
+<dt>������</dt>
+<dd>������������������ GB ���������</dd>
+</dlentry><dlentry>
+<dt>CDROM</dt>
+<dd>������������ KVM ��������� ISO ������������������������������������</dd>
+</dlentry><dlentry>
+<dt>���������</dt>
+<dd>������������������������������������</dd>
+</dlentry><dlentry>
+<dt>������</dt>
+<dd>������ KVM
������������������������������������������������������������������</dd>
+</dlentry></dl>
���������������������������������������������������������������������<uicontrol>������</uicontrol>���</p>
+</csbody>
+</cshelp>
+<cshelp id="kimhaddtempl">
+<title>������������</title>
+<shortdesc>������������������������������������������������������ ISO
������������������ISO������������������������������������</shortdesc>
+<csbody>
+<p>������������������������������������������������<dl>
+<dlentry>
+<dt>������ ISO ������</dt>
+<dd>������������������������������������������ ISO
���������������������������������</dd>
+</dlentry><dlentry>
+<dt>������ ISO ������</dt>
+<dd>��������������������������� ISO ������������������������</dd>
+</dlentry></dl></p>
+</csbody>
+</cshelp>
+<cshelp id="kimhaddloct">
+<title>������������ - ������ ISO ������</title>
+<shortdesc>��������� ISO ���������������������</shortdesc>
+<csbody>
+<p>��������������������������� ISO ���������<dl><dlentry>
+<dt>������������</dt>
+<dd>������������������������������������</dd>
+</dlentry><dlentry>
+<dt>������</dt>
+<dd>������������������������������������</dd>
+</dlentry><dlentry>
+<dt>������</dt>
+<dd>ISO ������������������</dd>
+</dlentry></dl></p>
+<p>������ ISO ���������������������������������������������������<ul>
+<li>������������������������������ ISO
���������������������<uicontrol>��������� ISO
������������</uicontrol>���</li>
+<li>������<uicontrol>������</uicontrol>������������������������ ISO
���������������������������������<uicontrol>��������� ISO
������������</uicontrol>���</li>
+<li>��������������������� ISO
������������������������������������������������������������������������<ul>
+<li>������<uicontrol>������������������ ISO ������</uicontrol>���������
ISO ������������������</li>
+<li>������<uicontrol>������������ ISO</uicontrol> ��������������� ISO
���������</li>
+</ul></li>
+</ul></p>
+</csbody>
+</cshelp>
+</cshelp>
+
+
+<!-- ENGL1SH_VERS10N 61085_5 DO NOT REMOVE OR CHANGE THIS LINE -->
+<!-- T9N_SRC_ID 229 -->
+<!-- T9N_SH1P_STR1NG KV211AAP001 1 -->
diff --git a/src/wok/plugins/kimchi/ui/pages/help/zh_TW/Makefile.am
b/src/wok/plugins/kimchi/ui/pages/help/zh_TW/Makefile.am
new file mode 100644
index 0000000..9c8ac26
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/pages/help/zh_TW/Makefile.am
@@ -0,0 +1,23 @@
+# Copyright IBM Corp, 2014
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+zh_TW_helpdir = $(datadir)/wok/plugins/kimchi/ui/pages/help/zh_TW
+
+dist_zh_TW_help_DATA = $(wildcard *.html) $(NULL)
+
+EXTRA_DIST = $(wildcard *.dita)
+
+CLEANFILES = $(wildcard *.html)
diff --git a/src/wok/plugins/kimchi/ui/pages/help/zh_TW/guests.dita
b/src/wok/plugins/kimchi/ui/pages/help/zh_TW/guests.dita
new file mode 100644
index 0000000..cf73785
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/pages/help/zh_TW/guests.dita
@@ -0,0 +1,120 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--Arbortext, Inc., 1988-2011, v.4002-->
+<!DOCTYPE cshelp PUBLIC "-//IBM//DTD DITA CSHelp//EN"
+ "..\dtd\cshelp.dtd">
+
+
+<!--This DITA specialized document type is not supported by the Authoring Tools
development team.
+For support please see:
+https://w3.opensource.ibm.com/projects/dita-cshelp/-->
+<cshelp id="kimhvirtm" xml:lang="zh-tw">
+<title>������</title>
+<shortdesc>���<wintitle>������</wintitle>������������������������������
KVM ���������������</shortdesc>
+<csbody>
+<p>���������������������������������������������������<dl><dlentry>
+<dt>������</dt>
+<dd>������������������������</dd>
+</dlentry><dlentry>
+<dt>CPU</dt>
+<dd>������������������������������������������������</dd>
+</dlentry><dlentry>
+<dt>������ I/O</dt>
+<dd>������������/������������������ (KB/s)���</dd>
+</dlentry><dlentry>
+<dt>������ I/O</dt>
+<dd>������������/������������������ (KB/s)���</dd>
+</dlentry><dlentry>
+<dt>Livetile</dt>
+<dd>��������������������������������������������������� <tm
tmtype="tm" trademark="Linux">Linux</tm>
������������������������������������������������������������������</dd>
+</dlentry></dl></p>
+<p>���������������������������������������������������������<dl>
+<dlentry>
+<dt>������</dt>
+<dd>���������������������������</dd>
+</dlentry><dlentry>
+<dt>���������������������������</dt>
+<dd>���������������������������������������������������������������������������������������������������������������������������������������������������</dd>
+</dlentry></dl> </p>
+<p>���������������������������������������������<ul>
+<li>������<uicontrol>������</uicontrol>���������������������������������������������������</li>
+<li>������<uicontrol>������������</uicontrol>���������������������������������</li>
+<li>������<uicontrol>������</uicontrol>������������������</li>
+<li>������<uicontrol>������</uicontrol>������������������������������������������������������������������������</li>
+<li>������<uicontrol>������</uicontrol>������������������</li>
+</ul>������������������������������������������������������������������������<uicontrol>������
(+)</uicontrol> ���������</p>
+</csbody>
+<cshelp id="kimhvirtmcrt" xml:lang="zh-tw">
+<title>������������������</title>
+<shortdesc>���������������������������������������</shortdesc>
+<csbody>
+<p> <ol>
+<li>������������������������������������������</li>
+<li rev="rev1">���������������<ul>
+<li>������������������������������������������������������</li>
+<li>���������������������������������<uicontrol>������������</uicontrol>������������������</li>
+</ul></li>
+<li>���������<uicontrol>������</uicontrol>���</li>
+</ol> </p>
+</csbody>
+</cshelp>
+<cshelp id="kimhvirtmedit" xml:lang="zh-tw">
+<title>������������</title>
+<shortdesc>������������������������������������������������������������������������������������������������������������������������������������</shortdesc>
+<csprolog><csmetadata></csmetadata></csprolog>
+<csbody>
+<p>������������������������������������<wintitle>������</wintitle>���������������������������������<dl>
+<dlentry>
+<dt>������</dt>
+<dd>������������������������������������������������������������������</dd>
+</dlentry><dlentry>
+<dt>CPU</dt>
+<dd>���������������������������������������������������������������������������������������������</dd>
+</dlentry><dlentry>
+<dt>���������</dt>
+<dd>���������������
(MB)������������������������������������������������������������������������������</dd>
+</dlentry><dlentry>
+<dt>������</dt>
+<dd>������������������������������������������������������������ (Livetile)
��������������� Linux ������������������������������</dd>
+</dlentry></dl></p>
+<p>���������������������������<wintitle>������</wintitle>���������������</p>
+<dl><dlentry>
+<dt>���������</dt>
+<dd>��������������������� ISO ������������������</dd>
+</dlentry></dl>
+<p>
���������������������������������������������������������������<uicontrol>������</uicontrol>���</p>
+</csbody>
+</cshelp>
+<cshelp id="kimstoragedevice" xml:lang="zh-tw">
+<title>������������������������������������</title>
+<shortdesc
rev="rev1">������������������������������������������������������������������������������������������
CDROM������������������������������������������������������</shortdesc>
+<csbody>
+<ol>
+<li>������<wintitle>������������</wintitle>������������������������<wintitle>���������</wintitle>������</li>
+<li>���������������������������������������������<uicontrol>������������
(/)</uicontrol> ���������������������������
+ISO
������������������������������<uicontrol>������</uicontrol>���</li>
+<li>���������������������������������������������<uicontrol>������������
(/)</uicontrol>
���������������������������������������������������<uicontrol>������</uicontrol>���</li>
+<li>���������������������������������������������������<uicontrol>������
(+)</uicontrol> ������������������������������������������
+ISO
������������������������������<uicontrol>������</uicontrol>���</li>
+</ol>
+</csbody>
+</cshelp>
+<cshelp id="kimreplacemedia" xml:lang="zh-tw">
+<title>��������������������� CDROM</title>
+<shortdesc rev="rev1">���������������������������������������������������
CDROM ������������</shortdesc>
+<csbody>
+<ol>
+<li>������������������������������</li>
+<li>������������������������������������<uicontrol>������������</uicontrol>���</li>
+<li>��������������������� CDROM ��������������������������������� hdc
���������������<uicontrol>������������ (/)</uicontrol> ���������</li>
+<li>������<wintitle>���������������������
CDROM</wintitle>��������������������� ISO
������������������������������������������������</li>
+<li>���������<uicontrol>������</uicontrol>���</li>
+</ol>
+</csbody>
+</cshelp>
+<?tm 1391540919 3?>
+</cshelp>
+
+
+<!-- ENGL1SH_VERS10N 45645_6 DO NOT REMOVE OR CHANGE THIS LINE -->
+<!-- T9N_SRC_ID 231 -->
+<!-- T9N_SH1P_STR1NG KV211AAP001 1 -->
diff --git a/src/wok/plugins/kimchi/ui/pages/help/zh_TW/host.dita
b/src/wok/plugins/kimchi/ui/pages/help/zh_TW/host.dita
new file mode 100644
index 0000000..a55aae4
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/pages/help/zh_TW/host.dita
@@ -0,0 +1,50 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--Arbortext, Inc., 1988-2011, v.4002-->
+<!DOCTYPE cshelp PUBLIC "-//IBM//DTD DITA CSHelp//EN"
+ "..\dtd\cshelp.dtd">
+
+
+<!--This DITA specialized document type is not supported by the Authoring Tools
development team.
+For support please see:
+https://w3.opensource.ibm.com/projects/dita-cshelp/-->
+<cshelp id="kimhhost" xml:lang="zh-tw">
+<title>������</title>
+<shortdesc>���<wintitle>������</wintitle>���������������������������������������������������������������������������������������������������������</shortdesc>
+<csbody>
+<p>������������������������������������������<ul>
+<li>������<uicontrol>������</uicontrol>������������������������</li>
+<li>������<uicontrol>������������</uicontrol>������������������������������</li>
+<li>������<uicontrol>������</uicontrol>��������������������������� VNC
������������������������������������������������</li>
+</ul></p>
+<p>������������������������������������������������������<dl>
+<dlentry>
+<dt>������������</dt>
+<dd>������������������������������������������������������������������������������������������������������������������
(GB)���</dd>
+</dlentry><dlentry>
+<dt>������������������</dt>
+<dd>��������������������������������������������������� CPU���������������������
I/O ��������� I/O
������������������������<uicontrol>���������������������������������</uicontrol>���������������������������������������������������������������</dd>
+</dlentry><dlentry>
+<dt>������������</dt>
+<dd>���������������������������������������������������������������������������������������������������������������������������������������������<uicontrol>������������</uicontrol>���������������������������������������������������������������������������</dd>
+</dlentry><dlentry>
+<dt>���������</dt>
+<dd>������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������
+Red Hat Enterprise Linux ��� Fedora������������������
<filepath>yum</filepath> ���������������������������������
+Ubuntu ��� Debian������������������ <filepath>deb</filepath>
������������<p>���������������������
+yum ��������������������������� GPG
���������������������������������������������������������������������������������������������<uicontrol>������</uicontrol>���������<uicontrol>���</uicontrol>���������
+GPG ��������������������������������� GPG ������������ URL���</p></dd>
+</dlentry><dlentry>
+<dt>������������</dt>
+<dd>���������������������������������������������������������������������������������������������������������������������������������������������������������<p>���������������������
+<cmdname>sosreport</cmdname> ������������������������������������ Red
+Hat Enterprise <tm tmtype="tm"
trademark="Linux">Linux</tm>���Fedora
+��� Ubuntu ��������������������������������� .tar
������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������</p>
</dd>
+</dlentry></dl></p>
+</csbody>
+<?tm 1392659967 1?>
+</cshelp>
+
+
+<!-- ENGL1SH_VERS10N 47930_4 DO NOT REMOVE OR CHANGE THIS LINE -->
+<!-- T9N_SRC_ID 232 -->
+<!-- T9N_SH1P_STR1NG KVM21AAP001 3 -->
diff --git a/src/wok/plugins/kimchi/ui/pages/help/zh_TW/network.dita
b/src/wok/plugins/kimchi/ui/pages/help/zh_TW/network.dita
new file mode 100644
index 0000000..f392060
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/pages/help/zh_TW/network.dita
@@ -0,0 +1,61 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--Arbortext, Inc., 1988-2011, v.4002-->
+<!DOCTYPE cshelp PUBLIC "-//IBM//DTD DITA CSHelp//EN"
+ "..\dtd\cshelp.dtd">
+
+
+<!--This DITA specialized document type is not supported by the Authoring Tools
development team.
+For support please see:
+https://w3.opensource.ibm.com/projects/dita-cshelp/-->
+<cshelp id="kimhnetw" xml:lang="zh-tw">
+<title>������</title>
+<shortdesc>���<wintitle>������</wintitle>������������������������������������������������</shortdesc>
+<csbody>
+<p><dl><dlentry>
+<dt>������������</dt>
+<dd>������������������������<uicontrol>���������</uicontrol>���</dd>
+</dlentry><dlentry>
+<dt>������</dt>
+<dd>���������������������������������������������������������������������</dd>
+</dlentry><dlentry>
+<dt>������������</dt>
+<dd>������������������������<uicontrol>NAT</uicontrol>���������������������</dd>
+</dlentry><dlentry>
+<dt>������</dt>
+<dd>������������������������<uicontrol>virbr0</uicontrol>������������������</dd>
+</dlentry><dlentry>
+<dt>������������</dt>
+<dd>IP ���������</dd>
+</dlentry></dl></p>
+<p>������������������������<ul>
+<li
rev="rev1">������<uicontrol>������</uicontrol>������������������������</li>
+<li>������<uicontrol>������</uicontrol>������������������������</li>
+<li>������<uicontrol>������</uicontrol>������������������������</li>
+</ul>���������������������������������������������������������<uicontrol>������
(+)</uicontrol> ���������</p>
+</csbody>
+<cshelp id="kimhnetwcrt" xml:lang="zh-tw">
+<title>������������</title>
+<shortdesc>������������</shortdesc>
+<csbody>
+<p> <ol>
+<li>������������������������</li>
+<li>���������������������������������<dl
rev="rev1"><dlentry>
+<dt><uicontrol>���������</uicontrol></dt>
+<dd>������������������������������������������������������������������������������������������������������������</dd>
+</dlentry><dlentry>
+<dt><uicontrol>NAT</uicontrol></dt>
+<dd>������������������������������������������������������������������ IP
������������������������������������������������������������</dd>
+</dlentry><dlentry>
+<dt><uicontrol>���������</uicontrol></dt>
+<dd>���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������
VLAN ���������</dd>
+</dlentry></dl></li>
+<li>���������<uicontrol>������</uicontrol>���</li>
+</ol> </p>
+</csbody>
+</cshelp>
+</cshelp>
+
+
+<!-- ENGL1SH_VERS10N 47050_3 DO NOT REMOVE OR CHANGE THIS LINE -->
+<!-- T9N_SRC_ID 230 -->
+<!-- T9N_SH1P_STR1NG KVM21AAP001 3 -->
diff --git a/src/wok/plugins/kimchi/ui/pages/help/zh_TW/storage.dita
b/src/wok/plugins/kimchi/ui/pages/help/zh_TW/storage.dita
new file mode 100644
index 0000000..971619c
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/pages/help/zh_TW/storage.dita
@@ -0,0 +1,88 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--Arbortext, Inc., 1988-2011, v.4002-->
+<!DOCTYPE cshelp PUBLIC "-//IBM//DTD DITA CSHelp//EN"
+ "..\dtd\cshelp.dtd">
+
+
+<!--This DITA specialized document type is not supported by the Authoring Tools
development team.
+For support please see:
+https://w3.opensource.ibm.com/projects/dita-cshelp/-->
+<cshelp id="kimhstor" xml:lang="zh-tw">
+<title>���������</title>
+<shortdesc>���<wintitle>���������</wintitle>������������������������������������������������������������������������������������
'ISO' ��������������������������������������� ISO���������������������
'ISO' ������������������</shortdesc>
+<csbody>
+<p>������������������������������������������������������<dl>
+<dlentry>
+<dt>������</dt>
+<dd>������������������������������������������</dd>
+</dlentry><dlentry>
+<dt>������</dt>
+<dd>������������������������������������������������������������������������</dd>
+</dlentry><dlentry>
+<dt>������</dt>
+<dd>���������������������������������</dd>
+</dlentry><dlentry>
+<dt>������</dt>
+<dd>������������������������������<uicontrol>dir</uicontrol>���</dd>
+</dlentry><dlentry>
+<dt>������</dt>
+<dd>������������������������������</dd>
+</dlentry><dlentry>
+<dt>���������</dt>
+<dd>���������������������������������������</dd>
+</dlentry></dl></p>
+<p>������������������������������������������������<ul>
+<li>������<uicontrol>������</uicontrol>������������������������������������������</li>
+<li>������<uicontrol>������������</uicontrol>���������������������������������������</li>
+<li>������<uicontrol>������������</uicontrol>������������������������������������</li>
+</ul></p>
+<p>������������������������������������������������������������������������������������������������������������������������������<dl><dlentry>
+<dt>������</dt>
+<dd>���������������������������<uicontrol>������</uicontrol>���</dd>
+</dlentry><dlentry>
+<dt>������</dt>
+<dd>���������������������������</dd>
+</dlentry><dlentry>
+<dt>������</dt>
+<dd>������������������������</dd>
+</dlentry><dlentry>
+<dt>������</dt>
+<dd>���������������������������������������</dd>
+</dlentry></dl>������������������������������������������������������������<uicontrol>������
(+)</uicontrol> ���������</p>
+</csbody>
+<cshelp id="kimhdefstor" xml:lang="zh-tw">
+<title>���������������</title>
+<shortdesc> ������������������</shortdesc>
+<csbody>
+<p> <ol>
+<li>���<uicontrol>���������������</uicontrol>���������������������������������������������������</li>
+<li>���<uicontrol>���������������</uicontrol>���������������������������<dl><dlentry>
+<dt><uicontrol>DIR</uicontrol></dt>
+<dd>��������������������������������� <uicontrol>DIR</uicontrol>
���������������<uicontrol>���������������</uicontrol>���������������������������</dd>
+</dlentry><dlentry>
+<dt><uicontrol>NFS</uicontrol></dt>
+<dd>���������������������������������������������
<uicontrol>NFS</uicontrol> ���������������
+<uicontrol>NFS ��������� IP</uicontrol> ��������� <uicontrol>NFS
+������</uicontrol>���������������������������������</dd>
+</dlentry><dlentry>
+<dt><uicontrol>iSCSI</uicontrol></dt>
+<dd>��������� iSCSI ���������������������������������������������������������
+<uicontrol>iSCSI</uicontrol> ��������������� <uicontrol>iSCSI
+���������</uicontrol> IP ��������� iSCSI
���������������<uicontrol>������</uicontrol>������������������������������������
iSCSI ���������</dd>
+</dlentry><dlentry>
+<dt><uicontrol>������</uicontrol></dt>
+<dd>���������������������������������<uicontrol>������������</uicontrol>���������������������������</dd>
+</dlentry><dlentry>
+<dt><uicontrol>SCSI ������������</uicontrol></dt>
+<dd>������ SCSI ������������������������������������������������ SCSI
������������</dd>
+</dlentry></dl></li>
+<li>���������<uicontrol>������</uicontrol>���</li>
+</ol> </p>
+</csbody>
+</cshelp>
+</cshelp>
+
+
+<!-- ENGL1SH_VERS10N 22336_4 DO NOT REMOVE OR CHANGE THIS LINE -->
+<!-- T9N_SRC_ID 233 -->
+<!-- T9N_SH1P_STR1NG KV211AAP001 1 -->
diff --git a/src/wok/plugins/kimchi/ui/pages/help/zh_TW/templates.dita
b/src/wok/plugins/kimchi/ui/pages/help/zh_TW/templates.dita
new file mode 100644
index 0000000..4b3a6a6
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/pages/help/zh_TW/templates.dita
@@ -0,0 +1,112 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--Arbortext, Inc., 1988-2011, v.4002-->
+<!DOCTYPE cshelp PUBLIC "-//IBM//DTD DITA CSHelp//EN"
+ "..\dtd\cshelp.dtd">
+
+
+<!--This DITA specialized document type is not supported by the Authoring Tools
development team.
+For support please see:
+https://w3.opensource.ibm.com/projects/dita-cshelp/-->
+<cshelp id="kimhtempl" xml:lang="zh-tw">
+<title>������</title>
+<shortdesc>���<wintitle>������</wintitle>���������������������������������
+KVM ���������������������������������������</shortdesc>
+<csbody>
+<p>���������������������������������������������������<dl>
+<dlentry>
+<dt>OS</dt>
+<dd>������������������������������������������������</dd>
+</dlentry><dlentry>
+<dt>������</dt>
+<dd>������������������������������������������������</dd>
+</dlentry><dlentry>
+<dt>CPU</dt>
+<dd>������������������������������������</dd>
+</dlentry><dlentry>
+<dt>���������</dt>
+<dd>��������������������������������������� (MB)���</dd>
+</dlentry></dl></p>
+<p>���������������������������������������������<ul>
+<li>������<uicontrol>������</uicontrol>������������������</li>
+<li>������<uicontrol>������</uicontrol>������������������</li>
+</ul>���������������������������������������������������������<uicontrol>������
(+)</uicontrol> ���������</p>
+</csbody>
+<cshelp id="kimhedittempl" xml:lang="zh-tw">
+<title>������������</title>
+<shortdesc>���������������������</shortdesc>
+<csbody>
+<p>���������������������������������������������������<dl>
+<dlentry>
+<dt>������</dt>
+<dd>������������������</dd>
+</dlentry><dlentry>
+<dt>���������</dt>
+<dd>������������������������������������������������������������������������������</dd>
+</dlentry><dlentry>
+<dt>������</dt>
+<dd>���������������������������������������������������������������</dd>
+</dlentry><dlentry>
+<dt>CPU ������</dt>
+<dd>������������������������������������</dd>
+</dlentry><dlentry>
+<dt>���������</dt>
+<dd>������������������������������������������ (MB)���</dd>
+</dlentry><dlentry>
+<dt>������</dt>
+<dd>������������ (GB)���</dd>
+</dlentry><dlentry>
+<dt>CDROM</dt>
+<dd>������������ KVM ��������� ISO ������������������������������</dd>
+</dlentry><dlentry>
+<dt>���������</dt>
+<dd>������������������������������������</dd>
+</dlentry><dlentry>
+<dt>������</dt>
+<dd>KVM
���������������������������������������������������������������������</dd>
+</dlentry></dl>
���������������������������������������������������������������<uicontrol>������</uicontrol>���</p>
+</csbody>
+</cshelp>
+<cshelp id="kimhaddtempl">
+<title>������������</title>
+<shortdesc>������������������������������������������������������ ISO
������������������ 'ISO' ������������������������������������</shortdesc>
+<csbody>
+<p>������������������������������������������������<dl>
+<dlentry>
+<dt>������ ISO ���������</dt>
+<dd>��������������������������������������������������������������� ISO
������������</dd>
+</dlentry><dlentry>
+<dt>������ ISO ���������</dt>
+<dd>��������������������������� ISO ���������������������������</dd>
+</dlentry></dl></p>
+</csbody>
+</cshelp>
+<cshelp id="kimhaddloct">
+<title>������������ - ������ ISO ���������</title>
+<shortdesc>��������� ISO ������������������������</shortdesc>
+<csbody>
+<p>������������������������������ ISO ������������<dl><dlentry>
+<dt>OS</dt>
+<dd>������������������������������������������������</dd>
+</dlentry><dlentry>
+<dt>������</dt>
+<dd>������������������������������������������������</dd>
+</dlentry><dlentry>
+<dt>������</dt>
+<dd>ISO ���������������������</dd>
+</dlentry></dl></p>
+<p>��������� ISO ������������������������������������������������������<ul>
+<li>������������������������������ ISO
���������������������������<uicontrol>��������� ISO
������������</uicontrol>���</li>
+<li>������<uicontrol>������</uicontrol>������������������������ ISO
���������������������������������������<uicontrol>��������� ISO
������������</uicontrol>���</li>
+<li>������������������ ISO
���������������������������������������������������������������������������<ul>
+<li>������<uicontrol>��������������������� ISO
������</uicontrol>��������� ISO ���������������������</li>
+<li>���������<uicontrol>������������ ISO</uicontrol> ���������������
ISO ������������</li>
+</ul></li>
+</ul></p>
+</csbody>
+</cshelp>
+</cshelp>
+
+
+<!-- ENGL1SH_VERS10N 61085_5 DO NOT REMOVE OR CHANGE THIS LINE -->
+<!-- T9N_SRC_ID 229 -->
+<!-- T9N_SH1P_STR1NG KV211AAP001 1 -->
diff --git a/src/wok/plugins/kimchi/ui/pages/host.html.tmpl
b/src/wok/plugins/kimchi/ui/pages/host.html.tmpl
new file mode 100644
index 0000000..d87debc
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/pages/host.html.tmpl
@@ -0,0 +1,177 @@
+#*
+ * Project Kimchi
+ *
+ * Copyright IBM, Corp. 2013-2015
+ *
+ * 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.
+ *#
+
+#unicode UTF-8
+#import gettext
+#from wok.cachebust import href
+#silent t = gettext.translation($lang.domain, $lang.localedir, languages=$lang.lang,
fallback=True)
+#silent _ = t.gettext
+#silent _t = t.gettext
+<!DOCTYPE html>
+<html>
+<head>
+<link rel="stylesheet"
href="plugins/kimchi/css/theme-default.min.css">
+<script src="plugins/kimchi/js/kimchi.min.js"></script>
+</head>
+<body>
+<div id="host-root-container">
+ <div class="toolbar">
+ <div class="tools">
+ </div>
+ </div>
+ <div id="host-content-container"
class="empty-when-logged-off"></div>
+</div>
+
+<script id="host-tmpl" type="kimchi/template">
+ <div class="host-panel">
+ <div class="logo-container">
+ <div class="logo" style="background-image:
url({logo});"></div>
+ </div>
+ <div id="host-info-container" class="info-container">
+ <h2 class="hostname">{hostname}</h2>
+ <div class="action-panel">
+ <button id="host-button-shutdown" class="btn-normal-1
stop">
+ <div class="button-icon
action-icon-stop"></div>
+ $_("Shut down")
+ </button>
+ <button id="host-button-restart" class="btn-normal-1
restart">
+ <div class="button-icon
action-icon-restart"></div>
+ $_("Restart")
+ </button>
+ <button class="btn-normal-1 connect"
disabled="disabled">
+ <div class="button-icon
action-icon-connect"></div>
+ $_("Connect")
+ </button>
+ </div>
+ <div class="host-section">
+ <h3 class="section-header"
+ aria-expanded="false"
+ aria-controls="content-sys-info">
+ $_("Basic Information")
+ </h3>
+ <div id="content-sys-info"
class="section-content">
+ <div class="section-row">
+ <div class="section-label">$_("OS
Distro")</div>
+ <div
class="section-value">{os_distro}</div>
+ </div>
+ <div class="section-row">
+ <div class="section-label">$_("OS
Version")</div>
+ <div
class="section-value">{os_version}</div>
+ </div>
+ <div class="section-row">
+ <div class="section-label">$_("OS Code
Name")</div>
+ <div
class="section-value">{os_codename}</div>
+ </div>
+ <div class="section-row">
+ <div
class="section-label">$_("Processor")</div>
+ <div
class="section-value">{cpu_model}</div>
+ </div>
+ <div class="section-row">
+ <div
class="section-label">$_("CPU(s)")</div>
+ <div class="section-value">{cpus}</div>
+ </div>
+ <div class="section-row">
+ <div
class="section-label">$_("Memory")</div>
+ <div class="section-value">{memory}</div>
+ </div>
+ </div>
+ </div>
+ <div class="host-section">
+ <h3 class="section-header"
+ aria-controls="content-sys-statistics">
+ $_("System Statistics")
+ </h3>
+ <div id="content-sys-statistics"
class="section-content">
+ <div class="section-row">
+ <div
class="section-label">$_("CPU")</div>
+ <div class="section-value">
+ <div id="container-chart-cpu"
class="inline-block"></div>
+ </div>
+ </div>
+ <div class="section-row">
+ <div
class="section-label">$_("Memory")</div>
+ <div class="section-value">
+ <div id="container-chart-memory"
class="inline-block"></div>
+ </div>
+ </div>
+ <div class="section-row">
+ <div class="section-label">$_("Disk
I/O")</div>
+ <div class="section-value">
+ <div id="container-chart-disk-io"
class="inline-block"></div>
+ </div>
+ </div>
+ <div class="section-row">
+ <div class="section-label">$_("Network
I/O")</div>
+ <div class="section-value">
+ <div id="container-chart-network-io"
class="inline-block"></div>
+ </div>
+ </div>
+ </div>
+ </div>
+ <div id="software-update-section" class="host-section
hidden">
+ <h3 class="section-header"
+ aria-controls="content-software-update">
+ $_("Software Updates")
+ </h3>
+ <div id="content-software-update"
class="section-content">
+ <div class="section-row">
+ <div class="section-value">
+ <div
id="software-updates-grid-container"></div>
+ <div id="software-updates-progress-container"
class="hidden">
+ <label
for="software-updates-progress-textarea">$_("Update
Progress")</label>
+ <textarea
id="software-updates-progress-textarea" readonly></textarea>
+ </div>
+ </div>
+ </div>
+ </div>
+ </div>
+ <div id="repositories-section" class="host-section
hidden">
+ <h3 class="section-header"
+ aria-controls="content-repositories">
+ $_("Repositories")
+ </h3>
+ <div id="content-repositories"
class="section-content">
+ <div class="section-row">
+ <div class="section-value">
+ <div
id="repositories-grid-container"></div>
+ </div>
+ </div>
+ </div>
+ </div>
+ <div id="debug-report-section" class="host-section
hidden">
+ <h3 class="section-header"
+ aria-controls="content-sys-reports">
+ $_("Debug Reports")
+ </h3>
+ <div id="content-sys-reports"
class="section-content">
+ <div class="section-row">
+ <div class="section-value">
+ <div
id="available-reports-grid-container"></div>
+ </div>
+ </div>
+ </div>
+ </div>
+ </div>
+ </div>
+</script>
+
+<script type="text/javascript">
+ kimchi.host_main();
+</script>
+</body>
+</html>
diff --git a/src/wok/plugins/kimchi/ui/pages/i18n.json.tmpl
b/src/wok/plugins/kimchi/ui/pages/i18n.json.tmpl
new file mode 100644
index 0000000..cd320e0
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/pages/i18n.json.tmpl
@@ -0,0 +1,187 @@
+#*
+ * Project Kimchi
+ *
+ * Copyright IBM, Corp. 2014-2015
+ *
+ * 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.
+ *#
+#unicode UTF-8
+#import gettext
+#from wok.cachebust import href
+#silent t = gettext.translation($lang.domain, $lang.localedir, languages=$lang.lang,
fallback=True)
+#silent _ = t.gettext
+#silent _t = t.gettext
+{
+ "KCHAUTH6001E": "$_("The username or password you entered is
incorrect. Please try again.")",
+ "KCHAUTH6002E": "$_("This field is required.")",
+
+ "KCHAUTH6001M": "$_("Log in")",
+ "KCHAUTH6002M": "$_("Logging in...")",
+
+ "Host": "$_("Host")",
+ "Guests": "$_("Guests")",
+ "Templates": "$_("Templates")",
+ "Storage": "$_("Storage")",
+ "Network": "$_("Network")",
+
+ "KCHAPI6002E": "$_("Failed to get application
configuration")",
+ "KCHAPI6003E": "$_("This is not a valid Linux path")",
+ "KCHAPI6004E": "$_("This is not a valid URL.")",
+ "KCHAPI6005E": "$_("No such data available.")",
+ "KCHAPI6007E": "$_("Can not contact the host system. Verify the
host system is up and that you have network connectivity to it. HTTP request response %1.
")",
+ "KCHAPI6008E": "$_("Unable to read file.")",
+ "KCHAPI6009E": "$_("Error while uploading file.")",
+
+ "KCHAPI6001M": "$_("Delete Confirmation")",
+ "KCHAPI6002M": "$_("OK")",
+ "KCHAPI6003M": "$_("Cancel")",
+ "KCHAPI6004M": "$_("Confirm")",
+ "KCHAPI6005M": "$_("Create")",
+ "KCHAPI6006M": "$_("Warning")",
+ "KCHAPI6007M": "$_("Save")",
+ "KCHAPI6008M": "$_("Creating...")",
+ "KCHAPI6009M": "$_("Cloning...")",
+
+ "KCHGRD6001M": "$_("Loading...")",
+ "KCHGRD6002M": "$_("An error occurred while retrieving system
information.")",
+ "KCHGRD6003M": "$_("Retry")",
+ "KCHGRD6004M": "$_("Detailed message:")",
+
+ "KCHTMPL6001W": "$_("No ISO found")",
+
+ "KCHTMPL6002E": "$_("This is not a valid ISO file.")",
+
+ "KCHTMPL6002M": "$_("This may take a long time. Do you want to
continue?")",
+ "KCHTMPL6003M": "$_("This will permanently delete the template.
Would you like to continue?")",
+
+ "KCHHOST6001E": "$_("Unable to shut down system as there are some
virtual machines running!")",
+
+ "KCHHOST6001M": "$_("Max:")",
+ "KCHHOST6002M": "$_("Utilization")",
+ "KCHHOST6003M": "$_("Available")",
+ "KCHHOST6004M": "$_("Read Rate")",
+ "KCHHOST6005M": "$_("Write Rate")",
+ "KCHHOST6006M": "$_("Received")",
+ "KCHHOST6007M": "$_("Sent")",
+ "KCHHOST6008M": "$_("Shutting down or restarting host will cause
unsaved work lost. Continue to shut down/restarting?")",
+
+
+ "KCHREPO6001M": "$_("Confirm")",
+ "KCHREPO6002M": "$_("Repository will be removed permanently and
can't be recovered. Do you want to continue?")",
+ "KCHREPO6003M": "$_("Repositories")",
+ "KCHREPO6004M": "$_("ID")",
+ "KCHREPO6005M": "$_("Name")",
+ "KCHREPO6006M": "$_("Base URL")",
+ "KCHREPO6007M": "$_("Is Mirror")",
+ "KCHREPO6008M": "$_("URL Args")",
+ "KCHREPO6009M": "$_("Enabled")",
+ "KCHREPO6010M": "$_("GPG Check")",
+ "KCHREPO6011M": "$_("GPG Key")",
+ "KCHREPO6012M": "$_("Add")",
+ "KCHREPO6013M": "$_("Edit")",
+ "KCHREPO6014M": "$_("Remove")",
+ "KCHREPO6016M": "$_("Enable")",
+ "KCHREPO6017M": "$_("Disable")",
+
+
+ "KCHUPD6001M": "$_("Software Updates")",
+ "KCHUPD6002M": "$_("Package Name")",
+ "KCHUPD6003M": "$_("Version")",
+ "KCHUPD6004M": "$_("Architecture")",
+ "KCHUPD6005M": "$_("Repository")",
+ "KCHUPD6006M": "$_("Update All")",
+ "KCHUPD6007M": "$_("Updating...")",
+ "KCHUPD6008M": "$_("Failed to retrieve packages update
information.")",
+ "KCHUPD6009M": "$_("Failed to update package(s).")",
+
+
+ "KCHDR6001M": "$_("Debug report will be removed permanently and
can't be recovered. Do you want to continue?")",
+ "KCHDR6002M": "$_("Debug Reports")",
+ "KCHDR6003M": "$_("Name")",
+ "KCHDR6005M": "$_("Generated Time")",
+ "KCHDR6006M": "$_("Generate")",
+ "KCHDR6007M": "$_("Generating...")",
+ "KCHDR6008M": "$_("Rename")",
+ "KCHDR6009M": "$_("Remove")",
+ "KCHDR6010M": "$_("Download")",
+ "KCHDR6011M": "$_("Report name should contain only letters,
digits, underscore ('_') and/or hyphen ('-').")",
+ "KCHDR6012M": "$_("Pending...")",
+ "KCHDR6013M": "$_("Report name is the same as the original
one.")",
+
+ "KCHVM6001M": "$_("This will delete the virtual machine and its
virtual disks. This operation cannot be undone. Would you like to continue?")",
+ "KCHVM6002M": "$_("Power off Confirmation")",
+ "KCHVM6003M": "$_("This action may produce undesirable results,
"
+ "for example unflushed disk cache in the guest. "
+ "Would you like to continue?")",
+ "KCHVM6004M": "$_("Reset Confirmation")",
+ "KCHVM6005M": "$_("There is a risk of data loss caused by reset
without"
+ " the guest OS shutdown. Would you like to
continue?")",
+ "KCHVM6006M": "$_("Shut Down Confirmation")",
+ "KCHVM6007M": "$_("Note the guest OS may ignore this request.
Would you like to continue?")",
+ "KCHVM6008M": "$_("Virtual Machine delete
Confirmation")",
+ "KCHVM6009M": "$_("This virtual machine is not persistent. Power
Off will delete it. Continue?")",
+ "KCHVM6010M": "$_("When the target guest has SCSI or iSCSI
volumes, they will be cloned on default storage pool. The same will happen when the target
pool does not have enough space to clone the volumes. Do you want to
continue?")",
+
+ "KCHVMCD6001M": "$_("This CDROM will be detached permanently and
you can re-attach it. Continue to detach it?")",
+ "KCHVMCD6002M": "$_("Attach")",
+ "KCHVMCD6003M": "$_("Attaching...")",
+ "KCHVMCD6004M": "$_("Replace")",
+ "KCHVMCD6005M": "$_("Replacing...")",
+ "KCHVMCD6006M": "$_("Successfully attached!")",
+ "KCHVMCD6007M": "$_("Successfully replaced!")",
+ "KCHVMCD6008M": "$_("Successfully detached!")",
+ "KCHVMCD6009M": "$_("This disk will be detached permanently and
you can re-attach it. Continue to detach it?")",
+
+ "KCHVMED6001M": "$_("interface:")",
+ "KCHVMED6002M": "$_("address:")",
+ "KCHVMED6003M": "$_("link_type:")",
+ "KCHVMED6004M": "$_("block:")",
+ "KCHVMED6005M": "$_("drive_type:")",
+ "KCHVMED6006M": "$_("model:")",
+ "KCHVMED6007M": "$_("Affected devices:")",
+
+ "KCHNET6001E": "$_("The VLAN id must be between 1 and
4094.")",
+
+ "KCHNET6001M": "$_("unavailable")",
+ "KCHNET6002M": "$_("This action will interrupt network
connectivity for any virtual machine that depend on this network.")",
+ "KCHNET6003M": "$_("Create a network")",
+ "KCHNET6004M": "$_("This network is not persistent. Instead of
stop, this action will permanently delete it. Would you like to continue?")",
+ "KCHNET6001W": "$_("The bridged VLAN tag may not work well with
NetworkManager enabled. You should consider disabling it.")",
+
+ "KCHPOOL6001M": "$_("This will permanently delete the storage
pool. Would you like to continue?")",
+ "KCHPOOL6002M": "$_("This storage pool is empty.")",
+ "KCHPOOL6003M": "$_("It will format your disk and you will loose
any data in there, are you sure to continue? ")",
+ "KCHPOOL6004M": "$_("SCSI Fibre Channel")",
+ "KCHPOOL6005M": "$_("No SCSI adapters found.")",
+ "KCHPOOL6006M": "$_("Loading iSCSI targets...")",
+ "KCHPOOL6007M": "$_("No iSCSI found. Please input
one.")",
+ "KCHPOOL6008M": "$_("Failed to load iSCSI targets.")",
+
+ "KCHPOOL6001E": "$_("The storage pool name can not be
blank.")",
+ "KCHPOOL6002E": "$_("The storage pool path can not be
blank.")",
+ "KCHPOOL6003E": "$_("NFS server mount path can not be
blank.")",
+ "KCHPOOL6005E": "$_("Invalid NFS mount path.")",
+ "KCHPOOL6006E": "$_("No logical device selected.")",
+ "KCHPOOL6007E": "$_("The iSCSI target can not be
blank.")",
+ "KCHPOOL6008E": "$_("Server name can not be blank.")",
+ "KCHPOOL6009E": "$_("This is not a valid Server Name or IP.
Please, modify it.")",
+ "KCHPOOL6010M": "$_("Looking for available partitions
...")",
+ "KCHPOOL6011M": "$_("No available partitions
found.")",
+ "KCHPOOL6012M": "$_("This storage pool is not persistent. Instead
of deactivate, this action will permanently delete it. Would you like to
continue?")",
+ "KCHPOOL6013M": "$_("Unable to retrieve partitions
information.")",
+ "KCHPOOL6014M": "$_("In progress...")",
+ "KCHPOOL6015M": "$_("Failed!")",
+
+ "KCHVMSTOR0001E": "$_("CDROM path needs to be a valid
local/remote path and cannot be blank.")",
+ "KCHVMSTOR0002E": "$_("Disk pool or volume cannot be
blank.")"
+}
diff --git a/src/wok/plugins/kimchi/ui/pages/network.html.tmpl
b/src/wok/plugins/kimchi/ui/pages/network.html.tmpl
new file mode 100644
index 0000000..915feac
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/pages/network.html.tmpl
@@ -0,0 +1,133 @@
+#*
+ * Project Kimchi
+ *
+ * Copyright IBM, Corp. 2013-2015
+ *
+ * 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.
+ *#
+
+#unicode UTF-8
+#import gettext
+#from wok.cachebust import href
+#silent t = gettext.translation($lang.domain, $lang.localedir, languages=$lang.lang,
fallback=True)
+#silent _ = t.gettext
+#silent _t = t.gettext
+<!DOCTYPE html>
+<html>
+<head>
+<link rel="stylesheet"
href="plugins/kimchi/css/theme-default.min.css">
+<script src="plugins/kimchi/js/kimchi.min.js"></script>
+</head>
+<body>
+<div class="toolbar">
+ <div class="tools" style="display:none">
+ <a id="networkAdd" class="btn-tool"
href="javascript:void(0);"><span class="icon
add">+</span></a>
+ </div>
+</div>
+<div id="network-content" class="network">
+ <div class="grid-control"><input type="text"
class="filter" placeholder="$_("Filter")"></div>
+ <div id="networkGrid" class="list">
+ <div>
+ <span class="column-name">$_("Network
Name")</span><!--
+ --><span
class="column-state">$_("State")</span><!--
+ --><span class="column-type">$_("Network
Type")</span><!--
+ --><span
class="column-interface">$_("Interface")</span><!--
+ --><span class="column-space">$_("Address
Space")</span><!--
+ --><span
style="display:none">$_("Actions")</span>
+ </div>
+ <div id="networkBody"
class="empty-when-logged-off"></div>
+ </div>
+ <div id="networkConfig" class="network-config">
+ <div class="section-container">
+ <div class="section-header">1. $_("Network
Name")</div>
+ <div class="section-content">
+ <input type="text" id="networkName" />
+ <div class="input-hint">
+ <span class="icon-info-circled light-grey c1
help-inline"></span>
+ <span class="input-hint-text
help-inline">$_("Name should not contain '/' and
'\"'.")</span>
+ </div>
+ </div>
+ </div>
+ <div class="section-container">
+ <div class="section-header">2. $_("Network
Type")</div>
+ <div class="section-content">
+ <div class="input-container">
+ <input type="radio" id="networkTypeIso"
name="networkType" value="isolated" />
+ <label for="networkTypeIso">$_("Isolated: no
external network connection")</label>
+ </div>
+ <div class="input-container">
+ <input type="radio" id="networkTypeNat"
name="networkType" value="nat" />
+ <label for="networkTypeNat">$_("NAT: outbound
physical network connection only")</label>
+ </div>
+ <div class="input-container">
+ <div class="bridged-inline">
+ <input type="radio" id="networkTypeBri"
name="networkType" value="bridged" />
+ </div>
+ <div class="bridged-inline">
+ <label for="networkTypeBri">$_("Bridged:
Virtual machines are connected to physical network directly")</label><br
/>
+ <label id="networkBriDisabledLabel"
style="display:none">$_("(No interfaces found)")</label>
+ </div>
+ </div>
+ <div id="bridgeOptions">
+ <div>
+ <div class="bridge-option-column">
+ <label
for="networkInterface">$_("Destination"): </label>
+ </div>
+ <div class="bridge-option-column">
+ <div class="network-type-wrapper-controls">
+ <div id ="networkDestinationID">
+ <input id="networkDestinationInputId"
name="type" type="hidden"/>
+ <span id="networkDestinationLabel"
type="text"></span><span class="arrow"></span>
+ <div>
+ <ul
id="networkInterface"></ul>
+ </div>
+ </div>
+ </div>
+ </div>
+ </div>
+ <div>
+ <input id="enableVlan" type="checkbox"
value="" />
+ <label for="enableVlan"
id="labelEnableVlan">$_("Enable VLAN") </label>
+ </div>
+ <label for="networkVlanID"
id="labelNetworkVlanID">$_("VLAN ID"): </label>
+ <input type="text" id="networkVlanID"
class="network-label"/>
+ </div>
+ </div>
+ </div>
+ </div>
+ </div>
+</div>
+<script id="networkItem" type="text/html">
+ <div id='{name}' class='remove-when-logged-off'>
+ <span class='column-name' title="{name}"
val="{name}">{name}</span><!--
+ --><span class='column-state' val="{state}"><span
class='network-state {state}'></span></span><!--
+ --><span class='column-type'
val="{type}">{type}</span><!--
+ --><span class='column-interface'
val="{interface}">{interface}</span><!--
+ --><span class='column-space'
val="{addrSpace}">{addrSpace}</span><!--
+ --><span class='column-action' style="display:none">
+ <span class="ui-button-secondary dropdown popable
action-button">
+ $_("Actions")
+ <ul class='popover actionsheet right-side menu-container'>
+ <li nwAct="start" class='{startClass}'><a
class='button-big'>$_("Start")</a></li>
+ <li nwAct="stop" class='{stopClass}'><a
{stopDisabled} class='button-big'>$_("Stop")</a></li>
+ <li nwAct="delete" class='{deleteClass}'><a
{deleteDisabled} class='red'>$_("Delete")</a></li>
+ </ul>
+ </span>
+ </span>
+ </div>
+</script>
+<script>
+ kimchi.initNetwork();
+</script>
+</body>
+</html>
diff --git a/src/wok/plugins/kimchi/ui/pages/report-add.html.tmpl
b/src/wok/plugins/kimchi/ui/pages/report-add.html.tmpl
new file mode 100644
index 0000000..25bf0a9
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/pages/report-add.html.tmpl
@@ -0,0 +1,56 @@
+#*
+ * Project Kimchi
+ *
+ * Copyright IBM, Corp. 2013-2015
+ *
+ * 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.
+ *#
+#unicode UTF-8
+#import gettext
+#from wok.cachebust import href
+#silent t = gettext.translation($lang.domain, $lang.localedir, languages=$lang.lang,
fallback=True)
+#silent _ = t.gettext
+#silent _t = t.gettext
+<!DOCTYPE html>
+<div id="report-add-window" class="window">
+ <header>
+ <h1 class="title h1 grey">$_("Generate a New Debug
Report")</h1>
+ </header>
+ <div class="content">
+ <form id="form-report-add">
+ <section class="form-section">
+ <h2>
+ <label for="report-name-textbox">$_("Report
Name")</label>
+ </h2>
+ <div class="field">
+ <input type="text" class="text"
id="report-name-textbox" name="name" />
+ <span class="icon-info-circled light-grey
c1"></span>
+ <span class="info-add-debug-report">
+ $_("The name used to identify the report. If omitted, a name
will be chosen based on current time. Name can contain: letters, digits, underscore
(\"_\") and hyphen (\"-\").")
+ </span>
+ </div>
+ </section>
+ </form>
+ </div>
+ <footer>
+ <div class="btn-group">
+ <button id="button-report-add"
class="btn-normal"><span
class="text">$_("Generate")</span></button>
+ <button id="button-report-cancel" class="btn-normal
close" type="button">
+ <span calss="text">$_("Cancel")</span>
+ </button>
+ </div>
+ </footer>
+</div>
+<script>
+ kimchi.report_add_main();
+</script>
diff --git a/src/wok/plugins/kimchi/ui/pages/report-rename.html.tmpl
b/src/wok/plugins/kimchi/ui/pages/report-rename.html.tmpl
new file mode 100644
index 0000000..90a0a80
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/pages/report-rename.html.tmpl
@@ -0,0 +1,56 @@
+#*
+ * Project Kimchi
+ *
+ * Copyright IBM, Corp. 2014-2015
+ *
+ * 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.
+ *#
+#unicode UTF-8
+#import gettext
+#from wok.cachebust import href
+#silent t = gettext.translation($lang.domain, $lang.localedir, languages=$lang.lang,
fallback=True)
+#silent _ = t.gettext
+#silent _t = t.gettext
+<!DOCTYPE html>
+<div id="report-rename-window" class="window">
+ <header>
+ <h1 class="title h1 grey">$_("Rename a Debug
Report")</h1>
+ </header>
+ <div class="content">
+ <form id="form-report-rename">
+ <section class="form-section">
+ <h2>
+ <label for="report-name-textbox">$_("Report
Name")</label>
+ </h2>
+ <div class="field">
+ <input type="text" class="text"
id="report-name-textbox" name="name" />
+ <span class="icon-info-circled light-grey
c1"></span>
+ <span class="info-debug-report-rename">
+ $_("The name used to identify the report. Name can contain:
letters, digits and hyphen (\"-\").")
+ </span>
+ </div>
+ </section>
+ </form>
+ </div>
+ <footer>
+ <div class="btn-group">
+ <button id="button-report-rename"
class="btn-normal"><span
class="text">$_("Submit")</span></button>
+ <button id-"button-report-rename-cancel" class="btn-normal
close" type="button">
+ <span class="text">$_("Cancel")</span>
+ </button>
+ </div>
+ </footer>
+</div>
+<script>
+ kimchi.report_rename_main();
+</script>
diff --git a/src/wok/plugins/kimchi/ui/pages/repository-add.html.tmpl
b/src/wok/plugins/kimchi/ui/pages/repository-add.html.tmpl
new file mode 100644
index 0000000..950252a
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/pages/repository-add.html.tmpl
@@ -0,0 +1,113 @@
+#*
+ * Project Kimchi
+ *
+ * Copyright IBM, Corp. 2014-2015
+ *
+ * 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.
+ *#
+#unicode UTF-8
+#import gettext
+#from wok.cachebust import href
+#silent t = gettext.translation($lang.domain, $lang.localedir, languages=$lang.lang,
fallback=True)
+#silent _ = t.gettext
+#silent _t = t.gettext
+<div id="repository-add-window" class="window">
+ <form id="form-repository-add">
+ <header class="window-header">
+ <h1 class="title h1 grey">$_("Add a
Repository")</h1>
+ </header>
+ <section>
+ <div class="content">
+ <div class="form-section yum">
+ <h2>$_("Identifier")</h2>
+ <div class="field">
+ <div class="textbox-wrapper">
+ <input type="text" class="text"
name="repo_id" />
+ </div>
+ <div class="icon-info-circled light-grey c1
help-inline"></div>
+ <p class="text-help help-inline">
+ $_("Single word, unique identifier for the
repository.")
+ </p>
+ </div>
+ </div>
+ <section class="form-section yum">
+ <h2>$_("Name")</h2>
+ <div class="field">
+ <div class="textbox-wrapper">
+ <input type="text" class="text"
name="config[repo_name]" />
+ </div>
+ <div class="icon-info-circled light-grey c1
help-inline"></div>
+ <p class="text-help help-inline">
+ $_("Textual name for the repository.")
+ </p>
+ </div>
+ </section>
+ <section class="form-section">
+ <h2>$_("URL")<span class="required"
role="presentation" title='$_("Required
Field")'>*</span></h2>
+ <div class="field">
+ <div class="textbox-wrapper">
+ <input type="text" class="text
required" name="baseurl" />
+ </div>
+ <div class="icon-info-circled light-grey c1
help-inline"></div>
+ <p class="text-help help-inline">
+ $_("URL to the repository. Supported protocols are http,
ftp, and file.")
+ </p>
+ </div>
+ <div class="field yum">
+ <p class="yum">
+ <input type="checkbox" name="isMirror"
value="true" id="isMirror" />
+ <label id="isMirrorLabel"
for="isMirror">$_("Repository is a mirror")</label>
+ </p>
+ </div>
+ </section>
+ <section class="form-section repository-dist deb">
+ <h2>$_("Distribution")</h2>
+ <div class="field">
+ <div class="textbox-wrapper">
+ <input type="text" class="text"
name="config[dist]" />
+ </div>
+ <div class="icon-info-circled light-grey c1
help-inline"></div>
+ <p class="text-help help-inline">
+ $_("Distribution of the DEB repository.")
+ </p>
+ </div>
+ </section>
+ <section class="form-section repository-comps deb">
+ <h2>$_("Components")</h2>
+ <div class="field">
+ <div class="textbox-wrapper">
+ <input type="text" class="text"
name="config[comps]" />
+ </div>
+ <div class="icon-info-circled light-grey c1
help-inline"></div>
+ <p class="text-help help-inline">
+ $_("List of components in DEB repository.")
+ </p>
+ </div>
+ </section>
+ </div>
+ </section>
+ <footer>
+ <div class="btn-group">
+ <button type="submit" id="button-repository-add"
class="btn-normal" disabled="disabled">
+ <span class="text">$_("Add")</span>
+ </button>
+ <button type="button" id="button-repository-close"
class="btn-normal close">
+ <span
class="text">$("Cancel")</span>
+ </button>
+ </div>
+ </footer>
+ </form>
+</div>
+<script>
+ kimchi.repository_add_main();
+</script>
diff --git a/src/wok/plugins/kimchi/ui/pages/repository-edit.html.tmpl
b/src/wok/plugins/kimchi/ui/pages/repository-edit.html.tmpl
new file mode 100644
index 0000000..e5a3cfb
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/pages/repository-edit.html.tmpl
@@ -0,0 +1,117 @@
+#*
+ * Project Kimchi
+ *
+ * Copyright IBM, Corp. 2014-2015
+ *
+ * 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.
+ *#
+#unicode UTF-8
+#import gettext
+#from wok.cachebust import href
+#silent t = gettext.translation($lang.domain, $lang.localedir, languages=$lang.lang,
fallback=True)
+#silent _ = t.gettext
+#silent _t = t.gettext
+
+<div id="repository-edit-window" class="window">
+ <form id="form-repository-edit">
+ <header>
+ <h1 class="title h1 grey">$_("Edit
Repository")</h1>
+ </header>
+ <div class="content">
+ <section id="form-repository-edit">
+ <fieldset class="repository-edit-fieldset">
+ <div class="repository-id yum">
+ <div class="repository-edit-wrapper-label">
+ <label
for="repository-edit-id-textbox">$_("ID")</label>
+ </div>
+ <div class="repository-edit-wrapper-controls">
+ <input id="repository-edit-id-textbox"
name="repo_id" type="text" disabled="disabled"
readonly="readonly"/>
+ </div>
+ </div>
+ <div class="repository-name yum">
+ <div class="repository-edit-wrapper-label">
+ <label
for="repository-edit-name-textbox">$_("Name")</label>
+ </div>
+ <div class="repository-edit-wrapper-controls">
+ <input id="repository-edit-name-textbox"
class="yum" name="config[repo_name]" type="text" />
+ </div>
+ </div>
+ <div class="repository-url">
+ <div class="repository-edit-wrapper-label">
+ <label
for="repository-edit-baseurl-textbox">$_("URL")</label>
+ </div>
+ <div class="repository-edit-wrapper-controls">
+ <input id="repository-edit-baseurl-textbox"
name="baseurl" type="text" />
+ </div>
+ </div>
+ <div class="repository-dist deb">
+ <div class="repository-edit-wrapper-label">
+ <label
for="repository-edit-urlargs-textbox">$_("Distribution")</label>
+ </div>
+ <div class="repository-edit-wrapper-controls">
+ <input id="repository-edit-urlargs-textbox"
class="deb" name="config[dist]" type="text" />
+ </div>
+ </div>
+ <div class="repository-mirrorlist yum">
+ <div class="repository-edit-wrapper-label">
+ <label
for="repository-edit-urlargs-textbox">$_("Mirror List
URL")</label>
+ </div>
+ <div class="repository-edit-wrapper-controls">
+ <input id="repository-edit-urlargs-textbox"
class="yum" name="config[mirrorlist]" type="text" />
+ </div>
+ </div>
+ <div class="repository-comps deb">
+ <div class="repository-edit-wrapper-label">
+ <label
for="repository-edit-urlargs-textbox">$_("Components")</label>
+ </div>
+ <div class="repository-edit-wrapper-controls">
+ <input id="repository-edit-urlargs-textbox"
class="deb" name="config[comps]" type="text" />
+ </div>
+ </div>
+ <div class="repository-gpgkey yum">
+ <div class="repository-edit-wrapper-label">
+ <label
for="repository-edit-gpgkey-textbox">$_("GPG Key")</label>
+ </div>
+ <div class="repository-edit-wrapper-controls">
+ <input id="repository-edit-gpgkey-textbox"
class="yum" name="config[gpgkey]" type="text" />
+ </div>
+ </div>
+ <div class="repository-gpgcheck yum">
+ <div class="repository-edit-wrapper-label">
+ <label>$_("GPG Check")</label>
+ </div>
+ <div class="repository-edit-wrapper-controls">
+ <input id="repository-edit-gpgcheck-radio-true"
class="yum" name="config[gpgcheck]" type="radio"
value="true" />
+ <label
for="repository-edit-gpgcheck-radio-true">$_("Yes")</label>
+ <input id="repository-edit-gpgcheck-radio-false"
class="yum" name="config[gpgcheck]" type="radio"
value="false" />
+ <label
for="repository-edit-gpgcheck-radio-false">$_("No")</label>
+ </div>
+ </div>
+ </fieldset>
+ </section>
+ </div>
+ <footer>
+ <div class="btn-group">
+ <button type="submit"
id="repository-edit-button-save" class="btn-normal">
+ <span class="text">$_("Save")</span>
+ </button>
+ <button type="button"
id="repository-edit-button-cancel" class="close btn-normal">
+ <span
class="text">$_("Cancel")</span>
+ </button>
+ </div>
+ </footer>
+ </form>
+</div>
+<script type="text/javascript">
+ kimchi.repository_edit_main();
+</script>
diff --git a/src/wok/plugins/kimchi/ui/pages/storage.html.tmpl
b/src/wok/plugins/kimchi/ui/pages/storage.html.tmpl
new file mode 100644
index 0000000..7b51a8b
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/pages/storage.html.tmpl
@@ -0,0 +1,143 @@
+#*
+ * Project Kimchi
+ *
+ * Copyright IBM, Corp. 2013-2015
+ *
+ * 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.
+ *#
+
+#unicode UTF-8
+#import gettext
+#silent t = gettext.translation($lang.domain, $lang.localedir, languages=$lang.lang,
fallback=True)
+#silent _ = t.gettext
+#silent _t = t.gettext
+<!DOCTYPE html>
+<html>
+<head>
+<link rel="stylesheet"
href="plugins/kimchi/css/theme-default.min.css">
+<script src="plugins/kimchi/js/kimchi.min.js"></script>
+</head>
+<body>
+<div class="toolbar">
+ <div class="tools" style="display:none">
+ <a id="storage-pool-add" class="btn-tool"
href="javascript:void(0);"><span class="icon
add">+</span></a>
+ </div>
+</div>
+<div class='storage'>
+<div class="grid-control"><input type="text"
class="filter" placeholder="$_("Filter")"></div>
+<div id='storageGrid'>
+ <div>
+ <span class="storage-name">$_("Name")</span>
+ <span class="storage-state" >$_("State")</span>
+ <span class="storage-type">$_("Type")</span>
+ <span
class="storage-capacity">$_("Capacity")</span>
+ <span
class="storage-allocate">$_("Allocated")</span>
+ <span
class="storage-location">$_("Location")</span>
+ </div>
+ <div id="storagepoolsList" class="list-storage
empty-when-logged-off"></div>
+</div>
+</div>
+<div id="logicalPoolExtend" title="$_("Device
path")">
+ <p id="loading-info" class="text-help">
+ <img src = "plugins/kimchi/images/theme-default/loading.gif" />
+ $_("Looking for available partitions ...")
+ </p>
+ <div class="host-partition">
+ </div>
+</div>
+<script id="storageTmpl" type="html/text">
+ <div id="{name}" class="storage-li in"
data-name="{name}" data-stat="{state}">
+ <span class="storage-name" val="{name}{usage}%">
+ <span title="{name}">{name}</span>
+ <span class="usage">{usage}%</span>
+ </span>
+ <span class="storage-state">
+ <div class="status-dot toolable active"
data-state="{state}">
+ <label
class="tooltip">$_("active")</label>
+ </div>
+ <div class="status-dot toolable inactive"
data-state="{state}">
+ <label
class="tooltip">$_("inactive")</label>
+ </div>
+ </span>
+ <span class="storage-type" val="{type}">
+ <div>{type}</div>
+ </span>
+ <span class="storage-capacity" val="{capacity}">
+ <div data-type="{type}">{capacity}</div>
+ </span>
+ <span class="storage-allocate" val="{allocated}">
+ <div data-type="{type}">{allocated}</div>
+ </span>
+ <span class="storage-location" val="{path}">
+ <div>{path}</div>
+ </span>
+ <span class="bottom storage-button"
style="display:none">
+ <div class="btn dropdown popable storage-action"
data-state="{state}" data-type="{type}"
data-name="{name}">
+ <span
class="text">$_("Actions")</span><span
class="arrow"></span>
+ <div class="popover actionsheet right-side"
style="width: 250px">
+ <button class="button-big pool-deactivate"
data-stat="{state}" data-name="{name}"
data-persistent="{persistent}"><span
class="text">$_("Deactivate")</span></button>
+ <button class="button-big pool-activate"
data-stat="{state}" data-name="{name}"><span
class="text">$_("Activate")</span></button>
+ <button class="button-big pool-add-volume"
data-stat="{state}" data-name="{name}"
data-type="{type}"><span class="text">$_("Add
Volume")</span></button>
+ <button class="button-big pool-extend {enableExt}"
data-stat="{state}" data-name="{name}"><span
class="text">$_("Extend")</span></button>
+ <button class="button-big red pool-delete"
data-stat="{state}" data-name="{name}"><span
class="text">$_("Undefine")</span></button>
+ </div>
+ </div>
+ </span>
+ <span class="handle">
+ <div class="arrow-down"></div>
+ </span>
+ <div class="volumes">
+ <div id="volume{name}" class="volumeslist"
data-name="{name}" ></div>
+ <div class="clear"></div>
+ </div>
+ </div>
+</script>
+<script id="volumeTmpl" type="html/text">
+ <div class="volume-box white-box"
data-volume-name="{name}">
+ <div class="storage-icon volume-default icon-{format} ">
+ </div>
+ <div class="volume-title">
+ <div class="volume-name"
title="{name}">{name}</div>
+ <div class="volume-progress hidden">
+ <div class="progress-bar-outer">
+ <div class="progress-bar-inner"></div>
+ </div>
+ <div class="progress-label">
+ <span class="progress-status"></span>
+ <span class="progress-transferred"></span>
+ </div>
+ </div>
+ </div>
+ <div class="volume-setting">
+ </div>
+ <div class="volume-type-position">
+ <div title="{type}"
class="volume-text">$_("Type"): {type}</div>
+ <div title="{format}"
class="volume-text">$_("Format"): {format}</div>
+ </div>
+ <div class="volume-quota-position">
+ <div title="{capacity}"
class="volume-textquota">$_("Capacity"): {capacity}</div>
+ <div
title="{allocation}"class="volume-textquota">$_("Allocation"):
{allocation}</div>
+ </div>
+ </div>
+</script>
+<script id="logicalPoolExtendTmpl" type="html/text">
+ <div>
+ <input type="checkbox" value="{path}"
name="devices">
+ <label for="{name}">{path}</label>
+ </div>
+</script>
+<script>
+ kimchi.storage_main();
+</script>
+</body>
+</html>
diff --git a/src/wok/plugins/kimchi/ui/pages/storagepool-add-volume.html.tmpl
b/src/wok/plugins/kimchi/ui/pages/storagepool-add-volume.html.tmpl
new file mode 100644
index 0000000..ab10939
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/pages/storagepool-add-volume.html.tmpl
@@ -0,0 +1,79 @@
+#*
+ * Project Kimchi
+ *
+ * Copyright IBM, Corp. 2014-2015
+ *
+ * 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.
+ *#
+#unicode UTF-8
+#import gettext
+#from wok.cachebust import href
+#silent t = gettext.translation($lang.domain, $lang.localedir, languages=$lang.lang,
fallback=True)
+#silent _ = t.gettext
+#silent _t = t.gettext
+<div id="sp-add-volume-window" class="window">
+ <form id="form-sp-add-volume">
+ <header class="window-header">
+ <h1 class="title h1 grey">$_("Add a Volume to Storage
Pool")</h1>
+ </header>
+ <section>
+ <div class="content">
+ <div class="form-section">
+ <h2>
+ <input type="radio"
id="volume-type-download" class="volume-type"
name="volumeType" value="download" checked="checked" />
+ <label for="volume-type-download">
+ $_("Fetch from remote URL")
+ </label>
+ </h2>
+ <div class="field">
+ <div class="textbox-wrapper">
+ <input type="text"
id="volume-remote-url" class="text volume-input download"
name="volumeRemoteURL" />
+ </div><br>
+ <div class="icon-info-circled light-grey c1
help-inline"></div>
+ <p class="text-help help-inline">
+ $_("Enter the remote URL here.")
+ </p>
+ </div>
+ </div>
+ <div class="form-section">
+ <h2>
+ <input type="radio"
id="volume-type-upload" class="volume-type"
name="volumeType" value="upload"/>
+ <label for="volume-type-upload">
+ $_("Upload a file")
+ </label>
+ </h2>
+ <div class="field">
+ <div class="icon-info-circled light-grey c1
help-inline"></div>
+ <p class="text-help help-inline">
+ $_("Choose the file you want to upload.")
+ </p>
+ <div class="textbox-wrapper">
+ <input type="file" class="volume-input
upload" id="volume-input-file" name="volumeLocalFile"
disabled="disabled" />
+ </div>
+ </div>
+ </div>
+ </div>
+ </section>
+ <footer>
+ <div class="btn-group">
+ <button type="submit" id="sp-add-volume-button"
class="btn-normal" disabled="disabled">
+ <span class="text">$_("Add")</span>
+ </button>
+ <button type="button" class="btn-normal
close"><span
class="text">$_("Cancel")</span></button>
+ </div>
+ </footer>
+ </form>
+</div>
+<script type="text/javascript">
+ kimchi.sp_add_volume_main();
+</script>
diff --git a/src/wok/plugins/kimchi/ui/pages/storagepool-add.html.tmpl
b/src/wok/plugins/kimchi/ui/pages/storagepool-add.html.tmpl
new file mode 100644
index 0000000..a697af5
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/pages/storagepool-add.html.tmpl
@@ -0,0 +1,186 @@
+#*
+ * Project Kimchi
+ *
+ * Copyright IBM, Corp. 2013-2015
+ *
+ * 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.
+ *#
+#unicode UTF-8
+#import gettext
+#silent t = gettext.translation($lang.domain, $lang.localedir, languages=$lang.lang,
fallback=True)
+#silent _ = t.gettext
+#silent _t = t.gettext
+<!DOCTYPE html>
+<html>
+<body>
+ <div class="window storage-window storage-admin">
+ <header>
+ <h1 class="title h1 grey">$_("Define a New Storage
Pool")</h1>
+ </header>
+ <div class="content">
+ <form id="form-pool-add">
+ <section class="form-section">
+ <h2>1. $_("Storage Pool Name")</h2>
+ <div class="field">
+ <input id="poolId" required="required"
type="text" class="text storage-base-input-width"
name="name"><br>
+ <div class="icon-info-circled light-grey c1
help-inline"></div>
+ <p class="text-help help-inline">
+ $_("The name used to identify the storage pools, and it
should not be empty.")
+ </p>
+ </div>
+ </section>
+ <section class="form-section">
+ <h2>2. $_("Storage Pool Type")</h2>
+ <div class="storage-type-wrapper-controls">
+ <div id="poolTypeId">
+ <input id="poolTypeInputId"
name="type" type="hidden" value="dir"/>
+ <span id="pool-type-label"
class="text"></span><span class="arrow"></span>
+ <div>
+ <ul id="storagePool-list">
+ </ul>
+ </div>
+ </div>
+ </div>
+ </section>
+ <div class="path-section">
+ <section class="form-section">
+ <h2>3. $_("Storage Path")</h2>
+ <div class="field">
+ <input id="pathId" type="text"
class="text storage-base-input-width"><br>
+ <div class="icon-info-circled light-grey c1
help-inline"></div>
+ <p class="text-help help-inline">
+ $_("The path of the Storage Pool. Each Storage Pool
must have a unique path.")</p><br>
+ <div class="icon-info-circled light-grey c1
help-inline"></div>
+ <p class="text-help help-inline">
+ $_("Kimchi will try to create the directory when it
does not already exist in your system.")</p>
+ </div>
+ <div class="clear"></div>
+ </section>
+ </div>
+ <div class="nfs-section tmpl-html">
+ <section class="form-section">
+ <h2>3. $_("NFS Server IP")</h2>
+ <div class="field storage-field">
+ <div id="serverComboboxId"
class="storage-add-input-width">
+ <input id="nfsserverId"/>
+ <div>
+ <ul id="nfs-server-used">
+ </ul>
+ </div>
+ </div><br>
+ <div class="icon-info-circled light-grey c1
help-inline"></div>
+ <p class="text-help help-inline">
+ $_("NFS server IP or hostname. It can be input or
chosen from history.")</p>
+ </div>
+ </section>
+ <section class="form-section">
+ <h2>4. $_("NFS Path")</h2>
+ <div class="field storage-field">
+ <div id="targetFilterSelectId"
class="storage-add-input-width">
+ <input id="nfspathId"
class="input" disabled/>
+ <div>
+ <ul id="nfs-server-target">
+ </ul>
+ </div>
+ </div><br>
+ <div class="icon-info-circled light-grey c1
help-inline"></div>
+ <p class="text-help help-inline">$_("The
NFS exported path on NFS server.")</p>
+ </div>
+ </section>
+ </div>
+ <div class="logical-section tmpl-html">
+ <section class="form-section storageType">
+ <h2>3. $_("Device path")</h2>
+ <div class="host-partition">
+ <div class="icon-info-circled light-grey c1
help-inline"></div>
+ <p class="text-help help-inline">
+ $_("Looking for available partitions ...")
+ <img src =
"plugins/kimchi/images/theme-default/loading.gif" />
+ </p>
+ </div>
+ </section>
+ </div>
+ <div class="iscsi-section tmpl-html">
+ <section class="form-section">
+ <h2>3. $_("iSCSI Server")</h2>
+ <div class="field">
+ <span class="filter-select popable"
id="iSCSIServer">
+ <input id="iscsiserverId"
type="text" placeholder="$_("Server")">
+ <div class="popover"><ul
class="option select-list"></ul></div>
+ </span>
+ <input id="iscsiportId"
placeholder="$_("Port")" type="text" class="text
storage-port-width" maxlength="4"><br>
+ <div class="icon-info-circled light-grey c1
help-inline"></div>
+ <p class="text-help help-inline">
+ $_("iSCSI server IP or hostname. It should not be
empty.")</p>
+ </div>
+ </section>
+ <section class="form-section">
+ <h2>4. $_("Target")</h2>
+ <div class="field">
+ <span class="filter-select popable"
id="iSCSITarget">
+ <input id="iscsiTargetId"
type="text">
+ <div class="popover"><ul
class="option select-list"></ul></div>
+ </span><br>
+ <div class="icon-info-circled light-grey c1
help-inline"></div>
+ <p class="text-help help-inline">$_("The
iSCSI target on iSCSI server")</p>
+ </div>
+ </section>
+ <section class="form-section">
+ <div class="field">
+ <input type="checkbox" id="authId"
name="authname">
+ <label for="authId">$_("Add iSCSI
Authentication")</label>
+ </div>
+ </section>
+ <section class="authenticationfield form-section
tmpl-html">
+ <h2>5. $_("iSCSI Authentication")</h2>
+ <div class="field">
+ <input id="usernameId"
placeholder="$_("User Name")" type="text" class="text
storage-auth-width">
+ <input id="passwordId"
placeholder="$_("Password")" type="password"
class="text storage-auth-width">
+ </div>
+ </section>
+ </div>
+ <div class="scsi-section tmpl-html">
+ <section class="form-section">
+ <h2>3. $_("SCSI Adapter")</h2>
+ <div class="storage-type-wrapper-controls">
+ <div id="scsiAdapter">
+ <input type="hidden"/>
+ <span class="text"></span><span
class="arrow"></span>
+ <div><ul></ul></div>
+ </div>
+ </div>
+ </section>
+ </div>
+ </form>
+ </div>
+ <footer>
+ <div class="btn-group">
+ <button id="pool-doAdd" class="btn-normal">
+ <span
class="text">$_("Create")</span>
+ </button>
+ <button class="btn-normal" id="pool-loading"
style="display: none"><span class="text">$_("Please,
wait...")</span></button>
+ <button class="btn-normal close"
type="button"><span
class="text">$_("Cancel")</span></button>
+ </div>
+ </footer>
+ </div>
+ <script>
+ kimchi.storagepool_add_main();
+ </script>
+ <script id="partitionTmpl" type="html/text">
+ <div>
+ <input type="checkbox" id="{name}"
value="{path}" name="devices">
+ <label for="{name}">{path}</label>
+ </div>
+ </script>
+</body>
+</html>
diff --git a/src/wok/plugins/kimchi/ui/pages/template-add.html.tmpl
b/src/wok/plugins/kimchi/ui/pages/template-add.html.tmpl
new file mode 100644
index 0000000..b44db79
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/pages/template-add.html.tmpl
@@ -0,0 +1,233 @@
+#*
+ * Project Kimchi
+ *
+ * Copyright IBM, Corp. 2013-2015
+ *
+ * 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.
+ *#
+#unicode UTF-8
+#import gettext
+#from wok.cachebust import href
+#silent t = gettext.translation($lang.domain, $lang.localedir, languages=$lang.lang,
fallback=True)
+#silent _ = t.gettext
+#silent _t = t.gettext
+<!DOCTYPE html>
+<html>
+<body>
+<div class="window" style="width: 992px;height: 660px;">
+ <header>
+ <h1 class="title h1 grey">$_("Add
Template")</h1>
+ </header>
+ <div class="content" style="margin-bottom: 0">
+ <div class="page-list">
+ <!-- 1 -->
+ <div class="page" id="iso-type-box"
style="left:0">
+ <h2 class="step-title">$_("Where is the source media
for this template? ")</h2>
+ <ul class="step-choose">
+ <li>
+ <a id="iso-local"
class="local">$_("Local ISO Image")</a>
+ </li>
+ <li>
+ <a id="vm-image-local"
class="local">$_("Local Image File")</a>
+ </li>
+ <li>
+ <a id="iso-remote"
class="remote">$_("Remote ISO Image")</a>
+ </li>
+ </ul>
+ </div>
+
+ <!-- 1-1 -->
+ <div class="page" id="iso-local-box">
+ <header>
+ <a class="back"
id="iso-local-box-back"></a>
+ <h2 class="step-title">$_("Local ISO
Image")</h2>
+ </header>
+
+ <button class="btn-normal" id="iso-search"
style="display: none"><span class="text">$_("Search
ISOs")</span></button>
+ <button class="btn-normal" id="iso-search-loading"
style="display: none"><span class="text">$_("Please,
wait...")</span></button>
+ <!-- 1-1-1 -->
+ <div id="local-iso-field" class="iso-field"
style="display: none;">
+ <h3 class="step-subtitle">
+ $_("The following ISOs are available:")
+ </h3>
+ <div class="toolbar">
+ <label class="check-all">
+ <input type="checkbox"
id="select-all-local-iso">$_("All")
+ </label>
+ </div>
+ <div>
+ <form id="form-local-iso">
+ <ul id="list-local-iso"
class="list-iso">
+ </ul>
+ </form>
+ <script id="tmpl-list-local-iso"
type="text/html">
+ <li>
+ <label>
+ <input type="checkbox"
name="iso" value="{isoId}">
+ <div class="box box-iso">
+ <div class="iso-icon
{os_distro}">
+ </div>
+ <h3 class="iso-title"
title="{name}">
+ {name}
+ </h3>
+ <div class="iso-info">
+ <div class="iso-info-col">
+ <div class="iso-info-item"
title="{os_distro}">
+ $_("OS: "){os_distro}
+ </div>
+ <div class="iso-info-item"
title="{os_version}">
+ $_("Version:
"){os_version}
+ </div>
+ </div>
+ <div class="iso-info-col">
+ <div class="iso-info-item"
title="{capacity}">
+ $_("Size: "){capacity}
+ </div>
+ </div>
+ </div>
+ </div>
+ </label>
+ </li>
+ </script>
+ </div>
+ <div class="button-field">
+ <button class="btn-normal" id="iso-more"
style="display: none"><span class="text">$_("Search more
ISOs")</span></button>
+ <button class="btn-normal"
id="iso-more-loading" style="display: none"><span
class="text">$_("Please, wait...")</span></button>
+ <button class="btn-normal"
id="btn-template-local-iso-create" disabled="disabled"><span
class="text">$_("Create Templates from Selected
ISO")</span></button>
+ </div>
+ </div>
+
+ <!-- 1-1-2 -->
+ <div id="iso-file-field">
+ <h3 class="step-subtitle">
+ <label>
+ <input type="checkbox"
id="iso-file-check">
+ $_("I want to use a specific ISO file")
+ </label>
+ </h3>
+ <div id="iso-file-box"
class="custom-iso-field">
+ <div class="input-wrapper"><input
type="text" class="text" id="iso-file"
name="iso-file"></div>
+ <button class="btn-normal"
id="btn-template-file-create" disabled="disabled"><span
class="text">$_("Create")</span></button>
+ </div>
+ </div>
+
+ </div>
+
+ <div class="page" id="vm-image-local-box">
+ <header>
+ <a class="back"
id="vm-image-local-box-back"></a>
+ <h2 class="step-title">$_("Local Image
File")</h2>
+ </header>
+ <div class="body">
+ <label for="vm-image-local-text">File
Path:</label>
+ <input type="text" id="vm-image-local-text"
/>
+ <button
class="ui-button-primary">$_("Create")</button>
+ </div>
+ </div>
+
+ <!-- 1-2 -->
+ <div class="page" id="iso-remote-box">
+ <header>
+ <a class="back"
id="iso-remote-box-back"></a>
+ <h2 class="step-title">$_("Remote ISO
Image")</h2>
+ </header>
+
+ <!-- 1-2-0 -->
+ <div id="load-remote-iso">
+ <h3 class="step-subtitle">
+ <label>
+ <img src =
"plugins/kimchi/images/theme-default/loading.gif" />
+ $_("Loading default remote ISOs ...")
+ </label>
+ </h3>
+ </div>
+
+ <!-- 1-2-1 -->
+ <div id="remote-iso-field" class="iso-field"
style="display: none;">
+ <h3 class="step-subtitle">
+ $_("The following ISOs are available:")
+ </h3>
+ <div class="toolbar">
+ <label class="check-all">
+ <input type="checkbox"
id="select-all-remote-iso">$_("All")
+ </label>
+ </div>
+ <div>
+ <form id="form-remote-iso">
+ <ul id="list-remote-iso"
class="list-iso">
+ </ul>
+ </form>
+ <script id="tmpl-list-remote-iso"
type="text/html">
+ <li>
+ <label>
+ <input type="checkbox"
name="iso" value="{isoId}">
+ <div class="box box-iso">
+ <div class="iso-icon
{os_distro}">
+ </div>
+ <h3 class="iso-title"
title="{name}">
+ {name}
+ </h3>
+ <div class="iso-info">
+ <div class="iso-info-col">
+ <div class="iso-info-item"
title="{os_distro}">
+ $_("OS: "){os_distro}
+ </div>
+ <div class="iso-info-item"
title="{os_version}">
+ $_("Version:
"){os_version}
+ </div>
+
+ </div>
+ <div class="iso-info-col">
+ <div class="iso-info-item"
title="{os_arch}">
+ $_("Arch: "){os_arch}
+ </div>
+ </div>
+ </div>
+ </div>
+ </label>
+ </li>
+ </script>
+ </div>
+ <div class="button-field">
+ <button class="btn-normal"
id="btn-template-remote-iso-create" disabled="disabled"><span
class="text">$_("Create Templates from Selected
ISO")</span></button>
+ </div>
+ </div>
+
+ <!-- 1-2-2 -->
+ <div id="iso-url-field" style="display:
none;">
+ <h3 class="step-subtitle">
+ <label>
+ <input type="checkbox"
id="iso-url-check">
+ $_("I want to use a custom URL")
+ </label>
+ </h3>
+ <div id="iso-url-box"
class="custom-iso-field">
+ <div class="input-wrapper"><input
type="text" class="text" id="iso-url"
name="iso-url"></div>
+ <button class="btn-normal"
id="btn-template-url-create" disabled="disabled"><span
class="text">$_("Create")</span></button>
+ </div>
+ </div>
+
+ </div>
+ </div>
+ </div>
+ <footer>
+ <div class="button-group">
+ <button class="btn-normal close"
type="button"><span
type="text">$_("Cancel")</span></button>
+ </div>
+ </footer>
+</div>
+<script>
+kimchi.template_add_main();
+</script>
+</body>
+</html>
diff --git a/src/wok/plugins/kimchi/ui/pages/template-edit.html.tmpl
b/src/wok/plugins/kimchi/ui/pages/template-edit.html.tmpl
new file mode 100644
index 0000000..0588294
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/pages/template-edit.html.tmpl
@@ -0,0 +1,193 @@
+#*
+ * Project Kimchi
+ *
+ * Copyright IBM, Corp. 2013-2015
+ *
+ * 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.
+ *#
+#unicode UTF-8
+#import gettext
+#from wok.cachebust import href
+#silent t = gettext.translation($lang.domain, $lang.localedir, languages=$lang.lang,
fallback=True)
+#silent _ = t.gettext
+#silent _t = t.gettext
+
+<div id="template-edit-window" class="window">
+ <header>
+ <h1 class="title h1 grey">$_("Edit
Template")</h1>
+ </header>
+ <div class="content">
+ <div id="edit-template-tabs">
+ <input type="hidden" id="template-name"
name="templateName" />
+ <ul>
+ <li>
+ <a
href="#form-template-general">$_("General")</a>
+ </li>
+ <li>
+ <a
href="#form-template-storage">$_("Storage")</a>
+ </li>
+ <li>
+ <a
href="#form-template-interface">$_("Interface")</a>
+ </li>
+ <li>
+ <a
href="#form-template-processor">$_("Processor")</a>
+ </li>
+ </ul>
+ <form id="form-template-general">
+ <div class="form-template-inline-wrapper">
+ <div class="template-edit-wrapper-label">
+ <label
for="template-edit-id-textbox">$_("Name")</label>
+ </div>
+ <div class="template-edit-wrapper-label">
+ <label
for="template-edit-vendor-textbox">$_("Vendor")</label>
+ </div>
+ <div class="template-edit-wrapper-label">
+ <label
for="template-edit-version-textbox">$_("Version")</label>
+ </div>
+ <div class="template-edit-wrapper-label">
+ <label
for="template-edit-memory-textbox">$_("Memory (MB)")</label>
+ </div>
+ <div class="template-edit-wrapper-label
templ-edit-cdrom">
+ <label
for="template-edit-cdrom-textbox">$_("CDROM")</label>
+ </div>
+ <div class="template-edit-wrapper-label templ-edit-vm-image
hide">
+ <label
for="template-edit-vmimage-textbox">$_("Image File")</label>
+ </div>
+ <div class="template-edit-wrapper-label">
+ <label>$_("Graphics")</label>
+ </div>
+ </div>
+ <div class="form-template-inline-wrapper">
+ <div class="template-edit-wrapper-controls">
+ <input id="template-edit-id-textbox"
name="name" type="text" />
+ </div>
+ <div class="template-edit-wrapper-controls">
+ <input id="template-edit-vendor-textbox"
name="os_distro" type="text" disabled="disabled" />
+ </div>
+ <div class="template-edit-wrapper-controls">
+ <input id="template-edit-version-textbox"
name="os_version" type="text" disabled="disabled" />
+ </div>
+ <div class="template-edit-wrapper-controls">
+ <input id="template-edit-memory-textbox"
name="memory" type="text" />
+ </div>
+ <div class="template-edit-wrapper-controls
templ-edit-cdrom">
+ <input id="template-edit-cdrom-textbox"
name="cdrom" type="text" disabled="disabled" />
+ </div>
+ <div class="template-edit-wrapper-controls
templ-edit-vm-image hide">
+ <input id="template-edit-vmimage-textbox"
name="vm-image" type="text" disabled="disabled" />
+ </div>
+ <div class="template-edit-wrapper-controls">
+ <div class="btn dropdown popable">
+ <input id="template-edit-graphics"
name="graphics" type="hidden" />
+ <span class="text"
id="template-edit-graphics-label"></span><span
class="arrow"></span>
+ <div class="popover" style="width:
100%">
+ <ul class="select-list"
id="template-edit-graphics-list" data-target="template-edit-graphics"
data-label="template-edit-graphics-label">
+ </ul>
+ </div>
+ </div>
+ </div>
+ </div>
+ </form>
+ <form id="form-template-storage">
+ <div class="template-tab-header">
+ <span class="template-storage-cell">$_("Storage
Pool")</span>
+ <span
class="template-storage-cell">$_("Type")</span>
+ <span
class="template-storage-cell">$_("Disk(GB)")</span>
+ <span class="template-storage-cell">$_("Disk
Format")</span>
+ <button type="button"
id="template-edit-storage-add-button"
class="action-area"></button>
+ </div>
+ <div class="template-tab-body">
+ </div>
+ </form>
+ <form id="form-template-interface">
+ <div class="template-tab-header">
+ <span
class="template-interface-cell">$_("Network")</span>
+ <span
class="template-interface-cell">$_("Type")</span>
+ <button type="button"
id="template-edit-interface-add-button"
class="action-area"></button>
+ </div>
+ <div class="template-tab-body"></div>
+ </form>
+ <form id="form-template-processor">
+ <div>
+ <label for="cpus">$_("CPU
Number"):</label>
+ <input type="text" value="1"
id="cpus" />
+ </div>
+ <div class="manual">
+ <input type="checkbox" id="cpus-check" />
+ <label for="cpus-check">$_("Manually set CPU
topology")</label>
+ </div>
+ <div class="topology hide">
+ <div>
+ <label
for="cores">$_("Cores"):</label>
+ <input type="text" value="1"
id="cores" />
+ </div>
+ <div>
+ <label
for="threads">$_("Threads"):</label>
+ <select id="threads"></select>
+ </div>
+ </div>
+ </form>
+ </div>
+ </div>
+ <footer>
+ <div class="btn-group">
+ <a id="tmpl-edit-button-save" class="btn-normal"
href="javascript:void(0);"><span
class="text">$_("Save")</span></a>
+ <button class="btn-normal close"
type="button"><span
class="text">$_("Cancel")</span></button>
+ </div>
+ </footer>
+</div>
+<script>
+ kimchi.template_edit_main();
+</script>
+<script id="template-storage-pool-tmpl" type="text/html">
+ <div class='item'>
+ <span class="template-storage-cell">
+ <input class="template-storage-name" value={storageName}
type="text" style="display:none" />
+ <select id="selectStorageName"></select>
+ </span>
+ <span class="template-storage-cell">
+ <input class="template-storage-type" value={storageType}
readonly=true type="text" />
+ </span>
+ <span class="template-storage-cell">
+ <input class="template-storage-disk" value={storageDisk}
type="text" />
+ </span>
+ <span class="template-storage-cell">
+ <input class="template-storage-disk-format"
value={storageDiskFormat} type="text" style="display:none" />
+ <select id="diskFormat">
+ <option value="qcow2">qcow2</option>
+ <option value="raw">raw</option>
+ <option value="bochs">bochs</option>
+ <option value="cloop">cloop</option>
+ <option value="cow">cow</option>
+ <option value="dmg">dmg</option>
+ <option value="qcow">qcow</option>
+ <option value="qed">qed</option>
+ <option value="vmdk">vmdk</option>
+ <option value="vpc">vpc</option>
+ </select>
+ </span>
+ </div>
+</script>
+<script id="template-interface-tmpl" type="text/html">
+ <div class="item" id={networkID}>
+ <span class="template-interface-cell">
+ <select></select>
+ </span>
+ <span class="template-interface-cell">
+ <input value={type} readonly=true type="text" />
+ </span>
+ <span class="action-area">
+ <button class="delete"></button>
+ </span>
+ </div>
+</script>
diff --git a/src/wok/plugins/kimchi/ui/pages/templates.html.tmpl
b/src/wok/plugins/kimchi/ui/pages/templates.html.tmpl
new file mode 100644
index 0000000..af1cf3f
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/pages/templates.html.tmpl
@@ -0,0 +1,77 @@
+#*
+ * Project Kimchi
+ *
+ * Copyright IBM, Corp. 2013-2014
+ *
+ * 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.
+ *#
+#unicode UTF-8
+#import gettext
+#from wok.cachebust import href
+#silent t = gettext.translation($lang.domain, $lang.localedir, languages=$lang.lang,
fallback=True)
+#silent _ = t.gettext
+#silent _t = t.gettext
+<!DOCTYPE html>
+<html>
+<head>
+<link rel="stylesheet"
href="plugins/kimchi/css/theme-default.min.css">
+<script src="plugins/kimchi/js/kimchi.min.js"></script>
+</head>
+<body>
+<div class="toolbar">
+ <div class="tools" style="display:none">
+ <a id="template-add" class="btn-tool"
href="javascript:void(0);"><span class="icon
add">+</span></a>
+ </div>
+</div>
+<div>
+ <div id="noTemplates" class="list-no-result"
style="display: none;">
+ $_("No templates found.")
+ </div>
+
+ <ul id="templateList"
class="empty-when-logged-off"></ul>
+
+ <script id="templateTmpl" type="html/text">
+
+ <div class="template-box white-box template-border">
+ <div class="btn dropdown popable" style="width:
70px">
+ <span
class="text">$_("Actions")</span><span
class="arrow"></span>
+ <div class="popover actionsheet right-side"
style="width: 250px">
+ <a class="button-big template-edit"
data-template='{name}'>$_("Edit")</a>
+ <a class="button-big template-clone"
data-template='{name}'>$_("Clone")</a>
+ <a class="button-big red template-delete"
data-template='{name}'>$_("Delete")</a>
+ </div>
+ </div>
+
+ <div class="template-icon template-icon-position">
+ <img alt="" src="{icon}">
+ <img alt="" src="{location}"
class="template-type-icon-position">
+ </div>
+ <div class="template-general template-title
template-title-position">
+ <h2 class="title"
title="{name}">{name}</h2>
+ </div>
+ <div class="template-os-position">
+ <div class="template-text">$_("OS"):
{os_distro}</div>
+ <div class="template-text">$_("Version"):
{os_version}</div>
+ </div>
+ <div class="template-cpu-position">
+ <div class="template-text">$_("CPUs"):
{cpus}</div>
+ <div class="template-text">$_("Memory"):
{memory}M</div>
+ </div>
+ </div>
+ </script>
+</div>
+<script>
+ kimchi.template_main();
+</script>
+</body>
+</html>
diff --git a/src/wok/plugins/kimchi/ui/robots.txt b/src/wok/plugins/kimchi/ui/robots.txt
new file mode 100644
index 0000000..1f53798
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/robots.txt
@@ -0,0 +1,2 @@
+User-agent: *
+Disallow: /
diff --git a/src/wok/plugins/kimchi/ui/spice-html5/Makefile.am
b/src/wok/plugins/kimchi/ui/spice-html5/Makefile.am
new file mode 100644
index 0000000..c43f1ef
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/spice-html5/Makefile.am
@@ -0,0 +1,25 @@
+#
+# Kimchi
+#
+# Copyright IBM, Corp. 2014
+#
+# 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.
+
+SUBDIRS = pages
+
+if WITH_SPICE
+SUBDIRS += css thirdparty
+
+spicehtml5dir = $(datadir)/wok/plugins/kimchi/ui/spice-html5
+dist_spicehtml5_DATA = $(wildcard *.js) $(NULL)
+endif
diff --git a/src/wok/plugins/kimchi/ui/spice-html5/atKeynames.js
b/src/wok/plugins/kimchi/ui/spice-html5/atKeynames.js
new file mode 100644
index 0000000..e1e27fd
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/spice-html5/atKeynames.js
@@ -0,0 +1,183 @@
+"use strict";
+/*
+ Copyright (C) 2012 by Aric Stewart <aric(a)codeweavers.com>
+
+ This file is part of spice-html5.
+
+ spice-html5 is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ spice-html5 is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with spice-html5. If not, see <
http://www.gnu.org/licenses/>.
+*/
+/*
+ * Copyright 1990,91 by Thomas Roell, Dinkelscherben, Germany.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of Thomas Roell not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Thomas Roell makes no representations
+ * about the suitability of this software for any purpose. It is provided
+ * "as is" without express or implied warranty.
+ *
+ * THOMAS ROELL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL THOMAS ROELL BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ *
+ */
+/*
+ * Copyright (c) 1994-2003 by The XFree86 Project, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Except as contained in this notice, the name of the copyright holder(s)
+ * and author(s) shall not be used in advertising or otherwise to promote
+ * the sale, use or other dealings in this Software without prior written
+ * authorization from the copyright holder(s) and author(s).
+ */
+
+/*
+ * NOTE: The AT/MF keyboards can generate (via the 8042) two (MF: three)
+ * sets of scancodes. Set3 can only be generated by a MF keyboard.
+ * Set2 sends a makecode for keypress, and the same code prefixed by a
+ * F0 for keyrelease. This is a little bit ugly to handle. Thus we use
+ * here for X386 the PC/XT compatible Set1. This set uses 8bit scancodes.
+ * Bit 7 ist set if the key is released. The code E0 switches to a
+ * different meaning to add the new MF cursorkeys, while not breaking old
+ * applications. E1 is another special prefix. Since I assume that there
+ * will be further versions of PC/XT scancode compatible keyboards, we
+ * may be in trouble one day.
+ *
+ * IDEA: 1) Use Set2 on AT84 keyboards and translate it to MF Set3.
+ * 2) Use the keyboards native set and translate it to common keysyms.
+ */
+
+/*
+ * definition of the AT84/MF101/MF102 Keyboard:
+ * ============================================================
+ * Defined Key Cap Glyphs Pressed value
+ * Key Name Main Also (hex) (dec)
+ * ---------------- ---------- ------- ------ ------
+ */
+
+var KEY_Escape =/* Escape 0x01 */ 1
+var KEY_1 =/* 1 ! 0x02 */ 2
+var KEY_2 =/* 2 @ 0x03 */ 3
+var KEY_3 =/* 3 # 0x04 */ 4
+var KEY_4 =/* 4 $ 0x05 */ 5
+var KEY_5 =/* 5 % 0x06 */ 6
+var KEY_6 =/* 6 ^ 0x07 */ 7
+var KEY_7 =/* 7 & 0x08 */ 8
+var KEY_8 =/* 8 * 0x09 */ 9
+var KEY_9 =/* 9 ( 0x0a */ 10
+var KEY_0 =/* 0 ) 0x0b */ 11
+var KEY_Minus =/* - (Minus) _ (Under) 0x0c */ 12
+var KEY_Equal =/* = (Equal) + 0x0d */ 13
+var KEY_BackSpace =/* Back Space 0x0e */ 14
+var KEY_Tab =/* Tab 0x0f */ 15
+var KEY_Q =/* Q 0x10 */ 16
+var KEY_W =/* W 0x11 */ 17
+var KEY_E =/* E 0x12 */ 18
+var KEY_R =/* R 0x13 */ 19
+var KEY_T =/* T 0x14 */ 20
+var KEY_Y =/* Y 0x15 */ 21
+var KEY_U =/* U 0x16 */ 22
+var KEY_I =/* I 0x17 */ 23
+var KEY_O =/* O 0x18 */ 24
+var KEY_P =/* P 0x19 */ 25
+var KEY_LBrace =/* [ { 0x1a */ 26
+var KEY_RBrace =/* ] } 0x1b */ 27
+var KEY_Enter =/* Enter 0x1c */ 28
+var KEY_LCtrl =/* Ctrl(left) 0x1d */ 29
+var KEY_A =/* A 0x1e */ 30
+var KEY_S =/* S 0x1f */ 31
+var KEY_D =/* D 0x20 */ 32
+var KEY_F =/* F 0x21 */ 33
+var KEY_G =/* G 0x22 */ 34
+var KEY_H =/* H 0x23 */ 35
+var KEY_J =/* J 0x24 */ 36
+var KEY_K =/* K 0x25 */ 37
+var KEY_L =/* L 0x26 */ 38
+var KEY_SemiColon =/* ;(SemiColon) :(Colon) 0x27 */ 39
+var KEY_Quote =/* ' (Apostr) " (Quote) 0x28 */ 40
+var KEY_Tilde =/* ` (Accent) ~ (Tilde) 0x29 */ 41
+var KEY_ShiftL =/* Shift(left) 0x2a */ 42
+var KEY_BSlash =/* \(BckSlash) |(VertBar)0x2b */ 43
+var KEY_Z =/* Z 0x2c */ 44
+var KEY_X =/* X 0x2d */ 45
+var KEY_C =/* C 0x2e */ 46
+var KEY_V =/* V 0x2f */ 47
+var KEY_B =/* B 0x30 */ 48
+var KEY_N =/* N 0x31 */ 49
+var KEY_M =/* M 0x32 */ 50
+var KEY_Comma =/* , (Comma) < (Less) 0x33 */ 51
+var KEY_Period =/* . (Period) >(Greater)0x34 */ 52
+var KEY_Slash =/* / (Slash) ? 0x35 */ 53
+var KEY_ShiftR =/* Shift(right) 0x36 */ 54
+var KEY_KP_Multiply =/* * 0x37 */ 55
+var KEY_Alt =/* Alt(left) 0x38 */ 56
+var KEY_Space =/* (SpaceBar) 0x39 */ 57
+var KEY_CapsLock =/* CapsLock 0x3a */ 58
+var KEY_F1 =/* F1 0x3b */ 59
+var KEY_F2 =/* F2 0x3c */ 60
+var KEY_F3 =/* F3 0x3d */ 61
+var KEY_F4 =/* F4 0x3e */ 62
+var KEY_F5 =/* F5 0x3f */ 63
+var KEY_F6 =/* F6 0x40 */ 64
+var KEY_F7 =/* F7 0x41 */ 65
+var KEY_F8 =/* F8 0x42 */ 66
+var KEY_F9 =/* F9 0x43 */ 67
+var KEY_F10 =/* F10 0x44 */ 68
+var KEY_NumLock =/* NumLock 0x45 */ 69
+var KEY_ScrollLock =/* ScrollLock 0x46 */ 70
+var KEY_KP_7 =/* 7 Home 0x47 */ 71
+var KEY_KP_8 =/* 8 Up 0x48 */ 72
+var KEY_KP_9 =/* 9 PgUp 0x49 */ 73
+var KEY_KP_Minus =/* - (Minus) 0x4a */ 74
+var KEY_KP_4 =/* 4 Left 0x4b */ 75
+var KEY_KP_5 =/* 5 0x4c */ 76
+var KEY_KP_6 =/* 6 Right 0x4d */ 77
+var KEY_KP_Plus =/* + (Plus) 0x4e */ 78
+var KEY_KP_1 =/* 1 End 0x4f */ 79
+var KEY_KP_2 =/* 2 Down 0x50 */ 80
+var KEY_KP_3 =/* 3 PgDown 0x51 */ 81
+var KEY_KP_0 =/* 0 Insert 0x52 */ 82
+var KEY_KP_Decimal =/* . (Decimal) Delete 0x53 */ 83
+var KEY_SysReqest =/* SysReqest 0x54 */ 84
+ /* NOTUSED 0x55 */
+var KEY_Less =/* < (Less) >(Greater) 0x56 */ 86
+var KEY_F11 =/* F11 0x57 */ 87
+var KEY_F12 =/* F12 0x58 */ 88
+
+var KEY_Prefix0 =/* special 0x60 */ 96
+var KEY_Prefix1 =/* specail 0x61 */ 97
diff --git a/src/wok/plugins/kimchi/ui/spice-html5/bitmap.js
b/src/wok/plugins/kimchi/ui/spice-html5/bitmap.js
new file mode 100644
index 0000000..03f5127
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/spice-html5/bitmap.js
@@ -0,0 +1,51 @@
+"use strict";
+/*
+ Copyright (C) 2012 by Jeremy P. White <jwhite(a)codeweavers.com>
+
+ This file is part of spice-html5.
+
+ spice-html5 is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ spice-html5 is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with spice-html5. If not, see <
http://www.gnu.org/licenses/>.
+*/
+
+
+/*----------------------------------------------------------------------------
+** bitmap.js
+** Handle SPICE_IMAGE_TYPE_BITMAP
+**--------------------------------------------------------------------------*/
+function convert_spice_bitmap_to_web(context, spice_bitmap)
+{
+ var ret;
+ var offset, x;
+ var u8 = new Uint8Array(spice_bitmap.data);
+ if (spice_bitmap.format != SPICE_BITMAP_FMT_32BIT &&
+ spice_bitmap.format != SPICE_BITMAP_FMT_RGBA)
+ return undefined;
+
+ ret = context.createImageData(spice_bitmap.x, spice_bitmap.y);
+ for (offset = 0; offset < (spice_bitmap.y * spice_bitmap.stride); )
+ for (x = 0; x < spice_bitmap.x; x++, offset += 4)
+ {
+ ret.data[offset + 0 ] = u8[offset + 2];
+ ret.data[offset + 1 ] = u8[offset + 1];
+ ret.data[offset + 2 ] = u8[offset + 0];
+
+ // FIXME - We effectively treat all images as having
SPICE_IMAGE_FLAGS_HIGH_BITS_SET
+ if (spice_bitmap.format == SPICE_BITMAP_FMT_32BIT)
+ ret.data[offset + 3] = 255;
+ else
+ ret.data[offset + 3] = u8[offset];
+ }
+
+ return ret;
+}
diff --git a/src/wok/plugins/kimchi/ui/spice-html5/css/Makefile.am
b/src/wok/plugins/kimchi/ui/spice-html5/css/Makefile.am
new file mode 100644
index 0000000..ed51972
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/spice-html5/css/Makefile.am
@@ -0,0 +1,20 @@
+#
+# Kimchi
+#
+# Copyright IBM, Corp. 2014
+#
+# 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.
+
+spicecssdir = $(datadir)/wok/plugins/kimchi/ui/spice-html5
+
+dist_spicecss_DATA = $(wildcard *.css) $(NULL)
diff --git a/src/wok/plugins/kimchi/ui/spice-html5/css/spice.css
b/src/wok/plugins/kimchi/ui/spice-html5/css/spice.css
new file mode 100644
index 0000000..5d092ba
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/spice-html5/css/spice.css
@@ -0,0 +1,118 @@
+body
+{
+ background-color: #999999;
+ color: #000000; margin: 0; padding: 0;
+ font-family: "Lucida Grande", "Lucida Sans Unicode",
"Helvetica Neue", Helvetica, Arial, Verdana, sans-serif;
+ font-size: 12pt;
+ line-height: 1.5em;
+}
+
+* { margin: 0; }
+
+#login
+{
+ width: 95%;
+ margin-left: auto;
+ margin-right: auto;
+ border: 1px solid #999999;
+ background: -webkit-gradient(linear, left top, left bottom, from(#fff),
to(#24414e));
+ background: -moz-linear-gradient(top, #fff, #24414e);
+ background-color: #24414e;
+ -moz-border-radius: 10px;
+ -webkit-border-radius: 10px;
+ border-radius: 10px;
+}
+#login span.logo
+{
+ display: inline-block;
+ margin-right: 5px;
+ padding: 2px 10px 2px 20px;
+ border-right: 1px solid #999999;
+ font-size: 20px;
+ font-weight: bolder;
+ text-shadow: #efefef 1px 1px 0px;
+}
+#login label { color: #ffffff; text-shadow: 1px 1px 0px rgba(175, 210, 220, 0.8); }
+#login input
+{
+ padding: 5px;
+ background-color: #fAfAfA;
+ border: 1px inset #999999;
+ outline: none;
+ -moz-border-radius: 3px; -webkit-border-radius: 3px; border-radius: 3px;
+ box-sizing: border-box;
+ -moz-box-sizing: border-box;
+ -webkit-box-sizing: border-box;
+}
+#login input#host { width: 200px; }
+#login input#port { width: 75px; }
+#login input#password { width: 100px; }
+#login button
+{
+ padding: 5px 10px 5px 10px;
+ margin-left: 5px;
+ text-shadow: #efefef 1px 1px 0px;
+ border: 1px outset #999999;
+ cursor: pointer;
+ -moz-border-radius: 5px; -webkit-border-radius: 5px; border-radius: 5px;
+}
+#login button:hover
+{
+ background-color: #666666;
+ color: #ffffff;
+}
+
+#spice-area
+{
+ height: 100%;
+ width: 95%;
+ padding: 0;
+ margin-left: auto;
+ margin-right: auto;
+ border: solid #222222 1px;
+ -webkit-box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.2);
+ -moz-box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.2);
+ box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.2);
+ -moz-border-radius: 10px;
+ -webkit-border-radius: 10px;
+ border-radius: 10px;
+}
+.spice-screen
+{
+ min-height: 600px;
+ height: 100%;
+ margin: 10px;
+ padding: 0;
+ background-color: #333333;
+}
+.spice-message {
+ width: 700px;
+ height: 50px;
+ overflow: auto;
+ margin-top: 5px;
+ margin-left: auto;
+ margin-right: auto;
+ padding: 10px;
+ background-color: #efefef;
+ border: solid #c3c3c3 2px;
+ font-size: 8pt;
+ line-height: 1.1em;
+ font-family: 'Andale Mono', monospace;
+ -moz-border-radius: 10px;
+ -webkit-border-radius: 10px;
+ border-radius: 10px;
+ -webkit-box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.2);
+ -moz-box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.2);
+ box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.2);
+}
+.spice-message p {
+ margin-bottom: 0em;
+ margin-top: 0em;
+}
+.spice-message-warning {
+ color: orange;
+}
+.spice-message-error {
+ color: red;
+}
+
diff --git a/src/wok/plugins/kimchi/ui/spice-html5/cursor.js
b/src/wok/plugins/kimchi/ui/spice-html5/cursor.js
new file mode 100644
index 0000000..71e941d
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/spice-html5/cursor.js
@@ -0,0 +1,110 @@
+"use strict";
+/*
+ Copyright (C) 2012 by Jeremy P. White <jwhite(a)codeweavers.com>
+
+ This file is part of spice-html5.
+
+ spice-html5 is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ spice-html5 is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with spice-html5. If not, see <
http://www.gnu.org/licenses/>.
+*/
+
+
+/*----------------------------------------------------------------------------
+** SpiceCursorConn
+** Drive the Spice Cursor Channel
+**--------------------------------------------------------------------------*/
+function SpiceCursorConn()
+{
+ SpiceConn.apply(this, arguments);
+}
+
+SpiceCursorConn.prototype = Object.create(SpiceConn.prototype);
+SpiceCursorConn.prototype.process_channel_message = function(msg)
+{
+ if (msg.type == SPICE_MSG_CURSOR_INIT)
+ {
+ var cursor_init = new SpiceMsgCursorInit(msg.data);
+ DEBUG > 1 && console.log("SpiceMsgCursorInit");
+ if (this.parent && this.parent.inputs &&
+ this.parent.inputs.mouse_mode == SPICE_MOUSE_MODE_SERVER)
+ {
+ // FIXME - this imagines that the server actually
+ // provides the current cursor position,
+ // instead of 0,0. As of May 11, 2012,
+ // that assumption was false :-(.
+ this.parent.inputs.mousex = cursor_init.position.x;
+ this.parent.inputs.mousey = cursor_init.position.y;
+ }
+ // FIXME - We don't handle most of the parameters here...
+ return true;
+ }
+
+ if (msg.type == SPICE_MSG_CURSOR_SET)
+ {
+ var cursor_set = new SpiceMsgCursorSet(msg.data);
+ DEBUG > 1 && console.log("SpiceMsgCursorSet");
+ if (cursor_set.flags & SPICE_CURSOR_FLAGS_NONE)
+ {
+ document.getElementById(this.parent.screen_id).style.cursor =
"none";
+ return true;
+ }
+
+ if (cursor_set.flags > 0)
+ this.log_warn("FIXME: No support for cursor flags " +
cursor_set.flags);
+
+ if (cursor_set.cursor.header.type != SPICE_CURSOR_TYPE_ALPHA)
+ {
+ this.log_warn("FIXME: No support for cursor type " +
cursor_set.cursor.header.type);
+ return false;
+ }
+
+ this.set_cursor(cursor_set.cursor);
+
+ return true;
+ }
+
+ if (msg.type == SPICE_MSG_CURSOR_HIDE)
+ {
+ DEBUG > 1 && console.log("SpiceMsgCursorHide");
+ document.getElementById(this.parent.screen_id).style.cursor = "none";
+ return true;
+ }
+
+ if (msg.type == SPICE_MSG_CURSOR_RESET)
+ {
+ DEBUG > 1 && console.log("SpiceMsgCursorReset");
+ document.getElementById(this.parent.screen_id).style.cursor = "auto";
+ return true;
+ }
+
+ if (msg.type == SPICE_MSG_CURSOR_INVAL_ALL)
+ {
+ DEBUG > 1 && console.log("SpiceMsgCursorInvalAll");
+ // FIXME - There may be something useful to do here...
+ return true;
+ }
+
+ return false;
+}
+
+SpiceCursorConn.prototype.set_cursor = function(cursor)
+{
+ var pngstr = create_rgba_png(cursor.header.height, cursor.header.width,
cursor.data);
+ var curstr = 'url(data:image/png,' + pngstr + ') ' +
+ cursor.header.hot_spot_x + ' ' + cursor.header.hot_spot_y + ",
default";
+ var screen = document.getElementById(this.parent.screen_id);
+ screen.style.cursor = 'auto';
+ screen.style.cursor = curstr;
+ if (window.getComputedStyle(screen, null).cursor == 'auto')
+ SpiceSimulateCursor.simulate_cursor(this, cursor, screen, pngstr);
+}
diff --git a/src/wok/plugins/kimchi/ui/spice-html5/display.js
b/src/wok/plugins/kimchi/ui/spice-html5/display.js
new file mode 100644
index 0000000..2aa5985
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/spice-html5/display.js
@@ -0,0 +1,823 @@
+"use strict";
+/*
+ Copyright (C) 2012 by Jeremy P. White <jwhite(a)codeweavers.com>
+
+ This file is part of spice-html5.
+
+ spice-html5 is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ spice-html5 is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with spice-html5. If not, see <
http://www.gnu.org/licenses/>.
+*/
+
+
+/*----------------------------------------------------------------------------
+** FIXME: putImageData does not support Alpha blending
+** or compositing. So if we have data in an ImageData
+** format, we have to draw it onto a context,
+** and then use drawImage to put it onto the target,
+** as drawImage does alpha.
+**--------------------------------------------------------------------------*/
+function putImageDataWithAlpha(context, d, x, y)
+{
+ var c = document.createElement("canvas");
+ var t = c.getContext("2d");
+ c.setAttribute('width', d.width);
+ c.setAttribute('height', d.height);
+ t.putImageData(d, 0, 0);
+ context.drawImage(c, x, y, d.width, d.height);
+}
+
+/*----------------------------------------------------------------------------
+** FIXME: Spice will send an image with '0' alpha when it is intended to
+** go on a surface w/no alpha. So in that case, we have to strip
+** out the alpha. The test case for this was flux box; in a Xspice
+** server, right click on the desktop to get the menu; the top bar
+** doesn't paint/highlight correctly w/out this change.
+**--------------------------------------------------------------------------*/
+function stripAlpha(d)
+{
+ var i;
+ for (i = 0; i < (d.width * d.height * 4); i += 4)
+ d.data[i + 3] = 255;
+}
+
+/*----------------------------------------------------------------------------
+** SpiceDisplayConn
+** Drive the Spice Display Channel
+**--------------------------------------------------------------------------*/
+function SpiceDisplayConn()
+{
+ SpiceConn.apply(this, arguments);
+}
+
+SpiceDisplayConn.prototype = Object.create(SpiceConn.prototype);
+SpiceDisplayConn.prototype.process_channel_message = function(msg)
+{
+ if (msg.type == SPICE_MSG_DISPLAY_MARK)
+ {
+ // FIXME - DISPLAY_MARK not implemented (may be hard or impossible)
+ this.known_unimplemented(msg.type, "Display Mark");
+ return true;
+ }
+
+ if (msg.type == SPICE_MSG_DISPLAY_RESET)
+ {
+ DEBUG > 2 && console.log("Display reset");
+ this.surfaces[this.primary_surface].canvas.context.restore();
+ return true;
+ }
+
+ if (msg.type == SPICE_MSG_DISPLAY_DRAW_COPY)
+ {
+ var draw_copy = new SpiceMsgDisplayDrawCopy(msg.data);
+
+ DEBUG > 1 && this.log_draw("DrawCopy", draw_copy);
+
+ if (! draw_copy.base.box.is_same_size(draw_copy.data.src_area))
+ this.log_warn("FIXME: DrawCopy src_area is a different size than
base.box; we do not handle that yet.");
+ if (draw_copy.base.clip.type != SPICE_CLIP_TYPE_NONE)
+ this.log_warn("FIXME: DrawCopy we don't handle clipping yet");
+ if (draw_copy.data.rop_descriptor != SPICE_ROPD_OP_PUT)
+ this.log_warn("FIXME: DrawCopy we don't handle ropd type: " +
draw_copy.data.rop_descriptor);
+ if (draw_copy.data.mask.flags)
+ this.log_warn("FIXME: DrawCopy we don't handle mask flag: " +
draw_copy.data.mask.flags);
+ if (draw_copy.data.mask.bitmap)
+ this.log_warn("FIXME: DrawCopy we don't handle mask");
+
+ if (draw_copy.data && draw_copy.data.src_bitmap)
+ {
+ if (draw_copy.data.src_bitmap.descriptor.flags &&
+ draw_copy.data.src_bitmap.descriptor.flags != SPICE_IMAGE_FLAGS_CACHE_ME
&&
+ draw_copy.data.src_bitmap.descriptor.flags !=
SPICE_IMAGE_FLAGS_HIGH_BITS_SET)
+ {
+ this.log_warn("FIXME: DrawCopy unhandled image flags: " +
draw_copy.data.src_bitmap.descriptor.flags);
+ DEBUG <= 1 && this.log_draw("DrawCopy", draw_copy);
+ }
+
+ if (draw_copy.data.src_bitmap.descriptor.type == SPICE_IMAGE_TYPE_QUIC)
+ {
+ var canvas = this.surfaces[draw_copy.base.surface_id].canvas;
+ if (! draw_copy.data.src_bitmap.quic)
+ {
+ this.log_warn("FIXME: DrawCopy could not handle this QUIC
file.");
+ return false;
+ }
+ var source_img = convert_spice_quic_to_web(canvas.context,
+ draw_copy.data.src_bitmap.quic);
+
+ return this.draw_copy_helper(
+ { base: draw_copy.base,
+ src_area: draw_copy.data.src_area,
+ image_data: source_img,
+ tag: "copyquic." + draw_copy.data.src_bitmap.quic.type,
+ has_alpha: (draw_copy.data.src_bitmap.quic.type ==
QUIC_IMAGE_TYPE_RGBA ? true : false) ,
+ descriptor : draw_copy.data.src_bitmap.descriptor
+ });
+ }
+ else if (draw_copy.data.src_bitmap.descriptor.type ==
SPICE_IMAGE_TYPE_FROM_CACHE ||
+ draw_copy.data.src_bitmap.descriptor.type ==
SPICE_IMAGE_TYPE_FROM_CACHE_LOSSLESS)
+ {
+ if (! this.cache || !
this.cache[draw_copy.data.src_bitmap.descriptor.id])
+ {
+ this.log_warn("FIXME: DrawCopy did not find image id " +
draw_copy.data.src_bitmap.descriptor.id + " in cache.");
+ return false;
+ }
+
+ return this.draw_copy_helper(
+ { base: draw_copy.base,
+ src_area: draw_copy.data.src_area,
+ image_data: this.cache[draw_copy.data.src_bitmap.descriptor.id],
+ tag: "copycache." +
draw_copy.data.src_bitmap.descriptor.id,
+ has_alpha: true, /* FIXME - may want this to be false... */
+ descriptor : draw_copy.data.src_bitmap.descriptor
+ });
+
+ /* FIXME - LOSSLESS CACHE ramifications not understood or handled */
+ }
+ else if (draw_copy.data.src_bitmap.descriptor.type ==
SPICE_IMAGE_TYPE_SURFACE)
+ {
+ var source_context =
this.surfaces[draw_copy.data.src_bitmap.surface_id].canvas.context;
+ var target_context =
this.surfaces[draw_copy.base.surface_id].canvas.context;
+
+ var source_img = source_context.getImageData(
+ draw_copy.data.src_area.left, draw_copy.data.src_area.top,
+ draw_copy.data.src_area.right - draw_copy.data.src_area.left,
+ draw_copy.data.src_area.bottom - draw_copy.data.src_area.top);
+ var computed_src_area = new SpiceRect;
+ computed_src_area.top = computed_src_area.left = 0;
+ computed_src_area.right = source_img.width;
+ computed_src_area.bottom = source_img.height;
+
+ /* FIXME - there is a potential optimization here.
+ That is, if the surface is from 0,0, and
+ both surfaces are alpha surfaces, you should
+ be able to just do a drawImage, which should
+ save time. */
+
+ return this.draw_copy_helper(
+ { base: draw_copy.base,
+ src_area: computed_src_area,
+ image_data: source_img,
+ tag: "copysurf." + draw_copy.data.src_bitmap.surface_id,
+ has_alpha:
this.surfaces[draw_copy.data.src_bitmap.surface_id].format == SPICE_SURFACE_FMT_32_xRGB ?
false : true,
+ descriptor : draw_copy.data.src_bitmap.descriptor
+ });
+
+ return true;
+ }
+ else if (draw_copy.data.src_bitmap.descriptor.type == SPICE_IMAGE_TYPE_JPEG)
+ {
+ if (! draw_copy.data.src_bitmap.jpeg)
+ {
+ this.log_warn("FIXME: DrawCopy could not handle this JPEG
file.");
+ return false;
+ }
+
+ // FIXME - how lame is this. Be have it in binary format, and we have
+ // to put it into string to get it back into jpeg. Blech.
+ var tmpstr = "data:image/jpeg,";
+ var img = new Image;
+ var i;
+ var qdv = new Uint8Array(draw_copy.data.src_bitmap.jpeg.data);
+ for (i = 0; i < qdv.length; i++)
+ {
+ tmpstr += '%';
+ if (qdv[i] < 16)
+ tmpstr += '0';
+ tmpstr += qdv[i].toString(16);
+ }
+
+ img.o =
+ { base: draw_copy.base,
+ tag: "jpeg." + draw_copy.data.src_bitmap.surface_id,
+ descriptor : draw_copy.data.src_bitmap.descriptor,
+ sc : this,
+ };
+ img.onload = handle_draw_jpeg_onload;
+ img.src = tmpstr;
+
+ return true;
+ }
+ else if (draw_copy.data.src_bitmap.descriptor.type ==
SPICE_IMAGE_TYPE_JPEG_ALPHA)
+ {
+ if (! draw_copy.data.src_bitmap.jpeg_alpha)
+ {
+ this.log_warn("FIXME: DrawCopy could not handle this JPEG ALPHA
file.");
+ return false;
+ }
+
+ // FIXME - how lame is this. Be have it in binary format, and we have
+ // to put it into string to get it back into jpeg. Blech.
+ var tmpstr = "data:image/jpeg,";
+ var img = new Image;
+ var i;
+ var qdv = new Uint8Array(draw_copy.data.src_bitmap.jpeg_alpha.data);
+ for (i = 0; i < qdv.length; i++)
+ {
+ tmpstr += '%';
+ if (qdv[i] < 16)
+ tmpstr += '0';
+ tmpstr += qdv[i].toString(16);
+ }
+
+ img.o =
+ { base: draw_copy.base,
+ tag: "jpeg." + draw_copy.data.src_bitmap.surface_id,
+ descriptor : draw_copy.data.src_bitmap.descriptor,
+ sc : this,
+ };
+
+ if (this.surfaces[draw_copy.base.surface_id].format ==
SPICE_SURFACE_FMT_32_ARGB)
+ {
+
+ var canvas = this.surfaces[draw_copy.base.surface_id].canvas;
+ img.alpha_img = convert_spice_lz_to_web(canvas.context,
+ draw_copy.data.src_bitmap.jpeg_alpha.alpha);
+ }
+ img.onload = handle_draw_jpeg_onload;
+ img.src = tmpstr;
+
+ return true;
+ }
+ else if (draw_copy.data.src_bitmap.descriptor.type ==
SPICE_IMAGE_TYPE_BITMAP)
+ {
+ var canvas = this.surfaces[draw_copy.base.surface_id].canvas;
+ if (! draw_copy.data.src_bitmap.bitmap)
+ {
+ this.log_err("null bitmap");
+ return false;
+ }
+
+ var source_img = convert_spice_bitmap_to_web(canvas.context,
+ draw_copy.data.src_bitmap.bitmap);
+ if (! source_img)
+ {
+ this.log_warn("FIXME: Unable to interpret bitmap of format:
" +
+ draw_copy.data.src_bitmap.bitmap.format);
+ return false;
+ }
+
+ return this.draw_copy_helper(
+ { base: draw_copy.base,
+ src_area: draw_copy.data.src_area,
+ image_data: source_img,
+ tag: "bitmap." +
draw_copy.data.src_bitmap.bitmap.format,
+ has_alpha: draw_copy.data.src_bitmap.bitmap ==
SPICE_BITMAP_FMT_32BIT ? false : true,
+ descriptor : draw_copy.data.src_bitmap.descriptor
+ });
+ }
+ else if (draw_copy.data.src_bitmap.descriptor.type ==
SPICE_IMAGE_TYPE_LZ_RGB)
+ {
+ var canvas = this.surfaces[draw_copy.base.surface_id].canvas;
+ if (! draw_copy.data.src_bitmap.lz_rgb)
+ {
+ this.log_err("null lz_rgb ");
+ return false;
+ }
+
+ if (draw_copy.data.src_bitmap.lz_rgb.top_down != 1)
+ this.log_warn("FIXME: Implement non top down support for
lz_rgb");
+
+ var source_img = convert_spice_lz_to_web(canvas.context,
+ draw_copy.data.src_bitmap.lz_rgb);
+ if (! source_img)
+ {
+ this.log_warn("FIXME: Unable to interpret bitmap of type: "
+
+ draw_copy.data.src_bitmap.lz_rgb.type);
+ return false;
+ }
+
+ return this.draw_copy_helper(
+ { base: draw_copy.base,
+ src_area: draw_copy.data.src_area,
+ image_data: source_img,
+ tag: "lz_rgb." + draw_copy.data.src_bitmap.lz_rgb.type,
+ has_alpha: draw_copy.data.src_bitmap.lz_rgb.type ==
LZ_IMAGE_TYPE_RGBA ? true : false ,
+ descriptor : draw_copy.data.src_bitmap.descriptor
+ });
+ }
+ else
+ {
+ this.log_warn("FIXME: DrawCopy unhandled image type: " +
draw_copy.data.src_bitmap.descriptor.type);
+ this.log_draw("DrawCopy", draw_copy);
+ return false;
+ }
+ }
+
+ this.log_warn("FIXME: DrawCopy no src_bitmap.");
+ return false;
+ }
+
+ if (msg.type == SPICE_MSG_DISPLAY_DRAW_FILL)
+ {
+ var draw_fill = new SpiceMsgDisplayDrawFill(msg.data);
+
+ DEBUG > 1 && this.log_draw("DrawFill", draw_fill);
+
+ if (draw_fill.data.rop_descriptor != SPICE_ROPD_OP_PUT)
+ this.log_warn("FIXME: DrawFill we don't handle ropd type: " +
draw_fill.data.rop_descriptor);
+ if (draw_fill.data.mask.flags)
+ this.log_warn("FIXME: DrawFill we don't handle mask flag: " +
draw_fill.data.mask.flags);
+ if (draw_fill.data.mask.bitmap)
+ this.log_warn("FIXME: DrawFill we don't handle mask");
+
+ if (draw_fill.data.brush.type == SPICE_BRUSH_TYPE_SOLID)
+ {
+ // FIXME - do brushes ever have alpha?
+ var color = draw_fill.data.brush.color & 0xffffff;
+ var color_str = "rgb(" + (color >> 16) + ", " +
((color >> 8) & 0xff) + ", " + (color & 0xff) + ")";
+ this.surfaces[draw_fill.base.surface_id].canvas.context.fillStyle =
color_str;
+
+ this.surfaces[draw_fill.base.surface_id].canvas.context.fillRect(
+ draw_fill.base.box.left, draw_fill.base.box.top,
+ draw_fill.base.box.right - draw_fill.base.box.left,
+ draw_fill.base.box.bottom - draw_fill.base.box.top);
+
+ if (DUMP_DRAWS && this.parent.dump_id)
+ {
+ var debug_canvas = document.createElement("canvas");
+ debug_canvas.setAttribute('width',
this.surfaces[draw_fill.base.surface_id].canvas.width);
+ debug_canvas.setAttribute('height',
this.surfaces[draw_fill.base.surface_id].canvas.height);
+ debug_canvas.setAttribute('id', "fillbrush." +
draw_fill.base.surface_id + "." +
this.surfaces[draw_fill.base.surface_id].draw_count);
+ debug_canvas.getContext("2d").fillStyle = color_str;
+ debug_canvas.getContext("2d").fillRect(
+ draw_fill.base.box.left, draw_fill.base.box.top,
+ draw_fill.base.box.right - draw_fill.base.box.left,
+ draw_fill.base.box.bottom - draw_fill.base.box.top);
+ document.getElementById(this.parent.dump_id).appendChild(debug_canvas);
+ }
+
+ this.surfaces[draw_fill.base.surface_id].draw_count++;
+
+ }
+ else
+ {
+ this.log_warn("FIXME: DrawFill can't handle brush type: " +
draw_fill.data.brush.type);
+ }
+ return true;
+ }
+
+ if (msg.type == SPICE_MSG_DISPLAY_COPY_BITS)
+ {
+ var copy_bits = new SpiceMsgDisplayCopyBits(msg.data);
+
+ DEBUG > 1 && this.log_draw("CopyBits", copy_bits);
+
+ var source_canvas = this.surfaces[copy_bits.base.surface_id].canvas;
+ var source_context = source_canvas.context;
+
+ var width = source_canvas.width - copy_bits.src_pos.x;
+ var height = source_canvas.height - copy_bits.src_pos.y;
+ if (width > (copy_bits.base.box.right - copy_bits.base.box.left))
+ width = copy_bits.base.box.right - copy_bits.base.box.left;
+ if (height > (copy_bits.base.box.bottom - copy_bits.base.box.top))
+ height = copy_bits.base.box.bottom - copy_bits.base.box.top;
+
+ var source_img = source_context.getImageData(
+ copy_bits.src_pos.x, copy_bits.src_pos.y, width, height);
+ //source_context.putImageData(source_img, copy_bits.base.box.left,
copy_bits.base.box.top);
+ putImageDataWithAlpha(source_context, source_img, copy_bits.base.box.left,
copy_bits.base.box.top);
+
+ if (DUMP_DRAWS && this.parent.dump_id)
+ {
+ var debug_canvas = document.createElement("canvas");
+ debug_canvas.setAttribute('width', width);
+ debug_canvas.setAttribute('height', height);
+ debug_canvas.setAttribute('id', "copybits" +
copy_bits.base.surface_id + "." +
this.surfaces[copy_bits.base.surface_id].draw_count);
+ debug_canvas.getContext("2d").putImageData(source_img, 0, 0);
+ document.getElementById(this.parent.dump_id).appendChild(debug_canvas);
+ }
+
+
+ this.surfaces[copy_bits.base.surface_id].draw_count++;
+ return true;
+ }
+
+ if (msg.type == SPICE_MSG_DISPLAY_INVAL_ALL_PALETTES)
+ {
+ this.known_unimplemented(msg.type, "Inval All Palettes");
+ return true;
+ }
+
+ if (msg.type == SPICE_MSG_DISPLAY_SURFACE_CREATE)
+ {
+ if (! ("surfaces" in this))
+ this.surfaces = [];
+
+ var m = new SpiceMsgSurfaceCreate(msg.data);
+ DEBUG > 1 && console.log(this.type + ": MsgSurfaceCreate id
" + m.surface.surface_id
+ + "; " + m.surface.width + "x" +
m.surface.height
+ + "; format " + m.surface.format
+ + "; flags " + m.surface.flags);
+ if (m.surface.format != SPICE_SURFACE_FMT_32_xRGB &&
+ m.surface.format != SPICE_SURFACE_FMT_32_ARGB)
+ {
+ this.log_warn("FIXME: cannot handle surface format " +
m.surface.format + " yet.");
+ return false;
+ }
+
+ var canvas = document.createElement("canvas");
+ canvas.setAttribute('width', m.surface.width);
+ canvas.setAttribute('height', m.surface.height);
+ canvas.setAttribute('id', "spice_surface_" +
m.surface.surface_id);
+ canvas.setAttribute('tabindex', m.surface.surface_id);
+ canvas.context = canvas.getContext("2d");
+
+ if (DUMP_CANVASES && this.parent.dump_id)
+ document.getElementById(this.parent.dump_id).appendChild(canvas);
+
+ m.surface.canvas = canvas;
+ m.surface.draw_count = 0;
+ this.surfaces[m.surface.surface_id] = m.surface;
+
+ if (m.surface.flags & SPICE_SURFACE_FLAGS_PRIMARY)
+ {
+ this.primary_surface = m.surface.surface_id;
+
+ /* This .save() is done entirely to enable SPICE_MSG_DISPLAY_RESET */
+ canvas.context.save();
+ document.getElementById(this.parent.screen_id).appendChild(canvas);
+
+ /* We're going to leave width dynamic, but correctly set the height */
+ document.getElementById(this.parent.screen_id).style.height =
m.surface.height + "px";
+ this.hook_events();
+ }
+ return true;
+ }
+
+ if (msg.type == SPICE_MSG_DISPLAY_SURFACE_DESTROY)
+ {
+ var m = new SpiceMsgSurfaceDestroy(msg.data);
+ DEBUG > 1 && console.log(this.type + ": MsgSurfaceDestroy id
" + m.surface_id);
+ this.delete_surface(m.surface_id);
+ return true;
+ }
+
+ if (msg.type == SPICE_MSG_DISPLAY_STREAM_CREATE)
+ {
+ var m = new SpiceMsgDisplayStreamCreate(msg.data);
+ DEBUG > 1 && console.log(this.type + ": MsgStreamCreate id"
+ m.id);
+ if (!this.streams)
+ this.streams = new Array();
+ if (this.streams[m.id])
+ console.log("Stream already exists");
+ else
+ this.streams[m.id] = m;
+ if (m.codec_type != SPICE_VIDEO_CODEC_TYPE_MJPEG)
+ console.log("Unhandled stream codec: "+m.codec_type);
+ return true;
+ }
+
+ if (msg.type == SPICE_MSG_DISPLAY_STREAM_DATA)
+ {
+ var m = new SpiceMsgDisplayStreamData(msg.data);
+ if (!this.streams[m.base.id])
+ {
+ console.log("no stream for data");
+ return false;
+ }
+ if (this.streams[m.base.id].codec_type === SPICE_VIDEO_CODEC_TYPE_MJPEG)
+ {
+ var tmpstr = "data:image/jpeg,";
+ var img = new Image;
+ var i;
+ for (i = 0; i < m.data.length; i++)
+ {
+ tmpstr += '%';
+ if (m.data[i] < 16)
+ tmpstr += '0';
+ tmpstr += m.data[i].toString(16);
+ }
+ var strm_base = new SpiceMsgDisplayBase();
+ strm_base.surface_id = this.streams[m.base.id].surface_id;
+ strm_base.box = this.streams[m.base.id].dest;
+ strm_base.clip = this.streams[m.base.id].clip;
+ img.o =
+ { base: strm_base,
+ tag: "mjpeg." + m.base.id,
+ descriptor: null,
+ sc : this,
+ };
+ img.onload = handle_draw_jpeg_onload;
+ img.src = tmpstr;
+ }
+ return true;
+ }
+
+ if (msg.type == SPICE_MSG_DISPLAY_STREAM_CLIP)
+ {
+ var m = new SpiceMsgDisplayStreamClip(msg.data);
+ DEBUG > 1 && console.log(this.type + ": MsgStreamClip id" +
m.id);
+ this.streams[m.id].clip = m.clip;
+ return true;
+ }
+
+ if (msg.type == SPICE_MSG_DISPLAY_STREAM_DESTROY)
+ {
+ var m = new SpiceMsgDisplayStreamDestroy(msg.data);
+ DEBUG > 1 && console.log(this.type + ": MsgStreamDestroy id"
+ m.id);
+ this.streams[m.id] = undefined;
+ return true;
+ }
+ if (msg.type == SPICE_MSG_DISPLAY_INVAL_LIST)
+ {
+ var m = new SpiceMsgDisplayInvalList(msg.data);
+ var i;
+ DEBUG > 1 && console.log(this.type + ": MsgInvalList " +
m.count + " items");
+ for (i = 0; i < m.count; i++)
+ if (this.cache[m.resources[i].id] != undefined)
+ delete this.cache[m.resources[i].id];
+ return true;
+ }
+
+ return false;
+}
+
+SpiceDisplayConn.prototype.delete_surface = function(surface_id)
+{
+ var canvas = document.getElementById("spice_surface_" + surface_id);
+ if (DUMP_CANVASES && this.parent.dump_id)
+ document.getElementById(this.parent.dump_id).removeChild(canvas);
+ if (this.primary_surface == surface_id)
+ {
+ this.unhook_events();
+ this.primary_surface = undefined;
+ document.getElementById(this.parent.screen_id).removeChild(canvas);
+ }
+
+ delete this.surfaces[surface_id];
+}
+
+
+SpiceDisplayConn.prototype.draw_copy_helper = function(o)
+{
+
+ var canvas = this.surfaces[o.base.surface_id].canvas;
+ if (o.has_alpha)
+ {
+ /* FIXME - This is based on trial + error, not a serious thoughtful
+ analysis of what Spice requires. See display.js for more. */
+ if (this.surfaces[o.base.surface_id].format == SPICE_SURFACE_FMT_32_xRGB)
+ {
+ stripAlpha(o.image_data);
+ canvas.context.putImageData(o.image_data, o.base.box.left, o.base.box.top);
+ }
+ else
+ putImageDataWithAlpha(canvas.context, o.image_data,
+ o.base.box.left, o.base.box.top);
+ }
+ else
+ canvas.context.putImageData(o.image_data, o.base.box.left, o.base.box.top);
+
+ if (o.src_area.left > 0 || o.src_area.top > 0)
+ {
+ this.log_warn("FIXME: DrawCopy not shifting draw copies just yet...");
+ }
+
+ if (o.descriptor && (o.descriptor.flags & SPICE_IMAGE_FLAGS_CACHE_ME))
+ {
+ if (! ("cache" in this))
+ this.cache = {};
+ this.cache[o.descriptor.id] = o.image_data;
+ }
+
+ if (DUMP_DRAWS && this.parent.dump_id)
+ {
+ var debug_canvas = document.createElement("canvas");
+ debug_canvas.setAttribute('width', o.image_data.width);
+ debug_canvas.setAttribute('height', o.image_data.height);
+ debug_canvas.setAttribute('id', o.tag + "." +
+ this.surfaces[o.base.surface_id].draw_count + "." +
+ o.base.surface_id + "@" + o.base.box.left + "x" +
o.base.box.top);
+ debug_canvas.getContext("2d").putImageData(o.image_data, 0, 0);
+ document.getElementById(this.parent.dump_id).appendChild(debug_canvas);
+ }
+
+ this.surfaces[o.base.surface_id].draw_count++;
+
+ return true;
+}
+
+
+SpiceDisplayConn.prototype.log_draw = function(prefix, draw)
+{
+ var str = prefix + "." + draw.base.surface_id + "." +
this.surfaces[draw.base.surface_id].draw_count + ": ";
+ str += "base.box " + draw.base.box.left + ", " +
draw.base.box.top + " to " +
+ draw.base.box.right + ", " + draw.base.box.bottom;
+ str += "; clip.type " + draw.base.clip.type;
+
+ if (draw.data)
+ {
+ if (draw.data.src_area)
+ str += "; src_area " + draw.data.src_area.left + ", " +
draw.data.src_area.top + " to "
+ + draw.data.src_area.right + ", " +
draw.data.src_area.bottom;
+
+ if (draw.data.src_bitmap && draw.data.src_bitmap != null)
+ {
+ str += "; src_bitmap id: " + draw.data.src_bitmap.descriptor.id;
+ str += "; src_bitmap width " +
draw.data.src_bitmap.descriptor.width + ", height " +
draw.data.src_bitmap.descriptor.height;
+ str += "; src_bitmap type " + draw.data.src_bitmap.descriptor.type
+ ", flags " + draw.data.src_bitmap.descriptor.flags;
+ if (draw.data.src_bitmap.surface_id !== undefined)
+ str += "; src_bitmap surface_id " +
draw.data.src_bitmap.surface_id;
+ if (draw.data.src_bitmap.quic)
+ str += "; QUIC type " + draw.data.src_bitmap.quic.type +
+ "; width " + draw.data.src_bitmap.quic.width +
+ "; height " + draw.data.src_bitmap.quic.height ;
+ if (draw.data.src_bitmap.lz_rgb)
+ str += "; LZ_RGB length " + draw.data.src_bitmap.lz_rgb.length
+
+ "; magic " + draw.data.src_bitmap.lz_rgb.magic +
+ "; version 0x" +
draw.data.src_bitmap.lz_rgb.version.toString(16) +
+ "; type " + draw.data.src_bitmap.lz_rgb.type +
+ "; width " + draw.data.src_bitmap.lz_rgb.width +
+ "; height " + draw.data.src_bitmap.lz_rgb.height +
+ "; stride " + draw.data.src_bitmap.lz_rgb.stride +
+ "; top down " + draw.data.src_bitmap.lz_rgb.top_down;
+ }
+ else
+ str += "; src_bitmap is null";
+
+ if (draw.data.brush)
+ {
+ if (draw.data.brush.type == SPICE_BRUSH_TYPE_SOLID)
+ str += "; brush.color 0x" +
draw.data.brush.color.toString(16);
+ if (draw.data.brush.type == SPICE_BRUSH_TYPE_PATTERN)
+ {
+ str += "; brush.pat ";
+ if (draw.data.brush.pattern.pat != null)
+ str += "[SpiceImage]";
+ else
+ str += "[null]";
+ str += " at " + draw.data.brush.pattern.pos.x + ", "
+ draw.data.brush.pattern.pos.y;
+ }
+ }
+
+ str += "; rop_descriptor " + draw.data.rop_descriptor;
+ if (draw.data.scale_mode !== undefined)
+ str += "; scale_mode " + draw.data.scale_mode;
+ str += "; mask.flags " + draw.data.mask.flags;
+ str += "; mask.pos " + draw.data.mask.pos.x + ", " +
draw.data.mask.pos.y;
+ if (draw.data.mask.bitmap != null)
+ {
+ str += "; mask.bitmap width " +
draw.data.mask.bitmap.descriptor.width + ", height " +
draw.data.mask.bitmap.descriptor.height;
+ str += "; mask.bitmap type " +
draw.data.mask.bitmap.descriptor.type + ", flags " +
draw.data.mask.bitmap.descriptor.flags;
+ }
+ else
+ str += "; mask.bitmap is null";
+ }
+
+ console.log(str);
+}
+
+SpiceDisplayConn.prototype.hook_events = function()
+{
+ if (this.primary_surface !== undefined)
+ {
+ var canvas = this.surfaces[this.primary_surface].canvas;
+ canvas.sc = this.parent;
+ canvas.addEventListener('mousemove', handle_mousemove);
+ canvas.addEventListener('mousedown', handle_mousedown);
+ canvas.addEventListener('contextmenu', handle_contextmenu);
+ canvas.addEventListener('mouseup', handle_mouseup);
+ canvas.addEventListener('keydown', handle_keydown);
+ canvas.addEventListener('keyup', handle_keyup);
+ canvas.addEventListener('mouseout', handle_mouseout);
+ canvas.addEventListener('mouseover', handle_mouseover);
+ canvas.addEventListener('mousewheel', handle_mousewheel);
+ canvas.focus();
+ }
+}
+
+SpiceDisplayConn.prototype.unhook_events = function()
+{
+ if (this.primary_surface !== undefined)
+ {
+ var canvas = this.surfaces[this.primary_surface].canvas;
+ canvas.removeEventListener('mousemove', handle_mousemove);
+ canvas.removeEventListener('mousedown', handle_mousedown);
+ canvas.removeEventListener('contextmenu', handle_contextmenu);
+ canvas.removeEventListener('mouseup', handle_mouseup);
+ canvas.removeEventListener('keydown', handle_keydown);
+ canvas.removeEventListener('keyup', handle_keyup);
+ canvas.removeEventListener('mouseout', handle_mouseout);
+ canvas.removeEventListener('mouseover', handle_mouseover);
+ canvas.removeEventListener('mousewheel', handle_mousewheel);
+ }
+}
+
+
+SpiceDisplayConn.prototype.destroy_surfaces = function()
+{
+ for (var s in this.surfaces)
+ {
+ this.delete_surface(this.surfaces[s].surface_id);
+ }
+
+ this.surfaces = undefined;
+}
+
+
+function handle_mouseover(e)
+{
+ this.focus();
+}
+
+function handle_mouseout(e)
+{
+ if (this.sc && this.sc.cursor &&
this.sc.cursor.spice_simulated_cursor)
+ this.sc.cursor.spice_simulated_cursor.style.display = 'none';
+ this.blur();
+}
+
+function handle_draw_jpeg_onload()
+{
+ var temp_canvas = null;
+ var context;
+
+ /*------------------------------------------------------------
+ ** FIXME:
+ ** The helper should be extended to be able to handle actual HtmlImageElements
+ ** ...and the cache should be modified to do so as well
+ **----------------------------------------------------------*/
+ if (this.o.sc.surfaces[this.o.base.surface_id] === undefined)
+ {
+ // This can happen; if the jpeg image loads after our surface
+ // has been destroyed (e.g. open a menu, close it quickly),
+ // we'll find we have no surface.
+ DEBUG > 2 && this.o.sc.log_info("Discarding jpeg; presumed lost
surface " + this.o.base.surface_id);
+ temp_canvas = document.createElement("canvas");
+ temp_canvas.setAttribute('width', this.o.base.box.right);
+ temp_canvas.setAttribute('height', this.o.base.box.bottom);
+ context = temp_canvas.getContext("2d");
+ }
+ else
+ context = this.o.sc.surfaces[this.o.base.surface_id].canvas.context;
+
+ if (this.alpha_img)
+ {
+ var c = document.createElement("canvas");
+ var t = c.getContext("2d");
+ c.setAttribute('width', this.alpha_img.width);
+ c.setAttribute('height', this.alpha_img.height);
+ t.putImageData(this.alpha_img, 0, 0);
+ t.globalCompositeOperation = 'source-in';
+ t.drawImage(this, 0, 0);
+
+ context.drawImage(c, this.o.base.box.left, this.o.base.box.top);
+
+ if (this.o.descriptor &&
+ (this.o.descriptor.flags & SPICE_IMAGE_FLAGS_CACHE_ME))
+ {
+ if (! ("cache" in this.o.sc))
+ this.o.sc.cache = {};
+
+ this.o.sc.cache[this.o.descriptor.id] =
+ t.getImageData(0, 0,
+ this.alpha_img.width,
+ this.alpha_img.height);
+ }
+ }
+ else
+ {
+ context.drawImage(this, this.o.base.box.left, this.o.base.box.top);
+
+ // Give the Garbage collector a clue to recycle this; avoids
+ // fairly massive memory leaks during video playback
+ this.src = null;
+
+ if (this.o.descriptor &&
+ (this.o.descriptor.flags & SPICE_IMAGE_FLAGS_CACHE_ME))
+ {
+ if (! ("cache" in this.o.sc))
+ this.o.sc.cache = {};
+
+ this.o.sc.cache[this.o.descriptor.id] =
+ context.getImageData(this.o.base.box.left, this.o.base.box.top,
+ this.o.base.box.right - this.o.base.box.left,
+ this.o.base.box.bottom - this.o.base.box.top);
+ }
+ }
+
+ if (temp_canvas == null)
+ {
+ if (DUMP_DRAWS && this.o.sc.parent.dump_id)
+ {
+ var debug_canvas = document.createElement("canvas");
+ debug_canvas.setAttribute('id', this.o.tag + "." +
+ this.o.sc.surfaces[this.o.base.surface_id].draw_count + "." +
+ this.o.base.surface_id + "@" + this.o.base.box.left +
"x" + this.o.base.box.top);
+ debug_canvas.getContext("2d").drawImage(this, 0, 0);
+ document.getElementById(this.o.sc.parent.dump_id).appendChild(debug_canvas);
+ }
+
+ this.o.sc.surfaces[this.o.base.surface_id].draw_count++;
+ }
+}
diff --git a/src/wok/plugins/kimchi/ui/spice-html5/enums.js
b/src/wok/plugins/kimchi/ui/spice-html5/enums.js
new file mode 100644
index 0000000..d99b38e
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/spice-html5/enums.js
@@ -0,0 +1,324 @@
+"use strict";
+/*
+ Copyright (C) 2012 by Jeremy P. White <jwhite(a)codeweavers.com>
+
+ This file is part of spice-html5.
+
+ spice-html5 is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ spice-html5 is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with spice-html5. If not, see <
http://www.gnu.org/licenses/>.
+*/
+
+
+/*----------------------------------------------------------------------------
+** enums.js
+** 'constants' for Spice
+**--------------------------------------------------------------------------*/
+var SPICE_MAGIC = "REDQ";
+var SPICE_VERSION_MAJOR = 2;
+var SPICE_VERSION_MINOR = 2;
+
+var SPICE_CONNECT_TIMEOUT = (30 * 1000);
+
+var SPICE_COMMON_CAP_PROTOCOL_AUTH_SELECTION = 0;
+var SPICE_COMMON_CAP_AUTH_SPICE = 1;
+var SPICE_COMMON_CAP_AUTH_SASL = 2;
+var SPICE_COMMON_CAP_MINI_HEADER = 3;
+
+var SPICE_TICKET_KEY_PAIR_LENGTH = 1024;
+var SPICE_TICKET_PUBKEY_BYTES = (SPICE_TICKET_KEY_PAIR_LENGTH / 8 + 34);
+
+var SPICE_LINK_ERR_OK = 0,
+ SPICE_LINK_ERR_ERROR = 1,
+ SPICE_LINK_ERR_INVALID_MAGIC = 2,
+ SPICE_LINK_ERR_INVALID_DATA = 3,
+ SPICE_LINK_ERR_VERSION_MISMATCH = 4,
+ SPICE_LINK_ERR_NEED_SECURED = 5,
+ SPICE_LINK_ERR_NEED_UNSECURED = 6,
+ SPICE_LINK_ERR_PERMISSION_DENIED = 7,
+ SPICE_LINK_ERR_BAD_CONNECTION_ID = 8,
+ SPICE_LINK_ERR_CHANNEL_NOT_AVAILABLE = 9;
+
+var SPICE_MSG_MIGRATE = 1;
+var SPICE_MSG_MIGRATE_DATA = 2;
+var SPICE_MSG_SET_ACK = 3;
+var SPICE_MSG_PING = 4;
+var SPICE_MSG_WAIT_FOR_CHANNELS = 5;
+var SPICE_MSG_DISCONNECTING = 6;
+var SPICE_MSG_NOTIFY = 7;
+var SPICE_MSG_LIST = 8;
+
+var SPICE_MSG_MAIN_MIGRATE_BEGIN = 101;
+var SPICE_MSG_MAIN_MIGRATE_CANCEL = 102;
+var SPICE_MSG_MAIN_INIT = 103;
+var SPICE_MSG_MAIN_CHANNELS_LIST = 104;
+var SPICE_MSG_MAIN_MOUSE_MODE = 105;
+var SPICE_MSG_MAIN_MULTI_MEDIA_TIME = 106;
+var SPICE_MSG_MAIN_AGENT_CONNECTED = 107;
+var SPICE_MSG_MAIN_AGENT_DISCONNECTED = 108;
+var SPICE_MSG_MAIN_AGENT_DATA = 109;
+var SPICE_MSG_MAIN_AGENT_TOKEN = 110;
+var SPICE_MSG_MAIN_MIGRATE_SWITCH_HOST = 111;
+var SPICE_MSG_MAIN_MIGRATE_END = 112;
+var SPICE_MSG_MAIN_NAME = 113;
+var SPICE_MSG_MAIN_UUID = 114;
+var SPICE_MSG_MAIN_AGENT_CONNECTED_TOKENS = 115;
+var SPICE_MSG_MAIN_MIGRATE_BEGIN_SEAMLESS = 116;
+var SPICE_MSG_MAIN_MIGRATE_DST_SEAMLESS_ACK = 117;
+var SPICE_MSG_MAIN_MIGRATE_DST_SEAMLESS_NACK = 118;
+var SPICE_MSG_END_MAIN = 119;
+
+
+
+var SPICE_MSGC_ACK_SYNC = 1;
+var SPICE_MSGC_ACK = 2;
+var SPICE_MSGC_PONG = 3;
+var SPICE_MSGC_MIGRATE_FLUSH_MARK = 4;
+var SPICE_MSGC_MIGRATE_DATA = 5;
+var SPICE_MSGC_DISCONNECTING = 6;
+
+
+var SPICE_MSGC_MAIN_CLIENT_INFO = 101;
+var SPICE_MSGC_MAIN_MIGRATE_CONNECTED = 102;
+var SPICE_MSGC_MAIN_MIGRATE_CONNECT_ERROR = 103;
+var SPICE_MSGC_MAIN_ATTACH_CHANNELS = 104;
+var SPICE_MSGC_MAIN_MOUSE_MODE_REQUEST = 105;
+var SPICE_MSGC_MAIN_AGENT_START = 106;
+var SPICE_MSGC_MAIN_AGENT_DATA = 107;
+var SPICE_MSGC_MAIN_AGENT_TOKEN = 108;
+var SPICE_MSGC_MAIN_MIGRATE_END = 109;
+var SPICE_MSGC_END_MAIN = 110;
+
+var SPICE_MSG_DISPLAY_MODE = 101;
+var SPICE_MSG_DISPLAY_MARK = 102;
+var SPICE_MSG_DISPLAY_RESET = 103;
+var SPICE_MSG_DISPLAY_COPY_BITS = 104;
+var SPICE_MSG_DISPLAY_INVAL_LIST = 105;
+var SPICE_MSG_DISPLAY_INVAL_ALL_PIXMAPS = 106;
+var SPICE_MSG_DISPLAY_INVAL_PALETTE = 107;
+var SPICE_MSG_DISPLAY_INVAL_ALL_PALETTES= 108;
+
+var SPICE_MSG_DISPLAY_STREAM_CREATE = 122;
+var SPICE_MSG_DISPLAY_STREAM_DATA = 123;
+var SPICE_MSG_DISPLAY_STREAM_CLIP = 124;
+var SPICE_MSG_DISPLAY_STREAM_DESTROY = 125;
+var SPICE_MSG_DISPLAY_STREAM_DESTROY_ALL= 126;
+
+var SPICE_MSG_DISPLAY_DRAW_FILL = 302;
+var SPICE_MSG_DISPLAY_DRAW_OPAQUE = 303;
+var SPICE_MSG_DISPLAY_DRAW_COPY = 304;
+var SPICE_MSG_DISPLAY_DRAW_BLEND = 305;
+var SPICE_MSG_DISPLAY_DRAW_BLACKNESS = 306;
+var SPICE_MSG_DISPLAY_DRAW_WHITENESS = 307;
+var SPICE_MSG_DISPLAY_DRAW_INVERS = 308;
+var SPICE_MSG_DISPLAY_DRAW_ROP3 = 309;
+var SPICE_MSG_DISPLAY_DRAW_STROKE = 310;
+var SPICE_MSG_DISPLAY_DRAW_TEXT = 311;
+var SPICE_MSG_DISPLAY_DRAW_TRANSPARENT = 312;
+var SPICE_MSG_DISPLAY_DRAW_ALPHA_BLEND = 313;
+var SPICE_MSG_DISPLAY_SURFACE_CREATE = 314;
+var SPICE_MSG_DISPLAY_SURFACE_DESTROY = 315;
+
+var SPICE_MSGC_DISPLAY_INIT = 101;
+
+var SPICE_MSG_INPUTS_INIT = 101;
+var SPICE_MSG_INPUTS_KEY_MODIFIERS = 102;
+
+var SPICE_MSG_INPUTS_MOUSE_MOTION_ACK = 111;
+
+var SPICE_MSGC_INPUTS_KEY_DOWN = 101;
+var SPICE_MSGC_INPUTS_KEY_UP = 102;
+var SPICE_MSGC_INPUTS_KEY_MODIFIERS = 103;
+
+var SPICE_MSGC_INPUTS_MOUSE_MOTION = 111;
+var SPICE_MSGC_INPUTS_MOUSE_POSITION = 112;
+var SPICE_MSGC_INPUTS_MOUSE_PRESS = 113;
+var SPICE_MSGC_INPUTS_MOUSE_RELEASE = 114;
+
+var SPICE_MSG_CURSOR_INIT = 101;
+var SPICE_MSG_CURSOR_RESET = 102;
+var SPICE_MSG_CURSOR_SET = 103;
+var SPICE_MSG_CURSOR_MOVE = 104;
+var SPICE_MSG_CURSOR_HIDE = 105;
+var SPICE_MSG_CURSOR_TRAIL = 106;
+var SPICE_MSG_CURSOR_INVAL_ONE = 107;
+var SPICE_MSG_CURSOR_INVAL_ALL = 108;
+
+var SPICE_MSG_PLAYBACK_DATA = 101;
+var SPICE_MSG_PLAYBACK_MODE = 102;
+var SPICE_MSG_PLAYBACK_START = 103;
+var SPICE_MSG_PLAYBACK_STOP = 104;
+var SPICE_MSG_PLAYBACK_VOLUME = 105;
+var SPICE_MSG_PLAYBACK_MUTE = 106;
+var SPICE_MSG_PLAYBACK_LATENCY = 107;
+
+var SPICE_PLAYBACK_CAP_CELT_0_5_1 = 0;
+var SPICE_PLAYBACK_CAP_VOLUME = 1;
+var SPICE_PLAYBACK_CAP_LATENCY = 2;
+var SPICE_PLAYBACK_CAP_OPUS = 3;
+
+var SPICE_AUDIO_DATA_MODE_INVALID = 0;
+var SPICE_AUDIO_DATA_MODE_RAW = 1;
+var SPICE_AUDIO_DATA_MODE_CELT_0_5_1 = 2;
+var SPICE_AUDIO_DATA_MODE_OPUS = 3;
+
+var SPICE_AUDIO_FMT_INVALID = 0;
+var SPICE_AUDIO_FMT_S16 = 1;
+
+var SPICE_CHANNEL_MAIN = 1;
+var SPICE_CHANNEL_DISPLAY = 2;
+var SPICE_CHANNEL_INPUTS = 3;
+var SPICE_CHANNEL_CURSOR = 4;
+var SPICE_CHANNEL_PLAYBACK = 5;
+var SPICE_CHANNEL_RECORD = 6;
+var SPICE_CHANNEL_TUNNEL = 7;
+var SPICE_CHANNEL_SMARTCARD = 8;
+var SPICE_CHANNEL_USBREDIR = 9;
+
+var SPICE_SURFACE_FLAGS_PRIMARY = (1 << 0);
+
+var SPICE_NOTIFY_SEVERITY_INFO = 0;
+var SPICE_NOTIFY_SEVERITY_WARN = 1;
+var SPICE_NOTIFY_SEVERITY_ERROR = 2;
+
+var SPICE_MOUSE_MODE_SERVER = (1 << 0),
+ SPICE_MOUSE_MODE_CLIENT = (1 << 1),
+ SPICE_MOUSE_MODE_MASK = 0x3;
+
+var SPICE_CLIP_TYPE_NONE = 0;
+var SPICE_CLIP_TYPE_RECTS = 1;
+
+var SPICE_IMAGE_TYPE_BITMAP = 0;
+var SPICE_IMAGE_TYPE_QUIC = 1;
+var SPICE_IMAGE_TYPE_RESERVED = 2;
+var SPICE_IMAGE_TYPE_LZ_PLT = 100;
+var SPICE_IMAGE_TYPE_LZ_RGB = 101;
+var SPICE_IMAGE_TYPE_GLZ_RGB = 102;
+var SPICE_IMAGE_TYPE_FROM_CACHE = 103;
+var SPICE_IMAGE_TYPE_SURFACE = 104;
+var SPICE_IMAGE_TYPE_JPEG = 105;
+var SPICE_IMAGE_TYPE_FROM_CACHE_LOSSLESS = 106;
+var SPICE_IMAGE_TYPE_ZLIB_GLZ_RGB = 107;
+var SPICE_IMAGE_TYPE_JPEG_ALPHA = 108;
+
+var SPICE_IMAGE_FLAGS_CACHE_ME = (1 << 0),
+ SPICE_IMAGE_FLAGS_HIGH_BITS_SET = (1 << 1),
+ SPICE_IMAGE_FLAGS_CACHE_REPLACE_ME = (1 << 2);
+
+var SPICE_BITMAP_FLAGS_PAL_CACHE_ME = (1 << 0),
+ SPICE_BITMAP_FLAGS_PAL_FROM_CACHE = (1 << 1),
+ SPICE_BITMAP_FLAGS_TOP_DOWN = (1 << 2),
+ SPICE_BITMAP_FLAGS_MASK = 0x7;
+
+var SPICE_BITMAP_FMT_INVALID = 0,
+ SPICE_BITMAP_FMT_1BIT_LE = 1,
+ SPICE_BITMAP_FMT_1BIT_BE = 2,
+ SPICE_BITMAP_FMT_4BIT_LE = 3,
+ SPICE_BITMAP_FMT_4BIT_BE = 4,
+ SPICE_BITMAP_FMT_8BIT = 5,
+ SPICE_BITMAP_FMT_16BIT = 6,
+ SPICE_BITMAP_FMT_24BIT = 7,
+ SPICE_BITMAP_FMT_32BIT = 8,
+ SPICE_BITMAP_FMT_RGBA = 9;
+
+
+var SPICE_CURSOR_FLAGS_NONE = (1 << 0),
+ SPICE_CURSOR_FLAGS_CACHE_ME = (1 << 1),
+ SPICE_CURSOR_FLAGS_FROM_CACHE = (1 << 2),
+ SPICE_CURSOR_FLAGS_MASK = 0x7;
+
+var SPICE_MOUSE_BUTTON_MASK_LEFT = (1 << 0),
+ SPICE_MOUSE_BUTTON_MASK_MIDDLE = (1 << 1),
+ SPICE_MOUSE_BUTTON_MASK_RIGHT = (1 << 2),
+ SPICE_MOUSE_BUTTON_MASK_MASK = 0x7;
+
+var SPICE_MOUSE_BUTTON_INVALID = 0;
+var SPICE_MOUSE_BUTTON_LEFT = 1;
+var SPICE_MOUSE_BUTTON_MIDDLE = 2;
+var SPICE_MOUSE_BUTTON_RIGHT = 3;
+var SPICE_MOUSE_BUTTON_UP = 4;
+var SPICE_MOUSE_BUTTON_DOWN = 5;
+
+var SPICE_BRUSH_TYPE_NONE = 0,
+ SPICE_BRUSH_TYPE_SOLID = 1,
+ SPICE_BRUSH_TYPE_PATTERN = 2;
+
+var SPICE_SURFACE_FMT_INVALID = 0,
+ SPICE_SURFACE_FMT_1_A = 1,
+ SPICE_SURFACE_FMT_8_A = 8,
+ SPICE_SURFACE_FMT_16_555 = 16,
+ SPICE_SURFACE_FMT_32_xRGB = 32,
+ SPICE_SURFACE_FMT_16_565 = 80,
+ SPICE_SURFACE_FMT_32_ARGB = 96;
+
+var SPICE_ROPD_INVERS_SRC = (1 << 0),
+ SPICE_ROPD_INVERS_BRUSH = (1 << 1),
+ SPICE_ROPD_INVERS_DEST = (1 << 2),
+ SPICE_ROPD_OP_PUT = (1 << 3),
+ SPICE_ROPD_OP_OR = (1 << 4),
+ SPICE_ROPD_OP_AND = (1 << 5),
+ SPICE_ROPD_OP_XOR = (1 << 6),
+ SPICE_ROPD_OP_BLACKNESS = (1 << 7),
+ SPICE_ROPD_OP_WHITENESS = (1 << 8),
+ SPICE_ROPD_OP_INVERS = (1 << 9),
+ SPICE_ROPD_INVERS_RES = (1 << 10),
+ SPICE_ROPD_MASK = 0x7ff;
+
+var LZ_IMAGE_TYPE_INVALID = 0,
+ LZ_IMAGE_TYPE_PLT1_LE = 1,
+ LZ_IMAGE_TYPE_PLT1_BE = 2, // PLT stands for palette
+ LZ_IMAGE_TYPE_PLT4_LE = 3,
+ LZ_IMAGE_TYPE_PLT4_BE = 4,
+ LZ_IMAGE_TYPE_PLT8 = 5,
+ LZ_IMAGE_TYPE_RGB16 = 6,
+ LZ_IMAGE_TYPE_RGB24 = 7,
+ LZ_IMAGE_TYPE_RGB32 = 8,
+ LZ_IMAGE_TYPE_RGBA = 9,
+ LZ_IMAGE_TYPE_XXXA = 10;
+
+
+var QUIC_IMAGE_TYPE_INVALID = 0,
+ QUIC_IMAGE_TYPE_GRAY = 1,
+ QUIC_IMAGE_TYPE_RGB16 = 2,
+ QUIC_IMAGE_TYPE_RGB24 = 3,
+ QUIC_IMAGE_TYPE_RGB32 = 4,
+ QUIC_IMAGE_TYPE_RGBA = 5;
+
+var SPICE_INPUT_MOTION_ACK_BUNCH = 4;
+
+
+var SPICE_CURSOR_TYPE_ALPHA = 0,
+ SPICE_CURSOR_TYPE_MONO = 1,
+ SPICE_CURSOR_TYPE_COLOR4 = 2,
+ SPICE_CURSOR_TYPE_COLOR8 = 3,
+ SPICE_CURSOR_TYPE_COLOR16 = 4,
+ SPICE_CURSOR_TYPE_COLOR24 = 5,
+ SPICE_CURSOR_TYPE_COLOR32 = 6;
+
+var SPICE_VIDEO_CODEC_TYPE_MJPEG = 1;
+
+var VD_AGENT_PROTOCOL = 1;
+
+var VD_AGENT_MOUSE_STATE = 1,
+ VD_AGENT_MONITORS_CONFIG = 2,
+ VD_AGENT_REPLY = 3,
+ VD_AGENT_CLIPBOARD = 4,
+ VD_AGENT_DISPLAY_CONFIG = 5,
+ VD_AGENT_ANNOUNCE_CAPABILITIES = 6,
+ VD_AGENT_CLIPBOARD_GRAB = 7,
+ VD_AGENT_CLIPBOARD_REQUEST = 8,
+ VD_AGENT_CLIPBOARD_RELEASE = 9,
+ VD_AGENT_FILE_XFER_START =10,
+ VD_AGENT_FILE_XFER_STATUS =11,
+ VD_AGENT_FILE_XFER_DATA =12,
+ VD_AGENT_CLIENT_DISCONNECTED =13,
+ VD_AGENT_MAX_CLIPBOARD =14;
diff --git a/src/wok/plugins/kimchi/ui/spice-html5/inputs.js
b/src/wok/plugins/kimchi/ui/spice-html5/inputs.js
new file mode 100644
index 0000000..c904eda
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/spice-html5/inputs.js
@@ -0,0 +1,280 @@
+"use strict";
+/*
+ Copyright (C) 2012 by Jeremy P. White <jwhite(a)codeweavers.com>
+
+ This file is part of spice-html5.
+
+ spice-html5 is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ spice-html5 is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with spice-html5. If not, see <
http://www.gnu.org/licenses/>.
+*/
+
+/*----------------------------------------------------------------------------
+ ** Modifier Keystates
+ ** These need to be tracked because focus in and out can get the keyboard
+ ** out of sync.
+ **------------------------------------------------------------------------*/
+var Shift_state = -1;
+var Ctrl_state = -1;
+var Alt_state = -1;
+var Meta_state = -1;
+
+/*----------------------------------------------------------------------------
+** SpiceInputsConn
+** Drive the Spice Inputs channel (e.g. mouse + keyboard)
+**--------------------------------------------------------------------------*/
+function SpiceInputsConn()
+{
+ SpiceConn.apply(this, arguments);
+
+ this.mousex = undefined;
+ this.mousey = undefined;
+ this.button_state = 0;
+ this.waiting_for_ack = 0;
+}
+
+SpiceInputsConn.prototype = Object.create(SpiceConn.prototype);
+SpiceInputsConn.prototype.process_channel_message = function(msg)
+{
+ if (msg.type == SPICE_MSG_INPUTS_INIT)
+ {
+ var inputs_init = new SpiceMsgInputsInit(msg.data);
+ this.keyboard_modifiers = inputs_init.keyboard_modifiers;
+ DEBUG > 1 && console.log("MsgInputsInit - modifier " +
this.keyboard_modifiers);
+ // FIXME - We don't do anything with the keyboard modifiers...
+ return true;
+ }
+ if (msg.type == SPICE_MSG_INPUTS_KEY_MODIFIERS)
+ {
+ var key = new SpiceMsgInputsKeyModifiers(msg.data);
+ this.keyboard_modifiers = key.keyboard_modifiers;
+ DEBUG > 1 && console.log("MsgInputsKeyModifiers - modifier "
+ this.keyboard_modifiers);
+ // FIXME - We don't do anything with the keyboard modifiers...
+ return true;
+ }
+ if (msg.type == SPICE_MSG_INPUTS_MOUSE_MOTION_ACK)
+ {
+ DEBUG > 1 && console.log("mouse motion ack");
+ this.waiting_for_ack -= SPICE_INPUT_MOTION_ACK_BUNCH;
+ return true;
+ }
+ return false;
+}
+
+
+
+function handle_mousemove(e)
+{
+ var msg = new SpiceMiniData();
+ var move;
+ if (this.sc.mouse_mode == SPICE_MOUSE_MODE_CLIENT)
+ {
+ move = new SpiceMsgcMousePosition(this.sc, e)
+ msg.build_msg(SPICE_MSGC_INPUTS_MOUSE_POSITION, move);
+ }
+ else
+ {
+ move = new SpiceMsgcMouseMotion(this.sc, e)
+ msg.build_msg(SPICE_MSGC_INPUTS_MOUSE_MOTION, move);
+ }
+ if (this.sc && this.sc.inputs && this.sc.inputs.state ===
"ready")
+ {
+ if (this.sc.inputs.waiting_for_ack < (2 * SPICE_INPUT_MOTION_ACK_BUNCH))
+ {
+ this.sc.inputs.send_msg(msg);
+ this.sc.inputs.waiting_for_ack++;
+ }
+ else
+ {
+ DEBUG > 0 && this.sc.log_info("Discarding mouse
motion");
+ }
+ }
+
+ if (this.sc && this.sc.cursor &&
this.sc.cursor.spice_simulated_cursor)
+ {
+ this.sc.cursor.spice_simulated_cursor.style.display = 'block';
+ this.sc.cursor.spice_simulated_cursor.style.left = e.pageX -
this.sc.cursor.spice_simulated_cursor.spice_hot_x + 'px';
+ this.sc.cursor.spice_simulated_cursor.style.top = e.pageY -
this.sc.cursor.spice_simulated_cursor.spice_hot_y + 'px';
+ e.preventDefault();
+ }
+
+}
+
+function handle_mousedown(e)
+{
+ var press = new SpiceMsgcMousePress(this.sc, e)
+ var msg = new SpiceMiniData();
+ msg.build_msg(SPICE_MSGC_INPUTS_MOUSE_PRESS, press);
+ if (this.sc && this.sc.inputs && this.sc.inputs.state ===
"ready")
+ this.sc.inputs.send_msg(msg);
+
+ e.preventDefault();
+}
+
+function handle_contextmenu(e)
+{
+ e.preventDefault();
+ return false;
+}
+
+function handle_mouseup(e)
+{
+ var release = new SpiceMsgcMouseRelease(this.sc, e)
+ var msg = new SpiceMiniData();
+ msg.build_msg(SPICE_MSGC_INPUTS_MOUSE_RELEASE, release);
+ if (this.sc && this.sc.inputs && this.sc.inputs.state ===
"ready")
+ this.sc.inputs.send_msg(msg);
+
+ e.preventDefault();
+}
+
+function handle_mousewheel(e)
+{
+ var press = new SpiceMsgcMousePress;
+ var release = new SpiceMsgcMouseRelease;
+ if (e.wheelDelta > 0)
+ press.button = release.button = SPICE_MOUSE_BUTTON_UP;
+ else
+ press.button = release.button = SPICE_MOUSE_BUTTON_DOWN;
+ press.buttons_state = 0;
+ release.buttons_state = 0;
+
+ var msg = new SpiceMiniData();
+ msg.build_msg(SPICE_MSGC_INPUTS_MOUSE_PRESS, press);
+ if (this.sc && this.sc.inputs && this.sc.inputs.state ===
"ready")
+ this.sc.inputs.send_msg(msg);
+
+ msg.build_msg(SPICE_MSGC_INPUTS_MOUSE_RELEASE, release);
+ if (this.sc && this.sc.inputs && this.sc.inputs.state ===
"ready")
+ this.sc.inputs.send_msg(msg);
+
+ e.preventDefault();
+}
+
+function handle_keydown(e)
+{
+ var key = new SpiceMsgcKeyDown(e)
+ var msg = new SpiceMiniData();
+ check_and_update_modifiers(e, key.code, this.sc);
+ msg.build_msg(SPICE_MSGC_INPUTS_KEY_DOWN, key);
+ if (this.sc && this.sc.inputs && this.sc.inputs.state ===
"ready")
+ this.sc.inputs.send_msg(msg);
+
+ e.preventDefault();
+}
+
+function handle_keyup(e)
+{
+ var key = new SpiceMsgcKeyUp(e)
+ var msg = new SpiceMiniData();
+ check_and_update_modifiers(e, key.code, this.sc);
+ msg.build_msg(SPICE_MSGC_INPUTS_KEY_UP, key);
+ if (this.sc && this.sc.inputs && this.sc.inputs.state ===
"ready")
+ this.sc.inputs.send_msg(msg);
+
+ e.preventDefault();
+}
+
+function sendCtrlAltDel()
+{
+ if (sc && sc.inputs && sc.inputs.state === "ready"){
+ var key = new SpiceMsgcKeyDown();
+ var msg = new SpiceMiniData();
+
+ update_modifier(true, KEY_LCtrl, sc);
+ update_modifier(true, KEY_Alt, sc);
+
+ key.code = KEY_KP_Decimal;
+ msg.build_msg(SPICE_MSGC_INPUTS_KEY_DOWN, key);
+ sc.inputs.send_msg(msg);
+ msg.build_msg(SPICE_MSGC_INPUTS_KEY_UP, key);
+ sc.inputs.send_msg(msg);
+
+ if(Ctrl_state == false) update_modifier(false, KEY_LCtrl, sc);
+ if(Alt_state == false) update_modifier(false, KEY_Alt, sc);
+ }
+}
+
+function update_modifier(state, code, sc)
+{
+ var msg = new SpiceMiniData();
+ if (!state)
+ {
+ var key = new SpiceMsgcKeyUp()
+ key.code =(0x80|code);
+ msg.build_msg(SPICE_MSGC_INPUTS_KEY_UP, key);
+ }
+ else
+ {
+ var key = new SpiceMsgcKeyDown()
+ key.code = code;
+ msg.build_msg(SPICE_MSGC_INPUTS_KEY_DOWN, key);
+ }
+
+ sc.inputs.send_msg(msg);
+}
+
+function check_and_update_modifiers(e, code, sc)
+{
+ if (Shift_state === -1)
+ {
+ Shift_state = e.shiftKey;
+ Ctrl_state = e.ctrlKey;
+ Alt_state = e.altKey;
+ Meta_state = e.metaKey;
+ }
+
+ if (code === KEY_ShiftL)
+ Shift_state = true;
+ else if (code === KEY_Alt)
+ Alt_state = true;
+ else if (code === KEY_LCtrl)
+ Ctrl_state = true;
+ else if (code === 0xE0B5)
+ Meta_state = true;
+ else if (code === (0x80|KEY_ShiftL))
+ Shift_state = false;
+ else if (code === (0x80|KEY_Alt))
+ Alt_state = false;
+ else if (code === (0x80|KEY_LCtrl))
+ Ctrl_state = false;
+ else if (code === (0x80|0xE0B5))
+ Meta_state = false;
+
+ if (sc && sc.inputs && sc.inputs.state === "ready")
+ {
+ if (Shift_state != e.shiftKey)
+ {
+ console.log("Shift state out of sync");
+ update_modifier(e.shiftKey, KEY_ShiftL, sc);
+ Shift_state = e.shiftKey;
+ }
+ if (Alt_state != e.altKey)
+ {
+ console.log("Alt state out of sync");
+ update_modifier(e.altKey, KEY_Alt, sc);
+ Alt_state = e.altKey;
+ }
+ if (Ctrl_state != e.ctrlKey)
+ {
+ console.log("Ctrl state out of sync");
+ update_modifier(e.ctrlKey, KEY_LCtrl, sc);
+ Ctrl_state = e.ctrlKey;
+ }
+ if (Meta_state != e.metaKey)
+ {
+ console.log("Meta state out of sync");
+ update_modifier(e.metaKey, 0xE0B5, sc);
+ Meta_state = e.metaKey;
+ }
+ }
+}
diff --git a/src/wok/plugins/kimchi/ui/spice-html5/lz.js
b/src/wok/plugins/kimchi/ui/spice-html5/lz.js
new file mode 100644
index 0000000..4292eac
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/spice-html5/lz.js
@@ -0,0 +1,166 @@
+"use strict";
+/*
+ Copyright (C) 2012 by Jeremy P. White <jwhite(a)codeweavers.com>
+
+ This file is part of spice-html5.
+
+ spice-html5 is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ spice-html5 is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with spice-html5. If not, see <
http://www.gnu.org/licenses/>.
+*/
+
+
+/*----------------------------------------------------------------------------
+** lz.js
+** Functions for handling SPICE_IMAGE_TYPE_LZ_RGB
+** Adapted from lz.c .
+**--------------------------------------------------------------------------*/
+function lz_rgb32_decompress(in_buf, at, out_buf, type, default_alpha)
+{
+ var encoder = at;
+ var op = 0;
+ var ctrl;
+ var ctr = 0;
+
+ for (ctrl = in_buf[encoder++]; (op * 4) < out_buf.length; ctrl =
in_buf[encoder++])
+ {
+ var ref = op;
+ var len = ctrl >> 5;
+ var ofs = (ctrl & 31) << 8;
+
+//if (type == LZ_IMAGE_TYPE_RGBA)
+//console.log(ctr++ + ": from " + (encoder + 28) + ", ctrl " + ctrl +
", len " + len + ", ofs " + ofs + ", op " + op);
+ if (ctrl >= 32) {
+
+ var code;
+ len--;
+
+ if (len == 7 - 1) {
+ do {
+ code = in_buf[encoder++];
+ len += code;
+ } while (code == 255);
+ }
+ code = in_buf[encoder++];
+ ofs += code;
+
+
+ if (code == 255) {
+ if ((ofs - code) == (31 << 8)) {
+ ofs = in_buf[encoder++] << 8;
+ ofs += in_buf[encoder++];
+ ofs += 8191;
+ }
+ }
+ len += 1;
+ if (type == LZ_IMAGE_TYPE_RGBA)
+ len += 2;
+
+ ofs += 1;
+
+ ref -= ofs;
+ if (ref == (op - 1)) {
+ var b = ref;
+//if (type == LZ_IMAGE_TYPE_RGBA) console.log("alpha " + out_buf[(b*4)+3] +
" dupped into pixel " + op + " through pixel " + (op + len));
+ for (; len; --len) {
+ if (type == LZ_IMAGE_TYPE_RGBA)
+ {
+ out_buf[(op*4) + 3] = out_buf[(b*4)+3];
+ }
+ else
+ {
+ for (i = 0; i < 4; i++)
+ out_buf[(op*4) + i] = out_buf[(b*4)+i];
+ }
+ op++;
+ }
+ } else {
+//if (type == LZ_IMAGE_TYPE_RGBA) console.log("alpha copied to pixel " + op +
" through " + (op + len) + " from " + ref);
+ for (; len; --len) {
+ if (type == LZ_IMAGE_TYPE_RGBA)
+ {
+ out_buf[(op*4) + 3] = out_buf[(ref*4)+3];
+ }
+ else
+ {
+ for (i = 0; i < 4; i++)
+ out_buf[(op*4) + i] = out_buf[(ref*4)+i];
+ }
+ op++; ref++;
+ }
+ }
+ } else {
+ ctrl++;
+
+ if (type == LZ_IMAGE_TYPE_RGBA)
+ {
+//console.log("alpha " + in_buf[encoder] + " set into pixel " + op);
+ out_buf[(op*4) + 3] = in_buf[encoder++];
+ }
+ else
+ {
+ out_buf[(op*4) + 0] = in_buf[encoder + 2];
+ out_buf[(op*4) + 1] = in_buf[encoder + 1];
+ out_buf[(op*4) + 2] = in_buf[encoder + 0];
+ if (default_alpha)
+ out_buf[(op*4) + 3] = 255;
+ encoder += 3;
+ }
+ op++;
+
+
+ for (--ctrl; ctrl; ctrl--) {
+ if (type == LZ_IMAGE_TYPE_RGBA)
+ {
+//console.log("alpha " + in_buf[encoder] + " set into pixel " + op);
+ out_buf[(op*4) + 3] = in_buf[encoder++];
+ }
+ else
+ {
+ out_buf[(op*4) + 0] = in_buf[encoder + 2];
+ out_buf[(op*4) + 1] = in_buf[encoder + 1];
+ out_buf[(op*4) + 2] = in_buf[encoder + 0];
+ if (default_alpha)
+ out_buf[(op*4) + 3] = 255;
+ encoder += 3;
+ }
+ op++;
+ }
+ }
+
+ }
+ return encoder - 1;
+}
+
+function convert_spice_lz_to_web(context, lz_image)
+{
+ var at;
+ if (lz_image.type === LZ_IMAGE_TYPE_RGB32 || lz_image.type === LZ_IMAGE_TYPE_RGBA)
+ {
+ var u8 = new Uint8Array(lz_image.data);
+ var ret = context.createImageData(lz_image.width, lz_image.height);
+
+ at = lz_rgb32_decompress(u8, 0, ret.data, LZ_IMAGE_TYPE_RGB32, lz_image.type !=
LZ_IMAGE_TYPE_RGBA);
+ if (lz_image.type == LZ_IMAGE_TYPE_RGBA)
+ lz_rgb32_decompress(u8, at, ret.data, LZ_IMAGE_TYPE_RGBA, false);
+ }
+ else if (lz_image.type === LZ_IMAGE_TYPE_XXXA)
+ {
+ var u8 = new Uint8Array(lz_image.data);
+ var ret = context.createImageData(lz_image.width, lz_image.height);
+ lz_rgb32_decompress(u8, 0, ret.data, LZ_IMAGE_TYPE_RGBA, false);
+ }
+ else
+ return undefined;
+
+ return ret;
+}
diff --git a/src/wok/plugins/kimchi/ui/spice-html5/main.js
b/src/wok/plugins/kimchi/ui/spice-html5/main.js
new file mode 100644
index 0000000..91f1963
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/spice-html5/main.js
@@ -0,0 +1,231 @@
+"use strict";
+/*
+ Copyright (C) 2012 by Jeremy P. White <jwhite(a)codeweavers.com>
+
+ This file is part of spice-html5.
+
+ spice-html5 is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ spice-html5 is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with spice-html5. If not, see <
http://www.gnu.org/licenses/>.
+*/
+
+/*----------------------------------------------------------------------------
+** SpiceMainConn
+** This is the master Javascript class for establishing and
+** managing a connection to a Spice Server.
+**
+** Invocation: You must pass an object with properties as follows:
+** uri (required) Uri of a WebSocket listener that is
+** connected to a spice server.
+** password (required) Password to send to the spice server
+** message_id (optional) Identifier of an element in the DOM
+** where SpiceConn will write messages.
+** It will use classes spice-messages-x,
+** where x is one of info, warning, or error.
+** screen_id (optional) Identifier of an element in the DOM
+** where SpiceConn will create any new
+** client screens. This is the main UI.
+** dump_id (optional) If given, an element to use for
+** dumping every single image + canvas drawn.
+** Sometimes useful for debugging.
+** onerror (optional) If given, a function to receive async
+** errors. Note that you should also catch
+** errors for ones that occur inline
+** onagent (optional) If given, a function to be called when
+** a VD agent is connected; a good opportunity
+** to request a resize
+**
+** Throws error if there are troubles. Requires a modern (by 2012 standards)
+** browser, including WebSocket and WebSocket.binaryType == arraybuffer
+**
+**--------------------------------------------------------------------------*/
+function SpiceMainConn()
+{
+ if (typeof WebSocket === "undefined")
+ throw new Error("WebSocket unavailable. You need to use a different
browser.");
+
+ SpiceConn.apply(this, arguments);
+
+}
+
+SpiceMainConn.prototype = Object.create(SpiceConn.prototype);
+SpiceMainConn.prototype.process_channel_message = function(msg)
+{
+ if (msg.type == SPICE_MSG_MAIN_INIT)
+ {
+ this.log_info("Connected to " + this.ws.url);
+ this.report_success("Connected")
+ this.main_init = new SpiceMsgMainInit(msg.data);
+ this.connection_id = this.main_init.session_id;
+
+ if (DEBUG > 0)
+ {
+ // FIXME - there is a lot here we don't handle; mouse modes, agent,
+ // ram_hint, multi_media_time
+ this.log_info("session id " +
this.main_init.session_id +
+ " ; display_channels_hint " +
this.main_init.display_channels_hint +
+ " ; supported_mouse_modes " +
this.main_init.supported_mouse_modes +
+ " ; current_mouse_mode " +
this.main_init.current_mouse_mode +
+ " ; agent_connected " +
this.main_init.agent_connected +
+ " ; agent_tokens " +
this.main_init.agent_tokens +
+ " ; multi_media_time " +
this.main_init.multi_media_time +
+ " ; ram_hint " +
this.main_init.ram_hint);
+ }
+
+ this.handle_mouse_mode(this.main_init.current_mouse_mode,
+ this.main_init.supported_mouse_modes);
+
+ if (this.main_init.agent_connected)
+ this.connect_agent();
+
+ var attach = new SpiceMiniData;
+ attach.type = SPICE_MSGC_MAIN_ATTACH_CHANNELS;
+ attach.size = attach.buffer_size();
+ this.send_msg(attach);
+ return true;
+ }
+
+ if (msg.type == SPICE_MSG_MAIN_MOUSE_MODE)
+ {
+ var mode = new SpiceMsgMainMouseMode(msg.data);
+ DEBUG > 0 && this.log_info("Mouse supported modes " +
mode.supported_modes + "; current " + mode.current_mode);
+ this.handle_mouse_mode(mode.current_mode, mode.supported_modes);
+ return true;
+ }
+
+ if (msg.type == SPICE_MSG_MAIN_CHANNELS_LIST)
+ {
+ var i;
+ var chans;
+ DEBUG > 0 && console.log("channels");
+ chans = new SpiceMsgChannels(msg.data);
+ for (i = 0; i < chans.channels.length; i++)
+ {
+ var conn = {
+ uri: this.ws.url,
+ parent: this,
+ connection_id : this.connection_id,
+ type : chans.channels[i].type,
+ chan_id : chans.channels[i].id
+ };
+ if (chans.channels[i].type == SPICE_CHANNEL_DISPLAY)
+ this.display = new SpiceDisplayConn(conn);
+ else if (chans.channels[i].type == SPICE_CHANNEL_INPUTS)
+ {
+ this.inputs = new SpiceInputsConn(conn);
+ this.inputs.mouse_mode = this.mouse_mode;
+ }
+ else if (chans.channels[i].type == SPICE_CHANNEL_CURSOR)
+ this.cursor = new SpiceCursorConn(conn);
+ else if (chans.channels[i].type == SPICE_CHANNEL_PLAYBACK)
+ this.cursor = new SpicePlaybackConn(conn);
+ else
+ {
+ this.log_err("Channel type " + chans.channels[i].type + "
unknown.");
+ if (! ("extra_channels" in this))
+ this.extra_channels = [];
+ this.extra_channels[i] = new SpiceConn(conn);
+ }
+
+ }
+
+ return true;
+ }
+
+ if (msg.type == SPICE_MSG_MAIN_AGENT_CONNECTED ||
+ msg.type == SPICE_MSG_MAIN_AGENT_CONNECTED_TOKENS)
+ {
+ this.connect_agent();
+ return true;
+ }
+
+ if (msg.type == SPICE_MSG_MAIN_AGENT_DISCONNECTED)
+ {
+ this.agent_connected = false;
+ return true;
+ }
+
+ return false;
+}
+
+SpiceMainConn.prototype.stop = function(msg)
+{
+ this.state = "closing";
+
+ if (this.inputs)
+ {
+ this.inputs.cleanup();
+ this.inputs = undefined;
+ }
+
+ if (this.cursor)
+ {
+ this.cursor.cleanup();
+ this.cursor = undefined;
+ }
+
+ if (this.display)
+ {
+ this.display.cleanup();
+ this.display.destroy_surfaces();
+ this.display = undefined;
+ }
+
+ this.cleanup();
+
+ if ("extra_channels" in this)
+ for (var e in this.extra_channels)
+ this.extra_channels[e].cleanup();
+ this.extra_channels = undefined;
+}
+
+SpiceMainConn.prototype.resize_window = function(flags, width, height, depth, x, y)
+{
+ if (this.agent_connected > 0)
+ {
+ var monitors_config = new VDAgentMonitorsConfig(flags, width, height, depth, x,
y);
+ var agent_data = new SpiceMsgcMainAgentData(VD_AGENT_MONITORS_CONFIG,
monitors_config);
+ var mr = new SpiceMiniData();
+ mr.build_msg(SPICE_MSGC_MAIN_AGENT_DATA, agent_data);
+ this.send_msg(mr);
+ }
+}
+
+SpiceMainConn.prototype.connect_agent = function()
+{
+ this.agent_connected = true;
+
+ var agent_start = new SpiceMsgcMainAgentStart(0);
+ var mr = new SpiceMiniData();
+ mr.build_msg(SPICE_MSGC_MAIN_AGENT_START, agent_start);
+ this.send_msg(mr);
+
+ if (this.onagent !== undefined)
+ this.onagent(this);
+
+}
+
+SpiceMainConn.prototype.handle_mouse_mode = function(current, supported)
+{
+ this.mouse_mode = current;
+ if (current != SPICE_MOUSE_MODE_CLIENT && (supported &
SPICE_MOUSE_MODE_CLIENT))
+ {
+ var mode_request = new SpiceMsgcMainMouseModeRequest(SPICE_MOUSE_MODE_CLIENT);
+ var mr = new SpiceMiniData();
+ mr.build_msg(SPICE_MSGC_MAIN_MOUSE_MODE_REQUEST, mode_request);
+ this.send_msg(mr);
+ }
+
+ if (this.inputs)
+ this.inputs.mouse_mode = current;
+}
+
diff --git a/src/wok/plugins/kimchi/ui/spice-html5/pages/Makefile.am
b/src/wok/plugins/kimchi/ui/spice-html5/pages/Makefile.am
new file mode 100644
index 0000000..431ec6c
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/spice-html5/pages/Makefile.am
@@ -0,0 +1,20 @@
+#
+# Kimchi
+#
+# Copyright IBM, Corp. 2014
+#
+# 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.
+
+spicepagesdir = $(datadir)/wok/plugins/kimchi/ui/spice-html5/pages
+
+dist_spicepages_DATA = $(wildcard *.html) $(NULL)
diff --git a/src/wok/plugins/kimchi/ui/spice-html5/pages/spice_auto.html
b/src/wok/plugins/kimchi/ui/spice-html5/pages/spice_auto.html
new file mode 100644
index 0000000..c87f5c2
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/spice-html5/pages/spice_auto.html
@@ -0,0 +1,200 @@
+<!--
+ Copyright (C) 2012 by Jeremy P. White <jwhite(a)codeweavers.com>
+
+ This file is part of spice-html5.
+
+ spice-html5 is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ spice-html5 is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with spice-html5. If not, see <
http://www.gnu.org/licenses/>.
+
+ --------------------------------------------------
+ Spice Javascript client template.
+ Refer to main.js for more detailed information
+ --------------------------------------------------
+
+-->
+
+<!doctype html>
+<html>
+ <head>
+
+ <!--
+ The below sources were updated according to Kimchi configuration
+ to get the Javascript and CSS files from the installed spice-html5
+ package.
+ Kimchi is not using the default spice_auto.html because Kimchi uses
+ wss:// for all connections and it is only supported by recent
+ versions of spice-html5.
+ In addition to it, Kimchi points user to the right token on URL
+ (check line 146 of this file).
+ -->
+ <title>Spice Javascript client</title>
+ <script src="spice-html5/spicearraybuffer.js"></script>
+ <script src="spice-html5/enums.js"></script>
+ <script src="spice-html5/atKeynames.js"></script>
+ <script src="spice-html5/utils.js"></script>
+ <script src="spice-html5/png.js"></script>
+ <script src="spice-html5/lz.js"></script>
+ <script src="spice-html5/quic.js"></script>
+ <script src="spice-html5/bitmap.js"></script>
+ <script src="spice-html5/spicedataview.js"></script>
+ <script src="spice-html5/spicetype.js"></script>
+ <script src="spice-html5/spicemsg.js"></script>
+ <script src="spice-html5/wire.js"></script>
+ <script src="spice-html5/spiceconn.js"></script>
+ <script src="spice-html5/display.js"></script>
+ <script src="spice-html5/main.js"></script>
+ <script src="spice-html5/inputs.js"></script>
+ <script src="spice-html5/webm.js"></script>
+ <script src="spice-html5/playback.js"></script>
+ <script src="spice-html5/simulatecursor.js"></script>
+ <script src="spice-html5/cursor.js"></script>
+ <script src="spice-html5/thirdparty/jsbn.js"></script>
+ <script src="spice-html5/thirdparty/rsa.js"></script>
+ <script src="spice-html5/thirdparty/prng4.js"></script>
+ <script src="spice-html5/thirdparty/rng.js"></script>
+ <script src="spice-html5/thirdparty/sha1.js"></script>
+ <script src="spice-html5/ticket.js"></script>
+ <script src="spice-html5/resize.js"></script>
+ <link rel="stylesheet" type="text/css"
href="spice-html5/spice.css" />
+
+ <script>
+ var host = null, port = null;
+ var sc;
+
+ function spice_set_cookie(name, value, days) {
+ var date, expires;
+ date = new Date();
+ date.setTime(date.getTime() + (days*24*60*60*1000));
+ expires = "; expires=" + date.toGMTString();
+ document.cookie = name + "=" + value + expires + ";
path=/";
+ };
+
+ function spice_query_var(name, defvalue) {
+ var match = RegExp('[?&]' + name + '=([^&]*)')
+ .exec(window.location.search);
+ return match ?
+ decodeURIComponent(match[1].replace(/\+/g, ' '))
+ : defvalue;
+ }
+
+ function spice_error(e)
+ {
+ disconnect();
+ }
+
+ function connect()
+ {
+ var host, port, password, scheme = "ws://", uri;
+
+ // By default, use the host and port of server that served this file
+ host = spice_query_var('host', window.location.hostname);
+
+ // Note that using the web server port only makes sense
+ // if your web server has a reverse proxy to relay the WebSocket
+ // traffic to the correct destination port.
+ var default_port = window.location.port;
+ if (!default_port) {
+ if (window.location.protocol == 'http:') {
+ default_port = 80;
+ }
+ else if (window.location.protocol == 'https:') {
+ default_port = 443;
+ }
+ }
+ port = spice_query_var('port', default_port);
+ if (window.location.protocol == 'https:') {
+ scheme = "wss://";
+ }
+
+ // If a token variable is passed in, set the parameter in a cookie.
+ // This is used by nova-spiceproxy.
+ token = spice_query_var('token', null);
+ if (token) {
+ spice_set_cookie('token', token, 1)
+ }
+
+ password = spice_query_var('password', '');
+ path = spice_query_var('path', 'websockify');
+
+ if ((!host) || (!port)) {
+ console.log("must specify host and port in URL");
+ return;
+ }
+
+ if (sc) {
+ sc.stop();
+ }
+
+ /*
+ * The following line was modified from the original one:
+ *
+ * 'uri = scheme + host + ":" + port;'
+ *
+ * to point wok.user to a specific console represented by
+ * token value.
+ */
+ uri = scheme + host + ":" + port + "/?token=" +
token;
+
+ try
+ {
+ sc = new SpiceMainConn({uri: uri, screen_id:
"spice-screen", dump_id: "debug-div",
+ message_id: "message-div", password: password,
onerror: spice_error, onagent: agent_connected });
+ }
+ catch (e)
+ {
+ alert(e.toString());
+ disconnect();
+ }
+
+ }
+
+ function disconnect()
+ {
+ console.log(">> disconnect");
+ if (sc) {
+ sc.stop();
+ }
+ console.log("<< disconnect");
+ }
+
+ function agent_connected(sc)
+ {
+ window.addEventListener('resize', handle_resize);
+ window.spice_connection = this;
+
+ resize_helper(this);
+ }
+
+ connect();
+ </script>
+
+ </head>
+
+ <body>
+
+ <div id="login">
+ <span class="logo">SPICE</span>
+ </div>
+
+ <div id="spice-area">
+ <div id="spice-screen"
class="spice-screen"></div>
+ </div>
+
+ <div id="message-div"
class="spice-message"></div>
+
+ <div id="debug-div">
+ <!-- If DUMPXXX is turned on, dumped images will go here -->
+ </div>
+
+ </body>
+</html>
diff --git a/src/wok/plugins/kimchi/ui/spice-html5/playback.js
b/src/wok/plugins/kimchi/ui/spice-html5/playback.js
new file mode 100644
index 0000000..7209fbe
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/spice-html5/playback.js
@@ -0,0 +1,278 @@
+"use strict";
+/*
+ Copyright (C) 2014 by Jeremy P. White <jwhite(a)codeweavers.com>
+
+ This file is part of spice-html5.
+
+ spice-html5 is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ spice-html5 is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with spice-html5. If not, see <
http://www.gnu.org/licenses/>.
+*/
+
+/*----------------------------------------------------------------------------
+** SpicePlaybackConn
+** Drive the Spice Playback channel (sound out)
+**--------------------------------------------------------------------------*/
+function SpicePlaybackConn()
+{
+ SpiceConn.apply(this, arguments);
+
+ this.queue = new Array();
+ this.append_okay = false;
+ this.start_time = 0;
+ this.skip_until = 0;
+ this.gap_time = 0;
+}
+
+SpicePlaybackConn.prototype = Object.create(SpiceConn.prototype);
+SpicePlaybackConn.prototype.process_channel_message = function(msg)
+{
+ if (!!!window.MediaSource)
+ {
+ this.log_err('MediaSource API is not available');
+ return false;
+ }
+
+ if (msg.type == SPICE_MSG_PLAYBACK_START)
+ {
+ var start = new SpiceMsgPlaybackStart(msg.data);
+
+ DEBUG > 0 && console.log("PlaybackStart; frequency " +
start.frequency);
+
+ if (start.frequency != OPUS_FREQUENCY)
+ {
+ this.log_err('This player cannot handle frequency ' +
start.frequency);
+ return false;
+ }
+
+ if (start.channels != OPUS_CHANNELS)
+ {
+ this.log_err('This player cannot handle ' + start.channels + '
channels');
+ return false;
+ }
+
+ if (start.format != SPICE_AUDIO_FMT_S16)
+ {
+ this.log_err('This player cannot format ' + start.format);
+ return false;
+ }
+
+ if (! this.source_buffer)
+ {
+ this.media_source = new MediaSource();
+ this.media_source.spiceconn = this;
+
+ this.audio = document.createElement("audio");
+ this.audio.setAttribute('autoplay', true);
+ this.audio.src = window.URL.createObjectURL(this.media_source);
+ document.getElementById(this.parent.screen_id).appendChild(this.audio);
+
+ this.media_source.addEventListener('sourceopen', handle_source_open,
false);
+ this.media_source.addEventListener('sourceended',
handle_source_ended, false);
+ this.media_source.addEventListener('sourceclosed',
handle_source_closed, false);
+
+ this.bytes_written = 0;
+
+ return true;
+ }
+ }
+
+ if (msg.type == SPICE_MSG_PLAYBACK_DATA)
+ {
+ var data = new SpiceMsgPlaybackData(msg.data);
+
+ // If this packet has the same time as the last, just bump up by one.
+ if (this.last_data_time && data.time <= this.last_data_time)
+ {
+ // FIXME - this is arguably wrong. But delaying the transmission was worse,
+ // in initial testing. Could use more research.
+ DEBUG > 1 && console.log("Hacking time of " + data.time
+ " to " + this.last_data_time + 1);
+ data.time = this.last_data_time + 1;
+ }
+
+ /* Gap detection: If there has been a delay since our last packet, then audio
must
+ have paused. Handling that gets tricky. In Chrome, you can seek forward,
+ but you cannot in Firefox. And seeking forward in Chrome is nice, as it
keeps
+ Chrome from being overly cautious in it's buffer strategy.
+
+ So we do two things. First, we seek forward. Second, we compute how much
of a gap
+ there would have been, and essentially eliminate it.
+ */
+ if (this.last_data_time && data.time >= (this.last_data_time +
GAP_DETECTION_THRESHOLD))
+ {
+ this.skip_until = data.time;
+ this.gap_time = (data.time - this.start_time) -
+ (this.source_buffer.buffered.end(this.source_buffer.buffered.end.length -
1) * 1000.0).toFixed(0);
+ }
+
+ this.last_data_time = data.time;
+
+
+ DEBUG > 1 && console.log("PlaybackData; time " + data.time +
"; length " + data.data.byteLength);
+
+ if (! this.source_buffer)
+ return true;
+
+ if (this.start_time == 0)
+ this.start_playback(data);
+
+ else if (data.time - this.cluster_time >= MAX_CLUSTER_TIME || this.skip_until
> 0)
+ this.new_cluster(data);
+
+ else
+ this.simple_block(data, false);
+
+ if (this.skip_until > 0)
+ {
+ this.audio.currentTime = (this.skip_until - this.start_time - this.gap_time)
/ 1000.0;
+ this.skip_until = 0;
+ }
+
+ if (this.audio.paused)
+ this.audio.play();
+
+ return true;
+ }
+
+ if (msg.type == SPICE_MSG_PLAYBACK_MODE)
+ {
+ var mode = new SpiceMsgPlaybackMode(msg.data);
+ if (mode.mode != SPICE_AUDIO_DATA_MODE_OPUS)
+ {
+ this.log_err('This player cannot handle mode ' + mode.mode);
+ delete this.source_buffer;
+ }
+ return true;
+ }
+
+ if (msg.type == SPICE_MSG_PLAYBACK_STOP)
+ {
+ return true;
+ }
+
+ return false;
+}
+
+SpicePlaybackConn.prototype.start_playback = function(data)
+{
+ this.start_time = data.time;
+
+ var h = new webm_Header();
+
+ var mb = new ArrayBuffer(h.buffer_size())
+
+ this.bytes_written = h.to_buffer(mb);
+
+ this.source_buffer.addEventListener('error', handle_sourcebuffer_error,
false);
+ this.source_buffer.addEventListener('updateend', handle_append_buffer_done,
false);
+ playback_append_buffer(this, mb);
+
+ this.new_cluster(data);
+}
+
+SpicePlaybackConn.prototype.new_cluster = function(data)
+{
+ this.cluster_time = data.time;
+
+ var c = new webm_Cluster(data.time - this.start_time - this.gap_time);
+
+ var mb = new ArrayBuffer(c.buffer_size());
+ this.bytes_written += c.to_buffer(mb);
+
+ if (this.append_okay)
+ playback_append_buffer(this, mb);
+ else
+ this.queue.push(mb);
+
+ this.simple_block(data, true);
+}
+
+SpicePlaybackConn.prototype.simple_block = function(data, keyframe)
+{
+ var sb = new webm_SimpleBlock(data.time - this.cluster_time, data.data, keyframe);
+ var mb = new ArrayBuffer(sb.buffer_size());
+
+ this.bytes_written += sb.to_buffer(mb);
+
+ if (this.append_okay)
+ playback_append_buffer(this, mb);
+ else
+ this.queue.push(mb);
+}
+
+function handle_source_open(e)
+{
+ var p = this.spiceconn;
+
+ if (p.source_buffer)
+ return;
+
+ p.source_buffer = this.addSourceBuffer(SPICE_PLAYBACK_CODEC);
+ if (! p.source_buffer)
+ {
+ p.log_err('Codec ' + SPICE_PLAYBACK_CODEC + ' not available.');
+ return;
+ }
+ p.source_buffer.spiceconn = p;
+ p.source_buffer.mode = "segments";
+
+ // FIXME - Experimentation with segments and sequences was unsatisfying.
+ // Switching to sequence did not solve our gap problem,
+ // but the browsers didn't fully support the time seek capability
+ // we would expect to gain from 'segments'.
+ // Segments worked at the time of this patch, so segments it is for now.
+
+}
+
+function handle_source_ended(e)
+{
+ var p = this.spiceconn;
+ p.log_err('Audio source unexpectedly ended.');
+}
+
+function handle_source_closed(e)
+{
+ var p = this.spiceconn;
+ p.log_err('Audio source unexpectedly closed.');
+}
+
+function handle_append_buffer_done(b)
+{
+ var p = this.spiceconn;
+ if (p.queue.length > 0)
+ {
+ var mb = p.queue.shift();
+ playback_append_buffer(p, mb);
+ }
+ else
+ p.append_okay = true;
+
+}
+
+function handle_sourcebuffer_error(e)
+{
+ var p = this.spiceconn;
+ p.log_err('source_buffer error ' + e.message);
+}
+
+function playback_append_buffer(p, b)
+{
+ try
+ {
+ p.source_buffer.appendBuffer(b);
+ p.append_okay = false;
+ }
+ catch (e)
+ {
+ p.log_err("Error invoking appendBuffer: " + e.message);
+ }
+}
diff --git a/src/wok/plugins/kimchi/ui/spice-html5/png.js
b/src/wok/plugins/kimchi/ui/spice-html5/png.js
new file mode 100644
index 0000000..6a26151
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/spice-html5/png.js
@@ -0,0 +1,256 @@
+"use strict";
+/*
+ Copyright (C) 2012 by Jeremy P. White <jwhite(a)codeweavers.com>
+
+ This file is part of spice-html5.
+
+ spice-html5 is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ spice-html5 is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with spice-html5. If not, see <
http://www.gnu.org/licenses/>.
+*/
+
+/*----------------------------------------------------------------------------
+** crc logic from rfc2083 ported to Javascript
+**--------------------------------------------------------------------------*/
+
+var rfc2083_crc_table = Array(256);
+var rfc2083_crc_table_computed = 0;
+/* Make the table for a fast CRC. */
+function rfc2083_make_crc_table()
+{
+ var c;
+ var n, k;
+ for (n = 0; n < 256; n++)
+ {
+ c = n;
+ for (k = 0; k < 8; k++)
+ {
+ if (c & 1)
+ c = ((0xedb88320 ^ (c >>> 1)) >>> 0) & 0xffffffff;
+ else
+ c = c >>> 1;
+ }
+ rfc2083_crc_table[n] = c;
+ }
+
+ rfc2083_crc_table_computed = 1;
+}
+
+/* Update a running CRC with the bytes buf[0..len-1]--the CRC
+ should be initialized to all 1's, and the transmitted value
+ is the 1's complement of the final running CRC (see the
+ crc() routine below)). */
+
+function rfc2083_update_crc(crc, u8buf, at, len)
+{
+ var c = crc;
+ var n;
+
+ if (!rfc2083_crc_table_computed)
+ rfc2083_make_crc_table();
+
+ for (n = 0; n < len; n++)
+ {
+ c = rfc2083_crc_table[(c ^ u8buf[at + n]) & 0xff] ^ (c >>> 8);
+ }
+
+ return c;
+}
+
+function rfc2083_crc(u8buf, at, len)
+{
+ return rfc2083_update_crc(0xffffffff, u8buf, at, len) ^ 0xffffffff;
+}
+
+function crc32(mb, at, len)
+{
+ var u8 = new Uint8Array(mb);
+ return rfc2083_crc(u8, at, len);
+}
+
+function PngIHDR(width, height)
+{
+ this.width = width;
+ this.height = height;
+ this.depth = 8;
+ this.type = 6;
+ this.compression = 0;
+ this.filter = 0;
+ this.interlace = 0;
+}
+
+PngIHDR.prototype =
+{
+ to_buffer: function(a, at)
+ {
+ at = at || 0;
+ var orig = at;
+ var dv = new SpiceDataView(a);
+ dv.setUint32(at, this.buffer_size() - 12); at += 4;
+ dv.setUint8(at, 'I'.charCodeAt(0)); at++;
+ dv.setUint8(at, 'H'.charCodeAt(0)); at++;
+ dv.setUint8(at, 'D'.charCodeAt(0)); at++;
+ dv.setUint8(at, 'R'.charCodeAt(0)); at++;
+ dv.setUint32(at, this.width); at += 4;
+ dv.setUint32(at, this.height); at += 4;
+ dv.setUint8(at, this.depth); at++;
+ dv.setUint8(at, this.type); at++;
+ dv.setUint8(at, this.compression); at++;
+ dv.setUint8(at, this.filter); at++;
+ dv.setUint8(at, this.interlace); at++;
+ dv.setUint32(at, crc32(a, orig + 4, this.buffer_size() - 8)); at += 4;
+ return at;
+ },
+ buffer_size: function()
+ {
+ return 12 + 13;
+ }
+}
+
+
+function adler()
+{
+ this.s1 = 1;
+ this.s2 = 0;
+}
+
+adler.prototype.update = function(b)
+{
+ this.s1 += b;
+ this.s1 %= 65521;
+ this.s2 += this.s1;
+ this.s2 %= 65521;
+}
+
+function PngIDAT(width, height, bytes)
+{
+ if (bytes.byteLength > 65535)
+ {
+ throw new Error("Cannot handle more than 64K");
+ }
+ this.data = bytes;
+ this.width = width;
+ this.height = height;
+}
+
+PngIDAT.prototype =
+{
+ to_buffer: function(a, at)
+ {
+ at = at || 0;
+ var orig = at;
+ var x, y, i, j;
+ var dv = new SpiceDataView(a);
+ var zsum = new adler();
+ dv.setUint32(at, this.buffer_size() - 12); at += 4;
+ dv.setUint8(at, 'I'.charCodeAt(0)); at++;
+ dv.setUint8(at, 'D'.charCodeAt(0)); at++;
+ dv.setUint8(at, 'A'.charCodeAt(0)); at++;
+ dv.setUint8(at, 'T'.charCodeAt(0)); at++;
+
+ /* zlib header. */
+ dv.setUint8(at, 0x78); at++;
+ dv.setUint8(at, 0x01); at++;
+
+ /* Deflate header. Specifies uncompressed, final bit */
+ dv.setUint8(at, 0x80); at++;
+ dv.setUint16(at, this.data.byteLength + this.height); at += 2;
+ dv.setUint16(at, ~(this.data.byteLength + this.height)); at += 2;
+ var u8 = new Uint8Array(this.data);
+ for (i = 0, y = 0; y < this.height; y++)
+ {
+ /* Filter type 0 - uncompressed */
+ dv.setUint8(at, 0); at++;
+ zsum.update(0);
+ for (x = 0; x < this.width && i < this.data.byteLength; x++)
+ {
+ zsum.update(u8[i]);
+ dv.setUint8(at, u8[i++]); at++;
+ zsum.update(u8[i]);
+ dv.setUint8(at, u8[i++]); at++;
+ zsum.update(u8[i]);
+ dv.setUint8(at, u8[i++]); at++;
+ zsum.update(u8[i]);
+ dv.setUint8(at, u8[i++]); at++;
+ }
+ }
+
+ /* zlib checksum. */
+ dv.setUint16(at, zsum.s2); at+=2;
+ dv.setUint16(at, zsum.s1); at+=2;
+
+ /* FIXME - something is not quite right with the zlib code;
+ you get an error from libpng if you open the image in
+ gimp. But it works, so it's good enough for now... */
+
+ dv.setUint32(at, crc32(a, orig + 4, this.buffer_size() - 8)); at += 4;
+ return at;
+ },
+ buffer_size: function()
+ {
+ return 12 + this.data.byteLength + this.height + 4 + 2 + 1 + 2 + 2;
+ }
+}
+
+
+function PngIEND()
+{
+}
+
+PngIEND.prototype =
+{
+ to_buffer: function(a, at)
+ {
+ at = at || 0;
+ var orig = at;
+ var i;
+ var dv = new SpiceDataView(a);
+ dv.setUint32(at, this.buffer_size() - 12); at += 4;
+ dv.setUint8(at, 'I'.charCodeAt(0)); at++;
+ dv.setUint8(at, 'E'.charCodeAt(0)); at++;
+ dv.setUint8(at, 'N'.charCodeAt(0)); at++;
+ dv.setUint8(at, 'D'.charCodeAt(0)); at++;
+ dv.setUint32(at, crc32(a, orig + 4, this.buffer_size() - 8)); at += 4;
+ return at;
+ },
+ buffer_size: function()
+ {
+ return 12;
+ }
+}
+
+
+function create_rgba_png(width, height, bytes)
+{
+ var i;
+ var ihdr = new PngIHDR(width, height);
+ var idat = new PngIDAT(width, height, bytes);
+ var iend = new PngIEND;
+
+ var mb = new ArrayBuffer(ihdr.buffer_size() + idat.buffer_size() +
iend.buffer_size());
+ var at = ihdr.to_buffer(mb);
+ at = idat.to_buffer(mb, at);
+ at = iend.to_buffer(mb, at);
+
+ var u8 = new Uint8Array(mb);
+ var str = "";
+ for (i = 0; i < at; i++)
+ {
+ str += "%";
+ if (u8[i] < 16)
+ str += "0";
+ str += u8[i].toString(16);
+ }
+
+
+ return "%89PNG%0D%0A%1A%0A" + str;
+}
diff --git a/src/wok/plugins/kimchi/ui/spice-html5/quic.js
b/src/wok/plugins/kimchi/ui/spice-html5/quic.js
new file mode 100644
index 0000000..9bb9f47
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/spice-html5/quic.js
@@ -0,0 +1,1335 @@
+/*"use strict";*/
+/* use strict is commented out because it results in a 5x slowdone in chrome */
+/*
+ * Copyright (C) 2012 by Jeremy P. White <jwhite(a)codeweavers.com>
+ * Copyright (C) 2012 by Aric Stewart <aric(a)codeweavers.com>
+ *
+ * This file is part of spice-html5.
+ *
+ * spice-html5 is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * spice-html5 is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with spice-html5. If not, see <
http://www.gnu.org/licenses/>.
+ */
+
+var encoder;
+
+var QUIC_IMAGE_TYPE_INVALID = 0;
+var QUIC_IMAGE_TYPE_GRAY = 1;
+var QUIC_IMAGE_TYPE_RGB16 = 2;
+var QUIC_IMAGE_TYPE_RGB24 = 3;
+var QUIC_IMAGE_TYPE_RGB32 = 4;
+var QUIC_IMAGE_TYPE_RGBA = 5;
+var DEFevol = 3;
+var DEFwmimax = 6;
+var DEFwminext = 2048;
+var need_init = true;
+var DEFmaxclen = 26;
+var evol = DEFevol;
+var wmimax = DEFwmimax;
+var wminext = DEFwminext;
+var family_5bpc = { nGRcodewords:[0,0,0,0,0,0,0,0],
+ notGRcwlen:[0,0,0,0,0,0,0,0],
+ notGRprefixmask:[0,0,0,0,0,0,0,0],
+ notGRsuffixlen:[0,0,0,0,0,0,0,0],
+ xlatU2L:[0,0,0,0,0,0,0,0],
+ xlatL2U:[0,0,0,0,0,0,0,0]
+ };
+var family_8bpc = { nGRcodewords:[0,0,0,0,0,0,0,0],
+ notGRcwlen:[0,0,0,0,0,0,0,0],
+ notGRprefixmask:[0,0,0,0,0,0,0,0],
+ notGRsuffixlen:[0,0,0,0,0,0,0,0],
+ xlatU2L:[0,0,0,0,0,0,0,0],
+ xlatL2U:[0,0,0,0,0,0,0,0]
+ };
+var bppmask = [ 0x00000000,
+ 0x00000001, 0x00000003, 0x00000007, 0x0000000f,
+ 0x0000001f, 0x0000003f, 0x0000007f, 0x000000ff,
+ 0x000001ff, 0x000003ff, 0x000007ff, 0x00000fff,
+ 0x00001fff, 0x00003fff, 0x00007fff, 0x0000ffff,
+ 0x0001ffff, 0x0003ffff, 0x0007ffff, 0x000fffff,
+ 0x001fffff, 0x003fffff, 0x007fffff, 0x00ffffff,
+ 0x01ffffff, 0x03ffffff, 0x07ffffff, 0x0fffffff,
+ 0x1fffffff, 0x3fffffff, 0x7fffffff, 0xffffffff];
+
+var zeroLUT = [];
+
+var besttrigtab = [
+ [ 550, 900, 800, 700, 500, 350, 300, 200, 180, 180, 160],
+ [ 110, 550, 900, 800, 550, 400, 350, 250, 140, 160, 140],
+ [ 100, 120, 550, 900, 700, 500, 400, 300, 220, 250, 160]];
+
+var J = [ 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 5, 5, 6, 6,
+ 7, 7, 8, 9, 10, 11, 12, 13, 14, 15];
+
+var lzeroes = [
+ 8, 7, 6, 6, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0];
+
+var tabrand_chaos = [
+ 0x02c57542, 0x35427717, 0x2f5a2153, 0x9244f155, 0x7bd26d07, 0x354c6052,
+ 0x57329b28, 0x2993868e, 0x6cd8808c, 0x147b46e0, 0x99db66af, 0xe32b4cac,
+ 0x1b671264, 0x9d433486, 0x62a4c192, 0x06089a4b, 0x9e3dce44, 0xdaabee13,
+ 0x222425ea, 0xa46f331d, 0xcd589250, 0x8bb81d7f, 0xc8b736b9, 0x35948d33,
+ 0xd7ac7fd0, 0x5fbe2803, 0x2cfbc105, 0x013dbc4e, 0x7a37820f, 0x39f88e9e,
+ 0xedd58794, 0xc5076689, 0xfcada5a4, 0x64c2f46d, 0xb3ba3243, 0x8974b4f9,
+ 0x5a05aebd, 0x20afcd00, 0x39e2b008, 0x88a18a45, 0x600bde29, 0xf3971ace,
+ 0xf37b0a6b, 0x7041495b, 0x70b707ab, 0x06beffbb, 0x4206051f, 0xe13c4ee3,
+ 0xc1a78327, 0x91aa067c, 0x8295f72a, 0x732917a6, 0x1d871b4d, 0x4048f136,
+ 0xf1840e7e, 0x6a6048c1, 0x696cb71a, 0x7ff501c3, 0x0fc6310b, 0x57e0f83d,
+ 0x8cc26e74, 0x11a525a2, 0x946934c7, 0x7cd888f0, 0x8f9d8604, 0x4f86e73b,
+ 0x04520316, 0xdeeea20c, 0xf1def496, 0x67687288, 0xf540c5b2, 0x22401484,
+ 0x3478658a, 0xc2385746, 0x01979c2c, 0x5dad73c8, 0x0321f58b, 0xf0fedbee,
+ 0x92826ddf, 0x284bec73, 0x5b1a1975, 0x03df1e11, 0x20963e01, 0xa17cf12b,
+ 0x740d776e, 0xa7a6bf3c, 0x01b5cce4, 0x1118aa76, 0xfc6fac0a, 0xce927e9b,
+ 0x00bf2567, 0x806f216c, 0xbca69056, 0x795bd3e9, 0xc9dc4557, 0x8929b6c2,
+ 0x789d52ec, 0x3f3fbf40, 0xb9197368, 0xa38c15b5, 0xc3b44fa8, 0xca8333b0,
+ 0xb7e8d590, 0xbe807feb, 0xbf5f8360, 0xd99e2f5c, 0x372928e1, 0x7c757c4c,
+ 0x0db5b154, 0xc01ede02, 0x1fc86e78, 0x1f3985be, 0xb4805c77, 0x00c880fa,
+ 0x974c1b12, 0x35ab0214, 0xb2dc840d, 0x5b00ae37, 0xd313b026, 0xb260969d,
+ 0x7f4c8879, 0x1734c4d3, 0x49068631, 0xb9f6a021, 0x6b863e6f, 0xcee5debf,
+ 0x29f8c9fb, 0x53dd6880, 0x72b61223, 0x1f67a9fd, 0x0a0f6993, 0x13e59119,
+ 0x11cca12e, 0xfe6b6766, 0x16b6effc, 0x97918fc4, 0xc2b8a563, 0x94f2f741,
+ 0x0bfa8c9a, 0xd1537ae8, 0xc1da349c, 0x873c60ca, 0x95005b85, 0x9b5c080e,
+ 0xbc8abbd9, 0xe1eab1d2, 0x6dac9070, 0x4ea9ebf1, 0xe0cf30d4, 0x1ef5bd7b,
+ 0xd161043e, 0x5d2fa2e2, 0xff5d3cae, 0x86ed9f87, 0x2aa1daa1, 0xbd731a34,
+ 0x9e8f4b22, 0xb1c2c67a, 0xc21758c9, 0xa182215d, 0xccb01948, 0x8d168df7,
+ 0x04238cfe, 0x368c3dbc, 0x0aeadca5, 0xbad21c24, 0x0a71fee5, 0x9fc5d872,
+ 0x54c152c6, 0xfc329483, 0x6783384a, 0xeddb3e1c, 0x65f90e30, 0x884ad098,
+ 0xce81675a, 0x4b372f7d, 0x68bf9a39, 0x43445f1e, 0x40f8d8cb, 0x90d5acb6,
+ 0x4cd07282, 0x349eeb06, 0x0c9d5332, 0x520b24ef, 0x80020447, 0x67976491,
+ 0x2f931ca3, 0xfe9b0535, 0xfcd30220, 0x61a9e6cc, 0xa487d8d7, 0x3f7c5dd1,
+ 0x7d0127c5, 0x48f51d15, 0x60dea871, 0xc9a91cb7, 0x58b53bb3, 0x9d5e0b2d,
+ 0x624a78b4, 0x30dbee1b, 0x9bdf22e7, 0x1df5c299, 0x2d5643a7, 0xf4dd35ff,
+ 0x03ca8fd6, 0x53b47ed8, 0x6f2c19aa, 0xfeb0c1f4, 0x49e54438, 0x2f2577e6,
+ 0xbf876969, 0x72440ea9, 0xfa0bafb8, 0x74f5b3a0, 0x7dd357cd, 0x89ce1358,
+ 0x6ef2cdda, 0x1e7767f3, 0xa6be9fdb, 0x4f5f88f8, 0xba994a3a, 0x08ca6b65,
+ 0xe0893818, 0x9e00a16a, 0xf42bfc8f, 0x9972eedc, 0x749c8b51, 0x32c05f5e,
+ 0xd706805f, 0x6bfbb7cf, 0xd9210a10, 0x31a1db97, 0x923a9559, 0x37a7a1f6,
+ 0x059f8861, 0xca493e62, 0x65157e81, 0x8f6467dd, 0xab85ff9f, 0x9331aff2,
+ 0x8616b9f5, 0xedbd5695, 0xee7e29b1, 0x313ac44f, 0xb903112f, 0x432ef649,
+ 0xdc0a36c0, 0x61cf2bba, 0x81474925, 0xa8b6c7ad, 0xee5931de, 0xb2f8158d,
+ 0x59fb7409, 0x2e3dfaed, 0x9af25a3f, 0xe1fed4d5 ];
+
+var rgb32_pixel_pad = 3;
+var rgb32_pixel_r = 2;
+var rgb32_pixel_g = 1;
+var rgb32_pixel_b = 0;
+var rgb32_pixel_size = 4;
+
+/* Helper Functions */
+
+function ceil_log_2(val)
+{
+ if (val === 1)
+ return 0;
+
+ var result = 1;
+ val -= 1;
+ while (val = val >>> 1)
+ result++;
+
+ return result;
+}
+
+function family_init(family, bpc, limit)
+{
+ var l;
+ for (l = 0; l < bpc; l++)
+ {
+ var altprefixlen, altcodewords;
+ altprefixlen = limit - bpc;
+ if (altprefixlen > bppmask[bpc - l])
+ altprefixlen = bppmask[bpc - l];
+
+ altcodewords = bppmask[bpc] + 1 - (altprefixlen << l);
+ family.nGRcodewords[l] = (altprefixlen << l);
+ family.notGRcwlen[l] = altprefixlen + ceil_log_2(altcodewords);
+ family.notGRprefixmask[l] = bppmask[32 - altprefixlen]>>>0;
+ family.notGRsuffixlen[l] = ceil_log_2(altcodewords);
+ }
+
+ /* decorelate_init */
+ var pixelbitmask = bppmask[bpc];
+ var pixelbitmaskshr = pixelbitmask >>> 1;
+ var s;
+ for (s = 0; s <= pixelbitmask; s++) {
+ if (s <= pixelbitmaskshr) {
+ family.xlatU2L[s] = s << 1;
+ } else {
+ family.xlatU2L[s] = ((pixelbitmask - s) << 1) + 1;
+ }
+ }
+
+ /* corelate_init */
+ for (s = 0; s <= pixelbitmask; s++) {
+ if (s & 0x01) {
+ family.xlatL2U[s] = pixelbitmask - (s >>> 1);
+ } else {
+ family.xlatL2U[s] = (s >>> 1);
+ }
+ }
+}
+
+function quic_image_bpc(type)
+{
+ switch (type) {
+ case QUIC_IMAGE_TYPE_GRAY:
+ return 8;
+ case QUIC_IMAGE_TYPE_RGB16:
+ return 5;
+ case QUIC_IMAGE_TYPE_RGB24:
+ return 8;
+ case QUIC_IMAGE_TYPE_RGB32:
+ return 8;
+ case QUIC_IMAGE_TYPE_RGBA:
+ return 8;
+ case QUIC_IMAGE_TYPE_INVALID:
+ default:
+ console.log("quic: bad image type\n");
+ return 0;
+ }
+}
+
+function cnt_l_zeroes(bits)
+{
+ if (bits & 0xff800000) {
+ return lzeroes[bits >>> 24];
+ } else if (bits & 0xffff8000) {
+ return 8 + lzeroes[(bits >>> 16) & 0x000000ff];
+ } else if (bits & 0xffffff80) {
+ return 16 + lzeroes[(bits >>> 8) & 0x000000ff];
+ } else {
+ return 24 + lzeroes[bits & 0x000000ff];
+ }
+}
+
+function golomb_decoding_8bpc(l, bits)
+{
+ var rc;
+ var cwlen;
+
+ if (bits < 0 || bits > family_8bpc.notGRprefixmask[l])
+ {
+ var zeroprefix = cnt_l_zeroes(bits);
+ cwlen = zeroprefix + 1 + l;
+ rc = (zeroprefix << l) | (bits >> (32-cwlen)) & bppmask[l];
+ }
+ else
+ {
+ cwlen = family_8bpc.notGRcwlen[l];
+ rc = family_8bpc.nGRcodewords[l] + ((bits >> (32-cwlen)) &
bppmask[family_8bpc.notGRsuffixlen[l]]);
+ }
+ return {'codewordlen':cwlen, 'rc':rc};
+}
+
+function golomb_code_len_8bpc(n, l)
+{
+ if (n < family_8bpc.nGRcodewords[l]) {
+ return (n >>> l) + 1 + l;
+ } else {
+ return family_8bpc.notGRcwlen[l];
+ }
+}
+
+function QuicModel(bpc)
+{
+ var bstart;
+ var bend = 0;
+
+ this.levels = 0x1 << bpc;
+ this.n_buckets_ptrs = 0;
+
+ switch (evol) {
+ case 1:
+ this.repfirst = 3;
+ this.firstsize = 1;
+ this.repnext = 2;
+ this.mulsize = 2;
+ break;
+ case 3:
+ this.repfirst = 1;
+ this.firstsize = 1;
+ this.repnext = 1;
+ this.mulsize = 2;
+ break;
+ case 5:
+ this.repfirst = 1;
+ this.firstsize = 1;
+ this.repnext = 1;
+ this.mulsize = 4;
+ break;
+ case 0:
+ case 2:
+ case 4:
+ console.log("quic: findmodelparams(): evol value obsolete!!!\n");
+ default:
+ console.log("quic: findmodelparams(): evol out of range!!!\n");
+ }
+
+ this.n_buckets = 0;
+ var repcntr = this.repfirst + 1;
+ var bsize = this.firstsize;
+
+ do {
+ if (this.n_buckets) {
+ bstart = bend + 1;
+ } else {
+ bstart = 0;
+ }
+
+ if (!--repcntr) {
+ repcntr = this.repnext;
+ bsize *= this.mulsize;
+ }
+
+ bend = bstart + bsize - 1;
+ if (bend + bsize >= this.levels) {
+ bend = this.levels - 1;
+ }
+
+ if (!this.n_buckets_ptrs) {
+ this.n_buckets_ptrs = this.levels;
+ }
+
+ (this.n_buckets)++;
+ } while (bend < this.levels - 1);
+}
+
+QuicModel.prototype = {
+ n_buckets : 0,
+ n_buckets_ptrs : 0,
+ repfirst : 0,
+ firstsize : 0,
+ repnext : 0,
+ mulsize : 0,
+ levels :0
+}
+
+function QuicBucket()
+{
+ this.counters = [0,0,0,0,0,0,0,0];
+}
+
+QuicBucket.prototype = {
+ bestcode: 0,
+
+ reste : function (bpp)
+ {
+ this.bestcode = bpp;
+ this.counters = [0,0,0,0,0,0,0,0];
+ },
+
+ update_model_8bpc : function (state, curval, bpp)
+ {
+ var i;
+
+ var bestcode = bpp - 1;
+ var bestcodelen = (this.counters[bestcode] += golomb_code_len_8bpc(curval,
bestcode));
+
+ for (i = bpp - 2; i >= 0; i--) {
+ var ithcodelen = (this.counters[i] += golomb_code_len_8bpc(curval, i));
+
+ if (ithcodelen < bestcodelen) {
+ bestcode = i;
+ bestcodelen = ithcodelen;
+ }
+ }
+
+ this.bestcode = bestcode;
+
+ if (bestcodelen > state.wm_trigger) {
+ for (i = 0; i < bpp; i++) {
+ this.counters[i] = this.counters[i] >>> 1;
+ }
+ }
+ }
+}
+
+function QuicFamilyStat()
+{
+ this.buckets_ptrs = [];
+ this.buckets_buf = [];
+}
+
+QuicFamilyStat.prototype = {
+
+ fill_model_structures : function(model)
+ {
+ var bstart;
+ var bend = 0;
+ var bnumber = 0;
+
+ var repcntr = model.repfirst + 1;
+ var bsize = model.firstsize;
+
+ do {
+ if (bnumber) {
+ bstart = bend + 1;
+ } else {
+ bstart = 0;
+ }
+
+ if (!--repcntr) {
+ repcntr = model.repnext;
+ bsize *= model.mulsize;
+ }
+
+ bend = bstart + bsize - 1;
+ if (bend + bsize >= model.levels) {
+ bend = model.levels - 1;
+ }
+
+ this.buckets_buf[bnumber] = new QuicBucket;
+
+ var i;
+ for (i = bstart; i <= bend; i++) {
+ this.buckets_ptrs[i] = this.buckets_buf[bnumber];
+ }
+
+ bnumber++;
+ } while (bend < model.levels - 1);
+ return true;
+ }
+}
+
+function QuicChannel(model_8bpc, model_5bpc)
+{
+ this.state = new CommonState;
+ this.family_stat_8bpc = new QuicFamilyStat;
+ this.family_stat_5bpc = new QuicFamilyStat;
+ this.correlate_row = { zero: 0 , row:[] };
+ this.model_8bpc = model_8bpc;
+ this.model_5bpc = model_5bpc;
+ this.buckets_ptrs = [];
+
+ if (!this.family_stat_8bpc.fill_model_structures(this.model_8bpc))
+ return undefined;
+
+ if (!this.family_stat_5bpc.fill_model_structures(this.model_5bpc))
+ return undefined;
+}
+
+QuicChannel.prototype = {
+
+ reste : function (bpc)
+ {
+ var j;
+ this.correlate_row = { zero: 0 , row: []};
+
+ if (bpc == 8) {
+ for (j = 0; j < this.model_8bpc.n_buckets; j++)
+ this.family_stat_8bpc.buckets_buf[j].reste(7);
+ this.buckets_ptrs = this.family_stat_8bpc.buckets_ptrs;
+ } else if (bpc == 5) {
+ for (j = 0; j < this.model_5bpc.n_buckets; j++)
+ this.family_stat_8bpc.buckets_buf[j].reste(4);
+ this.buckets_ptrs = this.family_stat_5bpc.buckets_ptrs;
+ } else {
+ console.log("quic: %s: bad bpc %d\n", __FUNCTION__, bpc);
+ return false;
+ }
+
+ this.state.reste();
+ return true;
+ }
+}
+
+function CommonState()
+{
+}
+
+CommonState.prototype = {
+ waitcnt: 0,
+ tabrand_seed: 0xff,
+ wm_trigger: 0,
+ wmidx: 0,
+ wmileft: wminext,
+ melcstate: 0,
+ melclen: 0,
+ melcorder: 0,
+
+ set_wm_trigger : function()
+ {
+ var wm = this.wmidx;
+ if (wm > 10) {
+ wm = 10;
+ }
+
+ this.wm_trigger = besttrigtab[Math.floor(evol / 2)][wm];
+ },
+
+ reste : function()
+ {
+ this.waitcnt = 0;
+ this.tabrand_seed = 0x0ff;
+ this.wmidx = 0;
+ this.wmileft = wminext;
+
+ this.set_wm_trigger();
+
+ this.melcstate = 0;
+ this.melclen = J[0];
+ this.melcorder = 1 << this.melclen;
+ },
+
+ tabrand : function()
+ {
+ this.tabrand_seed++;
+ return tabrand_chaos[this.tabrand_seed & 0x0ff];
+ }
+}
+
+
+function QuicEncoder()
+{
+ this.rgb_state = new CommonState;
+ this.model_8bpc = new QuicModel(8);
+ this.model_5bpc = new QuicModel(5);
+ this.channels = [];
+
+ var i;
+ for (i = 0; i < 4; i++) {
+ this.channels[i] = new QuicChannel(this.model_8bpc, this.model_5bpc);
+ if (!this.channels[i])
+ {
+ console.log("quic: failed to create channel");
+ return undefined;
+ }
+ }
+}
+
+QuicEncoder.prototype = {
+ type: 0,
+ width: 0,
+ height: 0,
+ io_idx: 0,
+ io_available_bits: 0,
+ io_word: 0,
+ io_next_word: 0,
+ io_now: 0,
+ io_end: 0,
+ rows_completed: 0,
+ };
+
+QuicEncoder.prototype.reste = function(io_ptr)
+{
+ this.rgb_state.reste();
+
+ this.io_now = io_ptr;
+ this.io_end = this.io_now.length;
+ this.io_idx = 0;
+ this.rows_completed = 0;
+ return true;
+}
+
+QuicEncoder.prototype.read_io_word = function()
+{
+ if (this.io_idx >= this.io_end)
+ throw("quic: out of data");
+ this.io_next_word = this.io_now[this.io_idx++] | this.io_now[this.io_idx++]<<8
| this.io_now[this.io_idx++]<<16 | this.io_now[this.io_idx++]<<24;
+}
+
+QuicEncoder.prototype.decode_eatbits = function (len)
+{
+ this.io_word = this.io_word << len;
+
+ var delta = (this.io_available_bits - len);
+ if (delta >= 0)
+ {
+ this.io_available_bits = delta;
+ this.io_word |= this.io_next_word >>> this.io_available_bits;
+ }
+ else
+ {
+ delta = -1 * delta;
+ this.io_word |= this.io_next_word << delta;
+ this.read_io_word();
+ this.io_available_bits = 32 - delta;
+ this.io_word |= this.io_next_word >>> this.io_available_bits;
+ }
+}
+
+QuicEncoder.prototype.decode_eat32bits = function()
+{
+ this.decode_eatbits(16);
+ this.decode_eatbits(16);
+}
+
+QuicEncoder.prototype.reste_channels = function(bpc)
+{
+ var i;
+
+ for (i = 0; i < 4; i++)
+ if (!this.channels[i].reste(bpc))
+ return false;
+ return true;
+}
+
+QuicEncoder.prototype.quic_decode_begin = function(io_ptr)
+{
+ if (!this.reste(io_ptr)) {
+ return false;
+ }
+
+ this.io_idx = 0;
+ this.io_next_word = this.io_now[this.io_idx++] | this.io_now[this.io_idx++]<<8
| this.io_now[this.io_idx++]<<16 | this.io_now[this.io_idx++]<<24;
+ this.io_word = this.io_next_word;
+ this.io_available_bits = 0;
+
+ var magic = this.io_word;
+ this.decode_eat32bits();
+ if (magic != 0x43495551) /*QUIC*/ {
+ console.log("quic: bad magic "+magic.toString(16));
+ return false;
+ }
+
+ var version = this.io_word;
+ this.decode_eat32bits();
+ if (version != ((0 << 16) | (0 & 0xffff))) {
+ console.log("quic: bad version "+version.toString(16));
+ return false;
+ }
+
+ this.type = this.io_word;
+ this.decode_eat32bits();
+
+ this.width = this.io_word;
+ this.decode_eat32bits();
+
+ this.height = this.io_word;
+ this.decode_eat32bits();
+
+ var bpc = quic_image_bpc(this.type);
+
+ if (!this.reste_channels(bpc))
+ return false;
+
+ return true;
+}
+
+QuicEncoder.prototype.quic_rgb32_uncompress_row0_seg = function (i, cur_row, end,
+ waitmask, bpc, bpc_mask)
+{
+ var stopidx;
+ var n_channels = 3;
+ var c;
+ var a;
+
+ if (!i) {
+ cur_row[rgb32_pixel_pad] = 0;
+ c = 0;
+ do
+ {
+ a =
golomb_decoding_8bpc(this.channels[c].buckets_ptrs[this.channels[c].correlate_row.zero].bestcode,
this.io_word);
+ this.channels[c].correlate_row.row[0] = a.rc;
+ cur_row[2-c] = (family_8bpc.xlatL2U[a.rc]&0xFF);
+ this.decode_eatbits(a.codewordlen);
+ } while (++c < n_channels);
+
+ if (this.rgb_state.waitcnt) {
+ --this.rgb_state.waitcnt;
+ } else {
+ this.rgb_state.waitcnt = (this.rgb_state.tabrand() & waitmask);
+ c = 0;
+ do
+ {
+
this.channels[c].buckets_ptrs[this.channels[c].correlate_row.zero].update_model_8bpc(this.rgb_state,
this.channels[c].correlate_row.row[0], bpc);
+ } while (++c < n_channels);
+ }
+ stopidx = ++i + this.rgb_state.waitcnt;
+ } else {
+ stopidx = i + this.rgb_state.waitcnt;
+ }
+
+ while (stopidx < end) {
+ for (; i <= stopidx; i++) {
+ cur_row[(i* rgb32_pixel_size)+rgb32_pixel_pad] = 0;
+ c = 0;
+ do
+ {
+ a =
golomb_decoding_8bpc(this.channels[c].buckets_ptrs[this.channels[c].correlate_row.row[i -
1]].bestcode, this.io_word);
+ this.channels[c].correlate_row.row[i] = a.rc;
+ cur_row[(i* rgb32_pixel_size)+(2-c)] = (family_8bpc.xlatL2U[a.rc] +
cur_row[((i-1) * rgb32_pixel_size) + (2-c)]) & bpc_mask;
+ this.decode_eatbits(a.codewordlen);
+ } while (++c < n_channels);
+ }
+ c = 0;
+ do
+ {
+ this.channels[c].buckets_ptrs[this.channels[c].correlate_row.row[stopidx -
1]].update_model_8bpc(this.rgb_state, this.channels[c].correlate_row.row[stopidx], bpc);
+ } while (++c < n_channels);
+ stopidx = i + (this.rgb_state.tabrand() & waitmask);
+ }
+
+ for (; i < end; i++) {
+ cur_row[(i* rgb32_pixel_size)+rgb32_pixel_pad] = 0;
+ c = 0;
+ do
+ {
+ a =
golomb_decoding_8bpc(this.channels[c].buckets_ptrs[this.channels[c].correlate_row.row[i -
1]].bestcode, this.io_word);
+ this.channels[c].correlate_row.row[i] = a.rc;
+ cur_row[(i* rgb32_pixel_size)+(2-c)] = (family_8bpc.xlatL2U[a.rc] +
cur_row[((i-1) * rgb32_pixel_size) + (2-c)]) & bpc_mask;
+ this.decode_eatbits(a.codewordlen);
+ } while (++c < n_channels);
+ }
+ this.rgb_state.waitcnt = stopidx - end;
+}
+
+QuicEncoder.prototype.quic_rgb32_uncompress_row0 = function (cur_row)
+{
+ var bpc = 8;
+ var bpc_mask = 0xff;
+ var pos = 0;
+ var width = this.width;
+
+ while ((wmimax > this.rgb_state.wmidx) && (this.rgb_state.wmileft <=
width)) {
+ if (this.rgb_state.wmileft) {
+ this.quic_rgb32_uncompress_row0_seg(pos, cur_row,
+ pos + this.rgb_state.wmileft,
+ bppmask[this.rgb_state.wmidx],
+ bpc, bpc_mask);
+ pos += this.rgb_state.wmileft;
+ width -= this.rgb_state.wmileft;
+ }
+
+ this.rgb_state.wmidx++;
+ this.rgb_state.set_wm_trigger();
+ this.rgb_state.wmileft = wminext;
+ }
+
+ if (width) {
+ this.quic_rgb32_uncompress_row0_seg(pos, cur_row, pos + width,
+ bppmask[this.rgb_state.wmidx], bpc, bpc_mask);
+ if (wmimax > this.rgb_state.wmidx) {
+ this.rgb_state.wmileft -= width;
+ }
+ }
+}
+
+QuicEncoder.prototype.quic_rgb32_uncompress_row_seg = function( prev_row, cur_row, i,
end, bpc, bpc_mask)
+{
+ var n_channels = 3;
+ var waitmask = bppmask[this.rgb_state.wmidx];
+
+ var a;
+ var run_index = 0;
+ var stopidx = 0;
+ var run_end = 0;
+ var c;
+
+ if (!i)
+ {
+ cur_row[rgb32_pixel_pad] = 0;
+
+ c = 0;
+ do {
+ a =
golomb_decoding_8bpc(this.channels[c].buckets_ptrs[this.channels[c].correlate_row.zero].bestcode,
this.io_word);
+ this.channels[c].correlate_row.row[0] = a.rc;
+ cur_row[2-c] = (family_8bpc.xlatL2U[this.channels[c].correlate_row.row[0]] +
prev_row[2-c]) & bpc_mask;
+ this.decode_eatbits(a.codewordlen);
+ } while (++c < n_channels);
+
+ if (this.rgb_state.waitcnt) {
+ --this.rgb_state.waitcnt;
+ } else {
+ this.rgb_state.waitcnt = (this.rgb_state.tabrand() & waitmask);
+ c = 0;
+ do {
+
this.channels[c].buckets_ptrs[this.channels[c].correlate_row.zero].update_model_8bpc(this.rgb_state,
this.channels[c].correlate_row.row[0], bpc);
+ } while (++c < n_channels);
+ }
+ stopidx = ++i + this.rgb_state.waitcnt;
+ } else {
+ stopidx = i + this.rgb_state.waitcnt;
+ }
+ for (;;) {
+ var rc = 0;
+ while (stopidx < end && !rc) {
+ for (; i <= stopidx && !rc; i++) {
+ var pixel = i * rgb32_pixel_size;
+ var pixelm1 = (i-1) * rgb32_pixel_size;
+ var pixelm2 = (i-2) * rgb32_pixel_size;
+
+ if ( prev_row[pixelm1+rgb32_pixel_r] == prev_row[pixel+rgb32_pixel_r]
&& prev_row[pixelm1+rgb32_pixel_g] == prev_row[pixel+rgb32_pixel_g] &&
prev_row[pixelm1 + rgb32_pixel_b] == prev_row[pixel+rgb32_pixel_b])
+ {
+ if (run_index != i && i > 2 &&
(cur_row[pixelm1+rgb32_pixel_r] == cur_row[pixelm2+rgb32_pixel_r] &&
cur_row[pixelm1+rgb32_pixel_g] == cur_row[pixelm2+rgb32_pixel_g] &&
cur_row[pixelm1+rgb32_pixel_b] == cur_row[pixelm2+rgb32_pixel_b]))
+ {
+ /* do run */
+ this.rgb_state.waitcnt = stopidx - i;
+ run_index = i;
+ run_end = i + this.decode_run(this.rgb_state);
+
+ for (; i < run_end; i++) {
+ var pixel = i * rgb32_pixel_size;
+ var pixelm1 = (i-1) * rgb32_pixel_size;
+ cur_row[pixel+rgb32_pixel_pad] = 0;
+ cur_row[pixel+rgb32_pixel_r] =
cur_row[pixelm1+rgb32_pixel_r];
+ cur_row[pixel+rgb32_pixel_g] =
cur_row[pixelm1+rgb32_pixel_g];
+ cur_row[pixel+rgb32_pixel_b] =
cur_row[pixelm1+rgb32_pixel_b];
+ }
+
+ if (i == end) {
+ return;
+ }
+ else
+ {
+ stopidx = i + this.rgb_state.waitcnt;
+ rc = 1;
+ break;
+ }
+ }
+ }
+
+ c = 0;
+ cur_row[pixel+rgb32_pixel_pad] = 0;
+ do {
+ var cc = this.channels[c];
+ var cr = cc.correlate_row;
+
+ a = golomb_decoding_8bpc(cc.buckets_ptrs[cr.row[i-1]].bestcode,
this.io_word);
+ cr.row[i] = a.rc;
+ cur_row[pixel+(2-c)] = (family_8bpc.xlatL2U[a.rc] +
((cur_row[pixelm1+(2-c)] + prev_row[pixel+(2-c)]) >> 1)) & bpc_mask;
+ this.decode_eatbits(a.codewordlen);
+ } while (++c < n_channels);
+ }
+ if (rc)
+ break;
+
+ c = 0;
+ do {
+ this.channels[c].buckets_ptrs[this.channels[c].correlate_row.row[stopidx
- 1]].update_model_8bpc(this.rgb_state, this.channels[c].correlate_row.row[stopidx],
bpc);
+ } while (++c < n_channels);
+
+ stopidx = i + (this.rgb_state.tabrand() & waitmask);
+ }
+
+ for (; i < end && !rc; i++) {
+ var pixel = i * rgb32_pixel_size;
+ var pixelm1 = (i-1) * rgb32_pixel_size;
+ var pixelm2 = (i-2) * rgb32_pixel_size;
+
+ if (prev_row[pixelm1+rgb32_pixel_r] == prev_row[pixel+rgb32_pixel_r]
&& prev_row[pixelm1+rgb32_pixel_g] == prev_row[pixel+rgb32_pixel_g] &&
prev_row[pixelm1+rgb32_pixel_b] == prev_row[pixel+rgb32_pixel_b])
+ {
+ if (run_index != i && i > 2 &&
(cur_row[pixelm1+rgb32_pixel_r] == cur_row[pixelm2+rgb32_pixel_r] &&
cur_row[pixelm1+rgb32_pixel_g] == cur_row[pixelm2+rgb32_pixel_g] &&
cur_row[pixelm1+rgb32_pixel_b] == cur_row[pixelm2+rgb32_pixel_b]))
+ {
+ /* do run */
+ this.rgb_state.waitcnt = stopidx - i;
+ run_index = i;
+ run_end = i + this.decode_run(this.rgb_state);
+
+ for (; i < run_end; i++) {
+ var pixel = i * rgb32_pixel_size;
+ var pixelm1 = (i-1) * rgb32_pixel_size;
+ cur_row[pixel+rgb32_pixel_pad] = 0;
+ cur_row[pixel+rgb32_pixel_r] = cur_row[pixelm1+rgb32_pixel_r];
+ cur_row[pixel+rgb32_pixel_g] = cur_row[pixelm1+rgb32_pixel_g];
+ cur_row[pixel+rgb32_pixel_b] = cur_row[pixelm1+rgb32_pixel_b];
+ }
+
+ if (i == end) {
+ return;
+ }
+ else
+ {
+ stopidx = i + this.rgb_state.waitcnt;
+ rc = 1;
+ break;
+ }
+ }
+ }
+
+ cur_row[pixel+rgb32_pixel_pad] = 0;
+ c = 0;
+ do
+ {
+ a =
golomb_decoding_8bpc(this.channels[c].buckets_ptrs[this.channels[c].correlate_row.row[i-1]].bestcode,
this.io_word);
+ this.channels[c].correlate_row.row[i] = a.rc;
+ cur_row[pixel+(2-c)] = (family_8bpc.xlatL2U[a.rc] +
((cur_row[pixelm1+(2-c)] + prev_row[pixel+(2-c)]) >> 1)) & bpc_mask;
+ this.decode_eatbits(a.codewordlen);
+ } while (++c < n_channels);
+ }
+
+ if (!rc)
+ {
+ this.rgb_state.waitcnt = stopidx - end;
+ return;
+ }
+ }
+}
+
+QuicEncoder.prototype.decode_run = function(state)
+{
+ var runlen = 0;
+
+ do {
+ var hits;
+ var x = (~(this.io_word >>> 24)>>>0)&0xff;
+ var temp = zeroLUT[x];
+
+ for (hits = 1; hits <= temp; hits++) {
+ runlen += state.melcorder;
+
+ if (state.melcstate < 32) {
+ state.melclen = J[++state.melcstate];
+ state.melcorder = (1 << state.melclen);
+ }
+ }
+ if (temp != 8) {
+ this.decode_eatbits(temp + 1);
+
+ break;
+ }
+ this.decode_eatbits(8);
+ } while (true);
+
+ if (state.melclen) {
+ runlen += this.io_word >>> (32 - state.melclen);
+ this.decode_eatbits(state.melclen);
+ }
+
+ if (state.melcstate) {
+ state.melclen = J[--state.melcstate];
+ state.melcorder = (1 << state.melclen);
+ }
+
+ return runlen;
+}
+
+QuicEncoder.prototype.quic_rgb32_uncompress_row = function (prev_row, cur_row)
+{
+ var bpc = 8;
+ var bpc_mask = 0xff;
+ var pos = 0;
+ var width = this.width;
+
+ while ((wmimax > this.rgb_state.wmidx) && (this.rgb_state.wmileft <=
width)) {
+ if (this.rgb_state.wmileft) {
+ this.quic_rgb32_uncompress_row_seg(prev_row, cur_row, pos,
+ pos + this.rgb_state.wmileft, bpc, bpc_mask);
+ pos += this.rgb_state.wmileft;
+ width -= this.rgb_state.wmileft;
+ }
+
+ this.rgb_state.wmidx++;
+ this.rgb_state.set_wm_trigger();
+ this.rgb_state.wmileft = wminext;
+ }
+
+ if (width) {
+ this.quic_rgb32_uncompress_row_seg(prev_row, cur_row, pos,
+ pos + width, bpc, bpc_mask);
+ if (wmimax > this.rgb_state.wmidx) {
+ this.rgb_state.wmileft -= width;
+ }
+ }
+}
+
+QuicEncoder.prototype.quic_four_uncompress_row0_seg = function (channel, i,
+ correlate_row, cur_row, end, waitmask,
+ bpc, bpc_mask)
+{
+ var stopidx;
+ var a;
+
+ if (i == 0) {
+ a = golomb_decoding_8bpc(channel.buckets_ptrs[correlate_row.zero].bestcode,
this.io_word);
+ correlate_row.row[0] = a.rc;
+ cur_row[rgb32_pixel_pad] = family_8bpc.xlatL2U[a.rc];
+ this.decode_eatbits(a.codewordlen);
+
+ if (channel.state.waitcnt) {
+ --channel.state.waitcnt;
+ } else {
+ channel.state.waitcnt = (channel.state.tabrand() & waitmask);
+ channel.buckets_ptrs[correlate_row.zero].update_model_8bpc(channel.state,
correlate_row.row[0], bpc);
+ }
+ stopidx = ++i + channel.state.waitcnt;
+ } else {
+ stopidx = i + channel.state.waitcnt;
+ }
+
+ while (stopidx < end) {
+ var pbucket;
+
+ for (; i <= stopidx; i++) {
+ pbucket = channel.buckets_ptrs[correlate_row.row[i - 1]];
+
+ a = golomb_decoding_8bpc(pbucket.bestcode, this.io_word);
+ correlate_row.row[i] = a.rc;
+ cur_row[(i*rgb32_pixel_size)+rgb32_pixel_pad] = (family_8bpc.xlatL2U[a.rc] +
cur_row[((i-1)*rgb32_pixel_size)+rgb32_pixel_pad]) & bpc_mask;
+ this.decode_eatbits(a.codewordlen);
+ }
+
+ pbucket.update_model_8bpc(channel.state, correlate_row.row[stopidx], bpc);
+
+ stopidx = i + (channel.state.tabrand() & waitmask);
+ }
+
+ for (; i < end; i++) {
+ a = golomb_decoding_8bpc(channel.buckets_ptrs[correlate_row.row[i-1]].bestcode,
this.io_word);
+
+ correlate_row.row[i] = a.rc;
+ cur_row[(i*rgb32_pixel_size)+rgb32_pixel_pad] = (family_8bpc.xlatL2U[a.rc] +
cur_row[((i-1)*rgb32_pixel_size)+rgb32_pixel_pad]) & bpc_mask;
+ this.decode_eatbits(a.codewordlen);
+ }
+ channel.state.waitcnt = stopidx - end;
+}
+
+QuicEncoder.prototype.quic_four_uncompress_row0 = function(channel, cur_row)
+{
+ var bpc = 8;
+ var bpc_mask = 0xff;
+ var correlate_row = channel.correlate_row;
+ var pos = 0;
+ var width = this.width;
+
+ while ((wmimax > channel.state.wmidx) && (channel.state.wmileft <=
width)) {
+ if (channel.state.wmileft) {
+ this.quic_four_uncompress_row0_seg(channel, pos, correlate_row, cur_row,
+ pos + channel.state.wmileft,
bppmask[channel.state.wmidx],
+ bpc, bpc_mask);
+ pos += channel.state.wmileft;
+ width -= channel.state.wmileft;
+ }
+
+ channel.state.wmidx++;
+ channel.state.set_wm_trigger();
+ channel.state.wmileft = wminext;
+ }
+
+ if (width) {
+ this.quic_four_uncompress_row0_seg(channel, pos, correlate_row, cur_row, pos +
width,
+ bppmask[channel.state.wmidx], bpc, bpc_mask);
+ if (wmimax > channel.state.wmidx) {
+ channel.state.wmileft -= width;
+ }
+ }
+}
+
+QuicEncoder.prototype.quic_four_uncompress_row_seg = function (channel,
+ correlate_row, prev_row, cur_row, i,
+ end, bpc, bpc_mask)
+{
+ var waitmask = bppmask[channel.state.wmidx];
+ var stopidx;
+
+ var run_index = 0;
+ var run_end;
+
+ var a;
+
+ if (i == 0) {
+ a = golomb_decoding_8bpc(channel.buckets_ptrs[correlate_row.zero].bestcode,
this.io_word);
+
+ correlate_row.row[0] = a.rc
+ cur_row[rgb32_pixel_pad] = (family_8bpc.xlatL2U[a.rc] +
prev_row[rgb32_pixel_pad]) & bpc_mask;
+ this.decode_eatbits(a.codewordlen);
+
+ if (channel.state.waitcnt) {
+ --channel.state.waitcnt;
+ } else {
+ channel.state.waitcnt = (channel.state.tabrand() & waitmask);
+ channel.buckets_ptrs[correlate_row.zero].update_model_8bpc(channel.state,
correlate_row.row[0], bpc);
+ }
+ stopidx = ++i + channel.state.waitcnt;
+ } else {
+ stopidx = i + channel.state.waitcnt;
+ }
+ for (;;) {
+ var rc = 0;
+ while (stopidx < end && !rc) {
+ var pbucket;
+ for (; i <= stopidx && !rc; i++) {
+ var pixel = i * rgb32_pixel_size;
+ var pixelm1 = (i-1) * rgb32_pixel_size;
+ var pixelm2 = (i-2) * rgb32_pixel_size;
+
+ if (prev_row[pixelm1+rgb32_pixel_pad] ==
prev_row[pixel+rgb32_pixel_pad])
+ {
+ if (run_index != i && i > 2 &&
cur_row[pixelm1+rgb32_pixel_pad] == cur_row[pixelm2+rgb32_pixel_pad])
+ {
+ /* do run */
+ channel.state.waitcnt = stopidx - i;
+ run_index = i;
+
+ run_end = i + this.decode_run(channel.state);
+
+ for (; i < run_end; i++) {
+ var pixel = i * rgb32_pixel_size;
+ var pixelm1 = (i-1) * rgb32_pixel_size;
+ cur_row[pixel+rgb32_pixel_pad] =
cur_row[pixelm1+rgb32_pixel_pad];
+ }
+
+ if (i == end) {
+ return;
+ }
+ else
+ {
+ stopidx = i + channel.state.waitcnt;
+ rc = 1;
+ break;
+ }
+ }
+ }
+
+ pbucket = channel.buckets_ptrs[correlate_row.row[i - 1]];
+ a = golomb_decoding_8bpc(pbucket.bestcode, this.io_word);
+ correlate_row.row[i] = a.rc
+ cur_row[pixel+rgb32_pixel_pad] = (family_8bpc.xlatL2U[a.rc] +
((cur_row[pixelm1+rgb32_pixel_pad] + prev_row[pixel+rgb32_pixel_pad]) >> 1)) &
bpc_mask;
+ this.decode_eatbits(a.codewordlen);
+ }
+ if (rc)
+ break;
+
+ pbucket.update_model_8bpc(channel.state, correlate_row.row[stopidx], bpc);
+
+ stopidx = i + (channel.state.tabrand() & waitmask);
+ }
+
+ for (; i < end && !rc; i++) {
+ var pixel = i * rgb32_pixel_size;
+ var pixelm1 = (i-1) * rgb32_pixel_size;
+ var pixelm2 = (i-2) * rgb32_pixel_size;
+ if (prev_row[pixelm1+rgb32_pixel_pad] == prev_row[pixel+rgb32_pixel_pad])
+ {
+ if (run_index != i && i > 2 &&
cur_row[pixelm1+rgb32_pixel_pad] == cur_row[pixelm2+rgb32_pixel_pad])
+ {
+ /* do run */
+ channel.state.waitcnt = stopidx - i;
+ run_index = i;
+
+ run_end = i + this.decode_run(channel.state);
+
+ for (; i < run_end; i++) {
+ var pixel = i * rgb32_pixel_size;
+ var pixelm1 = (i-1) * rgb32_pixel_size;
+ cur_row[pixel+rgb32_pixel_pad] =
cur_row[pixelm1+rgb32_pixel_pad];
+ }
+
+ if (i == end) {
+ return;
+ }
+ else
+ {
+ stopidx = i + channel.state.waitcnt;
+ rc = 1;
+ break;
+ }
+ }
+ }
+
+ a =
golomb_decoding_8bpc(channel.buckets_ptrs[correlate_row.row[i-1]].bestcode,
this.io_word);
+ correlate_row.row[i] = a.rc;
+ cur_row[pixel+rgb32_pixel_pad] = (family_8bpc.xlatL2U[a.rc] +
((cur_row[pixelm1+rgb32_pixel_pad] + prev_row[pixel+rgb32_pixel_pad]) >> 1)) &
bpc_mask;
+ this.decode_eatbits(a.codewordlen);
+ }
+
+ if (!rc)
+ {
+ channel.state.waitcnt = stopidx - end;
+ return;
+ }
+ }
+}
+
+QuicEncoder.prototype.quic_four_uncompress_row = function(channel, prev_row,
+ cur_row)
+{
+ var bpc = 8;
+ var bpc_mask = 0xff;
+ var correlate_row = channel.correlate_row;
+ var pos = 0;
+ var width = this.width;
+
+ while ((wmimax > channel.state.wmidx) && (channel.state.wmileft <=
width)) {
+ if (channel.state.wmileft) {
+ this.quic_four_uncompress_row_seg(channel, correlate_row, prev_row, cur_row,
pos,
+ pos + channel.state.wmileft, bpc, bpc_mask);
+ pos += channel.state.wmileft;
+ width -= channel.state.wmileft;
+ }
+
+ channel.state.wmidx++;
+ channel.state.set_wm_trigger();
+ channel.state.wmileft = wminext;
+ }
+
+ if (width) {
+ this.quic_four_uncompress_row_seg(channel, correlate_row, prev_row, cur_row,
pos,
+ pos + width, bpc, bpc_mask);
+ if (wmimax > channel.state.wmidx) {
+ channel.state.wmileft -= width;
+ }
+ }
+}
+
+/* We need to be generating rgb32 or rgba */
+QuicEncoder.prototype.quic_decode = function(buf, stride)
+{
+ var row;
+
+ switch (this.type)
+ {
+ case QUIC_IMAGE_TYPE_RGB32:
+ case QUIC_IMAGE_TYPE_RGB24:
+ this.channels[0].correlate_row.zero = 0;
+ this.channels[1].correlate_row.zero = 0;
+ this.channels[2].correlate_row.zero = 0;
+ this.quic_rgb32_uncompress_row0(buf);
+
+ this.rows_completed++;
+ for (row = 1; row < this.height; row++)
+ {
+ var prev = buf;
+ buf = prev.subarray(stride);
+ this.channels[0].correlate_row.zero =
this.channels[0].correlate_row.row[0];
+ this.channels[1].correlate_row.zero =
this.channels[1].correlate_row.row[0];
+ this.channels[2].correlate_row.zero =
this.channels[2].correlate_row.row[0];
+ this.quic_rgb32_uncompress_row(prev, buf);
+ this.rows_completed++;
+ };
+ break;
+ case QUIC_IMAGE_TYPE_RGB16:
+ console.log("quic: unsupported output format\n");
+ return false;
+ break;
+ case QUIC_IMAGE_TYPE_RGBA:
+ this.channels[0].correlate_row.zero = 0;
+ this.channels[1].correlate_row.zero = 0;
+ this.channels[2].correlate_row.zero = 0;
+ this.quic_rgb32_uncompress_row0(buf);
+
+ this.channels[3].correlate_row.zero = 0;
+ this.quic_four_uncompress_row0(this.channels[3], buf);
+
+ this.rows_completed++;
+ for (row = 1; row < this.height; row++) {
+ var prev = buf;
+ buf = prev.subarray(stride);
+
+ this.channels[0].correlate_row.zero =
this.channels[0].correlate_row.row[0];
+ this.channels[1].correlate_row.zero =
this.channels[1].correlate_row.row[0];
+ this.channels[2].correlate_row.zero =
this.channels[2].correlate_row.row[0];
+ this.quic_rgb32_uncompress_row(prev, buf);
+
+ this.channels[3].correlate_row.zero =
this.channels[3].correlate_row.row[0];
+ this.quic_four_uncompress_row(encoder.channels[3], prev, buf);
+ this.rows_completed++;
+ }
+ break;
+
+ case QUIC_IMAGE_TYPE_GRAY:
+ console.log("quic: unsupported output format\n");
+ return false;
+ break;
+
+ case QUIC_IMAGE_TYPE_INVALID:
+ default:
+ console.log("quic: bad image type\n");
+ return false;
+ }
+ return true;
+}
+
+QuicEncoder.prototype.simple_quic_decode = function(buf)
+{
+ var stride = 4; /* FIXME - proper stride calc please */
+ if (!this.quic_decode_begin(buf))
+ return undefined;
+ if (this.type != QUIC_IMAGE_TYPE_RGB32 && this.type != QUIC_IMAGE_TYPE_RGB24
+ && this.type != QUIC_IMAGE_TYPE_RGBA)
+ return undefined;
+ var out = new Uint8Array(this.width*this.height*4);
+ out[0] = 69;
+ if (this.quic_decode( out, (this.width * stride)))
+ return out;
+ return undefined;
+}
+
+function SpiceQuic()
+{
+}
+
+SpiceQuic.prototype =
+{
+ from_dv: function(dv, at, mb)
+ {
+ if (!encoder)
+ throw("quic: no quic encoder");
+ this.data_size = dv.getUint32(at, true);
+ at += 4;
+ var buf = new Uint8Array(mb.slice(at));
+ this.outptr = encoder.simple_quic_decode(buf);
+ if (this.outptr)
+ {
+ this.type = encoder.type;
+ this.width = encoder.width;
+ this.height = encoder.height;
+ }
+ at += buf.length;
+ return at;
+ },
+}
+
+function convert_spice_quic_to_web(context, spice_quic)
+{
+ var ret = context.createImageData(spice_quic.width, spice_quic.height);
+ var i;
+ for (i = 0; i < (ret.width * ret.height * 4); i+=4)
+ {
+ ret.data[i + 0] = spice_quic.outptr[i + 2];
+ ret.data[i + 1] = spice_quic.outptr[i + 1];
+ ret.data[i + 2] = spice_quic.outptr[i + 0];
+ if (spice_quic.type !== QUIC_IMAGE_TYPE_RGBA)
+ ret.data[i + 3] = 255;
+ else
+ ret.data[i + 3] = 255 - spice_quic.outptr[i + 3];
+ }
+ return ret;
+}
+
+/* Module initialization */
+if (need_init)
+{
+ need_init = false;
+
+ family_init(family_8bpc, 8, DEFmaxclen);
+ family_init(family_5bpc, 5, DEFmaxclen);
+ /* init_zeroLUT */
+ var i, j, k, l;
+
+ j = k = 1;
+ l = 8;
+ for (i = 0; i < 256; ++i) {
+ zeroLUT[i] = l;
+ --k;
+ if (k == 0) {
+ k = j;
+ --l;
+ j *= 2;
+ }
+ }
+
+ encoder = new QuicEncoder;
+
+ if (!encoder)
+ throw("quic: failed to create encoder");
+}
diff --git a/src/wok/plugins/kimchi/ui/spice-html5/resize.js
b/src/wok/plugins/kimchi/ui/spice-html5/resize.js
new file mode 100644
index 0000000..f5410d3
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/spice-html5/resize.js
@@ -0,0 +1,70 @@
+"use strict";
+/*
+ Copyright (C) 2014 by Jeremy P. White <jwhite(a)codeweavers.com>
+
+ This file is part of spice-html5.
+
+ spice-html5 is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ spice-html5 is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with spice-html5. If not, see <
http://www.gnu.org/licenses/>.
+*/
+
+/*----------------------------------------------------------------------------
+** resize.js
+** This bit of Javascript is a set of logic to help with window
+** resizing, using the agent channel to request screen resizes.
+**
+** It's a bit tricky, as we want to wait for resizing to settle down
+** before sending a size. Further, while horizontal resizing to use the whole
+** browser width is fairly easy to arrange with css, resizing an element to use
+** the whole vertical space (or to force a middle div to consume the bulk of the
browser
+** window size) is tricky, and the consensus seems to be that Javascript is
+** the only right way to do it.
+**--------------------------------------------------------------------------*/
+function resize_helper(sc)
+{
+ var w = document.getElementById(sc.screen_id).clientWidth;
+ var h = document.getElementById(sc.screen_id).clientHeight;
+
+ var m = document.getElementById(sc.message_id);
+
+ /* Resize vertically; basically we leave a 20 pixel margin
+ at the bottom, and use the position of the message window
+ to figure out how to resize */
+ var hd = window.innerHeight - m.offsetHeight - m.offsetTop - 20;
+
+ /* Xorg requires height be a multiple of 8; round up */
+ h = h + hd;
+ if (h % 8 > 0)
+ h += (8 - (h % 8));
+
+ /* Xorg requires width be a multiple of 8; round up */
+ if (w % 8 > 0)
+ w += (8 - (w % 8));
+
+
+ sc.resize_window(0, w, h, 32, 0, 0);
+ sc.spice_resize_timer = undefined;
+}
+
+function handle_resize(e)
+{
+ var sc = window.spice_connection;
+
+ if (sc && sc.spice_resize_timer)
+ {
+ window.clearTimeout(sc.spice_resize_timer);
+ sc.spice_resize_timer = undefined;
+ }
+
+ sc.spice_resize_timer = window.setTimeout(resize_helper, 200, sc);
+}
diff --git a/src/wok/plugins/kimchi/ui/spice-html5/simulatecursor.js
b/src/wok/plugins/kimchi/ui/spice-html5/simulatecursor.js
new file mode 100644
index 0000000..b1fce06
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/spice-html5/simulatecursor.js
@@ -0,0 +1,202 @@
+"use strict";
+/*
+ Copyright (C) 2013 by Jeremy P. White <jwhite(a)codeweavers.com>
+
+ This file is part of spice-html5.
+
+ spice-html5 is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ spice-html5 is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with spice-html5. If not, see <
http://www.gnu.org/licenses/>.
+*/
+
+/*----------------------------------------------------------------------------
+** SpiceSimulateCursor
+** Internet Explorer 10 does not support data uri's in cursor assignment.
+** This file provides a number of gimmicks to compensate. First, if there
+** is a preloaded cursor available, we will use that. Failing that, we will
+** simulate a cursor using an image that is moved around the screen.
+**--------------------------------------------------------------------------*/
+var SpiceSimulateCursor = {
+
+cursors : new Array(),
+unknown_cursors : new Array(),
+warned: false,
+
+add_cursor: function(sha1, value)
+{
+ SpiceSimulateCursor.cursors[sha1] = value;
+},
+
+unknown_cursor: function(sha1, curdata)
+{
+ if (! SpiceSimulateCursor.warned)
+ {
+ SpiceSimulateCursor.warned = true;
+ alert("Internet Explorer does not support dynamic cursors. " +
+ "This page will now simulate cursors with images, " +
+ "which will be imperfect. We recommend using Chrome or Firefox
instead. " +
+ "\n\nIf you need to use Internet Explorer, you can create a static
cursor " +
+ "file for each cursor your application uses. " +
+ "View the console log for more information on creating static cursors
for your environment.");
+ }
+
+ if (! SpiceSimulateCursor.unknown_cursors[sha1])
+ {
+ SpiceSimulateCursor.unknown_cursors[sha1] = curdata;
+ console.log('Unknown cursor. Simulation required. To avoid simulation for
this cursor, create and include a custom javascript file, and add the following
line:');
+ console.log('SpiceCursorSimulator.add_cursor("' + sha1 +
'"), "<your filename here>.cur");');
+ console.log('And then run following command, redirecting output into <your
filename here>.cur:');
+ console.log('php -r "echo urldecode(\'' + curdata +
'\');"');
+ }
+},
+
+simulate_cursor: function (spicecursor, cursor, screen, pngstr)
+{
+ var cursor_sha = hex_sha1(pngstr + ' ' + cursor.header.hot_spot_x + '
' + cursor.header.hot_spot_y);
+ if (typeof SpiceSimulateCursor.cursors != 'undefined')
+ if (typeof SpiceSimulateCursor.cursors[cursor_sha] != 'undefined')
+ {
+ var curstr = 'url(' + SpiceSimulateCursor.cursors[cursor_sha] +
'), default';
+ screen.style.cursor = curstr;
+ }
+
+ if (window.getComputedStyle(screen, null).cursor == 'auto')
+ {
+ SpiceSimulateCursor.unknown_cursor(cursor_sha,
+ SpiceSimulateCursor.create_icondir(cursor.header.width,
cursor.header.height,
+ cursor.data.byteLength, cursor.header.hot_spot_x, cursor.header.hot_spot_y) +
pngstr);
+
+ document.getElementById(spicecursor.parent.screen_id).style.cursor =
'none';
+ if (! spicecursor.spice_simulated_cursor)
+ {
+ spicecursor.spice_simulated_cursor = document.createElement('img');
+
+ spicecursor.spice_simulated_cursor.style.position = 'absolute';
+ spicecursor.spice_simulated_cursor.style.display = 'none';
+ spicecursor.spice_simulated_cursor.style.overflow = 'hidden';
+
+ spicecursor.spice_simulated_cursor.spice_screen =
document.getElementById(spicecursor.parent.screen_id);
+
+ spicecursor.spice_simulated_cursor.addEventListener('mousemove',
SpiceSimulateCursor.handle_sim_mousemove);
+
+
spicecursor.spice_simulated_cursor.spice_screen.appendChild(spicecursor.spice_simulated_cursor);
+ }
+
+ spicecursor.spice_simulated_cursor.src = 'data:image/png,' + pngstr;
+
+ spicecursor.spice_simulated_cursor.spice_hot_x = cursor.header.hot_spot_x;
+ spicecursor.spice_simulated_cursor.spice_hot_y = cursor.header.hot_spot_y;
+
+ spicecursor.spice_simulated_cursor.style.pointerEvents = "none";
+ }
+ else
+ {
+ if (spicecursor.spice_simulated_cursor)
+ {
+
spicecursor.spice_simulated_cursor.spice_screen.removeChild(spicecursor.spice_simulated_cursor);
+ delete spicecursor.spice_simulated_cursor;
+ }
+ }
+},
+
+handle_sim_mousemove: function(e)
+{
+ var retval;
+ var f = SpiceSimulateCursor.duplicate_mouse_event(e, this.spice_screen);
+ return this.spice_screen.dispatchEvent(f);
+},
+
+duplicate_mouse_event: function(e, target)
+{
+ var evt = document.createEvent("mouseevent");
+ evt.initMouseEvent(e.type, true, true, e.view, e.detail,
+ e.screenX, e.screenY, e.clientX, e.clientY,
+ e.ctrlKey, e.altKey, e.shiftKey, e.metaKey, e.button, e.relatedTarget);
+ return evt;
+},
+
+ICONDIR: function ()
+{
+},
+
+ICONDIRENTRY: function(width, height, bytes, hot_x, hot_y)
+{
+ this.width = width;
+ this.height = height;
+ this.bytes = bytes;
+ this.hot_x = hot_x;
+ this.hot_y = hot_y;
+},
+
+
+create_icondir: function (width, height, bytes, hot_x, hot_y)
+{
+ var i;
+ var header = new SpiceSimulateCursor.ICONDIR();
+ var entry = new SpiceSimulateCursor.ICONDIRENTRY(width, height, bytes, hot_x,
hot_y);
+
+ var mb = new ArrayBuffer(header.buffer_size() + entry.buffer_size());
+ var at = header.to_buffer(mb);
+ at = entry.to_buffer(mb, at);
+
+ var u8 = new Uint8Array(mb);
+ var str = "";
+ for (i = 0; i < at; i++)
+ {
+ str += "%";
+ if (u8[i] < 16)
+ str += "0";
+ str += u8[i].toString(16);
+ }
+ return str;
+},
+
+};
+
+SpiceSimulateCursor.ICONDIR.prototype =
+{
+ to_buffer: function(a, at)
+ {
+ at = at || 0;
+ var dv = new SpiceDataView(a);
+ dv.setUint16(at, 0, true); at += 2;
+ dv.setUint16(at, 2, true); at += 2;
+ dv.setUint16(at, 1, true); at += 2;
+ return at;
+ },
+ buffer_size: function()
+ {
+ return 6;
+ }
+};
+
+SpiceSimulateCursor.ICONDIRENTRY.prototype =
+{
+ to_buffer: function(a, at)
+ {
+ at = at || 0;
+ var dv = new SpiceDataView(a);
+ dv.setUint8(at, this.width); at++;
+ dv.setUint8(at, this.height); at++;
+ dv.setUint8(at, 0); at++; /* color palette count, unused */
+ dv.setUint8(at, 0); at++; /* reserved */
+ dv.setUint16(at, this.hot_x, true); at += 2;
+ dv.setUint16(at, this.hot_y, true); at += 2;
+ dv.setUint32(at, this.bytes, true); at += 4;
+ dv.setUint32(at, at + 4, true); at += 4; /* Offset to bytes */
+ return at;
+ },
+ buffer_size: function()
+ {
+ return 16;
+ }
+};
diff --git a/src/wok/plugins/kimchi/ui/spice-html5/spicearraybuffer.js
b/src/wok/plugins/kimchi/ui/spice-html5/spicearraybuffer.js
new file mode 100644
index 0000000..228bce6
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/spice-html5/spicearraybuffer.js
@@ -0,0 +1,58 @@
+"use strict";
+/*
+ Copyright (C) 2012 by Jeremy P. White <jwhite(a)codeweavers.com>
+
+ This file is part of spice-html5.
+
+ spice-html5 is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ spice-html5 is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with spice-html5. If not, see <
http://www.gnu.org/licenses/>.
+*/
+
+/*----------------------------------------------------------------------------
+** SpiceArrayBufferSlice
+** This function is a work around for IE 10, which has no slice()
+** method in it's subclass.
+**--------------------------------------------------------------------------*/
+function SpiceArrayBufferSlice(start, end)
+{
+ start = start || 0;
+ end = end || this.byteLength;
+ if (end < 0)
+ end = this.byteLength + end;
+ if (start < 0)
+ start = this.byteLength + start;
+ if (start < 0)
+ start = 0;
+ if (end < 0)
+ end = 0;
+ if (end > this.byteLength)
+ end = this.byteLength;
+ if (start > end)
+ start = end;
+
+ var ret = new ArrayBuffer(end - start);
+ var in1 = new Uint8Array(this, start, end - start);
+ var out = new Uint8Array(ret);
+ var i;
+
+ for (i = 0; i < end - start; i++)
+ out[i] = in1[i];
+
+ return ret;
+}
+
+if (! ArrayBuffer.prototype.slice)
+{
+ ArrayBuffer.prototype.slice = SpiceArrayBufferSlice;
+ console.log("WARNING: ArrayBuffer.slice() is missing; we are extending
ArrayBuffer to compensate");
+}
diff --git a/src/wok/plugins/kimchi/ui/spice-html5/spiceconn.js
b/src/wok/plugins/kimchi/ui/spice-html5/spiceconn.js
new file mode 100644
index 0000000..e33227e
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/spice-html5/spiceconn.js
@@ -0,0 +1,460 @@
+"use strict";
+/*
+ Copyright (C) 2012 by Jeremy P. White <jwhite(a)codeweavers.com>
+
+ This file is part of spice-html5.
+
+ spice-html5 is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ spice-html5 is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with spice-html5. If not, see <
http://www.gnu.org/licenses/>.
+*/
+
+/*----------------------------------------------------------------------------
+** SpiceConn
+** This is the base Javascript class for establishing and
+** managing a connection to a Spice Server.
+** It is used to provide core functionality to the Spice main,
+** display, inputs, and cursor channels. See main.js for
+** usage.
+**--------------------------------------------------------------------------*/
+function SpiceConn(o)
+{
+ if (o === undefined || o.uri === undefined || ! o.uri)
+ throw new Error("You must specify a uri");
+
+ this.ws = new WebSocket(o.uri, 'binary');
+
+ if (! this.ws.binaryType)
+ throw new Error("WebSocket doesn't support binaryType. Try a different
browser.");
+
+ this.connection_id = o.connection_id !== undefined ? o.connection_id : 0;
+ this.type = o.type !== undefined ? o.type : SPICE_CHANNEL_MAIN;
+ this.chan_id = o.chan_id !== undefined ? o.chan_id : 0;
+ if (o.parent !== undefined)
+ {
+ this.parent = o.parent;
+ this.message_id = o.parent.message_id;
+ this.password = o.parent.password;
+ }
+ if (o.screen_id !== undefined)
+ this.screen_id = o.screen_id;
+ if (o.dump_id !== undefined)
+ this.dump_id = o.dump_id;
+ if (o.message_id !== undefined)
+ this.message_id = o.message_id;
+ if (o.password !== undefined)
+ this.password = o.password;
+ if (o.onerror !== undefined)
+ this.onerror = o.onerror;
+ if (o.onsuccess !== undefined)
+ this.onsuccess = o.onsuccess;
+ if (o.onagent !== undefined)
+ this.onagent = o.onagent;
+
+ this.state = "connecting";
+ this.ws.parent = this;
+ this.wire_reader = new SpiceWireReader(this, this.process_inbound);
+ this.messages_sent = 0;
+ this.warnings = [];
+
+ this.ws.addEventListener('open', function(e) {
+ DEBUG > 0 && console.log(">> WebSockets.onopen");
+ DEBUG > 0 && console.log("id " + this.parent.connection_id
+"; type " + this.parent.type);
+
+ /***********************************************************************
+ ** WHERE IT ALL REALLY BEGINS
+ ***********************************************************************/
+ this.parent.send_hdr();
+ this.parent.wire_reader.request(SpiceLinkHeader.prototype.buffer_size());
+ this.parent.state = "start";
+ });
+ this.ws.addEventListener('error', function(e) {
+ this.parent.log_err(">> WebSockets.onerror" + e.toString());
+ this.parent.report_error(e);
+ });
+ this.ws.addEventListener('close', function(e) {
+ DEBUG > 0 && console.log(">> WebSockets.onclose");
+ DEBUG > 0 && console.log("id " + this.parent.connection_id
+"; type " + this.parent.type);
+ DEBUG > 0 && console.log(e);
+ if (this.parent.state != "closing" && this.parent.state !=
"error" && this.parent.onerror !== undefined)
+ {
+ var e;
+ if (this.parent.state == "connecting")
+ e = new Error("Connection refused.");
+ else if (this.parent.state == "start" || this.parent.state ==
"link")
+ e = new Error("Unexpected protocol mismatch.");
+ else if (this.parent.state == "ticket")
+ e = new Error("Bad password.");
+ else
+ e = new Error("Unexpected close while " + this.parent.state);
+
+ this.parent.onerror(e);
+ this.parent.log_err(e.toString());
+ }
+ });
+
+ if (this.ws.readyState == 2 || this.ws.readyState == 3)
+ throw new Error("Unable to connect to " + o.uri);
+
+ this.timeout = window.setTimeout(spiceconn_timeout, SPICE_CONNECT_TIMEOUT, this);
+}
+
+SpiceConn.prototype =
+{
+ send_hdr : function ()
+ {
+ var hdr = new SpiceLinkHeader;
+ var msg = new SpiceLinkMess;
+
+ msg.connection_id = this.connection_id;
+ msg.channel_type = this.type;
+ // FIXME - we're not setting a channel_id...
+ msg.common_caps.push(
+ (1 << SPICE_COMMON_CAP_PROTOCOL_AUTH_SELECTION) |
+ (1 << SPICE_COMMON_CAP_MINI_HEADER)
+ );
+
+ if (msg.channel_type == SPICE_CHANNEL_PLAYBACK)
+ msg.channel_caps.push(
+ (1 << SPICE_PLAYBACK_CAP_OPUS)
+ );
+
+ hdr.size = msg.buffer_size();
+
+ var mb = new ArrayBuffer(hdr.buffer_size() + msg.buffer_size());
+ hdr.to_buffer(mb);
+ msg.to_buffer(mb, hdr.buffer_size());
+
+ DEBUG > 1 && console.log("Sending header:");
+ DEBUG > 2 && hexdump_buffer(mb);
+ this.ws.send(mb);
+ },
+
+ send_ticket: function(ticket)
+ {
+ var hdr = new SpiceLinkAuthTicket();
+ hdr.auth_mechanism = SPICE_COMMON_CAP_AUTH_SPICE;
+ // FIXME - we need to implement RSA to make this work right
+ hdr.encrypted_data = ticket;
+ var mb = new ArrayBuffer(hdr.buffer_size());
+
+ hdr.to_buffer(mb);
+ DEBUG > 1 && console.log("Sending ticket:");
+ DEBUG > 2 && hexdump_buffer(mb);
+ this.ws.send(mb);
+ },
+
+ send_msg: function(msg)
+ {
+ var mb = new ArrayBuffer(msg.buffer_size());
+ msg.to_buffer(mb);
+ this.messages_sent++;
+ DEBUG > 0 && console.log(">> hdr " +
this.channel_type() + " type " + msg.type + " size " +
mb.byteLength);
+ DEBUG > 2 && hexdump_buffer(mb);
+ this.ws.send(mb);
+ },
+
+ process_inbound: function(mb, saved_header)
+ {
+ DEBUG > 2 && console.log(this.type + ": processing message of
size " + mb.byteLength + "; state is " + this.state);
+ if (this.state == "ready")
+ {
+ if (saved_header == undefined)
+ {
+ var msg = new SpiceMiniData(mb);
+
+ if (msg.type > 500)
+ {
+ alert("Something has gone very wrong; we think we have message
of type " + msg.type);
+ debugger;
+ }
+
+ if (msg.size == 0)
+ {
+ this.process_message(msg);
+ this.wire_reader.request(SpiceMiniData.prototype.buffer_size());
+ }
+ else
+ {
+ this.wire_reader.request(msg.size);
+ this.wire_reader.save_header(msg);
+ }
+ }
+ else
+ {
+ saved_header.data = mb;
+ this.process_message(saved_header);
+ this.wire_reader.request(SpiceMiniData.prototype.buffer_size());
+ this.wire_reader.save_header(undefined);
+ }
+ }
+
+ else if (this.state == "start")
+ {
+ this.reply_hdr = new SpiceLinkHeader(mb);
+ if (this.reply_hdr.magic != SPICE_MAGIC)
+ {
+ this.state = "error";
+ var e = new Error('Error: magic mismatch: ' +
this.reply_hdr.magic);
+ this.report_error(e);
+ }
+ else
+ {
+ // FIXME - Determine major/minor version requirements
+ this.wire_reader.request(this.reply_hdr.size);
+ this.state = "link";
+ }
+ }
+
+ else if (this.state == "link")
+ {
+ this.reply_link = new SpiceLinkReply(mb);
+ // FIXME - Screen the caps - require minihdr at least, right?
+ if (this.reply_link.error)
+ {
+ this.state = "error";
+ var e = new Error('Error: reply link error ' +
this.reply_link.error);
+ this.report_error(e);
+ }
+ else
+ {
+ this.send_ticket(rsa_encrypt(this.reply_link.pub_key, this.password +
String.fromCharCode(0)));
+ this.state = "ticket";
+ this.wire_reader.request(SpiceLinkAuthReply.prototype.buffer_size());
+ }
+ }
+
+ else if (this.state == "ticket")
+ {
+ this.auth_reply = new SpiceLinkAuthReply(mb);
+ if (this.auth_reply.auth_code == SPICE_LINK_ERR_OK)
+ {
+ DEBUG > 0 && console.log(this.type + ': Connected');
+
+ if (this.type == SPICE_CHANNEL_DISPLAY)
+ {
+ // FIXME - pixmap and glz dictionary config info?
+ var dinit = new SpiceMsgcDisplayInit();
+ var reply = new SpiceMiniData();
+ reply.build_msg(SPICE_MSGC_DISPLAY_INIT, dinit);
+ DEBUG > 0 && console.log("Request display
init");
+ this.send_msg(reply);
+ }
+ this.state = "ready";
+ this.wire_reader.request(SpiceMiniData.prototype.buffer_size());
+ if (this.timeout)
+ {
+ window.clearTimeout(this.timeout);
+ delete this.timeout;
+ }
+ }
+ else
+ {
+ this.state = "error";
+ if (this.auth_reply.auth_code == SPICE_LINK_ERR_PERMISSION_DENIED)
+ {
+ var e = new Error("Permission denied.");
+ }
+ else
+ {
+ var e = new Error("Unexpected link error " +
this.auth_reply.auth_code);
+ }
+ this.report_error(e);
+ }
+ }
+ },
+
+ process_common_messages : function(msg)
+ {
+ if (msg.type == SPICE_MSG_SET_ACK)
+ {
+ var ack = new SpiceMsgSetAck(msg.data);
+ // FIXME - what to do with generation?
+ this.ack_window = ack.window;
+ DEBUG > 1 && console.log(this.type + ": set ack to " +
ack.window);
+ this.msgs_until_ack = this.ack_window;
+ var ackack = new SpiceMsgcAckSync(ack);
+ var reply = new SpiceMiniData();
+ reply.build_msg(SPICE_MSGC_ACK_SYNC, ackack);
+ this.send_msg(reply);
+ return true;
+ }
+
+ if (msg.type == SPICE_MSG_PING)
+ {
+ DEBUG > 1 && console.log("ping!");
+ var pong = new SpiceMiniData;
+ pong.type = SPICE_MSGC_PONG;
+ if (msg.data)
+ {
+ pong.data = msg.data.slice(0, 12);
+ }
+ pong.size = pong.buffer_size();
+ this.send_msg(pong);
+ return true;
+ }
+
+ if (msg.type == SPICE_MSG_NOTIFY)
+ {
+ // FIXME - Visibility + what
+ var notify = new SpiceMsgNotify(msg.data);
+ if (notify.severity == SPICE_NOTIFY_SEVERITY_ERROR)
+ this.log_err(notify.message);
+ else if (notify.severity == SPICE_NOTIFY_SEVERITY_WARN )
+ this.log_warn(notify.message);
+ else
+ this.log_info(notify.message);
+ return true;
+ }
+
+ return false;
+
+ },
+
+ process_message: function(msg)
+ {
+ var rc;
+ DEBUG > 0 && console.log("<< hdr " +
this.channel_type() + " type " + msg.type + " size " + (msg.data
&& msg.data.byteLength));
+ rc = this.process_common_messages(msg);
+ if (! rc)
+ {
+ if (this.process_channel_message)
+ {
+ rc = this.process_channel_message(msg);
+ if (! rc)
+ this.log_warn(this.type + ": Unknown message type " +
msg.type + "!");
+ }
+ else
+ this.log_err(this.type + ": No message handlers for this channel;
message " + msg.type);
+ }
+
+ if (this.msgs_until_ack !== undefined && this.ack_window)
+ {
+ this.msgs_until_ack--;
+ if (this.msgs_until_ack <= 0)
+ {
+ this.msgs_until_ack = this.ack_window;
+ var ack = new SpiceMiniData();
+ ack.type = SPICE_MSGC_ACK;
+ this.send_msg(ack);
+ DEBUG > 1 && console.log(this.type + ": sent ack");
+ }
+ }
+
+ return rc;
+ },
+
+ channel_type: function()
+ {
+ if (this.type == SPICE_CHANNEL_MAIN)
+ return "main";
+ else if (this.type == SPICE_CHANNEL_DISPLAY)
+ return "display";
+ else if (this.type == SPICE_CHANNEL_INPUTS)
+ return "inputs";
+ else if (this.type == SPICE_CHANNEL_CURSOR)
+ return "cursor";
+ return "unknown-" + this.type;
+
+ },
+
+ log_info: function()
+ {
+ var msg = Array.prototype.join.call(arguments, " ");
+ console.log(msg);
+ if (this.message_id)
+ {
+ var p = document.createElement("p");
+ p.appendChild(document.createTextNode(msg));
+ p.className += "spice-message-info";
+ document.getElementById(this.message_id).appendChild(p);
+ }
+ },
+
+ log_warn: function()
+ {
+ var msg = Array.prototype.join.call(arguments, " ");
+ console.log("WARNING: " + msg);
+ if (this.message_id)
+ {
+ var p = document.createElement("p");
+ p.appendChild(document.createTextNode(msg));
+ p.className += "spice-message-warning";
+ document.getElementById(this.message_id).appendChild(p);
+ }
+ },
+
+ log_err: function()
+ {
+ var msg = Array.prototype.join.call(arguments, " ");
+ console.log("ERROR: " + msg);
+ if (this.message_id)
+ {
+ var p = document.createElement("p");
+ p.appendChild(document.createTextNode(msg));
+ p.className += "spice-message-error";
+ document.getElementById(this.message_id).appendChild(p);
+ }
+ },
+
+ known_unimplemented: function(type, msg)
+ {
+ if ( (!this.warnings[type]) || DEBUG > 1)
+ {
+ var str = "";
+ if (DEBUG <= 1)
+ str = " [ further notices suppressed ]";
+ this.log_warn("Unimplemented function " + type + "(" +
msg + ")" + str);
+ this.warnings[type] = true;
+ }
+ },
+
+ report_error: function(e)
+ {
+ this.log_err(e.toString());
+ if (this.onerror != undefined)
+ this.onerror(e);
+ else
+ throw(e);
+ },
+
+ report_success: function(m)
+ {
+ if (this.onsuccess != undefined)
+ this.onsuccess(m);
+ },
+
+ cleanup: function()
+ {
+ if (this.timeout)
+ {
+ window.clearTimeout(this.timeout);
+ delete this.timeout;
+ }
+ if (this.ws)
+ {
+ this.ws.close();
+ this.ws = undefined;
+ }
+ },
+
+ handle_timeout: function()
+ {
+ var e = new Error("Connection timed out.");
+ this.report_error(e);
+ },
+}
+
+function spiceconn_timeout(sc)
+{
+ SpiceConn.prototype.handle_timeout.call(sc);
+}
diff --git a/src/wok/plugins/kimchi/ui/spice-html5/spicedataview.js
b/src/wok/plugins/kimchi/ui/spice-html5/spicedataview.js
new file mode 100644
index 0000000..800df03
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/spice-html5/spicedataview.js
@@ -0,0 +1,120 @@
+"use strict";
+/*
+ Copyright (C) 2012 by Jeremy P. White <jwhite(a)codeweavers.com>
+
+ This file is part of spice-html5.
+
+ spice-html5 is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ spice-html5 is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with spice-html5. If not, see <
http://www.gnu.org/licenses/>.
+*/
+
+/*----------------------------------------------------------------------------
+** SpiceDataView
+** FIXME FIXME
+** This is used because Firefox does not have DataView yet.
+** We should use DataView if we have it, because it *has* to
+** be faster than this code
+**--------------------------------------------------------------------------*/
+function SpiceDataView(buffer, byteOffset, byteLength)
+{
+ if (byteOffset !== undefined)
+ {
+ if (byteLength !== undefined)
+ this.u8 = new Uint8Array(buffer, byteOffset, byteLength);
+ else
+ this.u8 = new Uint8Array(buffer, byteOffset);
+ }
+ else
+ this.u8 = new Uint8Array(buffer);
+};
+
+SpiceDataView.prototype = {
+ getUint8: function(byteOffset)
+ {
+ return this.u8[byteOffset];
+ },
+ getUint16: function(byteOffset, littleEndian)
+ {
+ var low = 1, high = 0;
+ if (littleEndian)
+ {
+ low = 0;
+ high = 1;
+ }
+
+ return (this.u8[byteOffset + high] << 8) | this.u8[byteOffset + low];
+ },
+ getUint32: function(byteOffset, littleEndian)
+ {
+ var low = 2, high = 0;
+ if (littleEndian)
+ {
+ low = 0;
+ high = 2;
+ }
+
+ return (this.getUint16(byteOffset + high, littleEndian) << 16) |
+ this.getUint16(byteOffset + low, littleEndian);
+ },
+ getUint64: function (byteOffset, littleEndian)
+ {
+ var low = 4, high = 0;
+ if (littleEndian)
+ {
+ low = 0;
+ high = 4;
+ }
+
+ return (this.getUint32(byteOffset + high, littleEndian) << 32) |
+ this.getUint32(byteOffset + low, littleEndian);
+ },
+ setUint8: function(byteOffset, b)
+ {
+ this.u8[byteOffset] = (b & 0xff);
+ },
+ setUint16: function(byteOffset, i, littleEndian)
+ {
+ var low = 1, high = 0;
+ if (littleEndian)
+ {
+ low = 0;
+ high = 1;
+ }
+ this.u8[byteOffset + high] = (i & 0xffff) >> 8;
+ this.u8[byteOffset + low] = (i & 0x00ff);
+ },
+ setUint32: function(byteOffset, w, littleEndian)
+ {
+ var low = 2, high = 0;
+ if (littleEndian)
+ {
+ low = 0;
+ high = 2;
+ }
+
+ this.setUint16(byteOffset + high, (w & 0xffffffff) >> 16,
littleEndian);
+ this.setUint16(byteOffset + low, (w & 0x0000ffff), littleEndian);
+ },
+ setUint64: function(byteOffset, w, littleEndian)
+ {
+ var low = 4, high = 0;
+ if (littleEndian)
+ {
+ low = 0;
+ high = 4;
+ }
+
+ this.setUint32(byteOffset + high, (w & 0xffffffffffffffff) >> 32,
littleEndian);
+ this.setUint32(byteOffset + low, (w & 0x00000000ffffffff), littleEndian);
+ },
+}
diff --git a/src/wok/plugins/kimchi/ui/spice-html5/spicemsg.js
b/src/wok/plugins/kimchi/ui/spice-html5/spicemsg.js
new file mode 100644
index 0000000..c64f5a3
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/spice-html5/spicemsg.js
@@ -0,0 +1,1047 @@
+"use strict";
+/*
+ Copyright (C) 2012 by Jeremy P. White <jwhite(a)codeweavers.com>
+
+ This file is part of spice-html5.
+
+ spice-html5 is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ spice-html5 is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with spice-html5. If not, see <
http://www.gnu.org/licenses/>.
+*/
+
+/*----------------------------------------------------------------------------
+** Spice messages
+** This file contains classes for passing messages to and from
+** a spice server. This file should arguably be generated from
+** spice.proto, but it was instead put together by hand.
+**--------------------------------------------------------------------------*/
+function SpiceLinkHeader(a, at)
+{
+ this.magic = SPICE_MAGIC;
+ this.major_version = SPICE_VERSION_MAJOR;
+ this.minor_version = SPICE_VERSION_MINOR;
+ this.size = 0;
+ if (a !== undefined)
+ this.from_buffer(a, at);
+}
+
+SpiceLinkHeader.prototype =
+{
+ from_buffer: function(a, at)
+ {
+ at = at || 0;
+ var dv = new SpiceDataView(a);
+ this.magic = "";
+ for (var i = 0; i < 4; i++)
+ this.magic += String.fromCharCode(dv.getUint8(at + i));
+ at += 4;
+
+ this.major_version = dv.getUint32(at, true); at += 4;
+ this.minor_version = dv.getUint32(at, true); at += 4;
+ this.size = dv.getUint32(at, true); at += 4;
+ },
+
+ to_buffer: function(a, at)
+ {
+ at = at || 0;
+ var dv = new SpiceDataView(a);
+ for (var i = 0; i < 4; i++)
+ dv.setUint8(at + i, this.magic.charCodeAt(i));
+ at += 4;
+
+ dv.setUint32(at, this.major_version, true); at += 4;
+ dv.setUint32(at, this.minor_version, true); at += 4;
+ dv.setUint32(at, this.size, true); at += 4;
+ },
+ buffer_size: function()
+ {
+ return 16;
+ },
+}
+
+function SpiceLinkMess(a, at)
+{
+ this.connection_id = 0;
+ this.channel_type = 0;
+ this.channel_id = 0;
+ this.common_caps = [];
+ this.channel_caps = [];
+
+ if (a !== undefined)
+ this.from_buffer(a, at);
+}
+
+SpiceLinkMess.prototype =
+{
+ from_buffer: function(a, at)
+ {
+ at = at || 0;
+ var i;
+ var orig_at = at;
+ var dv = new SpiceDataView(a);
+ this.connection_id = dv.getUint32(at, true); at += 4;
+ this.channel_type = dv.getUint8(at, true); at++;
+ this.channel_id = dv.getUint8(at, true); at++;
+ var num_common_caps = dv.getUint32(at, true); at += 4;
+ var num_channel_caps = dv.getUint32(at, true); at += 4;
+ var caps_offset = dv.getUint32(at, true); at += 4;
+
+ at = orig_at + caps_offset;
+ this.common_caps = [];
+ for (i = 0; i < num_common_caps; i++)
+ {
+ this.common_caps.unshift(dv.getUint32(at, true)); at += 4;
+ }
+
+ this.channel_caps = [];
+ for (i = 0; i < num_channel_caps; i++)
+ {
+ this.channel_caps.unshift(dv.getUint32(at, true)); at += 4;
+ }
+ },
+
+ to_buffer: function(a, at)
+ {
+ at = at || 0;
+ var orig_at = at;
+ var i;
+ var dv = new SpiceDataView(a);
+ dv.setUint32(at, this.connection_id, true); at += 4;
+ dv.setUint8(at, this.channel_type, true); at++;
+ dv.setUint8(at, this.channel_id, true); at++;
+ dv.setUint32(at, this.common_caps.length, true); at += 4;
+ dv.setUint32(at, this.channel_caps.length, true); at += 4;
+ dv.setUint32(at, (at - orig_at) + 4, true); at += 4;
+
+ for (i = 0; i < this.common_caps.length; i++)
+ {
+ dv.setUint32(at, this.common_caps[i], true); at += 4;
+ }
+
+ for (i = 0; i < this.channel_caps.length; i++)
+ {
+ dv.setUint32(at, this.channel_caps[i], true); at += 4;
+ }
+ },
+ buffer_size: function()
+ {
+ return 18 + (4 * this.common_caps.length) + (4 * this.channel_caps.length);
+ }
+}
+
+function SpiceLinkReply(a, at)
+{
+ this.error = 0;
+ this.pub_key = undefined;
+ this.common_caps = [];
+ this.channel_caps = [];
+
+ if (a !== undefined)
+ this.from_buffer(a, at);
+}
+
+SpiceLinkReply.prototype =
+{
+ from_buffer: function(a, at)
+ {
+ at = at || 0;
+ var i;
+ var orig_at = at;
+ var dv = new SpiceDataView(a);
+ this.error = dv.getUint32(at, true); at += 4;
+
+ this.pub_key = create_rsa_from_mb(a, at);
+ at += SPICE_TICKET_PUBKEY_BYTES;
+
+ var num_common_caps = dv.getUint32(at, true); at += 4;
+ var num_channel_caps = dv.getUint32(at, true); at += 4;
+ var caps_offset = dv.getUint32(at, true); at += 4;
+
+ at = orig_at + caps_offset;
+ this.common_caps = [];
+ for (i = 0; i < num_common_caps; i++)
+ {
+ this.common_caps.unshift(dv.getUint32(at, true)); at += 4;
+ }
+
+ this.channel_caps = [];
+ for (i = 0; i < num_channel_caps; i++)
+ {
+ this.channel_caps.unshift(dv.getUint32(at, true)); at += 4;
+ }
+ },
+}
+
+function SpiceLinkAuthTicket(a, at)
+{
+ this.auth_mechanism = 0;
+ this.encrypted_data = undefined;
+}
+
+SpiceLinkAuthTicket.prototype =
+{
+ to_buffer: function(a, at)
+ {
+ at = at || 0;
+ var i;
+ var dv = new SpiceDataView(a);
+ dv.setUint32(at, this.auth_mechanism, true); at += 4;
+ for (i = 0; i < SPICE_TICKET_KEY_PAIR_LENGTH / 8; i++)
+ {
+ if (this.encrypted_data && i < this.encrypted_data.length)
+ dv.setUint8(at, this.encrypted_data[i], true);
+ else
+ dv.setUint8(at, 0, true);
+ at++;
+ }
+ },
+ buffer_size: function()
+ {
+ return 4 + (SPICE_TICKET_KEY_PAIR_LENGTH / 8);
+ }
+}
+
+function SpiceLinkAuthReply(a, at)
+{
+ this.auth_code = 0;
+ if (a !== undefined)
+ this.from_buffer(a, at);
+}
+
+SpiceLinkAuthReply.prototype =
+{
+ from_buffer: function(a, at)
+ {
+ at = at || 0;
+ var dv = new SpiceDataView(a);
+ this.auth_code = dv.getUint32(at, true); at += 4;
+ },
+ buffer_size: function()
+ {
+ return 4;
+ }
+}
+
+function SpiceMiniData(a, at)
+{
+ this.type = 0;
+ this.size = 0;
+ this.data = undefined;
+ if (a !== undefined)
+ this.from_buffer(a, at);
+}
+
+SpiceMiniData.prototype =
+{
+ from_buffer: function(a, at)
+ {
+ at = at || 0;
+ var i;
+ var dv = new SpiceDataView(a);
+ this.type = dv.getUint16(at, true); at += 2;
+ this.size = dv.getUint32(at, true); at += 4;
+ if (a.byteLength > at)
+ {
+ this.data = a.slice(at);
+ at += this.data.byteLength;
+ }
+ },
+ to_buffer : function(a, at)
+ {
+ at = at || 0;
+ var i;
+ var dv = new SpiceDataView(a);
+ dv.setUint16(at, this.type, true); at += 2;
+ dv.setUint32(at, this.data ? this.data.byteLength : 0, true); at += 4;
+ if (this.data && this.data.byteLength > 0)
+ {
+ var u8arr = new Uint8Array(this.data);
+ for (i = 0; i < u8arr.length; i++, at++)
+ dv.setUint8(at, u8arr[i], true);
+ }
+ },
+ build_msg : function(in_type, extra)
+ {
+ this.type = in_type;
+ this.size = extra.buffer_size();
+ this.data = new ArrayBuffer(this.size);
+ extra.to_buffer(this.data);
+ },
+ buffer_size: function()
+ {
+ if (this.data)
+ return 6 + this.data.byteLength;
+ else
+ return 6;
+ },
+}
+
+function SpiceMsgChannels(a, at)
+{
+ this.num_of_channels = 0;
+ this.channels = [];
+ if (a !== undefined)
+ this.from_buffer(a, at);
+}
+
+SpiceMsgChannels.prototype =
+{
+ from_buffer: function(a, at)
+ {
+ at = at || 0;
+ var i;
+ var dv = new SpiceDataView(a);
+ this.num_of_channels = dv.getUint32(at, true); at += 4;
+ for (i = 0; i < this.num_of_channels; i++)
+ {
+ var chan = new SpiceChannelId();
+ at = chan.from_dv(dv, at, a);
+ this.channels.push(chan);
+ }
+ },
+}
+
+function SpiceMsgMainInit(a, at)
+{
+ this.from_buffer(a, at);
+}
+
+SpiceMsgMainInit.prototype =
+{
+ from_buffer: function(a, at)
+ {
+ at = at || 0;
+ var dv = new SpiceDataView(a);
+ this.session_id = dv.getUint32(at, true); at += 4;
+ this.display_channels_hint = dv.getUint32(at, true); at += 4;
+ this.supported_mouse_modes = dv.getUint32(at, true); at += 4;
+ this.current_mouse_mode = dv.getUint32(at, true); at += 4;
+ this.agent_connected = dv.getUint32(at, true); at += 4;
+ this.agent_tokens = dv.getUint32(at, true); at += 4;
+ this.multi_media_time = dv.getUint32(at, true); at += 4;
+ this.ram_hint = dv.getUint32(at, true); at += 4;
+ },
+}
+
+function SpiceMsgMainMouseMode(a, at)
+{
+ this.from_buffer(a, at);
+}
+
+SpiceMsgMainMouseMode.prototype =
+{
+ from_buffer: function(a, at)
+ {
+ at = at || 0;
+ var dv = new SpiceDataView(a);
+ this.supported_modes = dv.getUint16(at, true); at += 2;
+ this.current_mode = dv.getUint16(at, true); at += 2;
+ },
+}
+
+function SpiceMsgSetAck(a, at)
+{
+ this.from_buffer(a, at);
+}
+
+SpiceMsgSetAck.prototype =
+{
+ from_buffer: function(a, at)
+ {
+ at = at || 0;
+ var dv = new SpiceDataView(a);
+ this.generation = dv.getUint32(at, true); at += 4;
+ this.window = dv.getUint32(at, true); at += 4;
+ },
+}
+
+function SpiceMsgcAckSync(ack)
+{
+ this.generation = ack.generation;
+}
+
+SpiceMsgcAckSync.prototype =
+{
+ to_buffer: function(a, at)
+ {
+ at = at || 0;
+ var dv = new SpiceDataView(a);
+ dv.setUint32(at, this.generation, true); at += 4;
+ },
+ buffer_size: function()
+ {
+ return 4;
+ }
+}
+
+function SpiceMsgcMainMouseModeRequest(mode)
+{
+ this.mode = mode;
+}
+
+SpiceMsgcMainMouseModeRequest.prototype =
+{
+ to_buffer: function(a, at)
+ {
+ at = at || 0;
+ var dv = new SpiceDataView(a);
+ dv.setUint16(at, this.mode, true); at += 2;
+ },
+ buffer_size: function()
+ {
+ return 2;
+ }
+}
+
+function SpiceMsgcMainAgentStart(num_tokens)
+{
+ this.num_tokens = num_tokens;
+}
+
+SpiceMsgcMainAgentStart.prototype =
+{
+ to_buffer: function(a, at)
+ {
+ at = at || 0;
+ var dv = new SpiceDataView(a);
+ dv.setUint32(at, this.num_tokens, true); at += 4;
+ },
+ buffer_size: function()
+ {
+ return 4;
+ }
+}
+
+function SpiceMsgcMainAgentData(type, data)
+{
+ this.protocol = VD_AGENT_PROTOCOL;
+ this.type = type;
+ this.opaque = 0;
+ this.size = data.buffer_size();
+ this.data = data;
+}
+
+SpiceMsgcMainAgentData.prototype =
+{
+ to_buffer: function(a, at)
+ {
+ at = at || 0;
+ var dv = new SpiceDataView(a);
+ dv.setUint32(at, this.protocol, true); at += 4;
+ dv.setUint32(at, this.type, true); at += 4;
+ dv.setUint64(at, this.opaque, true); at += 8;
+ dv.setUint32(at, this.size, true); at += 4;
+ this.data.to_buffer(a, at);
+ },
+ buffer_size: function()
+ {
+ return 4 + 4 + 8 + 4 + this.data.buffer_size();
+ }
+}
+
+function VDAgentMonitorsConfig(flags, width, height, depth, x, y)
+{
+ this.num_mon = 1;
+ this.flags = flags;
+ this.width = width;
+ this.height = height;
+ this.depth = depth;
+ this.x = x;
+ this.y = y;
+}
+
+VDAgentMonitorsConfig.prototype =
+{
+ to_buffer: function(a, at)
+ {
+ at = at || 0;
+ var dv = new SpiceDataView(a);
+ dv.setUint32(at, this.num_mon, true); at += 4;
+ dv.setUint32(at, this.flags, true); at += 4;
+ dv.setUint32(at, this.height, true); at += 4;
+ dv.setUint32(at, this.width, true); at += 4;
+ dv.setUint32(at, this.depth, true); at += 4;
+ dv.setUint32(at, this.x, true); at += 4;
+ dv.setUint32(at, this.y, true); at += 4;
+ },
+ buffer_size: function()
+ {
+ return 28;
+ }
+}
+
+function SpiceMsgNotify(a, at)
+{
+ this.from_buffer(a, at);
+}
+
+SpiceMsgNotify.prototype =
+{
+ from_buffer: function(a, at)
+ {
+ at = at || 0;
+ var i;
+ var dv = new SpiceDataView(a);
+ this.time_stamp = dv.getUint64(at, true); at += 8;
+ this.severity = dv.getUint32(at, true); at += 4;
+ this.visibility = dv.getUint32(at, true); at += 4;
+ this.what = dv.getUint32(at, true); at += 4;
+ this.message_len = dv.getUint32(at, true); at += 4;
+ this.message = "";
+ for (i = 0; i < this.message_len; i++)
+ {
+ var c = dv.getUint8(at, true); at++;
+ this.message += String.fromCharCode(c);
+ }
+ },
+}
+
+function SpiceMsgcDisplayInit()
+{
+ this.pixmap_cache_id = 1;
+ this.glz_dictionary_id = 0;
+ this.pixmap_cache_size = 10 * 1024 * 1024;
+ this.glz_dictionary_window_size = 0;
+}
+
+SpiceMsgcDisplayInit.prototype =
+{
+ to_buffer: function(a, at)
+ {
+ at = at || 0;
+ var dv = new SpiceDataView(a);
+ dv.setUint8(at, this.pixmap_cache_id, true); at++;
+ dv.setUint64(at, this.pixmap_cache_size, true); at += 8;
+ dv.setUint8(at, this.glz_dictionary_id, true); at++;
+ dv.setUint32(at, this.glz_dictionary_window_size, true); at += 4;
+ },
+ buffer_size: function()
+ {
+ return 14;
+ }
+}
+
+function SpiceMsgDisplayBase()
+{
+}
+
+SpiceMsgDisplayBase.prototype =
+{
+ from_dv : function(dv, at, mb)
+ {
+ this.surface_id = dv.getUint32(at, true); at += 4;
+ this.box = new SpiceRect;
+ at = this.box.from_dv(dv, at, mb);
+ this.clip = new SpiceClip;
+ return this.clip.from_dv(dv, at, mb);
+ },
+}
+
+function SpiceMsgDisplayDrawCopy(a, at)
+{
+ this.from_buffer(a, at);
+}
+
+SpiceMsgDisplayDrawCopy.prototype =
+{
+ from_buffer: function(a, at)
+ {
+ at = at || 0;
+ var dv = new SpiceDataView(a);
+ this.base = new SpiceMsgDisplayBase;
+ at = this.base.from_dv(dv, at, a);
+ this.data = new SpiceCopy;
+ return this.data.from_dv(dv, at, a);
+ },
+}
+
+function SpiceMsgDisplayDrawFill(a, at)
+{
+ this.from_buffer(a, at);
+}
+
+SpiceMsgDisplayDrawFill.prototype =
+{
+ from_buffer: function(a, at)
+ {
+ at = at || 0;
+ var dv = new SpiceDataView(a);
+ this.base = new SpiceMsgDisplayBase;
+ at = this.base.from_dv(dv, at, a);
+ this.data = new SpiceFill;
+ return this.data.from_dv(dv, at, a);
+ },
+}
+
+function SpiceMsgDisplayCopyBits(a, at)
+{
+ this.from_buffer(a, at);
+}
+
+SpiceMsgDisplayCopyBits.prototype =
+{
+ from_buffer: function(a, at)
+ {
+ at = at || 0;
+ var dv = new SpiceDataView(a);
+ this.base = new SpiceMsgDisplayBase;
+ at = this.base.from_dv(dv, at, a);
+ this.src_pos = new SpicePoint;
+ return this.src_pos.from_dv(dv, at, a);
+ },
+}
+
+
+function SpiceMsgSurfaceCreate(a, at)
+{
+ this.from_buffer(a, at);
+}
+
+SpiceMsgSurfaceCreate.prototype =
+{
+ from_buffer: function(a, at)
+ {
+ at = at || 0;
+ var dv = new SpiceDataView(a);
+ this.surface = new SpiceSurface;
+ return this.surface.from_dv(dv, at, a);
+ },
+}
+
+function SpiceMsgSurfaceDestroy(a, at)
+{
+ this.from_buffer(a, at);
+}
+
+SpiceMsgSurfaceDestroy.prototype =
+{
+ from_buffer: function(a, at)
+ {
+ at = at || 0;
+ var dv = new SpiceDataView(a);
+ this.surface_id = dv.getUint32(at, true); at += 4;
+ },
+}
+
+function SpiceMsgInputsInit(a, at)
+{
+ this.from_buffer(a, at);
+}
+
+SpiceMsgInputsInit.prototype =
+{
+ from_buffer: function(a, at)
+ {
+ at = at || 0;
+ var dv = new SpiceDataView(a);
+ this.keyboard_modifiers = dv.getUint16(at, true); at += 2;
+ return at;
+ },
+}
+
+function SpiceMsgInputsKeyModifiers(a, at)
+{
+ this.from_buffer(a, at);
+}
+
+SpiceMsgInputsKeyModifiers.prototype =
+{
+ from_buffer: function(a, at)
+ {
+ at = at || 0;
+ var dv = new SpiceDataView(a);
+ this.keyboard_modifiers = dv.getUint16(at, true); at += 2;
+ return at;
+ },
+}
+
+function SpiceMsgCursorInit(a, at)
+{
+ this.from_buffer(a, at);
+}
+
+SpiceMsgCursorInit.prototype =
+{
+ from_buffer: function(a, at, mb)
+ {
+ at = at || 0;
+ var dv = new SpiceDataView(a);
+ this.position = new SpicePoint16;
+ at = this.position.from_dv(dv, at, mb);
+ this.trail_length = dv.getUint16(at, true); at += 2;
+ this.trail_frequency = dv.getUint16(at, true); at += 2;
+ this.visible = dv.getUint8(at, true); at ++;
+ this.cursor = new SpiceCursor;
+ return this.cursor.from_dv(dv, at, a);
+ },
+}
+
+function SpiceMsgPlaybackData(a, at)
+{
+ this.from_buffer(a, at);
+}
+
+SpiceMsgPlaybackData.prototype =
+{
+ from_buffer: function(a, at, mb)
+ {
+ at = at || 0;
+ var dv = new SpiceDataView(a);
+ this.time = dv.getUint32(at, true); at += 4;
+ if (a.byteLength > at)
+ {
+ this.data = a.slice(at);
+ at += this.data.byteLength;
+ }
+ return at;
+ },
+}
+
+function SpiceMsgPlaybackMode(a, at)
+{
+ this.from_buffer(a, at);
+}
+
+SpiceMsgPlaybackMode.prototype =
+{
+ from_buffer: function(a, at, mb)
+ {
+ at = at || 0;
+ var dv = new SpiceDataView(a);
+ this.time = dv.getUint32(at, true); at += 4;
+ this.mode = dv.getUint16(at, true); at += 2;
+ if (a.byteLength > at)
+ {
+ this.data = a.slice(at);
+ at += this.data.byteLength;
+ }
+ return at;
+ },
+}
+
+function SpiceMsgPlaybackStart(a, at)
+{
+ this.from_buffer(a, at);
+}
+
+SpiceMsgPlaybackStart.prototype =
+{
+ from_buffer: function(a, at, mb)
+ {
+ at = at || 0;
+ var dv = new SpiceDataView(a);
+ this.channels = dv.getUint32(at, true); at += 4;
+ this.format = dv.getUint16(at, true); at += 2;
+ this.frequency = dv.getUint32(at, true); at += 4;
+ this.time = dv.getUint32(at, true); at += 4;
+ return at;
+ },
+}
+
+
+
+function SpiceMsgCursorSet(a, at)
+{
+ this.from_buffer(a, at);
+}
+
+SpiceMsgCursorSet.prototype =
+{
+ from_buffer: function(a, at, mb)
+ {
+ at = at || 0;
+ var dv = new SpiceDataView(a);
+ this.position = new SpicePoint16;
+ at = this.position.from_dv(dv, at, mb);
+ this.visible = dv.getUint8(at, true); at ++;
+ this.cursor = new SpiceCursor;
+ return this.cursor.from_dv(dv, at, a);
+ },
+}
+
+
+function SpiceMsgcMousePosition(sc, e)
+{
+ // FIXME - figure out how to correctly compute display_id
+ this.display_id = 0;
+ this.buttons_state = sc.buttons_state;
+ if (e)
+ {
+ var scrollTop = document.body.scrollTop || document.documentElement.scrollTop;
+ var scrollLeft = document.body.scrollLeft ||
document.documentElement.scrollLeft;
+
+ this.x = e.clientX -
sc.display.surfaces[sc.display.primary_surface].canvas.offsetLeft + scrollLeft;
+ this.y = e.clientY -
sc.display.surfaces[sc.display.primary_surface].canvas.offsetTop + scrollTop;
+ sc.mousex = this.x;
+ sc.mousey = this.y;
+ }
+ else
+ {
+ this.x = this.y = this.buttons_state = 0;
+ }
+}
+
+SpiceMsgcMousePosition.prototype =
+{
+ to_buffer: function(a, at)
+ {
+ at = at || 0;
+ var dv = new SpiceDataView(a);
+ dv.setUint32(at, this.x, true); at += 4;
+ dv.setUint32(at, this.y, true); at += 4;
+ dv.setUint16(at, this.buttons_state, true); at += 2;
+ dv.setUint8(at, this.display_id, true); at += 1;
+ return at;
+ },
+ buffer_size: function()
+ {
+ return 11;
+ }
+}
+
+function SpiceMsgcMouseMotion(sc, e)
+{
+ // FIXME - figure out how to correctly compute display_id
+ this.display_id = 0;
+ this.buttons_state = sc.buttons_state;
+ if (e)
+ {
+ this.x = e.clientX -
sc.display.surfaces[sc.display.primary_surface].canvas.offsetLeft;
+ this.y = e.clientY -
sc.display.surfaces[sc.display.primary_surface].canvas.offsetTop;
+
+ if (sc.mousex !== undefined)
+ {
+ this.x -= sc.mousex;
+ this.y -= sc.mousey;
+ }
+ sc.mousex = e.clientX -
sc.display.surfaces[sc.display.primary_surface].canvas.offsetLeft;
+ sc.mousey = e.clientY -
sc.display.surfaces[sc.display.primary_surface].canvas.offsetTop;
+ }
+ else
+ {
+ this.x = this.y = this.buttons_state = 0;
+ }
+}
+
+/* Use the same functions as for MousePosition */
+SpiceMsgcMouseMotion.prototype.to_buffer = SpiceMsgcMousePosition.prototype.to_buffer;
+SpiceMsgcMouseMotion.prototype.buffer_size =
SpiceMsgcMousePosition.prototype.buffer_size;
+
+function SpiceMsgcMousePress(sc, e)
+{
+ if (e)
+ {
+ this.button = e.button + 1;
+ this.buttons_state = 1 << e.button;
+ sc.buttons_state = this.buttons_state;
+ }
+ else
+ {
+ this.button = SPICE_MOUSE_BUTTON_LEFT;
+ this.buttons_state = SPICE_MOUSE_BUTTON_MASK_LEFT;
+ }
+}
+
+SpiceMsgcMousePress.prototype =
+{
+ to_buffer: function(a, at)
+ {
+ at = at || 0;
+ var dv = new SpiceDataView(a);
+ dv.setUint8(at, this.button, true); at ++;
+ dv.setUint16(at, this.buttons_state, true); at += 2;
+ return at;
+ },
+ buffer_size: function()
+ {
+ return 3;
+ }
+}
+
+function SpiceMsgcMouseRelease(sc, e)
+{
+ if (e)
+ {
+ this.button = e.button + 1;
+ this.buttons_state = 0;
+ sc.buttons_state = this.buttons_state;
+ }
+ else
+ {
+ this.button = SPICE_MOUSE_BUTTON_LEFT;
+ this.buttons_state = 0;
+ }
+}
+
+/* Use the same functions as for MousePress */
+SpiceMsgcMouseRelease.prototype.to_buffer = SpiceMsgcMousePress.prototype.to_buffer;
+SpiceMsgcMouseRelease.prototype.buffer_size = SpiceMsgcMousePress.prototype.buffer_size;
+
+
+function SpiceMsgcKeyDown(e)
+{
+ if (e)
+ {
+ this.code = keycode_to_start_scan(e.keyCode);
+ }
+ else
+ {
+ this.code = 0;
+ }
+}
+
+SpiceMsgcKeyDown.prototype =
+{
+ to_buffer: function(a, at)
+ {
+ at = at || 0;
+ var dv = new SpiceDataView(a);
+ dv.setUint32(at, this.code, true); at += 4;
+ return at;
+ },
+ buffer_size: function()
+ {
+ return 4;
+ }
+}
+
+function SpiceMsgcKeyUp(e)
+{
+ if (e)
+ {
+ this.code = keycode_to_end_scan(e.keyCode);
+ }
+ else
+ {
+ this.code = 0;
+ }
+}
+
+/* Use the same functions as for KeyDown */
+SpiceMsgcKeyUp.prototype.to_buffer = SpiceMsgcKeyDown.prototype.to_buffer;
+SpiceMsgcKeyUp.prototype.buffer_size = SpiceMsgcKeyDown.prototype.buffer_size;
+
+function SpiceMsgDisplayStreamCreate(a, at)
+{
+ this.from_buffer(a, at);
+}
+
+SpiceMsgDisplayStreamCreate.prototype =
+{
+ from_buffer: function(a, at)
+ {
+ at = at || 0;
+ var dv = new SpiceDataView(a);
+ this.surface_id = dv.getUint32(at, true); at += 4;
+ this.id = dv.getUint32(at, true); at += 4;
+ this.flags = dv.getUint8(at, true); at += 1;
+ this.codec_type = dv.getUint8(at, true); at += 1;
+ this.stamp = dv.getUint64(at, true); at += 8;
+ this.stream_width = dv.getUint32(at, true); at += 4;
+ this.stream_height = dv.getUint32(at, true); at += 4;
+ this.src_width = dv.getUint32(at, true); at += 4;
+ this.src_height = dv.getUint32(at, true); at += 4;
+
+ this.dest = new SpiceRect;
+ at = this.dest.from_dv(dv, at, a);
+ this.clip = new SpiceClip;
+ this.clip.from_dv(dv, at, a);
+ },
+}
+
+function SpiceStreamDataHeader(a, at)
+{
+}
+
+SpiceStreamDataHeader.prototype =
+{
+ from_dv : function(dv, at, mb)
+ {
+ this.id = dv.getUint32(at, true); at += 4;
+ this.multi_media_time = dv.getUint32(at, true); at += 4;
+ return at;
+ },
+}
+
+function SpiceMsgDisplayStreamData(a, at)
+{
+ this.from_buffer(a, at);
+}
+
+SpiceMsgDisplayStreamData.prototype =
+{
+ from_buffer: function(a, at)
+ {
+ at = at || 0;
+ var dv = new SpiceDataView(a);
+ this.base = new SpiceStreamDataHeader;
+ at = this.base.from_dv(dv, at, a);
+ this.data_size = dv.getUint32(at, true); at += 4;
+ this.data = dv.u8.subarray(at, at + this.data_size);
+ },
+}
+
+function SpiceMsgDisplayStreamClip(a, at)
+{
+ this.from_buffer(a, at);
+}
+
+SpiceMsgDisplayStreamClip.prototype =
+{
+ from_buffer: function(a, at)
+ {
+ at = at || 0;
+ var dv = new SpiceDataView(a);
+ this.id = dv.getUint32(at, true); at += 4;
+ this.clip = new SpiceClip;
+ this.clip.from_dv(dv, at, a);
+ },
+}
+
+function SpiceMsgDisplayStreamDestroy(a, at)
+{
+ this.from_buffer(a, at);
+}
+
+SpiceMsgDisplayStreamDestroy.prototype =
+{
+ from_buffer: function(a, at)
+ {
+ at = at || 0;
+ var dv = new SpiceDataView(a);
+ this.id = dv.getUint32(at, true); at += 4;
+ },
+}
+
+function SpiceMsgDisplayInvalList(a, at)
+{
+ this.count = 0;
+ this.resources = [];
+ this.from_buffer(a,at);
+}
+
+SpiceMsgDisplayInvalList.prototype =
+{
+ from_buffer: function (a, at)
+ {
+ var i;
+ at = at || 0;
+ var dv = new SpiceDataView(a);
+ this.count = dv.getUint16(at, true); at += 2;
+ for (i = 0; i < this.count; i++)
+ {
+ this.resources[i] = {};
+ this.resources[i].type = dv.getUint8(at, true); at++;
+ this.resources[i].id = dv.getUint64(at, true); at += 8;
+ }
+ },
+}
diff --git a/src/wok/plugins/kimchi/ui/spice-html5/spicetype.js
b/src/wok/plugins/kimchi/ui/spice-html5/spicetype.js
new file mode 100644
index 0000000..951b277
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/spice-html5/spicetype.js
@@ -0,0 +1,473 @@
+"use strict";
+/*
+ Copyright (C) 2012 by Jeremy P. White <jwhite(a)codeweavers.com>
+
+ This file is part of spice-html5.
+
+ spice-html5 is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ spice-html5 is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with spice-html5. If not, see <
http://www.gnu.org/licenses/>.
+*/
+
+/*----------------------------------------------------------------------------
+** Spice types
+** This file contains classes for common spice types.
+** Generally, they are used as helpers in reading and writing messages
+** to and from the server.
+**--------------------------------------------------------------------------*/
+
+function SpiceChannelId()
+{
+}
+SpiceChannelId.prototype =
+{
+ from_dv: function(dv, at, mb)
+ {
+ this.type = dv.getUint8(at, true); at ++;
+ this.id = dv.getUint8(at, true); at ++;
+ return at;
+ },
+}
+
+function SpiceRect()
+{
+}
+
+SpiceRect.prototype =
+{
+ from_dv: function(dv, at, mb)
+ {
+ this.top = dv.getUint32(at, true); at += 4;
+ this.left = dv.getUint32(at, true); at += 4;
+ this.bottom = dv.getUint32(at, true); at += 4;
+ this.right = dv.getUint32(at, true); at += 4;
+ return at;
+ },
+ is_same_size : function(r)
+ {
+ if ((this.bottom - this.top) == (r.bottom - r.top) &&
+ (this.right - this.left) == (r.right - r.left) )
+ return true;
+
+ return false;
+ },
+}
+
+function SpiceClipRects()
+{
+}
+
+SpiceClipRects.prototype =
+{
+ from_dv: function(dv, at, mb)
+ {
+ var i;
+ this.num_rects = dv.getUint32(at, true); at += 4;
+ if (this.num_rects > 0)
+ this.rects = [];
+ for (i = 0; i < this.num_rects; i++)
+ {
+ this.rects[i] = new SpiceRect();
+ at = this.rects[i].from_dv(dv, at, mb);
+ }
+ return at;
+ },
+}
+
+function SpiceClip()
+{
+}
+
+SpiceClip.prototype =
+{
+ from_dv: function(dv, at, mb)
+ {
+ this.type = dv.getUint8(at, true); at ++;
+ if (this.type == SPICE_CLIP_TYPE_RECTS)
+ {
+ this.rects = new SpiceClipRects();
+ at = this.rects.from_dv(dv, at, mb);
+ }
+ return at;
+ },
+}
+
+function SpiceImageDescriptor()
+{
+}
+
+SpiceImageDescriptor.prototype =
+{
+ from_dv: function(dv, at, mb)
+ {
+ this.id = dv.getUint64(at, true); at += 8;
+ this.type = dv.getUint8(at, true); at ++;
+ this.flags = dv.getUint8(at, true); at ++;
+ this.width = dv.getUint32(at, true); at += 4;
+ this.height= dv.getUint32(at, true); at += 4;
+ return at;
+ },
+}
+
+function SpicePalette()
+{
+}
+
+SpicePalette.prototype =
+{
+ from_dv: function(dv, at, mb)
+ {
+ var i;
+ this.unique = dv.getUint64(at, true); at += 8;
+ this.num_ents = dv.getUint16(at, true); at += 2;
+ this.ents = [];
+ for (i = 0; i < this.num_ents; i++)
+ {
+ this.ents[i] = dv.getUint32(at, true); at += 4;
+ }
+ return at;
+ },
+}
+
+function SpiceBitmap()
+{
+}
+
+SpiceBitmap.prototype =
+{
+ from_dv: function(dv, at, mb)
+ {
+ this.format = dv.getUint8(at, true); at++;
+ this.flags = dv.getUint8(at, true); at++;
+ this.x = dv.getUint32(at, true); at += 4;
+ this.y = dv.getUint32(at, true); at += 4;
+ this.stride = dv.getUint32(at, true); at += 4;
+ if (this.flags & SPICE_BITMAP_FLAGS_PAL_FROM_CACHE)
+ {
+ this.palette_id = dv.getUint64(at, true); at += 8;
+ }
+ else
+ {
+ var offset = dv.getUint32(at, true); at += 4;
+ if (offset == 0)
+ this.palette = null;
+ else
+ {
+ this.palette = new SpicePalette;
+ this.palette.from_dv(dv, offset, mb);
+ }
+ }
+ // FIXME - should probably constrain this to the offset
+ // of palette, if non zero
+ this.data = mb.slice(at);
+ at += this.data.byteLength;
+ return at;
+ },
+}
+
+function SpiceImage()
+{
+}
+
+SpiceImage.prototype =
+{
+ from_dv: function(dv, at, mb)
+ {
+ this.descriptor = new SpiceImageDescriptor;
+ at = this.descriptor.from_dv(dv, at, mb);
+
+ if (this.descriptor.type == SPICE_IMAGE_TYPE_LZ_RGB)
+ {
+ this.lz_rgb = new Object();
+ this.lz_rgb.length = dv.getUint32(at, true); at += 4;
+ var initial_at = at;
+ this.lz_rgb.magic = "";
+ for (var i = 3; i >= 0; i--)
+ this.lz_rgb.magic += String.fromCharCode(dv.getUint8(at + i));
+ at += 4;
+
+ // NOTE: The endian change is *correct*
+ this.lz_rgb.version = dv.getUint32(at); at += 4;
+ this.lz_rgb.type = dv.getUint32(at); at += 4;
+ this.lz_rgb.width = dv.getUint32(at); at += 4;
+ this.lz_rgb.height = dv.getUint32(at); at += 4;
+ this.lz_rgb.stride = dv.getUint32(at); at += 4;
+ this.lz_rgb.top_down = dv.getUint32(at); at += 4;
+
+ var header_size = at - initial_at;
+
+ this.lz_rgb.data = mb.slice(at, this.lz_rgb.length + at - header_size);
+ at += this.lz_rgb.data.byteLength;
+
+ }
+
+ if (this.descriptor.type == SPICE_IMAGE_TYPE_BITMAP)
+ {
+ this.bitmap = new SpiceBitmap;
+ at = this.bitmap.from_dv(dv, at, mb);
+ }
+
+ if (this.descriptor.type == SPICE_IMAGE_TYPE_SURFACE)
+ {
+ this.surface_id = dv.getUint32(at, true); at += 4;
+ }
+
+ if (this.descriptor.type == SPICE_IMAGE_TYPE_JPEG)
+ {
+ this.jpeg = new Object;
+ this.jpeg.data_size = dv.getUint32(at, true); at += 4;
+ this.jpeg.data = mb.slice(at);
+ at += this.jpeg.data.byteLength;
+ }
+
+ if (this.descriptor.type == SPICE_IMAGE_TYPE_JPEG_ALPHA)
+ {
+ this.jpeg_alpha = new Object;
+ this.jpeg_alpha.flags = dv.getUint8(at, true); at += 1;
+ this.jpeg_alpha.jpeg_size = dv.getUint32(at, true); at += 4;
+ this.jpeg_alpha.data_size = dv.getUint32(at, true); at += 4;
+ this.jpeg_alpha.data = mb.slice(at, this.jpeg_alpha.jpeg_size + at);
+ at += this.jpeg_alpha.data.byteLength;
+ // Alpha channel is an LZ image
+ this.jpeg_alpha.alpha = new Object();
+ this.jpeg_alpha.alpha.length = this.jpeg_alpha.data_size -
this.jpeg_alpha.jpeg_size;
+ var initial_at = at;
+ this.jpeg_alpha.alpha.magic = "";
+ for (var i = 3; i >= 0; i--)
+ this.jpeg_alpha.alpha.magic += String.fromCharCode(dv.getUint8(at + i));
+ at += 4;
+
+ // NOTE: The endian change is *correct*
+ this.jpeg_alpha.alpha.version = dv.getUint32(at); at += 4;
+ this.jpeg_alpha.alpha.type = dv.getUint32(at); at += 4;
+ this.jpeg_alpha.alpha.width = dv.getUint32(at); at += 4;
+ this.jpeg_alpha.alpha.height = dv.getUint32(at); at += 4;
+ this.jpeg_alpha.alpha.stride = dv.getUint32(at); at += 4;
+ this.jpeg_alpha.alpha.top_down = dv.getUint32(at); at += 4;
+
+ var header_size = at - initial_at;
+
+ this.jpeg_alpha.alpha.data = mb.slice(at, this.jpeg_alpha.alpha.length + at
- header_size);
+ at += this.jpeg_alpha.alpha.data.byteLength;
+ }
+
+ if (this.descriptor.type == SPICE_IMAGE_TYPE_QUIC)
+ {
+ this.quic = new SpiceQuic;
+ at = this.quic.from_dv(dv, at, mb);
+ }
+ return at;
+ },
+}
+
+
+function SpiceQMask()
+{
+}
+
+SpiceQMask.prototype =
+{
+ from_dv: function(dv, at, mb)
+ {
+ this.flags = dv.getUint8(at, true); at++;
+ this.pos = new SpicePoint;
+ at = this.pos.from_dv(dv, at, mb);
+ var offset = dv.getUint32(at, true); at += 4;
+ if (offset == 0)
+ {
+ this.bitmap = null;
+ return at;
+ }
+
+ this.bitmap = new SpiceImage;
+ return this.bitmap.from_dv(dv, offset, mb);
+ },
+}
+
+
+function SpicePattern()
+{
+}
+
+SpicePattern.prototype =
+{
+ from_dv: function(dv, at, mb)
+ {
+ var offset = dv.getUint32(at, true); at += 4;
+ if (offset == 0)
+ {
+ this.pat = null;
+ }
+ else
+ {
+ this.pat = new SpiceImage;
+ this.pat.from_dv(dv, offset, mb);
+ }
+
+ this.pos = new SpicePoint;
+ return this.pos.from_dv(dv, at, mb);
+ }
+}
+
+function SpiceBrush()
+{
+}
+
+SpiceBrush.prototype =
+{
+ from_dv: function(dv, at, mb)
+ {
+ this.type = dv.getUint8(at, true); at ++;
+ if (this.type == SPICE_BRUSH_TYPE_SOLID)
+ {
+ this.color = dv.getUint32(at, true); at += 4;
+ }
+ else if (this.type == SPICE_BRUSH_TYPE_PATTERN)
+ {
+ this.pattern = new SpicePattern;
+ at = this.pattern.from_dv(dv, at, mb);
+ }
+ return at;
+ },
+}
+
+function SpiceFill()
+{
+}
+
+SpiceFill.prototype =
+{
+ from_dv: function(dv, at, mb)
+ {
+ this.brush = new SpiceBrush;
+ at = this.brush.from_dv(dv, at, mb);
+ this.rop_descriptor = dv.getUint16(at, true); at += 2;
+ this.mask = new SpiceQMask;
+ return this.mask.from_dv(dv, at, mb);
+ },
+}
+
+
+function SpiceCopy()
+{
+}
+
+SpiceCopy.prototype =
+{
+ from_dv: function(dv, at, mb)
+ {
+ var offset = dv.getUint32(at, true); at += 4;
+ if (offset == 0)
+ {
+ this.src_bitmap = null;
+ }
+ else
+ {
+ this.src_bitmap = new SpiceImage;
+ this.src_bitmap.from_dv(dv, offset, mb);
+ }
+ this.src_area = new SpiceRect;
+ at = this.src_area.from_dv(dv, at, mb);
+ this.rop_descriptor = dv.getUint16(at, true); at += 2;
+ this.scale_mode = dv.getUint8(at, true); at ++;
+ this.mask = new SpiceQMask;
+ return this.mask.from_dv(dv, at, mb);
+ },
+}
+
+function SpicePoint16()
+{
+}
+
+SpicePoint16.prototype =
+{
+ from_dv: function(dv, at, mb)
+ {
+ this.x = dv.getUint16(at, true); at += 2;
+ this.y = dv.getUint16(at, true); at += 2;
+ return at;
+ },
+}
+
+function SpicePoint()
+{
+}
+
+SpicePoint.prototype =
+{
+ from_dv: function(dv, at, mb)
+ {
+ this.x = dv.getUint32(at, true); at += 4;
+ this.y = dv.getUint32(at, true); at += 4;
+ return at;
+ },
+}
+
+function SpiceCursorHeader()
+{
+}
+
+SpiceCursorHeader.prototype =
+{
+ from_dv: function(dv, at, mb)
+ {
+ this.unique = dv.getUint64(at, true); at += 8;
+ this.type = dv.getUint8(at, true); at ++;
+ this.width = dv.getUint16(at, true); at += 2;
+ this.height = dv.getUint16(at, true); at += 2;
+ this.hot_spot_x = dv.getUint16(at, true); at += 2;
+ this.hot_spot_y = dv.getUint16(at, true); at += 2;
+ return at;
+ },
+}
+
+function SpiceCursor()
+{
+}
+
+SpiceCursor.prototype =
+{
+ from_dv: function(dv, at, mb)
+ {
+ this.flags = dv.getUint16(at, true); at += 2;
+ if (this.flags & SPICE_CURSOR_FLAGS_NONE)
+ this.header = null;
+ else
+ {
+ this.header = new SpiceCursorHeader;
+ at = this.header.from_dv(dv, at, mb);
+ this.data = mb.slice(at);
+ at += this.data.byteLength;
+ }
+ return at;
+ },
+}
+
+function SpiceSurface()
+{
+}
+
+SpiceSurface.prototype =
+{
+ from_dv: function(dv, at, mb)
+ {
+ this.surface_id = dv.getUint32(at, true); at += 4;
+ this.width = dv.getUint32(at, true); at += 4;
+ this.height = dv.getUint32(at, true); at += 4;
+ this.format = dv.getUint32(at, true); at += 4;
+ this.flags = dv.getUint32(at, true); at += 4;
+ return at;
+ },
+}
+
+/* FIXME - SpiceImage types lz_plt, jpeg, zlib_glz, and jpeg_alpha are
+ completely unimplemented */
diff --git a/src/wok/plugins/kimchi/ui/spice-html5/thirdparty/Makefile.am
b/src/wok/plugins/kimchi/ui/spice-html5/thirdparty/Makefile.am
new file mode 100644
index 0000000..474478d
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/spice-html5/thirdparty/Makefile.am
@@ -0,0 +1,20 @@
+#
+# Kimchi
+#
+# Copyright IBM, Corp. 2014
+#
+# 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.
+
+thirdpartydir = $(datadir)/wok/plugins/kimchi/ui/spice-html5/thirdparty
+
+dist_thirdparty_DATA = $(wildcard *.js) $(NULL)
diff --git a/src/wok/plugins/kimchi/ui/spice-html5/thirdparty/jsbn.js
b/src/wok/plugins/kimchi/ui/spice-html5/thirdparty/jsbn.js
new file mode 100644
index 0000000..9b9476e
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/spice-html5/thirdparty/jsbn.js
@@ -0,0 +1,589 @@
+// Downloaded from
http://www-cs-students.stanford.edu/~tjw/jsbn/ by Jeremy White on
6/1/2012
+
+/*
+ * Copyright (c) 2003-2005 Tom Wu
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
+ * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * IN NO EVENT SHALL TOM WU BE LIABLE FOR ANY SPECIAL, INCIDENTAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER OR NOT ADVISED OF
+ * THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF LIABILITY, ARISING OUT
+ * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * In addition, the following condition applies:
+ *
+ * All redistributions must retain an intact copy of this copyright notice
+ * and disclaimer.
+ */
+
+
+// Basic JavaScript BN library - subset useful for RSA encryption.
+
+// Bits per digit
+var dbits;
+
+// JavaScript engine analysis
+var canary = 0xdeadbeefcafe;
+var j_lm = ((canary&0xffffff)==0xefcafe);
+
+// (public) Constructor
+function BigInteger(a,b,c) {
+ if(a != null)
+ if("number" == typeof a) this.fromNumber(a,b,c);
+ else if(b == null && "string" != typeof a) this.fromString(a,256);
+ else this.fromString(a,b);
+}
+
+// return new, unset BigInteger
+function nbi() { return new BigInteger(null); }
+
+// am: Compute w_j += (x*this_i), propagate carries,
+// c is initial carry, returns final carry.
+// c < 3*dvalue, x < 2*dvalue, this_i < dvalue
+// We need to select the fastest one that works in this environment.
+
+// am1: use a single mult and divide to get the high bits,
+// max digit bits should be 26 because
+// max internal value = 2*dvalue^2-2*dvalue (< 2^53)
+function am1(i,x,w,j,c,n) {
+ while(--n >= 0) {
+ var v = x*this[i++]+w[j]+c;
+ c = Math.floor(v/0x4000000);
+ w[j++] = v&0x3ffffff;
+ }
+ return c;
+}
+// am2 avoids a big mult-and-extract completely.
+// Max digit bits should be <= 30 because we do bitwise ops
+// on values up to 2*hdvalue^2-hdvalue-1 (< 2^31)
+function am2(i,x,w,j,c,n) {
+ var xl = x&0x7fff, xh = x>>15;
+ while(--n >= 0) {
+ var l = this[i]&0x7fff;
+ var h = this[i++]>>15;
+ var m = xh*l+h*xl;
+ l = xl*l+((m&0x7fff)<<15)+w[j]+(c&0x3fffffff);
+ c = (l>>>30)+(m>>>15)+xh*h+(c>>>30);
+ w[j++] = l&0x3fffffff;
+ }
+ return c;
+}
+// Alternately, set max digit bits to 28 since some
+// browsers slow down when dealing with 32-bit numbers.
+function am3(i,x,w,j,c,n) {
+ var xl = x&0x3fff, xh = x>>14;
+ while(--n >= 0) {
+ var l = this[i]&0x3fff;
+ var h = this[i++]>>14;
+ var m = xh*l+h*xl;
+ l = xl*l+((m&0x3fff)<<14)+w[j]+c;
+ c = (l>>28)+(m>>14)+xh*h;
+ w[j++] = l&0xfffffff;
+ }
+ return c;
+}
+if(j_lm && (navigator.appName == "Microsoft Internet Explorer")) {
+ BigInteger.prototype.am = am2;
+ dbits = 30;
+}
+else if(j_lm && (navigator.appName != "Netscape")) {
+ BigInteger.prototype.am = am1;
+ dbits = 26;
+}
+else { // Mozilla/Netscape seems to prefer am3
+ BigInteger.prototype.am = am3;
+ dbits = 28;
+}
+
+BigInteger.prototype.DB = dbits;
+BigInteger.prototype.DM = ((1<<dbits)-1);
+BigInteger.prototype.DV = (1<<dbits);
+
+var BI_FP = 52;
+BigInteger.prototype.FV = Math.pow(2,BI_FP);
+BigInteger.prototype.F1 = BI_FP-dbits;
+BigInteger.prototype.F2 = 2*dbits-BI_FP;
+
+// Digit conversions
+var BI_RM = "0123456789abcdefghijklmnopqrstuvwxyz";
+var BI_RC = new Array();
+var rr,vv;
+rr = "0".charCodeAt(0);
+for(vv = 0; vv <= 9; ++vv) BI_RC[rr++] = vv;
+rr = "a".charCodeAt(0);
+for(vv = 10; vv < 36; ++vv) BI_RC[rr++] = vv;
+rr = "A".charCodeAt(0);
+for(vv = 10; vv < 36; ++vv) BI_RC[rr++] = vv;
+
+function int2char(n) { return BI_RM.charAt(n); }
+function intAt(s,i) {
+ var c = BI_RC[s.charCodeAt(i)];
+ return (c==null)?-1:c;
+}
+
+// (protected) copy this to r
+function bnpCopyTo(r) {
+ for(var i = this.t-1; i >= 0; --i) r[i] = this[i];
+ r.t = this.t;
+ r.s = this.s;
+}
+
+// (protected) set from integer value x, -DV <= x < DV
+function bnpFromInt(x) {
+ this.t = 1;
+ this.s = (x<0)?-1:0;
+ if(x > 0) this[0] = x;
+ else if(x < -1) this[0] = x+DV;
+ else this.t = 0;
+}
+
+// return bigint initialized to value
+function nbv(i) { var r = nbi(); r.fromInt(i); return r; }
+
+// (protected) set from string and radix
+function bnpFromString(s,b) {
+ var k;
+ if(b == 16) k = 4;
+ else if(b == 8) k = 3;
+ else if(b == 256) k = 8; // byte array
+ else if(b == 2) k = 1;
+ else if(b == 32) k = 5;
+ else if(b == 4) k = 2;
+ else { this.fromRadix(s,b); return; }
+ this.t = 0;
+ this.s = 0;
+ var i = s.length, mi = false, sh = 0;
+ while(--i >= 0) {
+ var x = (k==8)?s[i]&0xff:intAt(s,i);
+ if(x < 0) {
+ if(s.charAt(i) == "-") mi = true;
+ continue;
+ }
+ mi = false;
+ if(sh == 0)
+ this[this.t++] = x;
+ else if(sh+k > this.DB) {
+ this[this.t-1] |= (x&((1<<(this.DB-sh))-1))<<sh;
+ this[this.t++] = (x>>(this.DB-sh));
+ }
+ else
+ this[this.t-1] |= x<<sh;
+ sh += k;
+ if(sh >= this.DB) sh -= this.DB;
+ }
+ if(k == 8 && (s[0]&0x80) != 0) {
+ this.s = -1;
+ if(sh > 0) this[this.t-1] |= ((1<<(this.DB-sh))-1)<<sh;
+ }
+ this.clamp();
+ if(mi) BigInteger.ZERO.subTo(this,this);
+}
+
+// (protected) clamp off excess high words
+function bnpClamp() {
+ var c = this.s&this.DM;
+ while(this.t > 0 && this[this.t-1] == c) --this.t;
+}
+
+// (public) return string representation in given radix
+function bnToString(b) {
+ if(this.s < 0) return "-"+this.negate().toString(b);
+ var k;
+ if(b == 16) k = 4;
+ else if(b == 8) k = 3;
+ else if(b == 2) k = 1;
+ else if(b == 32) k = 5;
+ else if(b == 4) k = 2;
+ else return this.toRadix(b);
+ var km = (1<<k)-1, d, m = false, r = "", i = this.t;
+ var p = this.DB-(i*this.DB)%k;
+ if(i-- > 0) {
+ if(p < this.DB && (d = this[i]>>p) > 0) { m = true; r =
int2char(d); }
+ while(i >= 0) {
+ if(p < k) {
+ d = (this[i]&((1<<p)-1))<<(k-p);
+ d |= this[--i]>>(p+=this.DB-k);
+ }
+ else {
+ d = (this[i]>>(p-=k))&km;
+ if(p <= 0) { p += this.DB; --i; }
+ }
+ if(d > 0) m = true;
+ if(m) r += int2char(d);
+ }
+ }
+ return m?r:"0";
+}
+
+// (public) -this
+function bnNegate() { var r = nbi(); BigInteger.ZERO.subTo(this,r); return r; }
+
+// (public) |this|
+function bnAbs() { return (this.s<0)?this.negate():this; }
+
+// (public) return + if this > a, - if this < a, 0 if equal
+function bnCompareTo(a) {
+ var r = this.s-a.s;
+ if(r != 0) return r;
+ var i = this.t;
+ r = i-a.t;
+ if(r != 0) return r;
+ while(--i >= 0) if((r=this[i]-a[i]) != 0) return r;
+ return 0;
+}
+
+// returns bit length of the integer x
+function nbits(x) {
+ var r = 1, t;
+ if((t=x>>>16) != 0) { x = t; r += 16; }
+ if((t=x>>8) != 0) { x = t; r += 8; }
+ if((t=x>>4) != 0) { x = t; r += 4; }
+ if((t=x>>2) != 0) { x = t; r += 2; }
+ if((t=x>>1) != 0) { x = t; r += 1; }
+ return r;
+}
+
+// (public) return the number of bits in "this"
+function bnBitLength() {
+ if(this.t <= 0) return 0;
+ return this.DB*(this.t-1)+nbits(this[this.t-1]^(this.s&this.DM));
+}
+
+// (protected) r = this << n*DB
+function bnpDLShiftTo(n,r) {
+ var i;
+ for(i = this.t-1; i >= 0; --i) r[i+n] = this[i];
+ for(i = n-1; i >= 0; --i) r[i] = 0;
+ r.t = this.t+n;
+ r.s = this.s;
+}
+
+// (protected) r = this >> n*DB
+function bnpDRShiftTo(n,r) {
+ for(var i = n; i < this.t; ++i) r[i-n] = this[i];
+ r.t = Math.max(this.t-n,0);
+ r.s = this.s;
+}
+
+// (protected) r = this << n
+function bnpLShiftTo(n,r) {
+ var bs = n%this.DB;
+ var cbs = this.DB-bs;
+ var bm = (1<<cbs)-1;
+ var ds = Math.floor(n/this.DB), c = (this.s<<bs)&this.DM, i;
+ for(i = this.t-1; i >= 0; --i) {
+ r[i+ds+1] = (this[i]>>cbs)|c;
+ c = (this[i]&bm)<<bs;
+ }
+ for(i = ds-1; i >= 0; --i) r[i] = 0;
+ r[ds] = c;
+ r.t = this.t+ds+1;
+ r.s = this.s;
+ r.clamp();
+}
+
+// (protected) r = this >> n
+function bnpRShiftTo(n,r) {
+ r.s = this.s;
+ var ds = Math.floor(n/this.DB);
+ if(ds >= this.t) { r.t = 0; return; }
+ var bs = n%this.DB;
+ var cbs = this.DB-bs;
+ var bm = (1<<bs)-1;
+ r[0] = this[ds]>>bs;
+ for(var i = ds+1; i < this.t; ++i) {
+ r[i-ds-1] |= (this[i]&bm)<<cbs;
+ r[i-ds] = this[i]>>bs;
+ }
+ if(bs > 0) r[this.t-ds-1] |= (this.s&bm)<<cbs;
+ r.t = this.t-ds;
+ r.clamp();
+}
+
+// (protected) r = this - a
+function bnpSubTo(a,r) {
+ var i = 0, c = 0, m = Math.min(a.t,this.t);
+ while(i < m) {
+ c += this[i]-a[i];
+ r[i++] = c&this.DM;
+ c >>= this.DB;
+ }
+ if(a.t < this.t) {
+ c -= a.s;
+ while(i < this.t) {
+ c += this[i];
+ r[i++] = c&this.DM;
+ c >>= this.DB;
+ }
+ c += this.s;
+ }
+ else {
+ c += this.s;
+ while(i < a.t) {
+ c -= a[i];
+ r[i++] = c&this.DM;
+ c >>= this.DB;
+ }
+ c -= a.s;
+ }
+ r.s = (c<0)?-1:0;
+ if(c < -1) r[i++] = this.DV+c;
+ else if(c > 0) r[i++] = c;
+ r.t = i;
+ r.clamp();
+}
+
+// (protected) r = this * a, r != this,a (HAC 14.12)
+// "this" should be the larger one if appropriate.
+function bnpMultiplyTo(a,r) {
+ var x = this.abs(), y = a.abs();
+ var i = x.t;
+ r.t = i+y.t;
+ while(--i >= 0) r[i] = 0;
+ for(i = 0; i < y.t; ++i) r[i+x.t] = x.am(0,y[i],r,i,0,x.t);
+ r.s = 0;
+ r.clamp();
+ if(this.s != a.s) BigInteger.ZERO.subTo(r,r);
+}
+
+// (protected) r = this^2, r != this (HAC 14.16)
+function bnpSquareTo(r) {
+ var x = this.abs();
+ var i = r.t = 2*x.t;
+ while(--i >= 0) r[i] = 0;
+ for(i = 0; i < x.t-1; ++i) {
+ var c = x.am(i,x[i],r,2*i,0,1);
+ if((r[i+x.t]+=x.am(i+1,2*x[i],r,2*i+1,c,x.t-i-1)) >= x.DV) {
+ r[i+x.t] -= x.DV;
+ r[i+x.t+1] = 1;
+ }
+ }
+ if(r.t > 0) r[r.t-1] += x.am(i,x[i],r,2*i,0,1);
+ r.s = 0;
+ r.clamp();
+}
+
+// (protected) divide this by m, quotient and remainder to q, r (HAC 14.20)
+// r != q, this != m. q or r may be null.
+function bnpDivRemTo(m,q,r) {
+ var pm = m.abs();
+ if(pm.t <= 0) return;
+ var pt = this.abs();
+ if(pt.t < pm.t) {
+ if(q != null) q.fromInt(0);
+ if(r != null) this.copyTo(r);
+ return;
+ }
+ if(r == null) r = nbi();
+ var y = nbi(), ts = this.s, ms = m.s;
+ var nsh = this.DB-nbits(pm[pm.t-1]); // normalize modulus
+ if(nsh > 0) { pm.lShiftTo(nsh,y); pt.lShiftTo(nsh,r); }
+ else { pm.copyTo(y); pt.copyTo(r); }
+ var ys = y.t;
+ var y0 = y[ys-1];
+ if(y0 == 0) return;
+ var yt = y0*(1<<this.F1)+((ys>1)?y[ys-2]>>this.F2:0);
+ var d1 = this.FV/yt, d2 = (1<<this.F1)/yt, e = 1<<this.F2;
+ var i = r.t, j = i-ys, t = (q==null)?nbi():q;
+ y.dlShiftTo(j,t);
+ if(r.compareTo(t) >= 0) {
+ r[r.t++] = 1;
+ r.subTo(t,r);
+ }
+ BigInteger.ONE.dlShiftTo(ys,t);
+ t.subTo(y,y); // "negative" y so we can replace sub with am later
+ while(y.t < ys) y[y.t++] = 0;
+ while(--j >= 0) {
+ // Estimate quotient digit
+ var qd = (r[--i]==y0)?this.DM:Math.floor(r[i]*d1+(r[i-1]+e)*d2);
+ if((r[i]+=y.am(0,qd,r,j,0,ys)) < qd) { // Try it out
+ y.dlShiftTo(j,t);
+ r.subTo(t,r);
+ while(r[i] < --qd) r.subTo(t,r);
+ }
+ }
+ if(q != null) {
+ r.drShiftTo(ys,q);
+ if(ts != ms) BigInteger.ZERO.subTo(q,q);
+ }
+ r.t = ys;
+ r.clamp();
+ if(nsh > 0) r.rShiftTo(nsh,r); // Denormalize remainder
+ if(ts < 0) BigInteger.ZERO.subTo(r,r);
+}
+
+// (public) this mod a
+function bnMod(a) {
+ var r = nbi();
+ this.abs().divRemTo(a,null,r);
+ if(this.s < 0 && r.compareTo(BigInteger.ZERO) > 0) a.subTo(r,r);
+ return r;
+}
+
+// Modular reduction using "classic" algorithm
+function Classic(m) { this.m = m; }
+function cConvert(x) {
+ if(x.s < 0 || x.compareTo(this.m) >= 0) return x.mod(this.m);
+ else return x;
+}
+function cRevert(x) { return x; }
+function cReduce(x) { x.divRemTo(this.m,null,x); }
+function cMulTo(x,y,r) { x.multiplyTo(y,r); this.reduce(r); }
+function cSqrTo(x,r) { x.squareTo(r); this.reduce(r); }
+
+Classic.prototype.convert = cConvert;
+Classic.prototype.revert = cRevert;
+Classic.prototype.reduce = cReduce;
+Classic.prototype.mulTo = cMulTo;
+Classic.prototype.sqrTo = cSqrTo;
+
+// (protected) return "-1/this % 2^DB"; useful for Mont. reduction
+// justification:
+// xy == 1 (mod m)
+// xy = 1+km
+// xy(2-xy) = (1+km)(1-km)
+// x[y(2-xy)] = 1-k^2m^2
+// x[y(2-xy)] == 1 (mod m^2)
+// if y is 1/x mod m, then y(2-xy) is 1/x mod m^2
+// should reduce x and y(2-xy) by m^2 at each step to keep size bounded.
+// JS multiply "overflows" differently from C/C++, so care is needed here.
+function bnpInvDigit() {
+ if(this.t < 1) return 0;
+ var x = this[0];
+ if((x&1) == 0) return 0;
+ var y = x&3; // y == 1/x mod 2^2
+ y = (y*(2-(x&0xf)*y))&0xf; // y == 1/x mod 2^4
+ y = (y*(2-(x&0xff)*y))&0xff; // y == 1/x mod 2^8
+ y = (y*(2-(((x&0xffff)*y)&0xffff)))&0xffff; // y == 1/x mod 2^16
+ // last step - calculate inverse mod DV directly;
+ // assumes 16 < DB <= 32 and assumes ability to handle 48-bit ints
+ y = (y*(2-x*y%this.DV))%this.DV; // y == 1/x mod 2^dbits
+ // we really want the negative inverse, and -DV < y < DV
+ return (y>0)?this.DV-y:-y;
+}
+
+// Montgomery reduction
+function Montgomery(m) {
+ this.m = m;
+ this.mp = m.invDigit();
+ this.mpl = this.mp&0x7fff;
+ this.mph = this.mp>>15;
+ this.um = (1<<(m.DB-15))-1;
+ this.mt2 = 2*m.t;
+}
+
+// xR mod m
+function montConvert(x) {
+ var r = nbi();
+ x.abs().dlShiftTo(this.m.t,r);
+ r.divRemTo(this.m,null,r);
+ if(x.s < 0 && r.compareTo(BigInteger.ZERO) > 0) this.m.subTo(r,r);
+ return r;
+}
+
+// x/R mod m
+function montRevert(x) {
+ var r = nbi();
+ x.copyTo(r);
+ this.reduce(r);
+ return r;
+}
+
+// x = x/R mod m (HAC 14.32)
+function montReduce(x) {
+ while(x.t <= this.mt2) // pad x so am has enough room later
+ x[x.t++] = 0;
+ for(var i = 0; i < this.m.t; ++i) {
+ // faster way of calculating u0 = x[i]*mp mod DV
+ var j = x[i]&0x7fff;
+ var u0 =
(j*this.mpl+(((j*this.mph+(x[i]>>15)*this.mpl)&this.um)<<15))&x.DM;
+ // use am to combine the multiply-shift-add into one call
+ j = i+this.m.t;
+ x[j] += this.m.am(0,u0,x,i,0,this.m.t);
+ // propagate carry
+ while(x[j] >= x.DV) { x[j] -= x.DV; x[++j]++; }
+ }
+ x.clamp();
+ x.drShiftTo(this.m.t,x);
+ if(x.compareTo(this.m) >= 0) x.subTo(this.m,x);
+}
+
+// r = "x^2/R mod m"; x != r
+function montSqrTo(x,r) { x.squareTo(r); this.reduce(r); }
+
+// r = "xy/R mod m"; x,y != r
+function montMulTo(x,y,r) { x.multiplyTo(y,r); this.reduce(r); }
+
+Montgomery.prototype.convert = montConvert;
+Montgomery.prototype.revert = montRevert;
+Montgomery.prototype.reduce = montReduce;
+Montgomery.prototype.mulTo = montMulTo;
+Montgomery.prototype.sqrTo = montSqrTo;
+
+// (protected) true iff this is even
+function bnpIsEven() { return ((this.t>0)?(this[0]&1):this.s) == 0; }
+
+// (protected) this^e, e < 2^32, doing sqr and mul with "r" (HAC 14.79)
+function bnpExp(e,z) {
+ if(e > 0xffffffff || e < 1) return BigInteger.ONE;
+ var r = nbi(), r2 = nbi(), g = z.convert(this), i = nbits(e)-1;
+ g.copyTo(r);
+ while(--i >= 0) {
+ z.sqrTo(r,r2);
+ if((e&(1<<i)) > 0) z.mulTo(r2,g,r);
+ else { var t = r; r = r2; r2 = t; }
+ }
+ return z.revert(r);
+}
+
+// (public) this^e % m, 0 <= e < 2^32
+function bnModPowInt(e,m) {
+ var z;
+ if(e < 256 || m.isEven()) z = new Classic(m); else z = new Montgomery(m);
+ return this.exp(e,z);
+}
+
+// protected
+BigInteger.prototype.copyTo = bnpCopyTo;
+BigInteger.prototype.fromInt = bnpFromInt;
+BigInteger.prototype.fromString = bnpFromString;
+BigInteger.prototype.clamp = bnpClamp;
+BigInteger.prototype.dlShiftTo = bnpDLShiftTo;
+BigInteger.prototype.drShiftTo = bnpDRShiftTo;
+BigInteger.prototype.lShiftTo = bnpLShiftTo;
+BigInteger.prototype.rShiftTo = bnpRShiftTo;
+BigInteger.prototype.subTo = bnpSubTo;
+BigInteger.prototype.multiplyTo = bnpMultiplyTo;
+BigInteger.prototype.squareTo = bnpSquareTo;
+BigInteger.prototype.divRemTo = bnpDivRemTo;
+BigInteger.prototype.invDigit = bnpInvDigit;
+BigInteger.prototype.isEven = bnpIsEven;
+BigInteger.prototype.exp = bnpExp;
+
+// public
+BigInteger.prototype.toString = bnToString;
+BigInteger.prototype.negate = bnNegate;
+BigInteger.prototype.abs = bnAbs;
+BigInteger.prototype.compareTo = bnCompareTo;
+BigInteger.prototype.bitLength = bnBitLength;
+BigInteger.prototype.mod = bnMod;
+BigInteger.prototype.modPowInt = bnModPowInt;
+
+// "constants"
+BigInteger.ZERO = nbv(0);
+BigInteger.ONE = nbv(1);
diff --git a/src/wok/plugins/kimchi/ui/spice-html5/thirdparty/prng4.js
b/src/wok/plugins/kimchi/ui/spice-html5/thirdparty/prng4.js
new file mode 100644
index 0000000..4715372
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/spice-html5/thirdparty/prng4.js
@@ -0,0 +1,79 @@
+// Downloaded from
http://www-cs-students.stanford.edu/~tjw/jsbn/ by Jeremy White on
6/1/2012
+
+/*
+ * Copyright (c) 2003-2005 Tom Wu
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
+ * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * IN NO EVENT SHALL TOM WU BE LIABLE FOR ANY SPECIAL, INCIDENTAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER OR NOT ADVISED OF
+ * THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF LIABILITY, ARISING OUT
+ * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * In addition, the following condition applies:
+ *
+ * All redistributions must retain an intact copy of this copyright notice
+ * and disclaimer.
+ */
+
+
+// prng4.js - uses Arcfour as a PRNG
+
+function Arcfour() {
+ this.i = 0;
+ this.j = 0;
+ this.S = new Array();
+}
+
+// Initialize arcfour context from key, an array of ints, each from [0..255]
+function ARC4init(key) {
+ var i, j, t;
+ for(i = 0; i < 256; ++i)
+ this.S[i] = i;
+ j = 0;
+ for(i = 0; i < 256; ++i) {
+ j = (j + this.S[i] + key[i % key.length]) & 255;
+ t = this.S[i];
+ this.S[i] = this.S[j];
+ this.S[j] = t;
+ }
+ this.i = 0;
+ this.j = 0;
+}
+
+function ARC4next() {
+ var t;
+ this.i = (this.i + 1) & 255;
+ this.j = (this.j + this.S[this.i]) & 255;
+ t = this.S[this.i];
+ this.S[this.i] = this.S[this.j];
+ this.S[this.j] = t;
+ return this.S[(t + this.S[this.i]) & 255];
+}
+
+Arcfour.prototype.init = ARC4init;
+Arcfour.prototype.next = ARC4next;
+
+// Plug in your RNG constructor here
+function prng_newstate() {
+ return new Arcfour();
+}
+
+// Pool size must be a multiple of 4 and greater than 32.
+// An array of bytes the size of the pool will be passed to init()
+var rng_psize = 256;
diff --git a/src/wok/plugins/kimchi/ui/spice-html5/thirdparty/rng.js
b/src/wok/plugins/kimchi/ui/spice-html5/thirdparty/rng.js
new file mode 100644
index 0000000..829a23c
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/spice-html5/thirdparty/rng.js
@@ -0,0 +1,102 @@
+// Downloaded from
http://www-cs-students.stanford.edu/~tjw/jsbn/ by Jeremy White on
6/1/2012
+
+/*
+ * Copyright (c) 2003-2005 Tom Wu
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
+ * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * IN NO EVENT SHALL TOM WU BE LIABLE FOR ANY SPECIAL, INCIDENTAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER OR NOT ADVISED OF
+ * THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF LIABILITY, ARISING OUT
+ * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * In addition, the following condition applies:
+ *
+ * All redistributions must retain an intact copy of this copyright notice
+ * and disclaimer.
+ */
+
+
+// Random number generator - requires a PRNG backend, e.g. prng4.js
+
+// For best results, put code like
+// <body onClick='rng_seed_time();' onKeyPress='rng_seed_time();'>
+// in your main HTML document.
+
+var rng_state;
+var rng_pool;
+var rng_pptr;
+
+// Mix in a 32-bit integer into the pool
+function rng_seed_int(x) {
+ rng_pool[rng_pptr++] ^= x & 255;
+ rng_pool[rng_pptr++] ^= (x >> 8) & 255;
+ rng_pool[rng_pptr++] ^= (x >> 16) & 255;
+ rng_pool[rng_pptr++] ^= (x >> 24) & 255;
+ if(rng_pptr >= rng_psize) rng_pptr -= rng_psize;
+}
+
+// Mix in the current time (w/milliseconds) into the pool
+function rng_seed_time() {
+ rng_seed_int(new Date().getTime());
+}
+
+// Initialize the pool with junk if needed.
+if(rng_pool == null) {
+ rng_pool = new Array();
+ rng_pptr = 0;
+ var t;
+ if(navigator.appName == "Netscape" && navigator.appVersion <
"5" && window.crypto) {
+ // Extract entropy (256 bits) from NS4 RNG if available
+ var z = window.crypto.random(32);
+ for(t = 0; t < z.length; ++t)
+ rng_pool[rng_pptr++] = z.charCodeAt(t) & 255;
+ }
+ while(rng_pptr < rng_psize) { // extract some randomness from Math.random()
+ t = Math.floor(65536 * Math.random());
+ rng_pool[rng_pptr++] = t >>> 8;
+ rng_pool[rng_pptr++] = t & 255;
+ }
+ rng_pptr = 0;
+ rng_seed_time();
+ //rng_seed_int(window.screenX);
+ //rng_seed_int(window.screenY);
+}
+
+function rng_get_byte() {
+ if(rng_state == null) {
+ rng_seed_time();
+ rng_state = prng_newstate();
+ rng_state.init(rng_pool);
+ for(rng_pptr = 0; rng_pptr < rng_pool.length; ++rng_pptr)
+ rng_pool[rng_pptr] = 0;
+ rng_pptr = 0;
+ //rng_pool = null;
+ }
+ // TODO: allow reseeding after first request
+ return rng_state.next();
+}
+
+function rng_get_bytes(ba) {
+ var i;
+ for(i = 0; i < ba.length; ++i) ba[i] = rng_get_byte();
+}
+
+function SecureRandom() {}
+
+SecureRandom.prototype.nextBytes = rng_get_bytes;
diff --git a/src/wok/plugins/kimchi/ui/spice-html5/thirdparty/rsa.js
b/src/wok/plugins/kimchi/ui/spice-html5/thirdparty/rsa.js
new file mode 100644
index 0000000..1bbf249
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/spice-html5/thirdparty/rsa.js
@@ -0,0 +1,146 @@
+// Downloaded from
http://www-cs-students.stanford.edu/~tjw/jsbn/ by Jeremy White on
6/1/2012
+
+/*
+ * Copyright (c) 2003-2005 Tom Wu
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
+ * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * IN NO EVENT SHALL TOM WU BE LIABLE FOR ANY SPECIAL, INCIDENTAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER OR NOT ADVISED OF
+ * THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF LIABILITY, ARISING OUT
+ * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * In addition, the following condition applies:
+ *
+ * All redistributions must retain an intact copy of this copyright notice
+ * and disclaimer.
+ */
+
+
+// Depends on jsbn.js and rng.js
+
+// Version 1.1: support utf-8 encoding in pkcs1pad2
+
+// convert a (hex) string to a bignum object
+function parseBigInt(str,r) {
+ return new BigInteger(str,r);
+}
+
+function linebrk(s,n) {
+ var ret = "";
+ var i = 0;
+ while(i + n < s.length) {
+ ret += s.substring(i,i+n) + "\n";
+ i += n;
+ }
+ return ret + s.substring(i,s.length);
+}
+
+function byte2Hex(b) {
+ if(b < 0x10)
+ return "0" + b.toString(16);
+ else
+ return b.toString(16);
+}
+
+// PKCS#1 (type 2, random) pad input string s to n bytes, and return a bigint
+function pkcs1pad2(s,n) {
+ if(n < s.length + 11) { // TODO: fix for utf-8
+ alert("Message too long for RSA");
+ return null;
+ }
+ var ba = new Array();
+ var i = s.length - 1;
+ while(i >= 0 && n > 0) {
+ var c = s.charCodeAt(i--);
+ if(c < 128) { // encode using utf-8
+ ba[--n] = c;
+ }
+ else if((c > 127) && (c < 2048)) {
+ ba[--n] = (c & 63) | 128;
+ ba[--n] = (c >> 6) | 192;
+ }
+ else {
+ ba[--n] = (c & 63) | 128;
+ ba[--n] = ((c >> 6) & 63) | 128;
+ ba[--n] = (c >> 12) | 224;
+ }
+ }
+ ba[--n] = 0;
+ var rng = new SecureRandom();
+ var x = new Array();
+ while(n > 2) { // random non-zero pad
+ x[0] = 0;
+ while(x[0] == 0) rng.nextBytes(x);
+ ba[--n] = x[0];
+ }
+ ba[--n] = 2;
+ ba[--n] = 0;
+ return new BigInteger(ba);
+}
+
+// "empty" RSA key constructor
+function RSAKey() {
+ this.n = null;
+ this.e = 0;
+ this.d = null;
+ this.p = null;
+ this.q = null;
+ this.dmp1 = null;
+ this.dmq1 = null;
+ this.coeff = null;
+}
+
+// Set the public key fields N and e from hex strings
+function RSASetPublic(N,E) {
+ if(N != null && E != null && N.length > 0 && E.length >
0) {
+ this.n = parseBigInt(N,16);
+ this.e = parseInt(E,16);
+ }
+ else
+ alert("Invalid RSA public key");
+}
+
+// Perform raw public operation on "x": return x^e (mod n)
+function RSADoPublic(x) {
+ return x.modPowInt(this.e, this.n);
+}
+
+// Return the PKCS#1 RSA encryption of "text" as an even-length hex string
+function RSAEncrypt(text) {
+ var m = pkcs1pad2(text,(this.n.bitLength()+7)>>3);
+ if(m == null) return null;
+ var c = this.doPublic(m);
+ if(c == null) return null;
+ var h = c.toString(16);
+ if((h.length & 1) == 0) return h; else return "0" + h;
+}
+
+// Return the PKCS#1 RSA encryption of "text" as a Base64-encoded string
+//function RSAEncryptB64(text) {
+// var h = this.encrypt(text);
+// if(h) return hex2b64(h); else return null;
+//}
+
+// protected
+RSAKey.prototype.doPublic = RSADoPublic;
+
+// public
+RSAKey.prototype.setPublic = RSASetPublic;
+RSAKey.prototype.encrypt = RSAEncrypt;
+//RSAKey.prototype.encrypt_b64 = RSAEncryptB64;
diff --git a/src/wok/plugins/kimchi/ui/spice-html5/thirdparty/sha1.js
b/src/wok/plugins/kimchi/ui/spice-html5/thirdparty/sha1.js
new file mode 100644
index 0000000..8118cb4
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/spice-html5/thirdparty/sha1.js
@@ -0,0 +1,346 @@
+/*
+ * A JavaScript implementation of the Secure Hash Algorithm, SHA-1, as defined
+ * in FIPS 180-1
+ * Version 2.2 Copyright Paul Johnston 2000 - 2009.
+ * Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet
+ * Distributed under the BSD License
+ * See
http://pajhome.org.uk/crypt/md5 for details.
+ */
+
+ /* Downloaded 6/1/2012 from the above address by Jeremy White.
+ License reproduce here for completeness:
+
+Copyright (c) 1998 - 2009, Paul Johnston & Contributors
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification, are
permitted provided that the following conditions are met:
+
+Redistributions of source code must retain the above copyright notice, this list of
conditions and the following disclaimer. Redistributions in binary form must reproduce the
above copyright notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
+
+Neither the name of the author nor the names of its contributors may be used to endorse
or promote products derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+ */
+
+/*
+ * Configurable variables. You may need to tweak these to be compatible with
+ * the server-side, but the defaults work in most cases.
+ */
+var hexcase = 0; /* hex output format. 0 - lowercase; 1 - uppercase */
+var b64pad = ""; /* base-64 pad character. "=" for strict RFC
compliance */
+
+/*
+ * These are the functions you'll usually want to call
+ * They take string arguments and return either hex or base-64 encoded strings
+ */
+function hex_sha1(s) { return rstr2hex(rstr_sha1(str2rstr_utf8(s))); }
+function b64_sha1(s) { return rstr2b64(rstr_sha1(str2rstr_utf8(s))); }
+function any_sha1(s, e) { return rstr2any(rstr_sha1(str2rstr_utf8(s)), e); }
+function hex_hmac_sha1(k, d)
+ { return rstr2hex(rstr_hmac_sha1(str2rstr_utf8(k), str2rstr_utf8(d))); }
+function b64_hmac_sha1(k, d)
+ { return rstr2b64(rstr_hmac_sha1(str2rstr_utf8(k), str2rstr_utf8(d))); }
+function any_hmac_sha1(k, d, e)
+ { return rstr2any(rstr_hmac_sha1(str2rstr_utf8(k), str2rstr_utf8(d)), e); }
+
+/*
+ * Perform a simple self-test to see if the VM is working
+ */
+function sha1_vm_test()
+{
+ return hex_sha1("abc").toLowerCase() ==
"a9993e364706816aba3e25717850c26c9cd0d89d";
+}
+
+/*
+ * Calculate the SHA1 of a raw string
+ */
+function rstr_sha1(s)
+{
+ return binb2rstr(binb_sha1(rstr2binb(s), s.length * 8));
+}
+
+/*
+ * Calculate the HMAC-SHA1 of a key and some data (raw strings)
+ */
+function rstr_hmac_sha1(key, data)
+{
+ var bkey = rstr2binb(key);
+ if(bkey.length > 16) bkey = binb_sha1(bkey, key.length * 8);
+
+ var ipad = Array(16), opad = Array(16);
+ for(var i = 0; i < 16; i++)
+ {
+ ipad[i] = bkey[i] ^ 0x36363636;
+ opad[i] = bkey[i] ^ 0x5C5C5C5C;
+ }
+
+ var hash = binb_sha1(ipad.concat(rstr2binb(data)), 512 + data.length * 8);
+ return binb2rstr(binb_sha1(opad.concat(hash), 512 + 160));
+}
+
+/*
+ * Convert a raw string to a hex string
+ */
+function rstr2hex(input)
+{
+ try { hexcase } catch(e) { hexcase=0; }
+ var hex_tab = hexcase ? "0123456789ABCDEF" : "0123456789abcdef";
+ var output = "";
+ var x;
+ for(var i = 0; i < input.length; i++)
+ {
+ x = input.charCodeAt(i);
+ output += hex_tab.charAt((x >>> 4) & 0x0F)
+ + hex_tab.charAt( x & 0x0F);
+ }
+ return output;
+}
+
+/*
+ * Convert a raw string to a base-64 string
+ */
+function rstr2b64(input)
+{
+ try { b64pad } catch(e) { b64pad=''; }
+ var tab =
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
+ var output = "";
+ var len = input.length;
+ for(var i = 0; i < len; i += 3)
+ {
+ var triplet = (input.charCodeAt(i) << 16)
+ | (i + 1 < len ? input.charCodeAt(i+1) << 8 : 0)
+ | (i + 2 < len ? input.charCodeAt(i+2) : 0);
+ for(var j = 0; j < 4; j++)
+ {
+ if(i * 8 + j * 6 > input.length * 8) output += b64pad;
+ else output += tab.charAt((triplet >>> 6*(3-j)) & 0x3F);
+ }
+ }
+ return output;
+}
+
+/*
+ * Convert a raw string to an arbitrary string encoding
+ */
+function rstr2any(input, encoding)
+{
+ var divisor = encoding.length;
+ var remainders = Array();
+ var i, q, x, quotient;
+
+ /* Convert to an array of 16-bit big-endian values, forming the dividend */
+ var dividend = Array(Math.ceil(input.length / 2));
+ for(i = 0; i < dividend.length; i++)
+ {
+ dividend[i] = (input.charCodeAt(i * 2) << 8) | input.charCodeAt(i * 2 + 1);
+ }
+
+ /*
+ * Repeatedly perform a long division. The binary array forms the dividend,
+ * the length of the encoding is the divisor. Once computed, the quotient
+ * forms the dividend for the next step. We stop when the dividend is zero.
+ * All remainders are stored for later use.
+ */
+ while(dividend.length > 0)
+ {
+ quotient = Array();
+ x = 0;
+ for(i = 0; i < dividend.length; i++)
+ {
+ x = (x << 16) + dividend[i];
+ q = Math.floor(x / divisor);
+ x -= q * divisor;
+ if(quotient.length > 0 || q > 0)
+ quotient[quotient.length] = q;
+ }
+ remainders[remainders.length] = x;
+ dividend = quotient;
+ }
+
+ /* Convert the remainders to the output string */
+ var output = "";
+ for(i = remainders.length - 1; i >= 0; i--)
+ output += encoding.charAt(remainders[i]);
+
+ /* Append leading zero equivalents */
+ var full_length = Math.ceil(input.length * 8 /
+ (Math.log(encoding.length) / Math.log(2)))
+ for(i = output.length; i < full_length; i++)
+ output = encoding[0] + output;
+
+ return output;
+}
+
+/*
+ * Encode a string as utf-8.
+ * For efficiency, this assumes the input is valid utf-16.
+ */
+function str2rstr_utf8(input)
+{
+ var output = "";
+ var i = -1;
+ var x, y;
+
+ while(++i < input.length)
+ {
+ /* Decode utf-16 surrogate pairs */
+ x = input.charCodeAt(i);
+ y = i + 1 < input.length ? input.charCodeAt(i + 1) : 0;
+ if(0xD800 <= x && x <= 0xDBFF && 0xDC00 <= y && y
<= 0xDFFF)
+ {
+ x = 0x10000 + ((x & 0x03FF) << 10) + (y & 0x03FF);
+ i++;
+ }
+
+ /* Encode output as utf-8 */
+ if(x <= 0x7F)
+ output += String.fromCharCode(x);
+ else if(x <= 0x7FF)
+ output += String.fromCharCode(0xC0 | ((x >>> 6 ) & 0x1F),
+ 0x80 | ( x & 0x3F));
+ else if(x <= 0xFFFF)
+ output += String.fromCharCode(0xE0 | ((x >>> 12) & 0x0F),
+ 0x80 | ((x >>> 6 ) & 0x3F),
+ 0x80 | ( x & 0x3F));
+ else if(x <= 0x1FFFFF)
+ output += String.fromCharCode(0xF0 | ((x >>> 18) & 0x07),
+ 0x80 | ((x >>> 12) & 0x3F),
+ 0x80 | ((x >>> 6 ) & 0x3F),
+ 0x80 | ( x & 0x3F));
+ }
+ return output;
+}
+
+/*
+ * Encode a string as utf-16
+ */
+function str2rstr_utf16le(input)
+{
+ var output = "";
+ for(var i = 0; i < input.length; i++)
+ output += String.fromCharCode( input.charCodeAt(i) & 0xFF,
+ (input.charCodeAt(i) >>> 8) & 0xFF);
+ return output;
+}
+
+function str2rstr_utf16be(input)
+{
+ var output = "";
+ for(var i = 0; i < input.length; i++)
+ output += String.fromCharCode((input.charCodeAt(i) >>> 8) & 0xFF,
+ input.charCodeAt(i) & 0xFF);
+ return output;
+}
+
+/*
+ * Convert a raw string to an array of big-endian words
+ * Characters >255 have their high-byte silently ignored.
+ */
+function rstr2binb(input)
+{
+ var output = Array(input.length >> 2);
+ for(var i = 0; i < output.length; i++)
+ output[i] = 0;
+ for(var i = 0; i < input.length * 8; i += 8)
+ output[i>>5] |= (input.charCodeAt(i / 8) & 0xFF) << (24 - i % 32);
+ return output;
+}
+
+/*
+ * Convert an array of big-endian words to a string
+ */
+function binb2rstr(input)
+{
+ var output = "";
+ for(var i = 0; i < input.length * 32; i += 8)
+ output += String.fromCharCode((input[i>>5] >>> (24 - i % 32)) &
0xFF);
+ return output;
+}
+
+/*
+ * Calculate the SHA-1 of an array of big-endian words, and a bit length
+ */
+function binb_sha1(x, len)
+{
+ /* append padding */
+ x[len >> 5] |= 0x80 << (24 - len % 32);
+ x[((len + 64 >> 9) << 4) + 15] = len;
+
+ var w = Array(80);
+ var a = 1732584193;
+ var b = -271733879;
+ var c = -1732584194;
+ var d = 271733878;
+ var e = -1009589776;
+
+ for(var i = 0; i < x.length; i += 16)
+ {
+ var olda = a;
+ var oldb = b;
+ var oldc = c;
+ var oldd = d;
+ var olde = e;
+
+ for(var j = 0; j < 80; j++)
+ {
+ if(j < 16) w[j] = x[i + j];
+ else w[j] = bit_rol(w[j-3] ^ w[j-8] ^ w[j-14] ^ w[j-16], 1);
+ var t = safe_add(safe_add(bit_rol(a, 5), sha1_ft(j, b, c, d)),
+ safe_add(safe_add(e, w[j]), sha1_kt(j)));
+ e = d;
+ d = c;
+ c = bit_rol(b, 30);
+ b = a;
+ a = t;
+ }
+
+ a = safe_add(a, olda);
+ b = safe_add(b, oldb);
+ c = safe_add(c, oldc);
+ d = safe_add(d, oldd);
+ e = safe_add(e, olde);
+ }
+ return Array(a, b, c, d, e);
+
+}
+
+/*
+ * Perform the appropriate triplet combination function for the current
+ * iteration
+ */
+function sha1_ft(t, b, c, d)
+{
+ if(t < 20) return (b & c) | ((~b) & d);
+ if(t < 40) return b ^ c ^ d;
+ if(t < 60) return (b & c) | (b & d) | (c & d);
+ return b ^ c ^ d;
+}
+
+/*
+ * Determine the appropriate additive constant for the current iteration
+ */
+function sha1_kt(t)
+{
+ return (t < 20) ? 1518500249 : (t < 40) ? 1859775393 :
+ (t < 60) ? -1894007588 : -899497514;
+}
+
+/*
+ * Add integers, wrapping at 2^32. This uses 16-bit operations internally
+ * to work around bugs in some JS interpreters.
+ */
+function safe_add(x, y)
+{
+ var lsw = (x & 0xFFFF) + (y & 0xFFFF);
+ var msw = (x >> 16) + (y >> 16) + (lsw >> 16);
+ return (msw << 16) | (lsw & 0xFFFF);
+}
+
+/*
+ * Bitwise rotate a 32-bit number to the left.
+ */
+function bit_rol(num, cnt)
+{
+ return (num << cnt) | (num >>> (32 - cnt));
+}
diff --git a/src/wok/plugins/kimchi/ui/spice-html5/ticket.js
b/src/wok/plugins/kimchi/ui/spice-html5/ticket.js
new file mode 100644
index 0000000..96577a3
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/spice-html5/ticket.js
@@ -0,0 +1,250 @@
+"use strict";
+/*
+ Copyright (C) 2012 by Jeremy P. White <jwhite(a)codeweavers.com>
+
+ This file is part of spice-html5.
+
+ spice-html5 is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ spice-html5 is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with spice-html5. If not, see <
http://www.gnu.org/licenses/>.
+*/
+
+var SHA_DIGEST_LENGTH = 20;
+
+/*----------------------------------------------------------------------------
+** General ticket RSA encryption functions - just good enough to
+** support what we need to send back an encrypted ticket.
+**--------------------------------------------------------------------------*/
+
+
+/*----------------------------------------------------------------------------
+** OAEP padding functions. Inspired by the OpenSSL implementation.
+**--------------------------------------------------------------------------*/
+function MGF1(mask, seed)
+{
+ var i, j, outlen;
+ for (i = 0, outlen = 0; outlen < mask.length; i++)
+ {
+ var combo_buf = new String;
+
+ for (j = 0; j < seed.length; j++)
+ combo_buf += String.fromCharCode(seed[j]);
+ combo_buf += String.fromCharCode((i >> 24) & 255);
+ combo_buf += String.fromCharCode((i >> 16) & 255);
+ combo_buf += String.fromCharCode((i >> 8) & 255);
+ combo_buf += String.fromCharCode((i) & 255);
+
+ var combo_hash = rstr_sha1(combo_buf);
+ for (j = 0; j < combo_hash.length && outlen < mask.length; j++,
outlen++)
+ {
+ mask[outlen] = combo_hash.charCodeAt(j);
+ }
+ }
+}
+
+
+function RSA_padding_add_PKCS1_OAEP(tolen, from, param)
+{
+ var seed = new Array(SHA_DIGEST_LENGTH);
+ var rand = new SecureRandom();
+ rand.nextBytes(seed);
+
+ var dblen = tolen - 1 - seed.length;
+ var db = new Array(dblen);
+ var padlen = dblen - from.length - 1;
+ var i;
+
+ if (param === undefined)
+ param = "";
+
+ if (padlen < SHA_DIGEST_LENGTH)
+ {
+ console.log("Error - data too large for key size.");
+ return null;
+ }
+
+ for (i = 0; i < padlen; i++)
+ db[i] = 0;
+
+ var param_hash = rstr_sha1(param);
+ for (i = 0; i < param_hash.length; i++)
+ db[i] = param_hash.charCodeAt(i);
+
+ db[padlen] = 1;
+ for (i = 0; i < from.length; i++)
+ db[i + padlen + 1] = from.charCodeAt(i);
+
+ var dbmask = new Array(dblen);
+ if (MGF1(dbmask, seed) < 0)
+ return null;
+
+ for (i = 0; i < dbmask.length; i++)
+ db[i] ^= dbmask[i];
+
+
+ var seedmask = Array(SHA_DIGEST_LENGTH);
+ if (MGF1(seedmask, db) < 0)
+ return null;
+
+ for (i = 0; i < seedmask.length; i++)
+ seed[i] ^= seedmask[i];
+
+ var ret = new String;
+ ret += String.fromCharCode(0);
+ for (i = 0; i < seed.length; i++)
+ ret += String.fromCharCode(seed[i]);
+ for (i = 0; i < db.length; i++)
+ ret += String.fromCharCode(db[i]);
+ return ret;
+}
+
+
+function asn_get_length(u8, at)
+{
+ var len = u8[at++];
+ if (len > 0x80)
+ {
+ if (len != 0x81)
+ {
+ console.log("Error: we lazily don't support keys bigger than 255
bytes. It'd be easy to fix.");
+ return null;
+ }
+ len = u8[at++];
+ }
+
+ return [ at, len];
+}
+
+function find_sequence(u8, at)
+{
+ var lenblock;
+ at = at || 0;
+ if (u8[at++] != 0x30)
+ {
+ console.log("Error: public key should start with a sequence flag.");
+ return null;
+ }
+
+ lenblock = asn_get_length(u8, at);
+ if (! lenblock)
+ return null;
+ return lenblock;
+}
+
+/*----------------------------------------------------------------------------
+** Extract an RSA key from a memory buffer
+**--------------------------------------------------------------------------*/
+function create_rsa_from_mb(mb, at)
+{
+ var u8 = new Uint8Array(mb);
+ var lenblock;
+ var seq;
+ var ba;
+ var i;
+ var ret;
+
+ /* We have a sequence which contains a sequence followed by a bit string */
+ seq = find_sequence(u8, at);
+ if (! seq)
+ return null;
+
+ at = seq[0];
+ seq = find_sequence(u8, at);
+ if (! seq)
+ return null;
+
+ /* Skip over the contained sequence */
+ at = seq[0] + seq[1];
+ if (u8[at++] != 0x3)
+ {
+ console.log("Error: expecting bit string next.");
+ return null;
+ }
+
+ /* Get the bit string, which is *itself* a sequence. Having fun yet? */
+ lenblock = asn_get_length(u8, at);
+ if (! lenblock)
+ return null;
+
+ at = lenblock[0];
+ if (u8[at] != 0 && u8[at + 1] != 0x30)
+ {
+ console.log("Error: unexpected values in bit string.");
+ return null;
+ }
+
+ /* Okay, now we have a sequence of two binary values, we hope. */
+ seq = find_sequence(u8, at + 1);
+ if (! seq)
+ return null;
+
+ at = seq[0];
+ if (u8[at++] != 0x02)
+ {
+ console.log("Error: expecting integer n next.");
+ return null;
+ }
+ lenblock = asn_get_length(u8, at);
+ if (! lenblock)
+ return null;
+ at = lenblock[0];
+
+ ba = new Array(lenblock[1]);
+ for (i = 0; i < lenblock[1]; i++)
+ ba[i] = u8[at + i];
+
+ ret = new RSAKey();
+ ret.n = new BigInteger(ba);
+
+ at += lenblock[1];
+
+ if (u8[at++] != 0x02)
+ {
+ console.log("Error: expecting integer e next.");
+ return null;
+ }
+ lenblock = asn_get_length(u8, at);
+ if (! lenblock)
+ return null;
+ at = lenblock[0];
+
+ ret.e = u8[at++];
+ for (i = 1; i < lenblock[1]; i++)
+ {
+ ret.e <<= 8;
+ ret.e |= u8[at++];
+ }
+
+ return ret;
+}
+
+function rsa_encrypt(rsa, str)
+{
+ var i;
+ var ret = [];
+ var oaep = RSA_padding_add_PKCS1_OAEP((rsa.n.bitLength()+7)>>3, str);
+ if (! oaep)
+ return null;
+
+ var ba = new Array(oaep.length);
+
+ for (i = 0; i < oaep.length; i++)
+ ba[i] = oaep.charCodeAt(i);
+ var bigint = new BigInteger(ba);
+ var enc = rsa.doPublic(bigint);
+ var h = enc.toString(16);
+ if ((h.length & 1) != 0)
+ h = "0" + h;
+ for (i = 0; i < h.length; i += 2)
+ ret[i / 2] = parseInt(h.substring(i, i + 2), 16);
+ return ret;
+}
diff --git a/src/wok/plugins/kimchi/ui/spice-html5/utils.js
b/src/wok/plugins/kimchi/ui/spice-html5/utils.js
new file mode 100644
index 0000000..9eb42ff
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/spice-html5/utils.js
@@ -0,0 +1,265 @@
+"use strict";
+/*
+ Copyright (C) 2012 by Jeremy P. White <jwhite(a)codeweavers.com>
+
+ This file is part of spice-html5.
+
+ spice-html5 is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ spice-html5 is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with spice-html5. If not, see <
http://www.gnu.org/licenses/>.
+*/
+
+/*----------------------------------------------------------------------------
+** Utility settings and functions for Spice
+**--------------------------------------------------------------------------*/
+var DEBUG = 0;
+var DUMP_DRAWS = false;
+var DUMP_CANVASES = false;
+
+
+/*----------------------------------------------------------------------------
+** combine_array_buffers
+** Combine two array buffers.
+** FIXME - this can't be optimal. See wire.js about eliminating the need.
+**--------------------------------------------------------------------------*/
+function combine_array_buffers(a1, a2)
+{
+ var in1 = new Uint8Array(a1);
+ var in2 = new Uint8Array(a2);
+ var ret = new ArrayBuffer(a1.byteLength + a2.byteLength);
+ var out = new Uint8Array(ret);
+ var o = 0;
+ var i;
+ for (i = 0; i < in1.length; i++)
+ out[o++] = in1[i];
+ for (i = 0; i < in2.length; i++)
+ out[o++] = in2[i];
+
+ return ret;
+}
+
+/*----------------------------------------------------------------------------
+** hexdump_buffer
+**--------------------------------------------------------------------------*/
+function hexdump_buffer(a)
+{
+ var mg = new Uint8Array(a);
+ var hex = "";
+ var str = "";
+ var last_zeros = 0;
+ for (var i = 0; i < mg.length; i++)
+ {
+ var h = Number(mg[i]).toString(16);
+ if (h.length == 1)
+ hex += "0";
+ hex += h + " ";
+
+ if (mg[i] == 10 || mg[i] == 13 || mg[i] == 8)
+ str += ".";
+ else
+ str += String.fromCharCode(mg[i]);
+
+ if ((i % 16 == 15) || (i == (mg.length - 1)))
+ {
+ while (i % 16 != 15)
+ {
+ hex += " ";
+ i++;
+ }
+
+ if (last_zeros == 0)
+ console.log(hex + " | " + str);
+
+ if (hex == "00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ")
+ {
+ if (last_zeros == 1)
+ {
+ console.log(".");
+ last_zeros++;
+ }
+ else if (last_zeros == 0)
+ last_zeros++;
+ }
+ else
+ last_zeros = 0;
+
+ hex = str = "";
+ }
+ }
+}
+
+/*----------------------------------------------------------------------------
+** Converting keycodes to AT scancodes is very hard.
+** luckly there are some resources on the web and in the Xorg driver that help
+** us figure out what browser depenend keycodes match to what scancodes.
+**
+** This will most likely not work for non US keyboard and browsers other than
+** modern Chrome and FireFox.
+**--------------------------------------------------------------------------*/
+var common_scanmap = [];
+common_scanmap['Q'.charCodeAt(0)] = KEY_Q;
+common_scanmap['W'.charCodeAt(0)] = KEY_W;
+common_scanmap['E'.charCodeAt(0)] = KEY_E;
+common_scanmap['R'.charCodeAt(0)] = KEY_R;
+common_scanmap['T'.charCodeAt(0)] = KEY_T;
+common_scanmap['Y'.charCodeAt(0)] = KEY_Y;
+common_scanmap['U'.charCodeAt(0)] = KEY_U;
+common_scanmap['I'.charCodeAt(0)] = KEY_I;
+common_scanmap['O'.charCodeAt(0)] = KEY_O;
+common_scanmap['P'.charCodeAt(0)] = KEY_P;
+common_scanmap['A'.charCodeAt(0)] = KEY_A;
+common_scanmap['S'.charCodeAt(0)] = KEY_S;
+common_scanmap['D'.charCodeAt(0)] = KEY_D;
+common_scanmap['F'.charCodeAt(0)] = KEY_F;
+common_scanmap['G'.charCodeAt(0)] = KEY_G;
+common_scanmap['H'.charCodeAt(0)] = KEY_H;
+common_scanmap['J'.charCodeAt(0)] = KEY_J;
+common_scanmap['K'.charCodeAt(0)] = KEY_K;
+common_scanmap['L'.charCodeAt(0)] = KEY_L;
+common_scanmap['Z'.charCodeAt(0)] = KEY_Z;
+common_scanmap['X'.charCodeAt(0)] = KEY_X;
+common_scanmap['C'.charCodeAt(0)] = KEY_C;
+common_scanmap['V'.charCodeAt(0)] = KEY_V;
+common_scanmap['B'.charCodeAt(0)] = KEY_B;
+common_scanmap['N'.charCodeAt(0)] = KEY_N;
+common_scanmap['M'.charCodeAt(0)] = KEY_M;
+common_scanmap[' '.charCodeAt(0)] = KEY_Space;
+common_scanmap[13] = KEY_Enter;
+common_scanmap[27] = KEY_Escape;
+common_scanmap[8] = KEY_BackSpace;
+common_scanmap[9] = KEY_Tab;
+common_scanmap[16] = KEY_ShiftL;
+common_scanmap[17] = KEY_LCtrl;
+common_scanmap[18] = KEY_Alt;
+common_scanmap[20] = KEY_CapsLock;
+common_scanmap[144] = KEY_NumLock;
+common_scanmap[112] = KEY_F1;
+common_scanmap[113] = KEY_F2;
+common_scanmap[114] = KEY_F3;
+common_scanmap[115] = KEY_F4;
+common_scanmap[116] = KEY_F5;
+common_scanmap[117] = KEY_F6;
+common_scanmap[118] = KEY_F7;
+common_scanmap[119] = KEY_F8;
+common_scanmap[120] = KEY_F9;
+common_scanmap[121] = KEY_F10;
+common_scanmap[122] = KEY_F11;
+common_scanmap[123] = KEY_F12;
+
+/* These externded scancodes do not line up with values from atKeynames */
+common_scanmap[42] = 99;
+common_scanmap[19] = 101; // Break
+common_scanmap[111] = 0xE035; // KP_Divide
+common_scanmap[106] = 0xE037; // KP_Multiply
+common_scanmap[36] = 0xE047; // Home
+common_scanmap[38] = 0xE048; // Up
+common_scanmap[33] = 0xE049; // PgUp
+common_scanmap[37] = 0xE04B; // Left
+common_scanmap[39] = 0xE04D; // Right
+common_scanmap[35] = 0xE04F; // End
+common_scanmap[40] = 0xE050; // Down
+common_scanmap[34] = 0xE051; // PgDown
+common_scanmap[45] = 0xE052; // Insert
+common_scanmap[46] = 0xE053; // Delete
+common_scanmap[44] = 0x2A37; // Print
+
+/* These are not common between ALL browsers but are between Firefox and DOM3 */
+common_scanmap['1'.charCodeAt(0)] = KEY_1;
+common_scanmap['2'.charCodeAt(0)] = KEY_2;
+common_scanmap['3'.charCodeAt(0)] = KEY_3;
+common_scanmap['4'.charCodeAt(0)] = KEY_4;
+common_scanmap['5'.charCodeAt(0)] = KEY_5;
+common_scanmap['6'.charCodeAt(0)] = KEY_6;
+common_scanmap['7'.charCodeAt(0)] = KEY_7;
+common_scanmap['8'.charCodeAt(0)] = KEY_8;
+common_scanmap['9'.charCodeAt(0)] = KEY_9;
+common_scanmap['0'.charCodeAt(0)] = KEY_0;
+common_scanmap[145] = KEY_ScrollLock;
+common_scanmap[103] = KEY_KP_7;
+common_scanmap[104] = KEY_KP_8;
+common_scanmap[105] = KEY_KP_9;
+common_scanmap[100] = KEY_KP_4;
+common_scanmap[101] = KEY_KP_5;
+common_scanmap[102] = KEY_KP_6;
+common_scanmap[107] = KEY_KP_Plus;
+common_scanmap[97] = KEY_KP_1;
+common_scanmap[98] = KEY_KP_2;
+common_scanmap[99] = KEY_KP_3;
+common_scanmap[96] = KEY_KP_0;
+common_scanmap[110] = KEY_KP_Decimal;
+common_scanmap[191] = KEY_Slash;
+common_scanmap[190] = KEY_Period;
+common_scanmap[188] = KEY_Comma;
+common_scanmap[220] = KEY_BSlash;
+common_scanmap[192] = KEY_Tilde;
+common_scanmap[222] = KEY_Quote;
+common_scanmap[219] = KEY_LBrace;
+common_scanmap[221] = KEY_RBrace;
+
+common_scanmap[91] = 0xE05B; //KEY_LMeta
+common_scanmap[92] = 0xE05C; //KEY_RMeta
+common_scanmap[93] = 0xE05D; //KEY_Menu
+
+/* Firefox/Mozilla codes */
+var firefox_scanmap = [];
+firefox_scanmap[173] = KEY_Minus;
+firefox_scanmap[109] = KEY_Minus;
+firefox_scanmap[61] = KEY_Equal;
+firefox_scanmap[59] = KEY_SemiColon;
+
+/* DOM3 codes */
+var DOM_scanmap = [];
+DOM_scanmap[189] = KEY_Minus;
+DOM_scanmap[187] = KEY_Equal;
+DOM_scanmap[186] = KEY_SemiColon;
+
+function get_scancode(code)
+{
+ if (common_scanmap[code] === undefined)
+ {
+ if (navigator.userAgent.indexOf("Firefox") != -1)
+ return firefox_scanmap[code];
+ else
+ return DOM_scanmap[code];
+ }
+ else
+ return common_scanmap[code];
+}
+
+function keycode_to_start_scan(code)
+{
+ var scancode = get_scancode(code);
+ if (scancode === undefined)
+ {
+ alert('no map for ' + code);
+ return 0;
+ }
+
+ if (scancode < 0x100) {
+ return scancode;
+ } else {
+ return 0xe0 | ((scancode - 0x100) << 8);
+ }
+}
+
+function keycode_to_end_scan(code)
+{
+ var scancode = get_scancode(code);
+ if (scancode === undefined)
+ return 0;
+
+ if (scancode < 0x100) {
+ return scancode | 0x80;
+ } else {
+ return 0x80e0 | ((scancode - 0x100) << 8);
+ }
+}
diff --git a/src/wok/plugins/kimchi/ui/spice-html5/webm.js
b/src/wok/plugins/kimchi/ui/spice-html5/webm.js
new file mode 100644
index 0000000..35cbc07
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/spice-html5/webm.js
@@ -0,0 +1,553 @@
+"use strict";
+/*
+ Copyright (C) 2014 by Jeremy P. White <jwhite(a)codeweavers.com>
+
+ This file is part of spice-html5.
+
+ spice-html5 is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ spice-html5 is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with spice-html5. If not, see <
http://www.gnu.org/licenses/>.
+*/
+
+
+/*----------------------------------------------------------------------------
+** EBML identifiers
+**--------------------------------------------------------------------------*/
+var EBML_HEADER = [ 0x1a, 0x45, 0xdf, 0xa3 ];
+var EBML_HEADER_VERSION = [ 0x42, 0x86 ];
+var EBML_HEADER_READ_VERSION = [ 0x42, 0xf7 ];
+var EBML_HEADER_MAX_ID_LENGTH = [ 0x42, 0xf2 ];
+var EBML_HEADER_MAX_SIZE_LENGTH = [ 0x42, 0xf3 ];
+var EBML_HEADER_DOC_TYPE = [ 0x42, 0x82 ];
+var EBML_HEADER_DOC_TYPE_VERSION = [ 0x42, 0x87 ];
+var EBML_HEADER_DOC_TYPE_READ_VERSION = [ 0x42, 0x85 ];
+
+var WEBM_SEGMENT_HEADER = [ 0x18, 0x53, 0x80, 0x67 ];
+var WEBM_SEGMENT_INFORMATION = [ 0x15, 0x49, 0xA9, 0x66 ];
+
+var WEBM_TIMECODE_SCALE = [ 0x2A, 0xD7, 0xB1 ];
+var WEBM_MUXING_APP = [ 0x4D, 0x80 ];
+var WEBM_WRITING_APP = [ 0x57, 0x41 ];
+
+var WEBM_SEEK_HEAD = [ 0x11, 0x4D, 0x9B, 0x74 ];
+var WEBM_SEEK = [ 0x4D, 0xBB ];
+var WEBM_SEEK_ID = [ 0x53, 0xAB ];
+var WEBM_SEEK_POSITION = [ 0x53, 0xAC ];
+
+var WEBM_TRACKS = [ 0x16, 0x54, 0xAE, 0x6B ];
+var WEBM_TRACK_ENTRY = [ 0xAE ];
+var WEBM_TRACK_NUMBER = [ 0xD7 ];
+var WEBM_TRACK_UID = [ 0x73, 0xC5 ];
+var WEBM_TRACK_TYPE = [ 0x83 ];
+var WEBM_FLAG_ENABLED = [ 0xB9 ];
+var WEBM_FLAG_DEFAULT = [ 0x88 ];
+var WEBM_FLAG_FORCED = [ 0x55, 0xAA ];
+var WEBM_FLAG_LACING = [ 0x9C ];
+var WEBM_MIN_CACHE = [ 0x6D, 0xE7 ];
+
+var WEBM_MAX_BLOCK_ADDITION_ID = [ 0x55, 0xEE ];
+var WEBM_CODEC_DECODE_ALL = [ 0xAA ];
+var WEBM_SEEK_PRE_ROLL = [ 0x56, 0xBB ];
+var WEBM_CODEC_DELAY = [ 0x56, 0xAA ];
+var WEBM_CODEC_PRIVATE = [ 0x63, 0xA2 ];
+var WEBM_CODEC_ID = [ 0x86 ];
+
+var WEBM_AUDIO = [ 0xE1 ] ;
+var WEBM_SAMPLING_FREQUENCY = [ 0xB5 ] ;
+var WEBM_CHANNELS = [ 0x9F ] ;
+
+var WEBM_CLUSTER = [ 0x1F, 0x43, 0xB6, 0x75 ];
+var WEBM_TIME_CODE = [ 0xE7 ] ;
+var WEBM_SIMPLE_BLOCK = [ 0xA3 ] ;
+
+/*----------------------------------------------------------------------------
+** Various OPUS / Webm constants
+**--------------------------------------------------------------------------*/
+var CLUSTER_SIMPLEBLOCK_FLAG_KEYFRAME = 1 << 7;
+
+var OPUS_FREQUENCY = 48000;
+var OPUS_CHANNELS = 2;
+
+var SPICE_PLAYBACK_CODEC = 'audio/webm;
codecs="opus"';
+var MAX_CLUSTER_TIME = 1000;
+
+var GAP_DETECTION_THRESHOLD = 50;
+
+/*----------------------------------------------------------------------------
+** EBML utility functions
+** These classes can create the binary representation of a webm file
+**--------------------------------------------------------------------------*/
+function EBML_write_u1_data_len(len, dv, at)
+{
+ var b = 0x80 | len;
+ dv.setUint8(at, b);
+ return at + 1;
+}
+
+function EBML_write_u8_value(id, val, dv, at)
+{
+ at = EBML_write_array(id, dv, at);
+ at = EBML_write_u1_data_len(1, dv, at);
+ dv.setUint8(at, val);
+ return at + 1;
+}
+
+function EBML_write_u32_value(id, val, dv, at)
+{
+ at = EBML_write_array(id, dv, at);
+ at = EBML_write_u1_data_len(4, dv, at);
+ dv.setUint32(at, val);
+ return at + 4;
+}
+
+function EBML_write_u16_value(id, val, dv, at)
+{
+ at = EBML_write_array(id, dv, at);
+ at = EBML_write_u1_data_len(2, dv, at);
+ dv.setUint16(at, val);
+ return at + 2;
+}
+
+function EBML_write_float_value(id, val, dv, at)
+{
+ at = EBML_write_array(id, dv, at);
+ at = EBML_write_u1_data_len(4, dv, at);
+ dv.setFloat32(at, val);
+ return at + 4;
+}
+
+
+
+function EBML_write_u64_data_len(len, dv, at)
+{
+ /* Javascript doesn't do 64 bit ints, so this cheats and
+ just has a max of 32 bits. Fine for our purposes */
+ dv.setUint8(at++, 0x01);
+ dv.setUint8(at++, 0x00);
+ dv.setUint8(at++, 0x00);
+ dv.setUint8(at++, 0x00);
+ var val = len & 0xFFFFFFFF;
+ for (var shift = 24; shift >= 0; shift -= 8)
+ dv.setUint8(at++, val >> shift);
+ return at;
+}
+
+function EBML_write_array(arr, dv, at)
+{
+ for (var i = 0; i < arr.length; i++)
+ dv.setUint8(at + i, arr[i]);
+ return at + arr.length;
+}
+
+function EBML_write_string(str, dv, at)
+{
+ for (var i = 0; i < str.length; i++)
+ dv.setUint8(at + i, str.charCodeAt(i));
+ return at + str.length;
+}
+
+function EBML_write_data(id, data, dv, at)
+{
+ at = EBML_write_array(id, dv, at);
+ if (data.length < 127)
+ at = EBML_write_u1_data_len(data.length, dv, at);
+ else
+ at = EBML_write_u64_data_len(data.length, dv, at);
+ if ((typeof data) == "string")
+ at = EBML_write_string(data, dv, at);
+ else
+ at = EBML_write_array(data, dv, at);
+ return at;
+}
+
+/*----------------------------------------------------------------------------
+** Webm objects
+** These classes can create the binary representation of a webm file
+**--------------------------------------------------------------------------*/
+function EBMLHeader()
+{
+ this.id = EBML_HEADER;
+ this.Version = 1;
+ this.ReadVersion = 1;
+ this.MaxIDLength = 4;
+ this.MaxSizeLength = 8;
+ this.DocType = "webm";
+ this.DocTypeVersion = 2; /* Not well specified by the WebM guys, but functionally
required for Firefox */
+ this.DocTypeReadVersion = 2;
+}
+
+EBMLHeader.prototype =
+{
+ to_buffer: function(a, at)
+ {
+ at = at || 0;
+ var dv = new DataView(a);
+
+ at = EBML_write_array(this.id, dv, at);
+ at = EBML_write_u64_data_len(0x1f, dv, at);
+ at = EBML_write_u8_value(EBML_HEADER_VERSION, this.Version, dv, at);
+ at = EBML_write_u8_value(EBML_HEADER_READ_VERSION, this.ReadVersion, dv, at);
+ at = EBML_write_u8_value(EBML_HEADER_MAX_ID_LENGTH, this.MaxIDLength, dv, at);
+ at = EBML_write_u8_value(EBML_HEADER_MAX_SIZE_LENGTH, this.MaxSizeLength, dv,
at);
+ at = EBML_write_data(EBML_HEADER_DOC_TYPE, this.DocType, dv, at);
+ at = EBML_write_u8_value(EBML_HEADER_DOC_TYPE_VERSION, this.DocTypeVersion, dv,
at);
+ at = EBML_write_u8_value(EBML_HEADER_DOC_TYPE_READ_VERSION,
this.DocTypeReadVersion, dv, at);
+
+ return at;
+ },
+ buffer_size: function()
+ {
+ return 0x1f + 8 + this.id.length;
+ },
+}
+
+function webm_Segment()
+{
+ this.id = WEBM_SEGMENT_HEADER;
+}
+
+webm_Segment.prototype =
+{
+ to_buffer: function(a, at)
+ {
+ at = at || 0;
+ var dv = new DataView(a);
+
+ at = EBML_write_array(this.id, dv, at);
+ dv.setUint8(at++, 0xff);
+ return at;
+ },
+ buffer_size: function()
+ {
+ return this.id.length + 1;
+ },
+}
+
+function webm_SegmentInformation()
+{
+ this.id = WEBM_SEGMENT_INFORMATION;
+ this.timecode_scale = 1000000; /* 1 ms */
+ this.muxing_app = "spice";
+ this.writing_app = "spice-html5";
+
+}
+
+webm_SegmentInformation.prototype =
+{
+ to_buffer: function(a, at)
+ {
+ at = at || 0;
+ var dv = new DataView(a);
+
+ at = EBML_write_array(this.id, dv, at);
+ at = EBML_write_u64_data_len(this.buffer_size() - 8 - this.id.length, dv, at);
+ at = EBML_write_u32_value(WEBM_TIMECODE_SCALE, this.timecode_scale, dv, at);
+ at = EBML_write_data(WEBM_MUXING_APP, this.muxing_app, dv, at);
+ at = EBML_write_data(WEBM_WRITING_APP, this.writing_app, dv, at);
+ return at;
+ },
+ buffer_size: function()
+ {
+ return this.id.length + 8 +
+ WEBM_TIMECODE_SCALE.length + 1 + 4 +
+ WEBM_MUXING_APP.length + 1 + this.muxing_app.length +
+ WEBM_WRITING_APP.length + 1 + this.writing_app.length;
+ },
+}
+
+function webm_Audio(frequency)
+{
+ this.id = WEBM_AUDIO;
+ this.sampling_frequency = frequency;
+ this.channels = OPUS_CHANNELS;
+}
+
+webm_Audio.prototype =
+{
+ to_buffer: function(a, at)
+ {
+ at = at || 0;
+ var dv = new DataView(a);
+ at = EBML_write_array(this.id, dv, at);
+ at = EBML_write_u64_data_len(this.buffer_size() - 8 - this.id.length, dv, at);
+ at = EBML_write_u8_value(WEBM_CHANNELS, this.channels, dv, at);
+ at = EBML_write_float_value(WEBM_SAMPLING_FREQUENCY, this.sampling_frequency, dv,
at);
+ return at;
+ },
+ buffer_size: function()
+ {
+ return this.id.length + 8 +
+ WEBM_SAMPLING_FREQUENCY.length + 1 + 4 +
+ WEBM_CHANNELS.length + 1 + 1;
+ },
+}
+
+
+/* ---------------------------
+ SeekHead not currently used. Hopefully not needed.
+*/
+function webm_Seek(seekid, pos)
+{
+ this.id = WEBM_SEEK;
+ this.pos = pos;
+ this.seekid = seekid;
+}
+
+webm_Seek.prototype =
+{
+ to_buffer: function(a, at)
+ {
+ at = at || 0;
+ var dv = new DataView(a);
+ at = EBML_write_array(this.id, dv, at);
+ at = EBML_write_u1_data_len(this.buffer_size() - 1 - this.id.length, dv, at);
+
+ at = EBML_write_data(WEBM_SEEK_ID, this.seekid, dv, at)
+ at = EBML_write_u16_value(WEBM_SEEK_POSITION, this.pos, dv, at)
+
+ return at;
+ },
+ buffer_size: function()
+ {
+ return this.id.length + 1 +
+ WEBM_SEEK_ID.length + 1 + this.seekid.length +
+ WEBM_SEEK_POSITION.length + 1 + 2;
+ },
+}
+function webm_SeekHead(info_pos, track_pos)
+{
+ this.id = WEBM_SEEK_HEAD;
+ this.info = new webm_Seek(WEBM_SEGMENT_INFORMATION, info_pos);
+ this.track = new webm_Seek(WEBM_TRACKS, track_pos);
+}
+
+webm_SeekHead.prototype =
+{
+ to_buffer: function(a, at)
+ {
+ at = at || 0;
+ var dv = new DataView(a);
+ at = EBML_write_array(this.id, dv, at);
+ at = EBML_write_u64_data_len(this.buffer_size() - 8 - this.id.length, dv, at);
+
+ at = this.info.to_buffer(a, at);
+ at = this.track.to_buffer(a, at);
+
+ return at;
+ },
+ buffer_size: function()
+ {
+ return this.id.length + 8 +
+ this.info.buffer_size() +
+ this.track.buffer_size();
+ },
+}
+
+/* -------------------------------
+ End of Seek Head
+*/
+
+function webm_TrackEntry()
+{
+ this.id = WEBM_TRACK_ENTRY;
+ this.number = 1;
+ this.uid = 1;
+ this.type = 2; // Audio
+ this.flag_enabled = 1;
+ this.flag_default = 1;
+ this.flag_forced = 1;
+ this.flag_lacing = 0;
+ this.min_cache = 0; // fixme - check
+ this.max_block_addition_id = 0;
+ this.codec_decode_all = 0; // fixme - check
+ this.seek_pre_roll = 0; // 80000000; // fixme - check
+ this.codec_delay = 80000000; // Must match codec_private.preskip
+ this.codec_id = "A_OPUS";
+ this.audio = new webm_Audio(OPUS_FREQUENCY);
+
+ // See:
http://tools.ietf.org/html/draft-terriberry-oggopus-01
+ this.codec_private = [ 0x4f, 0x70, 0x75, 0x73, 0x48, 0x65, 0x61, 0x64, // OpusHead
+ 0x01, // Version
+ OPUS_CHANNELS,
+ 0x00, 0x0F, // Preskip - 3840 samples - should be 8ms at
48kHz
+ 0x80, 0xbb, 0x00, 0x00, // 48000
+ 0x00, 0x00, // Output gain
+ 0x00 // Channel mapping family
+ ];
+}
+
+webm_TrackEntry.prototype =
+{
+ to_buffer: function(a, at)
+ {
+ at = at || 0;
+ var dv = new DataView(a);
+ at = EBML_write_array(this.id, dv, at);
+ at = EBML_write_u64_data_len(this.buffer_size() - 8 - this.id.length, dv, at);
+ at = EBML_write_u8_value(WEBM_TRACK_NUMBER, this.number, dv, at);
+ at = EBML_write_u8_value(WEBM_TRACK_UID, this.uid, dv, at);
+ at = EBML_write_u8_value(WEBM_FLAG_ENABLED, this.flag_enabled, dv, at);
+ at = EBML_write_u8_value(WEBM_FLAG_DEFAULT, this.flag_default, dv, at);
+ at = EBML_write_u8_value(WEBM_FLAG_FORCED, this.flag_forced, dv, at);
+ at = EBML_write_u8_value(WEBM_FLAG_LACING, this.flag_lacing, dv, at);
+ at = EBML_write_data(WEBM_CODEC_ID, this.codec_id, dv, at);
+ at = EBML_write_u8_value(WEBM_MIN_CACHE, this.min_cache, dv, at);
+ at = EBML_write_u8_value(WEBM_MAX_BLOCK_ADDITION_ID, this.max_block_addition_id,
dv, at);
+ at = EBML_write_u8_value(WEBM_CODEC_DECODE_ALL, this.codec_decode_all, dv, at);
+ at = EBML_write_u32_value(WEBM_CODEC_DELAY, this.codec_delay, dv, at);
+ at = EBML_write_u32_value(WEBM_SEEK_PRE_ROLL, this.seek_pre_roll, dv, at);
+ at = EBML_write_u8_value(WEBM_TRACK_TYPE, this.type, dv, at);
+ at = EBML_write_data(WEBM_CODEC_PRIVATE, this.codec_private, dv, at);
+
+ at = this.audio.to_buffer(a, at);
+ return at;
+ },
+ buffer_size: function()
+ {
+ return this.id.length + 8 +
+ WEBM_TRACK_NUMBER.length + 1 + 1 +
+ WEBM_TRACK_UID.length + 1 + 1 +
+ WEBM_TRACK_TYPE.length + 1 + 1 +
+ WEBM_FLAG_ENABLED.length + 1 + 1 +
+ WEBM_FLAG_DEFAULT.length + 1 + 1 +
+ WEBM_FLAG_FORCED.length + 1 + 1 +
+ WEBM_FLAG_LACING.length + 1 + 1 +
+ WEBM_MIN_CACHE.length + 1 + 1 +
+ WEBM_MAX_BLOCK_ADDITION_ID.length + 1 + 1 +
+ WEBM_CODEC_DECODE_ALL.length + 1 + 1 +
+ WEBM_SEEK_PRE_ROLL.length + 1 + 4 +
+ WEBM_CODEC_DELAY.length + 1 + 4 +
+ WEBM_CODEC_ID.length + this.codec_id.length + 1 +
+ WEBM_CODEC_PRIVATE.length + 1 + this.codec_private.length +
+ this.audio.buffer_size();
+ },
+}
+function webm_Tracks(entry)
+{
+ this.id = WEBM_TRACKS;
+ this.track_entry = entry;
+}
+
+webm_Tracks.prototype =
+{
+ to_buffer: function(a, at)
+ {
+ at = at || 0;
+ var dv = new DataView(a);
+ at = EBML_write_array(this.id, dv, at);
+ at = EBML_write_u64_data_len(this.buffer_size() - 8 - this.id.length, dv, at);
+ at = this.track_entry.to_buffer(a, at);
+ return at;
+ },
+ buffer_size: function()
+ {
+ return this.id.length + 8 +
+ this.track_entry.buffer_size();
+ },
+}
+
+function webm_Cluster(timecode, data)
+{
+ this.id = WEBM_CLUSTER;
+ this.timecode = timecode;
+ this.data = data;
+}
+
+webm_Cluster.prototype =
+{
+ to_buffer: function(a, at)
+ {
+ at = at || 0;
+ var dv = new DataView(a);
+ at = EBML_write_array(this.id, dv, at);
+ dv.setUint8(at++, 0xff);
+ at = EBML_write_u32_value(WEBM_TIME_CODE, this.timecode, dv, at);
+ return at;
+ },
+ buffer_size: function()
+ {
+ return this.id.length + 1 +
+ WEBM_TIME_CODE.length + 1 + 4;
+ },
+}
+
+function webm_SimpleBlock(timecode, data, keyframe)
+{
+ this.id = WEBM_SIMPLE_BLOCK;
+ this.timecode = timecode;
+ this.data = data;
+ this.keyframe = keyframe;
+}
+
+webm_SimpleBlock.prototype =
+{
+ to_buffer: function(a, at)
+ {
+ at = at || 0;
+ var dv = new DataView(a);
+ at = EBML_write_array(this.id, dv, at);
+ at = EBML_write_u64_data_len(this.data.byteLength + 4, dv, at);
+ at = EBML_write_u1_data_len(1, dv, at); // Track #
+ dv.setUint16(at, this.timecode); at += 2; // timecode - relative to cluster
+ dv.setUint8(at, this.keyframe ? CLUSTER_SIMPLEBLOCK_FLAG_KEYFRAME : 0); at += 1;
// flags
+
+ // FIXME - There should be a better way to copy
+ var u8 = new Uint8Array(this.data);
+ for (var i = 0; i < this.data.byteLength; i++)
+ dv.setUint8(at++, u8[i]);
+
+ return at;
+ },
+ buffer_size: function()
+ {
+ return this.id.length + 8 +
+ 1 + 2 + 1 +
+ this.data.byteLength;
+ },
+}
+
+function webm_Header()
+{
+ this.ebml = new EBMLHeader;
+ this.segment = new webm_Segment;
+ this.seek_head = new webm_SeekHead(0, 0);
+
+ this.seek_head.info.pos = this.segment.buffer_size() + this.seek_head.buffer_size();
+
+ this.info = new webm_SegmentInformation;
+
+ this.seek_head.track.pos = this.seek_head.info.pos + this.info.buffer_size();
+
+ this.track_entry = new webm_TrackEntry;
+ this.tracks = new webm_Tracks(this.track_entry);
+}
+
+webm_Header.prototype =
+{
+ to_buffer: function(a, at)
+ {
+ at = at || 0;
+ at = this.ebml.to_buffer(a, at);
+ at = this.segment.to_buffer(a, at);
+ at = this.info.to_buffer(a, at);
+ at = this.tracks.to_buffer(a, at);
+
+ return at;
+ },
+ buffer_size: function()
+ {
+ return this.ebml.buffer_size() +
+ this.segment.buffer_size() +
+ this.info.buffer_size() +
+ this.tracks.buffer_size();
+ },
+}
diff --git a/src/wok/plugins/kimchi/ui/spice-html5/wire.js
b/src/wok/plugins/kimchi/ui/spice-html5/wire.js
new file mode 100644
index 0000000..7407ce7
--- /dev/null
+++ b/src/wok/plugins/kimchi/ui/spice-html5/wire.js
@@ -0,0 +1,123 @@
+"use strict";
+/*
+ Copyright (C) 2012 by Jeremy P. White <jwhite(a)codeweavers.com>
+
+ This file is part of spice-html5.
+
+ spice-html5 is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ spice-html5 is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with spice-html5. If not, see <
http://www.gnu.org/licenses/>.
+*/
+
+/*--------------------------------------------------------------------------------------
+** SpiceWireReader
+** This class will receive messages from a WebSocket and relay it to a given
+** callback. It will optionally save and pass along a header, useful in processing
+** the mini message format.
+**--------------------------------------------------------------------------------------*/
+function SpiceWireReader(sc, callback)
+{
+ this.sc = sc;
+ this.callback = callback;
+ this.needed = 0;
+
+ this.buffers = [];
+
+ this.sc.ws.wire_reader = this;
+ this.sc.ws.binaryType = "arraybuffer";
+ this.sc.ws.addEventListener('message', wire_blob_catcher);
+}
+
+SpiceWireReader.prototype =
+{
+
+ /*------------------------------------------------------------------------
+ ** Process messages coming in from our WebSocket
+ **----------------------------------------------------------------------*/
+ inbound: function (mb)
+ {
+ var at;
+
+ /* Just buffer if we don't need anything yet */
+ if (this.needed == 0)
+ {
+ this.buffers.push(mb);
+ return;
+ }
+
+ /* Optimization - if we have just one inbound block, and it's
+ suitable for our needs, just use it. */
+ if (this.buffers.length == 0 && mb.byteLength >= this.needed)
+ {
+ if (mb.byteLength > this.needed)
+ {
+ this.buffers.push(mb.slice(this.needed));
+ mb = mb.slice(0, this.needed);
+ }
+ this.callback.call(this.sc, mb,
+ this.saved_msg_header || undefined);
+ }
+ else
+ {
+ this.buffers.push(mb);
+ }
+
+
+ /* If we have fragments that add up to what we need, combine them */
+ /* FIXME - it would be faster to revise the processing code to handle
+ ** multiple fragments directly. Essentially, we should be
+ ** able to do this without any slice() or combine_array_buffers() calls
*/
+ while (this.buffers.length > 1 && this.buffers[0].byteLength <
this.needed)
+ {
+ var mb1 = this.buffers.shift();
+ var mb2 = this.buffers.shift();
+
+ this.buffers.unshift(combine_array_buffers(mb1, mb2));
+ }
+
+
+ while (this.buffers.length > 0 && this.buffers[0].byteLength >=
this.needed)
+ {
+ mb = this.buffers.shift();
+ if (mb.byteLength > this.needed)
+ {
+ this.buffers.unshift(mb.slice(this.needed));
+ mb = mb.slice(0, this.needed);
+ }
+ this.callback.call(this.sc, mb,
+ this.saved_msg_header || undefined);
+ }
+
+ },
+
+ request: function(n)
+ {
+ this.needed = n;
+ },
+
+ save_header: function(h)
+ {
+ this.saved_msg_header = h;
+ },
+
+ clear_header: function()
+ {
+ this.saved_msg_header = undefined;
+ },
+}
+
+function wire_blob_catcher(e)
+{
+ DEBUG > 1 && console.log(">> WebSockets.onmessage");
+ DEBUG > 1 && console.log("id " +
this.wire_reader.sc.connection_id +"; type " + this.wire_reader.sc.type);
+ SpiceWireReader.prototype.inbound.call(this.wire_reader, e.data);
+}
diff --git a/src/wok/plugins/kimchi/utils.py b/src/wok/plugins/kimchi/utils.py
new file mode 100644
index 0000000..2480362
--- /dev/null
+++ b/src/wok/plugins/kimchi/utils.py
@@ -0,0 +1,39 @@
+#
+# Project Kimchi
+#
+# Copyright IBM, Corp. 2013-2015
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+#
+
+import re
+
+from wok.exception import InvalidParameter
+
+
+def _uri_to_name(collection, uri):
+ expr = '/plugins/kimchi/%s/(.*?)$' % collection
+ m = re.match(expr, uri)
+ if not m:
+ raise InvalidParameter("WOKUTILS0001E", {'uri': uri})
+ return m.group(1)
+
+
+def template_name_from_uri(uri):
+ return _uri_to_name('templates', uri)
+
+
+def pool_name_from_uri(uri):
+ return _uri_to_name('storagepools', uri)
diff --git a/src/wok/plugins/kimchi/vmtemplate.py b/src/wok/plugins/kimchi/vmtemplate.py
new file mode 100644
index 0000000..07e70ba
--- /dev/null
+++ b/src/wok/plugins/kimchi/vmtemplate.py
@@ -0,0 +1,431 @@
+#
+# Project Kimchi
+#
+# Copyright IBM, Corp. 2013-2015
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+import os
+import stat
+import time
+import urlparse
+import uuid
+from lxml import etree
+from lxml.builder import E
+
+from wok.exception import InvalidParameter, ImageFormatError, IsoFormatError
+from wok.exception import MissingParameter, OperationFailed
+from wok.utils import check_url_path
+
+import imageinfo
+import osinfo
+from isoinfo import IsoImage
+from utils import pool_name_from_uri
+from xmlutils.cpu import get_cpu_xml
+from xmlutils.disk import get_disk_xml
+from xmlutils.graphics import get_graphics_xml
+from xmlutils.interface import get_iface_xml
+from xmlutils.qemucmdline import get_qemucmdline_xml
+
+
+class VMTemplate(object):
+ def __init__(self, args, scan=False):
+ """
+ Construct a VM Template from a widely variable amount of information.
+ The only required parameter is a name for the VMTemplate. If present,
+ the os_distro and os_version fields are used to lookup recommended
+ settings. Any parameters provided by the caller will override the
+ defaults. If scan is True and a cdrom or a base img is present, the
+ operating system will be detected by probing the installation media.
+ """
+ self.info = {}
+ self.fc_host_support = args.get('fc_host_support')
+
+ # Fetch defaults based on the os distro and version
+ try:
+ distro, version = self._get_os_info(args, scan)
+ except ImageFormatError as e:
+ raise OperationFailed('KCHTMPL0020E', {'err': e.message})
+ os_distro = args.get('os_distro', distro)
+ os_version = args.get('os_version', version)
+ entry = osinfo.lookup(os_distro, os_version)
+ self.info.update(entry)
+
+ # Auto-generate a template name and no one is passed
+ if 'name' not in args or args['name'] == '':
+ args['name'] = self._gen_name(distro, version)
+ self.name = args['name']
+
+ # Override with the passed in parameters
+ graph_args = args.get('graphics')
+ if graph_args:
+ graphics = dict(self.info['graphics'])
+ graphics.update(graph_args)
+ args['graphics'] = graphics
+ self.info.update(args)
+
+ # Assign right disk format to logical and [i]scsi storagepools
+ if self._get_storage_type() in ['logical', 'iscsi',
'scsi']:
+ for i, disk in enumerate(self.info['disks']):
+ self.info['disks'][i]['format'] = 'raw'
+
+ def _get_os_info(self, args, scan):
+ distro = version = 'unknown'
+
+ # Identify the cdrom if present
+ iso = args.get('cdrom', '')
+ if len(iso) > 0:
+ if not iso.startswith('/'):
+ self.info.update({'iso_stream': True})
+
+ if scan:
+ distro, version = self.get_iso_info(iso)
+
+ return distro, version
+
+ # CDROM is not presented: check for base image
+ base_imgs = []
+ for d in args.get('disks', []):
+ if 'base' in d.keys():
+ base_imgs.append(d)
+ if scan:
+ distro, version = imageinfo.probe_image(d['base'])
+
+ if 'size' not in d.keys():
+ d_info = imageinfo.probe_img_info(d['base'])
+ d['size'] = d_info['virtual-size']
+
+ if len(base_imgs) == 0:
+ raise MissingParameter("KCHTMPL0016E")
+
+ return distro, version
+
+ def _gen_name(self, distro, version):
+ if distro == 'unknown':
+ name = str(uuid.uuid4())
+ else:
+ name = distro + version + '.' + str(int(time.time() * 1000))
+ return name
+
+ def get_iso_info(self, iso):
+ iso_prefixes = ['/', 'http', 'https', 'ftp',
'ftps', 'tftp']
+ if len(filter(iso.startswith, iso_prefixes)) == 0:
+ raise InvalidParameter("KCHTMPL0006E", {'param': iso})
+ try:
+ iso_img = IsoImage(iso)
+ return iso_img.probe()
+ except IsoFormatError:
+ raise InvalidParameter("KCHISO0001E", {'filename': iso})
+
+ def _get_cdrom_xml(self, libvirt_stream_protocols):
+ if 'cdrom' not in self.info:
+ return ''
+
+ params = {}
+ params['type'] = 'cdrom'
+ params['format'] = 'raw'
+ params['bus'] = self.info['cdrom_bus']
+ params['index'] = self.info['cdrom_index']
+ params['path'] = self.info['cdrom']
+
+ if self.info.get('iso_stream', False):
+ protocol = urlparse.urlparse(params['path']).scheme
+ if protocol not in libvirt_stream_protocols:
+ driveOpt = 'file=%(path)s,if=none,id=drive-%(bus)s0-1-0,'
+ driveOpt += 'readonly=on,format=%(format)s'
+
+ deviceOpt = '%(bus)s-cd,bus=%(bus)s.1,unit=0,'
+ deviceOpt += 'drive=drive-%(bus)s0-1-0,id=%(bus)s0-1-0'
+
+ args = {}
+ args['-drive'] = driveOpt % params
+ args['-device'] = deviceOpt % params
+ # return qemucmdline XML
+ return get_qemucmdline_xml(args)
+
+ dev, xml = get_disk_xml(params)
+ return xml
+
+ def _get_disks_xml(self, vm_uuid):
+ # Current implementation just allows to create disk in one single
+ # storage pool, so we cannot mix the types (scsi volumes vs img file)
+ storage_type = self._get_storage_type()
+ storage_path = self._get_storage_path()
+
+ base_disk_params = {'type': 'disk', 'disk':
'file',
+ 'bus': self.info['disk_bus'],
'format': 'qcow2'}
+ logical_disk_params = {'format': 'raw'}
+ iscsi_disk_params = {'disk': 'block', 'format':
'raw'}
+
+ scsi_disk = 'volume' if self.fc_host_support else 'block'
+ scsi_disk_params = {'disk': scsi_disk, 'type': 'lun',
+ 'format': 'raw', 'bus':
'scsi'}
+
+ disks_xml = ''
+ pool_name = pool_name_from_uri(self.info['storagepool'])
+ for index, disk in enumerate(self.info['disks']):
+ params = dict(base_disk_params)
+ params['format'] = disk.get('format',
params['format'])
+ params.update(locals().get('%s_disk_params' % storage_type, {}))
+ params['index'] = index
+
+ volume = disk.get('volume')
+ if volume is not None:
+ params['path'] = self._get_volume_path(pool_name, volume)
+ else:
+ volume = "%s-%s.img" % (vm_uuid, params['index'])
+ params['path'] = os.path.join(storage_path, volume)
+
+ disks_xml += get_disk_xml(params)[1]
+
+ return unicode(disks_xml, 'utf-8')
+
+ def to_volume_list(self, vm_uuid):
+ storage_path = self._get_storage_path()
+ fmt = 'raw' if self._get_storage_type() in ['logical'] else
'qcow2'
+ ret = []
+ for i, d in enumerate(self.info['disks']):
+ index = d.get('index', i)
+ volume = "%s-%s.img" % (vm_uuid, index)
+
+ info = {'name': volume,
+ 'capacity': d['size'],
+ 'format': fmt,
+ 'path': '%s/%s' % (storage_path, volume)}
+
+ if 'logical' == self._get_storage_type() or \
+ fmt not in ['qcow2', 'raw']:
+ info['allocation'] = info['capacity']
+ else:
+ info['allocation'] = 0
+
+ if 'base' in d:
+ info['base'] = dict()
+ base_fmt = imageinfo.probe_img_info(d['base'])['format']
+ if base_fmt is None:
+ raise InvalidParameter("KCHTMPL0024E", {'path':
d['base']})
+ info['base']['path'] = d['base']
+ info['base']['format'] = base_fmt
+
+ v_tree = E.volume(E.name(info['name']))
+ v_tree.append(E.allocation(str(info['allocation']),
unit='G'))
+ v_tree.append(E.capacity(str(info['capacity']), unit='G'))
+ target = E.target(
+ E.format(type=info['format']), E.path(info['path']))
+ if 'base' in d:
+ v_tree.append(E.backingStore(
+ E.path(info['base']['path']),
+ E.format(type=info['base']['format'])))
+ v_tree.append(target)
+ info['xml'] = etree.tostring(v_tree)
+ ret.append(info)
+ return ret
+
+ def _get_networks_xml(self):
+ networks = ""
+ params = {'type': 'network',
+ 'model': self.info['nic_model']}
+ for nw in self.info['networks']:
+ params['network'] = nw
+ networks += get_iface_xml(params, self.info['arch'],
+ self.info['os_distro'],
+ self.info['os_version'])
+ return unicode(networks, 'utf-8')
+
+ def _get_input_output_xml(self):
+ sound = """
+ <sound model='%(sound_model)s' />
+ """
+ mouse = """
+ <input type='mouse' bus='%(mouse_bus)s'/>
+ """
+
+ keyboard = """
+ <input type='%(kbd_type)s' bus='%(kbd_bus)s'>
</input>
+ """
+
+ tablet = """
+ <input type='tablet' bus='%(kbd_bus)s'> </input>
+ """
+
+ video = """
+ <video>
+ <model type='%(video_model)s'/>
+ </video>
+ """
+
+ input_output = ""
+ if 'mouse_bus' in self.info.keys():
+ input_output += mouse % self.info
+ if 'kbd_bus' in self.info.keys():
+ input_output += keyboard % self.info
+ if 'tablet_bus' in self.info.keys():
+ input_output += tablet % self.info
+ if 'sound_model' in self.info.keys():
+ input_output += sound % self.info
+ if 'video_model' in self.info.keys():
+ input_output += video % self.info
+ return input_output
+
+ def _get_cpu_xml(self):
+ # Include CPU topology, if provided
+ cpu_info = self.info.get('cpu_info')
+ if cpu_info is not None:
+ cpu_topo = cpu_info.get('topology')
+ return get_cpu_xml(self.info.get('cpus'),
+ self.info.get('memory') << 10,
+ cpu_topo)
+
+ def to_vm_xml(self, vm_name, vm_uuid, **kwargs):
+ params = dict(self.info)
+ params['name'] = vm_name
+ params['uuid'] = vm_uuid
+ params['networks'] = self._get_networks_xml()
+ params['input_output'] = self._get_input_output_xml()
+ params['qemu-namespace'] = ''
+ params['cdroms'] = ''
+ params['qemu-stream-cmdline'] = ''
+ params['cpu_info'] = self._get_cpu_xml()
+ params['disks'] = self._get_disks_xml(vm_uuid)
+
+ graphics = dict(self.info['graphics'])
+ graphics.update(kwargs.get('graphics', {}))
+ params['graphics'] = get_graphics_xml(graphics)
+
+ libvirt_stream_protocols = kwargs.get('libvirt_stream_protocols', [])
+ cdrom_xml = self._get_cdrom_xml(libvirt_stream_protocols)
+
+ if not urlparse.urlparse(self.info.get('cdrom', "")).scheme in
\
+ libvirt_stream_protocols and \
+ params.get('iso_stream', False):
+ params['qemu-stream-cmdline'] = cdrom_xml
+ else:
+ params['cdroms'] = cdrom_xml
+
+ # Setting maximum number of slots to avoid errors when hotplug memory
+ # Number of slots are the numbers of chunks of 1GB that fit inside
+ # the max_memory of the host minus memory assigned to the VM
+ params['slots'] = ((params['max_memory'] >> 10) -
+ params['memory']) >> 10
+ if params['slots'] < 0:
+ raise OperationFailed("KCHVM0041E")
+ elif params['slots'] == 0:
+ params['slots'] = 1
+
+ xml = """
+ <domain type='%(domain)s'>
+ %(qemu-stream-cmdline)s
+ <name>%(name)s</name>
+ <uuid>%(uuid)s</uuid>
+ <maxMemory slots='%(slots)s'
unit='KiB'>%(max_memory)s</maxMemory>
+ <memory unit='MiB'>%(memory)s</memory>
+ <vcpu>%(cpus)s</vcpu>
+ %(cpu_info)s
+ <os>
+ <type arch='%(arch)s'>hvm</type>
+ <boot dev='hd'/>
+ <boot dev='cdrom'/>
+ </os>
+ <features>
+ <acpi/>
+ <apic/>
+ <pae/>
+ </features>
+ <clock offset='utc'/>
+ <on_poweroff>destroy</on_poweroff>
+ <on_reboot>restart</on_reboot>
+ <on_crash>restart</on_crash>
+ <devices>
+ %(disks)s
+ %(cdroms)s
+ %(networks)s
+ %(graphics)s
+ %(input_output)s
+ <memballoon model='virtio' />
+ </devices>
+ </domain>
+ """ % params
+
+ # Adding PPC console configuration
+ if params['arch'] in ['ppc', 'ppc64']:
+ ppc_console = """<memballoon model='virtio' />
+ <console type='pty'>
+ <target type='serial' port='1'/>
+ <address type='spapr-vio' reg='0x30001000'/>
+ </console>"""
+ xml = xml.replace("<memballoon model='virtio' />",
ppc_console)
+
+ return xml
+
+ def validate(self):
+ self._storage_validate()
+ self._network_validate()
+ self._iso_validate()
+
+ def _iso_validate(self):
+ pass
+
+ def _network_validate(self):
+ pass
+
+ def _storage_validate(self):
+ pass
+
+ def fork_vm_storage(self, vm_uuid):
+ pass
+
+ def _get_storage_path(self):
+ return ''
+
+ def _get_storage_type(self):
+ return ''
+
+ def _get_volume_path(self):
+ return ''
+
+ def _get_all_networks_name(self):
+ return []
+
+ def _get_all_storagepools_name(self):
+ return []
+
+ def validate_integrity(self):
+ invalid = {}
+ # validate networks integrity
+ invalid_networks = list(set(self.info['networks']) -
+ set(self._get_all_networks_name()))
+ if invalid_networks:
+ invalid['networks'] = invalid_networks
+
+ # validate storagepools integrity
+ pool_uri = self.info['storagepool']
+ pool_name = pool_name_from_uri(pool_uri)
+ if pool_name not in self._get_all_storagepools_name():
+ invalid['storagepools'] = [pool_name]
+
+ # validate iso integrity
+ # FIXME when we support multiples cdrom devices
+ iso = self.info.get('cdrom')
+ if iso:
+ if os.path.exists(iso):
+ st_mode = os.stat(iso).st_mode
+ if not (stat.S_ISREG(st_mode) or stat.S_ISBLK(st_mode)):
+ invalid['cdrom'] = [iso]
+ elif not check_url_path(iso):
+ invalid['cdrom'] = [iso]
+
+ self.info['invalid'] = invalid
+
+ return self.info
diff --git a/src/wok/plugins/kimchi/vnc.py b/src/wok/plugins/kimchi/vnc.py
new file mode 100644
index 0000000..2532449
--- /dev/null
+++ b/src/wok/plugins/kimchi/vnc.py
@@ -0,0 +1,77 @@
+#!/usr/bin/env python2
+#
+# Project Kimchi
+#
+# Copyright IBM, Corp. 2013-2015
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+import base64
+import errno
+import os
+from multiprocessing import Process
+from websockify import WebSocketProxy
+
+from wok.config import config, paths
+
+
+WS_TOKENS_DIR = '/var/lib/wok/vnc-tokens'
+
+
+def new_ws_proxy():
+ try:
+ os.makedirs(WS_TOKENS_DIR, mode=0755)
+ except OSError as e:
+ if e.errno == errno.EEXIST:
+ pass
+
+ cert = config.get('server', 'ssl_cert')
+ key = config.get('server', 'ssl_key')
+ if not (cert and key):
+ cert = '%s/wok-cert.pem' % paths.conf_dir
+ key = '%s/wok-key.pem' % paths.conf_dir
+
+ params = {'web': os.path.join(paths.ui_dir, 'pages/websockify'),
+ 'listen_port': config.get('display',
'display_proxy_port'),
+ 'target_cfg': WS_TOKENS_DIR,
+ 'key': key, 'cert': cert, 'ssl_only': True}
+
+ def start_proxy():
+ server = WebSocketProxy(**params)
+ server.start_server()
+
+ proc = Process(target=start_proxy)
+ proc.start()
+ return proc
+
+
+def add_proxy_token(name, port):
+ with open(os.path.join(WS_TOKENS_DIR, name), 'w') as f:
+ """
+ From python documentation base64.urlsafe_b64encode(s)
+ substitutes - instead of + and _ instead of / in the
+ standard Base64 alphabet, BUT the result can still
+ contain = which is not safe in a URL query component.
+ So remove it when needed as base64 can work well without it.
+ """
+ name = base64.urlsafe_b64encode(name).rstrip('=')
+ f.write('%s: localhost:%s' % (name.encode('utf-8'), port))
+
+
+def remove_proxy_token(name):
+ try:
+ os.unlink(os.path.join(WS_TOKENS_DIR, name))
+ except OSError:
+ pass
diff --git a/src/wok/plugins/kimchi/xmlutils/Makefile.am
b/src/wok/plugins/kimchi/xmlutils/Makefile.am
new file mode 100644
index 0000000..207ad7f
--- /dev/null
+++ b/src/wok/plugins/kimchi/xmlutils/Makefile.am
@@ -0,0 +1,25 @@
+#
+# Kimchi
+#
+# Copyright IBM Corp, 2014
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+xmlutils_PYTHON = *.py
+
+xmlutilsdir = $(pythondir)/wok/plugins/kimchi/xmlutils
+
+install-data-local:
+ $(MKDIR_P) $(DESTDIR)$(xmlutilsdir)
diff --git a/src/wok/plugins/kimchi/xmlutils/__init__.py
b/src/wok/plugins/kimchi/xmlutils/__init__.py
new file mode 100644
index 0000000..ca7ede4
--- /dev/null
+++ b/src/wok/plugins/kimchi/xmlutils/__init__.py
@@ -0,0 +1,18 @@
+#
+# Project Kimchi
+#
+# Copyright IBM, Corp. 2014
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
diff --git a/src/wok/plugins/kimchi/xmlutils/cpu.py
b/src/wok/plugins/kimchi/xmlutils/cpu.py
new file mode 100644
index 0000000..32c01a4
--- /dev/null
+++ b/src/wok/plugins/kimchi/xmlutils/cpu.py
@@ -0,0 +1,60 @@
+#
+# Project Kimchi
+#
+# Copyright IBM, Corp. 2015
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+import lxml.etree as ET
+from lxml.builder import E
+
+
+def get_numa_xml(cpus, memory):
+ # Returns the NUMA xml to be add into CPU element
+ # Currently, supports only one node/cell
+ # <numa>
+ # <cell id='0' cpus='0-3' memory='512000'
unit='KiB'/>
+ # </numa>
+ xml = E.numa(E.cell(
+ id='0',
+ cpus='0-' + str(cpus - 1) if cpus > 1 else '0',
+ memory=str(memory),
+ unit='KiB'))
+ return ET.tostring(xml)
+
+
+def get_topology_xml(cpu_topo):
+ # Return the cpu TOPOLOGY element
+ # <topology sockets='1' cores='2' threads='1'/>
+ xml = E.topology(
+ sockets=str(cpu_topo['sockets']),
+ cores=str(cpu_topo['cores']),
+ threads=str(cpu_topo['threads']))
+ return ET.tostring(xml)
+
+
+def get_cpu_xml(cpus, memory, cpu_topo=None):
+ # Returns the libvirt CPU element based on given numa and topology
+ # CPU element will always have numa element
+ # <cpu>
+ # <numa>
+ # <cell id='0' cpus='0-3' memory='512000'
unit='KiB'/>
+ # </numa>
+ # <topology sockets='1' cores='2' threads='1'/>
+ # </cpu>
+ xml = E.cpu(ET.fromstring(get_numa_xml(cpus, memory)))
+ if cpu_topo is not None:
+ xml.insert(0, ET.fromstring(get_topology_xml(cpu_topo)))
+ return ET.tostring(xml)
diff --git a/src/wok/plugins/kimchi/xmlutils/disk.py
b/src/wok/plugins/kimchi/xmlutils/disk.py
new file mode 100644
index 0000000..126ce77
--- /dev/null
+++ b/src/wok/plugins/kimchi/xmlutils/disk.py
@@ -0,0 +1,164 @@
+#
+# Project Kimchi
+#
+# Copyright IBM, Corp. 2014
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+import lxml.etree as ET
+import os
+import socket
+import stat
+import string
+import urlparse
+from lxml import objectify
+from lxml.builder import E
+
+from wok.exception import InvalidParameter, NotFoundError
+from wok.utils import check_url_path
+
+
+BUS_TO_DEV_MAP = {'ide': 'hd', 'virtio': 'vd',
'scsi': 'sd'}
+DEV_TYPE_SRC_ATTR_MAP = {'file': 'file', 'block': 'dev'}
+
+
+def get_disk_xml(params):
+ """
+ <disk type='file' device='cdrom'>
+ <driver name='qemu' type='raw'/>
+
+ [source XML according to src_type]
+
+ <target dev='%(dev)s' bus='%(bus)s'/>
+ <readonly/>
+ </disk>
+ """
+ path = params['path']
+ disk_type = params.get('disk', None)
+ if disk_type is None:
+ disk_type = _get_disk_type(path) if len(path) > 0 else 'file'
+ disk = E.disk(type=disk_type, device=params['type'])
+ driver = E.driver(name='qemu', type=params['format'])
+ if params['type'] != 'cdrom':
+ driver.set('cache', 'none')
+
+ disk.append(driver)
+
+ # Get device name according to bus and index values
+ dev = params.get('dev', (BUS_TO_DEV_MAP[params['bus']] +
+ string.lowercase[params.get('index', 0)]))
+ disk.append(E.target(dev=dev, bus=params['bus']))
+
+ if params.get('address'):
+ # ide disk target id is always '0'
+ disk.append(E.address(
+ type='drive',
controller=params['address']['controller'],
+ bus=params['address']['bus'], target='0',
+ unit=params['address']['unit']))
+
+ if len(params['path']) == 0:
+ return (dev, ET.tostring(disk, encoding='utf-8', pretty_print=True))
+
+ if disk_type == 'network':
+ """
+ <source protocol='%(protocol)s' name='%(url_path)s'>
+ <host name='%(hostname)s' port='%(port)s'/>
+ </source>
+ """
+ output = urlparse.urlparse(params['path'])
+ port = str(output.port or socket.getservbyname(output.scheme))
+
+ source = E.source(protocol=output.scheme, name=output.path)
+ source.append(E.host(name=output.hostname, port=port))
+ else:
+ """
+ <source file='%(src)s' />
+ """
+ source = E.source()
+ source.set(DEV_TYPE_SRC_ATTR_MAP[disk_type], params['path'])
+
+ disk.append(source)
+ return (dev, ET.tostring(disk, encoding='utf-8', pretty_print=True))
+
+
+def _get_disk_type(path):
+ if check_url_path(path):
+ return 'network'
+
+ if not os.path.exists(path):
+ raise InvalidParameter("KCHVMSTOR0003E", {'value': path})
+
+ # Check if path is a valid local path
+ if os.path.isfile(path):
+ return 'file'
+
+ r_path = os.path.realpath(path)
+ if stat.S_ISBLK(os.stat(r_path).st_mode):
+ return 'block'
+
+ raise InvalidParameter("KCHVMSTOR0003E", {'value': path})
+
+
+def get_device_node(dom, dev_name):
+ xml = dom.XMLDesc(0)
+ devices = objectify.fromstring(xml).devices
+ disk = devices.xpath("./disk/target[@dev='%s']/.." % dev_name)
+
+ if not disk:
+ raise NotFoundError("KCHVMSTOR0007E",
+ {'dev_name': dev_name,
+ 'vm_name': dom.name()})
+
+ return disk[0]
+
+
+def get_vm_disk_info(dom, dev_name):
+ # Retrieve disk xml and format return dict
+ disk = get_device_node(dom, dev_name)
+ if disk is None:
+ return None
+
+ try:
+ source = disk.source
+ if source is not None:
+ src_type = disk.attrib['type']
+ if src_type == 'network':
+ host = source.host
+ path = (source.attrib['protocol'] + '://' +
+ host.attrib['name'] + ':' +
+ host.attrib['port'] + source.attrib['name'])
+ else:
+ path = source.attrib[DEV_TYPE_SRC_ATTR_MAP[src_type]]
+ except:
+ path = ""
+
+ return {'dev': dev_name,
+ 'path': path,
+ 'type': disk.attrib['device'],
+ 'format': disk.driver.attrib['type'],
+ 'bus': disk.target.attrib['bus']}
+
+
+def get_vm_disks(dom):
+ xml = dom.XMLDesc(0)
+ devices = objectify.fromstring(xml).devices
+
+ storages = {}
+ all_disks = devices.xpath("./disk[@device='disk']")
+ all_disks.extend(devices.xpath("./disk[@device='cdrom']"))
+ for disk in all_disks:
+ storages[disk.target.attrib['dev']] = disk.target.attrib['bus']
+
+ return storages
diff --git a/src/wok/plugins/kimchi/xmlutils/graphics.py
b/src/wok/plugins/kimchi/xmlutils/graphics.py
new file mode 100644
index 0000000..2b4346a
--- /dev/null
+++ b/src/wok/plugins/kimchi/xmlutils/graphics.py
@@ -0,0 +1,45 @@
+#
+# Project Kimchi
+#
+# Copyright IBM, Corp. 2014
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+import lxml.etree as ET
+from lxml.builder import E
+
+
+def get_graphics_xml(params):
+ """
+ <graphics type='%(type)s' autoport='yes'
listen='%(listen)s'/>
+
+ - For spice graphics:
+
+ <channel type='spicevmc'>
+ <target type='virtio' name='com.redhat.spice.0'/>
+ </channel>
+ """
+ graphics = E.graphics(type=params['type'], autoport='yes',
+ listen=params['listen'])
+ graphics_xml = ET.tostring(graphics, encoding='utf-8', pretty_print=True)
+
+ if params['type'] == 'vnc':
+ return graphics_xml
+
+ # For spice graphics, a channel also must be configured
+ channel = E.channel(type='spicevmc')
+ channel.append(E.target(type='virtio', name='com.redhat.spice.0'))
+ channel_xml = ET.tostring(channel, encoding='utf-8', pretty_print=True)
+ return graphics_xml + channel_xml
diff --git a/src/wok/plugins/kimchi/xmlutils/interface.py
b/src/wok/plugins/kimchi/xmlutils/interface.py
new file mode 100644
index 0000000..0f3e848
--- /dev/null
+++ b/src/wok/plugins/kimchi/xmlutils/interface.py
@@ -0,0 +1,61 @@
+#
+# Project Kimchi
+#
+# Copyright IBM, Corp. 2014-2015
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+import lxml.etree as ET
+from distutils.version import LooseVersion
+from lxml.builder import E
+
+from .. import osinfo
+
+
+def get_iface_xml(params, arch=None, os_distro=None, os_version=None):
+ """
+ <interface type='network'>
+ <source network='default'/>
+ <model type='virtio'/>
+ </interface>
+ """
+ interface = E.interface(type=params['type'])
+ interface.append(E.source(network=params['network']))
+
+ model = params.get('model')
+
+ # no model specified; let's try querying osinfo
+ if model is None:
+ # if os_distro and os_version are invalid, nic_model will also be None
+ model = osinfo.lookup(os_distro, os_version).get('nic_model')
+
+ # only append 'model' to the XML if it's been specified as a parameter
or
+ # returned by osinfo.lookup; otherwise let libvirt use its default value
+ if model is not None:
+ interface.append(E.model(type=model))
+
+ mac = params.get('mac', None)
+ if mac is not None:
+ interface.append(E.mac(address=mac))
+
+ # Hack to disable vhost feature in Ubuntu LE and SLES LE (PPC)
+ if arch == 'ppc64' and \
+ ((os_distro == 'ubuntu' and
+ LooseVersion(os_version) >= LooseVersion('14.04')) or
+ (os_distro == 'sles' and
+ LooseVersion(os_version) >= LooseVersion('12'))):
+ interface.append(E.driver(name='qemu'))
+
+ return ET.tostring(interface, encoding='utf-8', pretty_print=True)
diff --git a/src/wok/plugins/kimchi/xmlutils/network.py
b/src/wok/plugins/kimchi/xmlutils/network.py
new file mode 100644
index 0000000..c73aad9
--- /dev/null
+++ b/src/wok/plugins/kimchi/xmlutils/network.py
@@ -0,0 +1,122 @@
+#
+# Project Kimchi
+#
+# Copyright IBM, Corp. 2014
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+import ipaddr
+import lxml.etree as ET
+from lxml.builder import E
+
+
+# FIXME, do not support ipv6
+def _get_dhcp_elem(**kwargs):
+ """
+ <dhcp>
+ <range start="192.168.122.100" end="192.168.122.254" />
+ <host mac="00:16:3e:77:e2:ed" name="foo.test.com"
ip="192.168.122.10" />
+ <host mac="00:16:3e:3e:a9:1a" name="bar.test.com"
ip="192.168.122.11" />
+ </dhcp>
+ """
+ dhcp = E.dhcp()
+ if 'range' in kwargs.keys():
+ dhcp_range = E.range(start=kwargs['range']['start'],
+ end=kwargs['range']['end'])
+ dhcp.append(dhcp_range)
+
+ if 'hosts' in kwargs.keys():
+ for host in kwargs['hosts']:
+ dhcp.append(E.host(mac=host['mac'],
+ name=host['name'],
+ ip=host['ip']))
+
+ return dhcp if len(dhcp) > 0 else None
+
+
+def _get_ip_elem(**kwargs):
+ """
+ <ip address="192.168.152.1" netmask="255.255.255.0">
+ <dhcp>
+ <range start="192.168.152.2" end="192.168.152.254" />
+ </dhcp>
+ </ip>
+ """
+ if 'net' not in kwargs.keys():
+ return None
+
+ net = ipaddr.IPNetwork(kwargs['net'])
+ ip = E.ip(address=str(net.ip), netmask=str(net.netmask))
+
+ dhcp_params = kwargs.get('dhcp', {})
+ dhcp = _get_dhcp_elem(**dhcp_params)
+ if dhcp is not None:
+ ip.append(dhcp)
+
+ return ip
+
+
+def _get_forward_elem(**kwargs):
+ """
+ <forward mode='hostdev' dev='eth0' managed='yes'>
+ </forward>
+ """
+ if "mode" in kwargs.keys() and kwargs['mode'] is None:
+ return None
+
+ forward = E.forward()
+ if 'mode' in kwargs.keys():
+ forward.set('mode', kwargs['mode'])
+
+ if 'dev' in kwargs.keys():
+ forward.set('dev', kwargs['dev'])
+
+ if 'managed' in kwargs.keys():
+ forward.set('managed', kwargs['managed'])
+
+ return forward
+
+
+def to_network_xml(**kwargs):
+ network = E.network(E.name(kwargs['name']))
+ bridge = kwargs.get('bridge')
+ if bridge:
+ network.append(E.bridge(name=bridge))
+
+ # None means is Isolated network, {} means default mode nat
+ params = kwargs.get('forward', {"mode": None})
+ forward = _get_forward_elem(**params)
+ if forward is not None:
+ network.append(forward)
+
+ if 'net' in kwargs:
+ network.append(_get_ip_elem(**kwargs))
+
+ return ET.tostring(network)
+
+
+def create_vlan_tagged_bridge_xml(bridge, interface, vlan_id):
+ vlan = E.vlan(E.interface(name=interface))
+ vlan.set('tag', vlan_id)
+ m = E.interface(
+ E.start(mode='onboot'),
+ E.bridge(
+ E.interface(
+ vlan,
+ type='vlan',
+ name='.'.join([interface, vlan_id]))),
+ type='bridge',
+ name=bridge)
+ return ET.tostring(m)
diff --git a/src/wok/plugins/kimchi/xmlutils/qemucmdline.py
b/src/wok/plugins/kimchi/xmlutils/qemucmdline.py
new file mode 100644
index 0000000..66238a7
--- /dev/null
+++ b/src/wok/plugins/kimchi/xmlutils/qemucmdline.py
@@ -0,0 +1,45 @@
+#
+# Project Kimchi
+#
+# Copyright IBM, Corp. 2014
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+import lxml.etree as ET
+from lxml.builder import ElementMaker
+
+QEMU_NAMESPACE = "http://libvirt.org/schemas/domain/qemu/1.0"
+
+
+def get_qemucmdline_xml(args):
+ """
+ <qemu:commandline
xmlns:qemu="http://libvirt.org/schemas/domain/qemu/1.0">
+ <qemu:arg value='-drive'/>
+ <qemu:arg value='file=%(path)s,if=none,id=drive-%(bus)s0-1-0,
+ readonly=on,format=%(format)s'/>
+ <qemu:arg value='-device'/>
+ <qemu:arg value='%(bus)s-cd,bus=%(bus)s.1,unit=0,
+ drive=drive-%(bus)s0-1-0,id=%(bus)s0-1-0'/>
+ </qemu:commandline>
+ """
+ EM = ElementMaker(namespace=QEMU_NAMESPACE,
+ nsmap={'qemu': QEMU_NAMESPACE})
+
+ root = EM.commandline()
+ for opt, value in args.iteritems():
+ root.append(EM.arg(value=opt))
+ root.append(EM.arg(value=value))
+
+ return ET.tostring(root, encoding='utf-8', pretty_print=True)
diff --git a/src/wok/plugins/kimchi/yumparser.py b/src/wok/plugins/kimchi/yumparser.py
new file mode 100644
index 0000000..74f9fa0
--- /dev/null
+++ b/src/wok/plugins/kimchi/yumparser.py
@@ -0,0 +1,283 @@
+#
+# Project Kimchi
+#
+# Copyright IBM, Corp. 2015
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+import subprocess
+from os import listdir
+from os.path import isfile, splitext
+
+
+class YumRepoObject(object):
+
+ def __init__(self, repo_id, repofile):
+ self.repo_id = repo_id
+ self.name = None
+ self.baseurl = None
+ self.enabled = True
+ self.gpgcheck = True
+ self.gpgkey = None
+ self.metalink = None
+ self.mirrorlist = None
+ self.repofile = repofile
+ self.string_attrs = ['baseurl', 'gpgkey', 'name',
+ 'metalink', 'mirrorlist']
+ self.boolean_attrs = ['enabled', 'gpgcheck']
+
+ def set_attribute(self, key, strvalue):
+ if key in self.string_attrs:
+ setattr(self, key, strvalue)
+ elif key in self.boolean_attrs:
+ setattr(self, key, (strvalue == '1'))
+
+ def get_attribute_str(self, key):
+ if key not in self.get_attributes():
+ return None
+
+ if key in self.boolean_attrs:
+ str_value = '1' if getattr(self, key) is True else '0'
+ else:
+ str_value = getattr(self, key)
+
+ if str_value is None:
+ return None
+
+ return key + '=' + str_value
+
+ def get_attributes(self):
+ return self.string_attrs + self.boolean_attrs
+
+ def enable(self):
+ self.enabled = True
+
+ def disable(self):
+ self.enabled = False
+
+ def __str__(self):
+ str_obj = '[' + self.repo_id + ']' + '\n'
+ for key in self.get_attributes():
+ if self.get_attribute_str(key) is not None:
+ str_obj += self.get_attribute_str(key) + '\n'
+ return str_obj
+
+
+def get_repo_files():
+ def _is_repository_file(f):
+ _, f_extension = splitext(f)
+ return isfile(f) and (f_extension == '.repo')
+
+ YUM_REPO_DIR = '/etc/yum.repos.d'
+ return [YUM_REPO_DIR+'/'+f for f in listdir(YUM_REPO_DIR)
+ if _is_repository_file(YUM_REPO_DIR+'/'+f)]
+
+
+def _ignore_line_repo_file(line):
+ return line.startswith("#") or '=' not in line
+
+
+def _get_repos_from_file(repo_file):
+ repos_from_file = {}
+ current_repo = None
+ current_repo_id = None
+ with open(repo_file) as f:
+ for line in f.readlines():
+ line = line.strip()
+ if line.startswith("["):
+ if current_repo is not None:
+ repos_from_file[current_repo_id] = current_repo
+ current_repo_id = line.strip('[]')
+ current_repo = YumRepoObject(current_repo_id, repo_file)
+ continue
+ if _ignore_line_repo_file(line):
+ continue
+ key, value = line.split('=', 1)
+ key = key.strip()
+ value = value.strip()
+ current_repo.set_attribute(key, value)
+
+ # add the last repo from file.
+ if current_repo is not None:
+ repos_from_file[current_repo_id] = current_repo
+
+ return repos_from_file
+
+
+def get_yum_repositories():
+ repo_files = get_repo_files()
+ repos = {}
+ for yum_repo in repo_files:
+ repos.update(_get_repos_from_file(yum_repo))
+
+ return repos
+
+
+def _retrieve_repo_line_index(data, repo):
+ repo_entry = '[' + repo.repo_id + ']\n'
+ try:
+ repo_index = data.index(repo_entry)
+ except:
+ return None
+ return repo_index
+
+
+def _update_repo_file_data(data, repo, repo_index):
+ remaining_repo_attrs = repo.get_attributes()
+
+ for i in range(repo_index + 1, len(data)):
+ line = data[i].strip()
+ if line.startswith('['):
+ break
+ if _ignore_line_repo_file(line):
+ continue
+ key, _ = line.split('=', 1)
+ key = key.strip()
+ attr_str = repo.get_attribute_str(key)
+ if attr_str is None:
+ continue
+ remaining_repo_attrs.remove(key)
+ data[i] = attr_str + '\n'
+
+ for attr in remaining_repo_attrs:
+ attr_str = repo.get_attribute_str(attr)
+ if attr_str is None:
+ continue
+ data.insert(repo_index+1, attr_str + '\n')
+
+ return data
+
+
+def write_repo_to_file(repo):
+ with open(repo.repofile) as f:
+ data = f.readlines()
+
+ repo_index = _retrieve_repo_line_index(data, repo)
+ if repo_index is None:
+ return
+
+ data = _update_repo_file_data(data, repo, repo_index)
+
+ with open(repo.repofile, 'w') as f:
+ f.writelines(data)
+
+
+def _get_last_line_repo(data, repo_index):
+ stop_delete_index = None
+ for i in range(repo_index+1, len(data)):
+ line = data[i].strip()
+ if line.startswith('['):
+ stop_delete_index = i - 1
+ break
+ if stop_delete_index is None:
+ stop_delete_index = len(data) - 1
+
+ return stop_delete_index
+
+
+def _remove_repo_file_data(data, repo_index):
+ last_line_repo = _get_last_line_repo(data, repo_index)
+ for i in range(last_line_repo, repo_index - 1, -1):
+ data.pop(i)
+ return data
+
+
+def delete_repo_from_file(repo):
+ with open(repo.repofile) as f:
+ data = f.readlines()
+
+ repo_index = _retrieve_repo_line_index(data, repo)
+ if repo_index is None:
+ return
+
+ data = _remove_repo_file_data(data, repo_index)
+
+ with open(repo.repofile, 'w') as f:
+ f.writelines(data)
+
+
+class YumUpdatePackageObject(object):
+
+ def __init__(self, name, arch, version, repo):
+ self.name = name
+ self.arch = arch
+ self.version = version
+ self.ui_from_repo = repo
+
+
+def _include_line_checkupdate_output(line):
+ tokens = line.split()
+
+ if len(tokens) != 3:
+ return False
+
+ if '.' not in tokens[0]:
+ return False
+
+ return True
+
+
+def _ignore_obsoleting_packages_in(output):
+ out = ''
+ for l in output.split('\n'):
+ if 'Obsoleting ' in l:
+ break
+ out += l + '\n'
+ return out
+
+
+def _filter_lines_checkupdate_output(output):
+ if output is None:
+ return []
+
+ output = _ignore_obsoleting_packages_in(output)
+
+ out = [l for l in output.split('\n')
+ if _include_line_checkupdate_output(l)]
+ return out
+
+
+def _get_yum_checkupdate_output():
+ cmd = ['yum', 'check-update', '-d0']
+ yum_update_cmd = subprocess.Popen(cmd,
+ stdout=subprocess.PIPE,
+ stderr=subprocess.PIPE)
+ out, error = yum_update_cmd.communicate()
+ return_code = yum_update_cmd.returncode
+ if return_code == 1:
+ return None
+
+ return out
+
+
+def get_yum_packages_list_update(checkupdate_output=None):
+ if checkupdate_output is None:
+ checkupdate_output = _get_yum_checkupdate_output()
+
+ filtered_output = _filter_lines_checkupdate_output(checkupdate_output)
+
+ packages = []
+ for line in filtered_output:
+ line = line.split()
+ index = 0
+ name_arch = line[index]
+ index += 1
+ version = line[index]
+ index += 1
+ repo = line[index]
+ name, arch = name_arch.rsplit('.', 1)
+ packages.append(YumUpdatePackageObject(name, arch, version, repo))
+
+ return packages
diff --git a/src/wok/plugins/sample/API.json b/src/wok/plugins/sample/API.json
new file mode 100644
index 0000000..6ee7d91
--- /dev/null
+++ b/src/wok/plugins/sample/API.json
@@ -0,0 +1,56 @@
+{
+ "$schema": "http://json-schema.org/draft-03/schema#",
+ "title": "Plugin Sample API",
+ "description": "Json schema for Wok's Sample Plugin API",
+ "type": "object",
+ "error": "SPAPI0001E",
+ "properties": {
+ "rectangles_create": {
+ "type": "object",
+ "error": "SPRET0003E",
+ "properties": {
+ "name": {
+ "description": "The name of the new rectangle
instance",
+ "type": "string",
+ "required": true,
+ "error": "SPRET0004E"
+ },
+ "length": {
+ "$ref": "#/definitions/positiveNumber",
+ "required": true,
+ "error": "SPRET0005E"
+ },
+ "width": {
+ "$ref": "#/definitions/positiveNumber",
+ "required": true,
+ "error": "SPRET0006E"
+ }
+ }
+ },
+ "circles_create": {
+ "type": "object",
+ "error": "SPCIRC0003E",
+ "properties": {
+ "name": {
+ "description": "The name of the new circle
instance",
+ "type": "string",
+ "required": true,
+ "error": "SPCIRC0004E"
+ },
+ "radius": {
+ "$ref": "#/definitions/positiveNumber",
+ "required": true,
+ "error": "SPCIRC0005E"
+ }
+ }
+ }
+ },
+ "definitions": {
+ "positiveNumber": {
+ "error": "SPAPI0002E",
+ "type": "number",
+ "minimum": 0,
+ "exclusiveMinimum": true
+ }
+ }
+}
diff --git a/src/wok/plugins/sample/Makefile.am b/src/wok/plugins/sample/Makefile.am
new file mode 100644
index 0000000..876ab54
--- /dev/null
+++ b/src/wok/plugins/sample/Makefile.am
@@ -0,0 +1,29 @@
+#
+# Kimchi
+#
+# Copyright IBM Corp, 2013
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+SUBDIRS = ui po
+
+EXTRA_DIST = API.json sample.conf.in $(wildcard *.py) config.status
+
+all-local:
+ while read L && test -n "$$L"; do \
+ dir=mo/$$L/LC_MESSAGES ; \
+ $(MKDIR_P) $$dir ; \
+ ln -sf ../../../po/$$L.gmo $$dir/sample.mo ; \
+ done < po/LINGUAS
diff --git a/src/wok/plugins/sample/__init__.py b/src/wok/plugins/sample/__init__.py
new file mode 100644
index 0000000..a3a8f05
--- /dev/null
+++ b/src/wok/plugins/sample/__init__.py
@@ -0,0 +1,97 @@
+#
+# Project Kimchi
+#
+# Copyright IBM, Corp. 2013-2014
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+import json
+import os
+from cherrypy import expose
+
+
+from wok.config import PluginPaths
+from wok.control.base import Collection, Resource
+from wok.root import WokRoot
+
+
+from plugins.sample.i18n import messages
+from plugins.sample.model import Model
+
+
+model = Model()
+
+
+class Drawings(WokRoot):
+ def __init__(self, wok_options):
+ Resource.__init__(self, model)
+ self.description = Description(model)
+ self.rectangles = Rectangles(model)
+ self.circles = Circles(model)
+ self.paths = PluginPaths('sample')
+ self.domain = 'sample'
+ self.messages = messages
+ self.api_schema = json.load(open(os.path.join(os.path.dirname(
+ os.path.abspath(__file__)), 'API.json')))
+
+ @expose
+ def index(self):
+ return 'This is a sample plugin for Wok'
+
+
+class Description(Resource):
+ def __init__(self, model):
+ super(Description, self).__init__(model)
+
+ @property
+ def data(self):
+ return {'name': 'sample', 'version': '0.1'}
+
+
+class Circles(Collection):
+ def __init__(self, model):
+ super(Circles, self).__init__(model)
+ self.resource = Circle
+ self.admin_methods = ['POST', 'PUT']
+
+
+class Rectangles(Collection):
+ def __init__(self, model):
+ super(Rectangles, self).__init__(model)
+ self.resource = Rectangle
+ self.admin_methods = ['POST', 'PUT']
+
+
+class Circle(Resource):
+ def __init__(self, model, ident):
+ super(Circle, self).__init__(model, ident)
+ self.update_params = ['radius']
+
+ @property
+ def data(self):
+ ret = {'name': self.ident}
+ ret.update(self.info)
+ return ret
+
+
+class Rectangle(Resource):
+ def __init__(self, model, ident):
+ super(Rectangle, self).__init__(model, ident)
+ self.update_params = ['length', 'width']
+
+ @property
+ def data(self):
+ self.info.update({'name': self.ident})
+ return self.info
diff --git a/src/wok/plugins/sample/config.status b/src/wok/plugins/sample/config.status
new file mode 120000
index 0000000..6cd6b4f
--- /dev/null
+++ b/src/wok/plugins/sample/config.status
@@ -0,0 +1 @@
+../../config.status
\ No newline at end of file
diff --git a/src/wok/plugins/sample/i18n.py b/src/wok/plugins/sample/i18n.py
new file mode 100644
index 0000000..763970f
--- /dev/null
+++ b/src/wok/plugins/sample/i18n.py
@@ -0,0 +1,40 @@
+#
+# Project Kimchi
+#
+# Copyright IBM, Corp. 2014
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+import gettext
+
+_ = gettext.gettext
+
+
+messages = {
+ "SPAPI0001E": _("Unkown parameter specified %(value)s"),
+ "SPAPI0002E": _("The specified value %(value)s is not a positive
number"),
+
+ "SPCIRC0002E": _("Circle %(name)s does not exist"),
+ "SPCIRC0003E": _("Specify name and radius to create a Circle"),
+ "SPCIRC0004E": _("Circle name must be a string"),
+ "SPCIRC0005E": _("Circle radius must be a positive number"),
+
+ "SPRET0001E": _("Rectangle %(name)s already exists"),
+ "SPRET0002E": _("Rectangle %(name)s does not exist"),
+ "SPRET0003E": _("Specify name, length and width to create a
Rectangle"),
+ "SPRET0004E": _("Rectangle name must be a string"),
+ "SPRET0005E": _("Rectangle length must be a positive number"),
+ "SPRET0006E": _("Rectangle width must be a positive number"),
+}
diff --git a/src/wok/plugins/sample/model.py b/src/wok/plugins/sample/model.py
new file mode 100644
index 0000000..4ada648
--- /dev/null
+++ b/src/wok/plugins/sample/model.py
@@ -0,0 +1,131 @@
+#
+# Project Kimchi
+#
+# Copyright IBM, Corp. 2013-2014
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+from wok.basemodel import BaseModel
+from wok.exception import InvalidOperation, NotFoundError
+
+
+class CirclesModel(object):
+ def __init__(self):
+ self._circles = {}
+
+ def create(self, params):
+ name = params['name']
+ if name in self._circles:
+ raise InvalidOperation("SPCIRCLE0001E", {'name': name})
+ self._circles[name] = Circle(params['radius'])
+ return name
+
+ def get_list(self):
+ return sorted(self._circles)
+
+
+class CircleModel(object):
+ def __init__(self, parent_model):
+ # Circel and Circles models are friends, it's OK to share _circles.
+ self._circles = parent_model._circles
+
+ def lookup(self, name):
+ try:
+ circle = self._circles[name]
+ except KeyError:
+ raise NotFoundError("SPCIRC0002E", {'name': name})
+ return {'radius': circle.radius}
+
+ def update(self, name, params):
+ if name not in self._circles:
+ raise NotFoundError("SPCIRC0002E", {'name': name})
+ self._circles[name].radius = params['radius']
+ return name
+
+ def delete(self, name):
+ try:
+ del self._circles[name]
+ except KeyError:
+ pass
+
+
+class RectanglesModel(object):
+ def __init__(self):
+ self._rectangles = {}
+
+ def create(self, params):
+ name = params['name']
+ if name in self._rectangles:
+ raise InvalidOperation("SPRET0001E", {'name': name})
+ self._rectangles[name] = Rectangle(params['length'],
params['width'])
+ return name
+
+ def get_list(self):
+ return sorted(self._rectangles)
+
+
+class RectangleModel(object):
+ def __init__(self, parent_model):
+ self._rectangles = parent_model._rectangles
+
+ def lookup(self, name):
+ try:
+ rectangle = self._rectangles[name]
+ except KeyError:
+ raise NotFoundError("SPRET0002E", {'name': name})
+ return {'length': rectangle.length, 'width': rectangle.width}
+
+ def update(self, name, params):
+ if name not in self._rectangles:
+ raise NotFoundError("SPRET0002E", {'name': name})
+ try:
+ self._rectangles[name].length = params['length']
+ except KeyError:
+ pass
+
+ try:
+ self._rectangles[name].width = params['width']
+ except KeyError:
+ pass
+ return name
+
+ def delete(self, name):
+ try:
+ del self._rectangles[name]
+ except KeyError:
+ pass
+
+
+class Model(BaseModel):
+ def __init__(self):
+ circles = CirclesModel()
+ circle = CircleModel(circles)
+
+ rectangles = RectanglesModel()
+ rectangle = RectangleModel(rectangles)
+
+ return super(Model, self).__init__(
+ [circle, circles, rectangle, rectangles])
+
+
+class Rectangle(object):
+ def __init__(self, length, width):
+ self.length = length
+ self.width = width
+
+
+class Circle(object):
+ def __init__(self, radius):
+ self.radius = radius
diff --git a/src/wok/plugins/sample/po/LINGUAS b/src/wok/plugins/sample/po/LINGUAS
new file mode 100644
index 0000000..469998e
--- /dev/null
+++ b/src/wok/plugins/sample/po/LINGUAS
@@ -0,0 +1,3 @@
+en_US
+pt_BR
+zh_CN
diff --git a/src/wok/plugins/sample/po/Makefile.in.in
b/src/wok/plugins/sample/po/Makefile.in.in
new file mode 100644
index 0000000..52ab81c
--- /dev/null
+++ b/src/wok/plugins/sample/po/Makefile.in.in
@@ -0,0 +1,400 @@
+# Makefile for PO directory in any package using GNU gettext.
+# Copyright (C) 1995-1997, 2000-2007, 2009-2010 by Ulrich Drepper
<drepper(a)gnu.ai.mit.edu>
+#
+# This file can be copied and used freely without restrictions. It can
+# be used in projects which are not available under the GNU General Public
+# License but which still want to provide support for the GNU gettext
+# functionality.
+# Please note that the actual code of GNU gettext is covered by the GNU
+# General Public License and is *not* in the public domain.
+#
+# Origin: gettext-0.18
+GETTEXT_MACRO_VERSION = 0.18
+
+PACKAGE = @PACKAGE@
+VERSION = @VERSION@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+
+SHELL = /bin/sh
+@SET_MAKE@
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH = @srcdir@
+
+prefix = @prefix@
+exec_prefix = @exec_prefix@
+datarootdir = @datarootdir@
+datadir = @datadir@
+localedir = @prefix@/share/locale
+gettextsrcdir = $(datadir)/gettext/po
+
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+
+# We use $(MKDIR_P).
+# This macro uses the 'mkdir -p' command if possible. Otherwise, it falls back
+# on invoking install-sh with the -d option, so your package should contain
+# install-sh as described under AC_PROG_INSTALL.
+mkinstalldirs = $(SHELL) @install_sh@ -d
+install_sh = $(SHELL) @install_sh@
+MKDIR_P = @MKDIR_P@
+MKDIR_P = @MKDIR_P@
+
+GMSGFMT_ = @GMSGFMT@
+GMSGFMT_no = @GMSGFMT@
+GMSGFMT_yes = @GMSGFMT_015@
+GMSGFMT = $(GMSGFMT_$(USE_MSGCTXT))
+MSGFMT_ = @MSGFMT@
+MSGFMT_no = @MSGFMT@
+MSGFMT_yes = @MSGFMT_015@
+MSGFMT = $(MSGFMT_$(USE_MSGCTXT))
+XGETTEXT_ = @XGETTEXT@
+XGETTEXT_no = @XGETTEXT@
+XGETTEXT_yes = @XGETTEXT_015@
+XGETTEXT = $(XGETTEXT_$(USE_MSGCTXT))
+MSGMERGE = msgmerge
+MSGMERGE_UPDATE = @MSGMERGE@ --update
+MSGINIT = msginit
+MSGCONV = msgconv
+MSGFILTER = msgfilter
+
+POFILES = @POFILES@
+GMOFILES = @GMOFILES@
+UPDATEPOFILES = @UPDATEPOFILES@
+DUMMYPOFILES = @DUMMYPOFILES@
+DISTFILES.common = Makefile.in.in \
+$(DISTFILES.common.extra1) $(DISTFILES.common.extra2) $(DISTFILES.common.extra3)
+DISTFILES = $(DISTFILES.common) Makevars POTFILES.in gen-pot \
+$(POFILES) $(GMOFILES) \
+$(DISTFILES.extra1) $(DISTFILES.extra2) $(DISTFILES.extra3)
+
+POTFILES = \
+
+CATALOGS = @CATALOGS@
+
+# Makevars gets inserted here. (Don't remove this line!)
+
+.SUFFIXES:
+.SUFFIXES: .po .gmo .mo .sed .sin .nop .po-create .po-update
+
+.po.mo:
+ @echo "$(MSGFMT) -c -o $@ $<"; \
+ $(MSGFMT) -c -o t-$@ $< && mv t-$@ $@
+
+.po.gmo:
+ @lang=`echo $* | sed -e 's,.*/,,'`; \
+ test "$(srcdir)" = . && cdcmd="" || cdcmd="cd $(srcdir)
&& "; \
+ echo "$${cdcmd}rm -f $${lang}.gmo && $(GMSGFMT) -c --statistics --verbose
-o $${lang}.gmo $${lang}.po"; \
+ cd $(srcdir) && rm -f $${lang}.gmo && $(GMSGFMT) -c --statistics
--verbose -o t-$${lang}.gmo $${lang}.po && mv t-$${lang}.gmo $${lang}.gmo
+
+.sin.sed:
+ sed -e '/^#/d' $< > t-$@
+ mv t-$@ $@
+
+
+all: check-macro-version update-gmo all-@USE_NLS@
+
+all-yes: stamp-po
+all-no:
+
+# Ensure that the gettext macros and this Makefile.in.in are in sync.
+check-macro-version:
+ @test "$(GETTEXT_MACRO_VERSION)" = "@GETTEXT_MACRO_VERSION@" \
+ || { echo "*** error: gettext infrastructure mismatch: using a Makefile.in.in
from gettext version $(GETTEXT_MACRO_VERSION) but the autoconf macros are from gettext
version @GETTEXT_MACRO_VERSION@" 1>&2; \
+ exit 1; \
+ }
+
+# $(srcdir)/$(DOMAIN).pot is only created when needed. When xgettext finds no
+# internationalized messages, no $(srcdir)/$(DOMAIN).pot is created (because
+# we don't want to bother translators with empty POT files). We assume that
+# LINGUAS is empty in this case, i.e. $(POFILES) and $(GMOFILES) are empty.
+# In this case, stamp-po is a nop (i.e. a phony target).
+
+# stamp-po is a timestamp denoting the last time at which the CATALOGS have
+# been loosely updated. Its purpose is that when a developer or translator
+# checks out the package via CVS, and the $(DOMAIN).pot file is not in CVS,
+# "make" will update the $(DOMAIN).pot and the $(CATALOGS), but subsequent
+# invocations of "make" will do nothing. This timestamp would not be necessary
+# if updating the $(CATALOGS) would always touch them; however, the rule for
+# $(POFILES) has been designed to not touch files that don't need to be
+# changed.
+stamp-po: $(srcdir)/$(DOMAIN).pot
+ test ! -f $(srcdir)/$(DOMAIN).pot || \
+ test -z "$(GMOFILES)" || $(MAKE) $(GMOFILES)
+ @test ! -f $(srcdir)/$(DOMAIN).pot || { \
+ echo "touch stamp-po" && \
+ echo timestamp > stamp-poT && \
+ mv stamp-poT stamp-po; \
+ }
+
+# Note: Target 'all' must not depend on target '$(DOMAIN).pot-update',
+# otherwise packages like GCC can not be built if only parts of the source
+# have been downloaded.
+
+$(DOMAIN).pot-update: $(POTFILES) $(srcdir)/POTFILES.in
+ $(srcdir)/gen-pot $(POTFILES)
+
+# This rule has no dependencies: we don't need to update $(DOMAIN).pot at
+# every "make" invocation, only create it when it is missing.
+# Only "make $(DOMAIN).pot-update" or "make dist" will force an
update.
+$(srcdir)/$(DOMAIN).pot:
+ $(MAKE) $(DOMAIN).pot-update
+
+# This target rebuilds a PO file if $(DOMAIN).pot has changed.
+# Note that a PO file is not touched if it doesn't need to be changed.
+$(POFILES): $(srcdir)/$(DOMAIN).pot
+ @lang=`echo $@ | sed -e 's,.*/,,' -e 's/\.po$$//'`; \
+ if test -f "$(srcdir)/$${lang}.po"; then \
+ test "$(srcdir)" = . && cdcmd="" || cdcmd="cd
$(srcdir) && "; \
+ echo "$${cdcmd}$(MSGMERGE_UPDATE) $(MSGMERGE_OPTIONS) --lang=$${lang} $${lang}.po
$(DOMAIN).pot"; \
+ cd $(srcdir) \
+ && { case `$(MSGMERGE_UPDATE) --version | sed 1q | sed -e
's,^[^0-9]*,,'` in \
+ '' | 0.[0-9] | 0.[0-9].* | 0.1[0-7] | 0.1[0-7].*) \
+ $(MSGMERGE_UPDATE) $(MSGMERGE_OPTIONS) $${lang}.po $(DOMAIN).pot;; \
+ *) \
+ $(MSGMERGE_UPDATE) $(MSGMERGE_OPTIONS) --lang=$${lang} $${lang}.po
$(DOMAIN).pot;; \
+ esac; \
+ }; \
+ else \
+ $(MAKE) $${lang}.po-create; \
+ fi
+
+
+install:
+
+install-exec:
+install-data: install-data-@USE_NLS@
+ if test "$(PACKAGE)" = "gettext-tools"; then \
+ $(MKDIR_P) $(DESTDIR)$(gettextsrcdir); \
+ for file in $(DISTFILES.common) Makevars.template; do \
+ $(INSTALL_DATA) $(srcdir)/$$file \
+ $(DESTDIR)$(gettextsrcdir)/$$file; \
+ done; \
+ for file in Makevars; do \
+ rm -f $(DESTDIR)$(gettextsrcdir)/$$file; \
+ done; \
+ else \
+ : ; \
+ fi
+install-data-no: all
+install-data-yes: all
+ @catalogs='$(CATALOGS)'; \
+ for cat in $$catalogs; do \
+ cat=`basename $$cat`; \
+ lang=`echo $$cat | sed -e 's/\.gmo$$//'`; \
+ dir=$(localedir)/$$lang/LC_MESSAGES; \
+ $(MKDIR_P) $(DESTDIR)$$dir; \
+ if test -r $$cat; then realcat=$$cat; else realcat=$(srcdir)/$$cat; fi; \
+ $(INSTALL_DATA) $$realcat $(DESTDIR)$$dir/$(DOMAIN).mo; \
+ echo "installing $$realcat as $(DESTDIR)$$dir/$(DOMAIN).mo"; \
+ for lc in '' $(EXTRA_LOCALE_CATEGORIES); do \
+ if test -n "$$lc"; then \
+ if (cd $(DESTDIR)$(localedir)/$$lang && LC_ALL=C ls -l -d $$lc
2>/dev/null) | grep ' -> ' >/dev/null; then \
+ link=`cd $(DESTDIR)$(localedir)/$$lang && LC_ALL=C ls -l -d $$lc | sed
-e 's/^.* -> //'`; \
+ mv $(DESTDIR)$(localedir)/$$lang/$$lc $(DESTDIR)$(localedir)/$$lang/$$lc.old; \
+ mkdir $(DESTDIR)$(localedir)/$$lang/$$lc; \
+ (cd $(DESTDIR)$(localedir)/$$lang/$$lc.old && \
+ for file in *; do \
+ if test -f $$file; then \
+ ln -s ../$$link/$$file $(DESTDIR)$(localedir)/$$lang/$$lc/$$file; \
+ fi; \
+ done); \
+ rm -f $(DESTDIR)$(localedir)/$$lang/$$lc.old; \
+ else \
+ if test -d $(DESTDIR)$(localedir)/$$lang/$$lc; then \
+ :; \
+ else \
+ rm -f $(DESTDIR)$(localedir)/$$lang/$$lc; \
+ mkdir $(DESTDIR)$(localedir)/$$lang/$$lc; \
+ fi; \
+ fi; \
+ rm -f $(DESTDIR)$(localedir)/$$lang/$$lc/$(DOMAIN).mo; \
+ ln -s ../LC_MESSAGES/$(DOMAIN).mo $(DESTDIR)$(localedir)/$$lang/$$lc/$(DOMAIN).mo
2>/dev/null || \
+ ln $(DESTDIR)$(localedir)/$$lang/LC_MESSAGES/$(DOMAIN).mo
$(DESTDIR)$(localedir)/$$lang/$$lc/$(DOMAIN).mo 2>/dev/null || \
+ cp -p $(DESTDIR)$(localedir)/$$lang/LC_MESSAGES/$(DOMAIN).mo
$(DESTDIR)$(localedir)/$$lang/$$lc/$(DOMAIN).mo; \
+ echo "installing $$realcat link as
$(DESTDIR)$(localedir)/$$lang/$$lc/$(DOMAIN).mo"; \
+ fi; \
+ done; \
+ done
+
+install-strip: install
+
+installdirs: installdirs-exec installdirs-data
+installdirs-exec:
+installdirs-data: installdirs-data-@USE_NLS@
+ if test "$(PACKAGE)" = "gettext-tools"; then \
+ $(MKDIR_P) $(DESTDIR)$(gettextsrcdir); \
+ else \
+ : ; \
+ fi
+installdirs-data-no:
+installdirs-data-yes:
+ @catalogs='$(CATALOGS)'; \
+ for cat in $$catalogs; do \
+ cat=`basename $$cat`; \
+ lang=`echo $$cat | sed -e 's/\.gmo$$//'`; \
+ dir=$(localedir)/$$lang/LC_MESSAGES; \
+ $(MKDIR_P) $(DESTDIR)$$dir; \
+ for lc in '' $(EXTRA_LOCALE_CATEGORIES); do \
+ if test -n "$$lc"; then \
+ if (cd $(DESTDIR)$(localedir)/$$lang && LC_ALL=C ls -l -d $$lc
2>/dev/null) | grep ' -> ' >/dev/null; then \
+ link=`cd $(DESTDIR)$(localedir)/$$lang && LC_ALL=C ls -l -d $$lc | sed
-e 's/^.* -> //'`; \
+ mv $(DESTDIR)$(localedir)/$$lang/$$lc $(DESTDIR)$(localedir)/$$lang/$$lc.old; \
+ mkdir $(DESTDIR)$(localedir)/$$lang/$$lc; \
+ (cd $(DESTDIR)$(localedir)/$$lang/$$lc.old && \
+ for file in *; do \
+ if test -f $$file; then \
+ ln -s ../$$link/$$file $(DESTDIR)$(localedir)/$$lang/$$lc/$$file; \
+ fi; \
+ done); \
+ rm -f $(DESTDIR)$(localedir)/$$lang/$$lc.old; \
+ else \
+ if test -d $(DESTDIR)$(localedir)/$$lang/$$lc; then \
+ :; \
+ else \
+ rm -f $(DESTDIR)$(localedir)/$$lang/$$lc; \
+ mkdir $(DESTDIR)$(localedir)/$$lang/$$lc; \
+ fi; \
+ fi; \
+ fi; \
+ done; \
+ done
+
+# Define this as empty until I found a useful application.
+installcheck:
+
+uninstall:
+
+uninstall-exec:
+uninstall-data: uninstall-data-@USE_NLS@
+ if test "$(PACKAGE)" = "gettext-tools"; then \
+ for file in $(DISTFILES.common) Makevars.template; do \
+ rm -f $(DESTDIR)$(gettextsrcdir)/$$file; \
+ done; \
+ else \
+ : ; \
+ fi
+uninstall-data-no:
+uninstall-data-yes:
+ catalogs='$(CATALOGS)'; \
+ for cat in $$catalogs; do \
+ cat=`basename $$cat`; \
+ lang=`echo $$cat | sed -e 's/\.gmo$$//'`; \
+ for lc in LC_MESSAGES $(EXTRA_LOCALE_CATEGORIES); do \
+ rm -f $(DESTDIR)$(localedir)/$$lang/$$lc/$(DOMAIN).mo; \
+ done; \
+ done
+
+check: all
+
+info dvi ps pdf html tags TAGS ctags CTAGS ID:
+
+mostlyclean:
+ rm -f remove-potcdate.sed
+ rm -f stamp-poT
+ rm -f core core.* $(DOMAIN).po $(DOMAIN).1po $(DOMAIN).2po *.new.po
+ rm -fr *.o
+
+clean: mostlyclean
+
+distclean: clean
+ rm -f Makefile Makefile.in POTFILES *.mo
+
+maintainer-clean: distclean
+ @echo "This command is intended for maintainers to use;"
+ @echo "it deletes files that may require special tools to rebuild."
+ rm -f stamp-po $(GMOFILES)
+
+distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir)
+dist distdir:
+ $(MAKE) update-po
+ @$(MAKE) dist2
+# This is a separate target because 'update-po' must be executed before.
+dist2: stamp-po $(DISTFILES)
+ dists="$(DISTFILES)"; \
+ if test "$(PACKAGE)" = "gettext-tools"; then \
+ dists="$$dists Makevars.template"; \
+ fi; \
+ if test -f $(srcdir)/$(DOMAIN).pot; then \
+ dists="$$dists $(DOMAIN).pot stamp-po"; \
+ fi; \
+ if test -f $(srcdir)/ChangeLog; then \
+ dists="$$dists ChangeLog"; \
+ fi; \
+ for i in 0 1 2 3 4 5 6 7 8 9; do \
+ if test -f $(srcdir)/ChangeLog.$$i; then \
+ dists="$$dists ChangeLog.$$i"; \
+ fi; \
+ done; \
+ if test -f $(srcdir)/LINGUAS; then dists="$$dists LINGUAS"; fi; \
+ for file in $$dists; do \
+ if test -f $$file; then \
+ cp -p $$file $(distdir) || exit 1; \
+ else \
+ cp -p $(srcdir)/$$file $(distdir) || exit 1; \
+ fi; \
+ done
+
+update-po: Makefile
+ $(MAKE) $(DOMAIN).pot-update
+ test -z "$(UPDATEPOFILES)" || $(MAKE) $(UPDATEPOFILES)
+ $(MAKE) update-gmo
+
+# General rule for creating PO files.
+
+.nop.po-create:
+ @lang=`echo $@ | sed -e 's/\.po-create$$//'`; \
+ echo "File $$lang.po does not exist. If you are a translator, you can create it
through 'msginit'." 1>&2; \
+ exit 1
+
+# General rule for updating PO files.
+
+.nop.po-update:
+ @lang=`echo $@ | sed -e 's/\.po-update$$//'`; \
+ if test "$(PACKAGE)" = "gettext-tools"; then
PATH=`pwd`/../src:$$PATH; fi; \
+ tmpdir=`pwd`; \
+ echo "$$lang:"; \
+ test "$(srcdir)" = . && cdcmd="" || cdcmd="cd $(srcdir)
&& "; \
+ echo "$${cdcmd}$(MSGMERGE) $(MSGMERGE_OPTIONS) --lang=$$lang $$lang.po
$(DOMAIN).pot -o $$lang.new.po"; \
+ cd $(srcdir); \
+ if { case `$(MSGMERGE) --version | sed 1q | sed -e 's,^[^0-9]*,,'` in \
+ '' | 0.[0-9] | 0.[0-9].* | 0.1[0-7] | 0.1[0-7].*) \
+ $(MSGMERGE) $(MSGMERGE_OPTIONS) -o $$tmpdir/$$lang.new.po $$lang.po
$(DOMAIN).pot;; \
+ *) \
+ $(MSGMERGE) $(MSGMERGE_OPTIONS) --lang=$$lang -o $$tmpdir/$$lang.new.po
$$lang.po $(DOMAIN).pot;; \
+ esac; \
+ }; then \
+ if cmp $$lang.po $$tmpdir/$$lang.new.po >/dev/null 2>&1; then \
+ rm -f $$tmpdir/$$lang.new.po; \
+ else \
+ if mv -f $$tmpdir/$$lang.new.po $$lang.po; then \
+ :; \
+ else \
+ echo "msgmerge for $$lang.po failed: cannot move $$tmpdir/$$lang.new.po to
$$lang.po" 1>&2; \
+ exit 1; \
+ fi; \
+ fi; \
+ else \
+ echo "msgmerge for $$lang.po failed!" 1>&2; \
+ rm -f $$tmpdir/$$lang.new.po; \
+ fi
+
+$(DUMMYPOFILES):
+
+update-gmo: Makefile $(GMOFILES)
+ @:
+
+# Recreate Makefile by invoking config.status. Explicitly invoke the shell,
+# because execution permission bits may not work on the current file system.
+# Use @SHELL@, which is the shell determined by autoconf for the use by its
+# scripts, not $(SHELL) which is hardwired to /bin/sh and may be deficient.
+Makefile: Makefile.in.in Makevars $(top_builddir)/config.status @POMAKEFILEDEPS@
+ cd $(top_builddir) \
+ && @SHELL@ ./config.status $(subdir)/$@.in po-directories
+
+force:
+
+# Tell versions [3.59,3.63) of GNU make not to export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/src/wok/plugins/sample/po/Makevars b/src/wok/plugins/sample/po/Makevars
new file mode 100644
index 0000000..60de3f1
--- /dev/null
+++ b/src/wok/plugins/sample/po/Makevars
@@ -0,0 +1,41 @@
+# Makefile variables for PO directory in any package using GNU gettext.
+
+# Usually the message domain is the same as the package name.
+DOMAIN = sample
+
+# These two variables depend on the location of this directory.
+subdir = po
+top_builddir = ..
+
+# These options get passed to xgettext.
+XGETTEXT_OPTIONS = --keyword=_ --keyword=N_
+
+# This is the copyright holder that gets inserted into the header of the
+# $(DOMAIN).pot file. Set this to the copyright holder of the surrounding
+# package. (Note that the msgstr strings, extracted from the package's
+# sources, belong to the copyright holder of the package.) Translators are
+# expected to transfer the copyright for their translations to this person
+# or entity, or to disclaim their copyright. The empty string stands for
+# the public domain; in this case the translators are expected to disclaim
+# their copyright.
+COPYRIGHT_HOLDER =
+
+# This is the email address or URL to which the translators shall report
+# bugs in the untranslated strings:
+# - Strings which are not entire sentences, see the maintainer guidelines
+# in the GNU gettext documentation, section 'Preparing Strings'.
+# - Strings which use unclear terms or require additional context to be
+# understood.
+# - Strings which make invalid assumptions about notation of date, time or
+# money.
+# - Pluralisation problems.
+# - Incorrect English spelling.
+# - Incorrect formatting.
+# It can be your email address, or a mailing list address where translators
+# can write to without being subscribed, or the URL of a web page through
+# which the translators can contact you.
+MSGID_BUGS_ADDRESS = kimchi-devel(a)ovirt.org
+
+# This is the list of locale categories, beyond LC_MESSAGES, for which the
+# message catalogs shall be used. It is usually empty.
+EXTRA_LOCALE_CATEGORIES =
diff --git a/src/wok/plugins/sample/po/POTFILES.in
b/src/wok/plugins/sample/po/POTFILES.in
new file mode 100644
index 0000000..7dbfb6c
--- /dev/null
+++ b/src/wok/plugins/sample/po/POTFILES.in
@@ -0,0 +1,2 @@
+# List of source files which contain translatable strings.
+plugins/sample/ui/pages/*.tmpl
diff --git a/src/wok/plugins/sample/po/en_US.po b/src/wok/plugins/sample/po/en_US.po
new file mode 100644
index 0000000..207d3c3
--- /dev/null
+++ b/src/wok/plugins/sample/po/en_US.po
@@ -0,0 +1,21 @@
+# English translations for kimchi package.
+# Copyright (C) 2014 THE kimchi'S COPYRIGHT HOLDER
+# This file is distributed under the same license as the kimchi package.
+# shhfeng <shaohef(a)linux.vnet.ibm.com>, 2014.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: kimchi 1.2.0\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2015-06-24 09:39-0300\n"
+"PO-Revision-Date: 2014-05-17 02:08+0800\n"
+"Last-Translator: shhfeng <shaohef(a)linux.vnet.ibm.com>\n"
+"Language-Team: English\n"
+"Language: en_US\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=ASCII\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Generated-By: pygettext.py 1.5\n"
+
+msgid "SampleTab"
+msgstr "SampleTab"
diff --git a/src/wok/plugins/sample/po/gen-pot b/src/wok/plugins/sample/po/gen-pot
new file mode 100755
index 0000000..c1cfb8f
--- /dev/null
+++ b/src/wok/plugins/sample/po/gen-pot
@@ -0,0 +1,9 @@
+#!/bin/bash
+
+for src in $@; do
+ if [ ${src: -3} == ".py" ]; then
+ cat $src
+ else
+ cat $src | cheetah compile -
+ fi
+done | xgettext --no-location -o sample.pot -L Python -
diff --git a/src/wok/plugins/sample/po/pt_BR.po b/src/wok/plugins/sample/po/pt_BR.po
new file mode 100644
index 0000000..8519d74
--- /dev/null
+++ b/src/wok/plugins/sample/po/pt_BR.po
@@ -0,0 +1,24 @@
+# Portuguese translations for kimchi package
+# Copyright (C) 2014 THE kimchi'S COPYRIGHT HOLDER
+# This file is distributed under the same license as the kimchi package.
+# shhfeng <shaohef(a)linux.vnet.ibm.com>, 2014.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: kimchi 1.2.0\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2015-06-24 09:39-0300\n"
+"PO-Revision-Date: 2014-05-17 02:09+0800\n"
+"Last-Translator: Cr��stian Viana <vianac(a)linux.vnet.ibm.com>\n"
+"Language-Team: Aline Manera <alinefm(a)br.ibm.com>\n"
+"Language: pt_BR\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Generated-By: pygettext.py 1.5\n"
+"X-Poedit-Country: Brazil\n"
+"X-Poedit-Language: Portuguese\n"
+"X-Poedit-SourceCharset: utf-8\n"
+
+msgid "SampleTab"
+msgstr "Tab de exemplo"
diff --git a/src/wok/plugins/sample/po/sample.pot b/src/wok/plugins/sample/po/sample.pot
new file mode 100644
index 0000000..458ffe9
--- /dev/null
+++ b/src/wok/plugins/sample/po/sample.pot
@@ -0,0 +1,21 @@
+# SOME DESCRIPTIVE TITLE.
+# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
+# This file is distributed under the same license as the PACKAGE package.
+# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
+#
+#, fuzzy
+msgid ""
+msgstr ""
+"Project-Id-Version: PACKAGE VERSION\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2015-06-24 09:39-0300\n"
+"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
+"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
+"Language-Team: LANGUAGE <LL(a)li.org>\n"
+"Language: \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=CHARSET\n"
+"Content-Transfer-Encoding: 8bit\n"
+
+msgid "SampleTab"
+msgstr ""
diff --git a/src/wok/plugins/sample/po/zh_CN.po b/src/wok/plugins/sample/po/zh_CN.po
new file mode 100644
index 0000000..04b2501
--- /dev/null
+++ b/src/wok/plugins/sample/po/zh_CN.po
@@ -0,0 +1,24 @@
+# Chinese translations for kimchi package
+# Copyright (C) 2014 THE kimchi'S COPYRIGHT HOLDER
+# This file is distributed under the same license as the kimchi package.
+# shhfeng <shaohef(a)linux.vnet.ibm.com>, 2014.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: kimchi 1.2.0\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2015-06-24 09:39-0300\n"
+"PO-Revision-Date: 2014-05-17 02:10+0800\n"
+"Last-Translator: shhfeng <shaohef(a)linux.vnet.ibm.com>\n"
+"Language-Team: Chinese (simplified)\n"
+"Language: zh_CN\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Generated-By: pygettext.py 1.5\n"
+"X-Poedit-Country: CHINA\n"
+"X-Poedit-Language: Chinese\n"
+"X-Poedit-SourceCharset: utf-8\n"
+
+msgid "SampleTab"
+msgstr "������������"
diff --git a/src/wok/plugins/sample/sample.conf.in
b/src/wok/plugins/sample/sample.conf.in
new file mode 100644
index 0000000..9da33e1
--- /dev/null
+++ b/src/wok/plugins/sample/sample.conf.in
@@ -0,0 +1,27 @@
+[wok]
+enable = @ENABLE_SAMPLE@
+plugin_class = "Drawings"
+uri = "/plugins/sample"
+
+[/]
+tools.nocache.on = True
+tools.trailing_slash.on = False
+tools.sessions.on = True
+tools.sessions.name = 'wok'
+tools.sessions.httponly = True
+tools.sessions.locking = 'explicit'
+tools.sessions.storage_type = 'ram'
+
+[/description]
+tools.wokauth.on = True
+
+[/rectangles]
+tools.wokauth.on = True
+
+[/circles]
+tools.wokauth.on = True
+
+[/help]
+tools.staticdir.on = True
+tools.nocache.on = True
+tools.staticdir.dir = wok.config.PluginPaths('sample').ui_dir +
'/pages/help'
diff --git a/src/wok/plugins/sample/ui/Makefile.am
b/src/wok/plugins/sample/ui/Makefile.am
new file mode 100644
index 0000000..37fec98
--- /dev/null
+++ b/src/wok/plugins/sample/ui/Makefile.am
@@ -0,0 +1,22 @@
+#
+# Kimchi
+#
+# Copyright IBM Corp, 2013
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+SUBDIRS = config js pages
+
+
diff --git a/src/wok/plugins/sample/ui/config/Makefile.am
b/src/wok/plugins/sample/ui/config/Makefile.am
new file mode 100644
index 0000000..cf9e09e
--- /dev/null
+++ b/src/wok/plugins/sample/ui/config/Makefile.am
@@ -0,0 +1,21 @@
+#
+# Kimchi
+#
+# Copyright IBM Corp, 2013
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+EXTRA_DIST = tab-ext.xml
+
diff --git a/src/wok/plugins/sample/ui/config/tab-ext.xml
b/src/wok/plugins/sample/ui/config/tab-ext.xml
new file mode 100644
index 0000000..aff0d14
--- /dev/null
+++ b/src/wok/plugins/sample/ui/config/tab-ext.xml
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="utf-8"?>
+<tabs-ext>
+ <tab>
+ <access role="admin" mode="admin"/>
+ <access role="user" mode="none"/>
+
+ <title>SampleTab 1</title>
+ <path>plugins/sample/sample-tab1.html</path>
+ </tab>
+ <tab>
+ <access role="admin" mode="admin"/>
+ <access role="user" mode="none"/>
+
+ <title>SampleTab 2</title>
+ <path>plugins/sample/sample-tab2.html</path>
+ </tab>
+</tabs-ext>
diff --git a/src/wok/plugins/sample/ui/css/.gitignore
b/src/wok/plugins/sample/ui/css/.gitignore
new file mode 100644
index 0000000..e69de29
diff --git a/src/wok/plugins/sample/ui/images/.gitignore
b/src/wok/plugins/sample/ui/images/.gitignore
new file mode 100644
index 0000000..e69de29
diff --git a/src/wok/plugins/sample/ui/js/.gitignore
b/src/wok/plugins/sample/ui/js/.gitignore
new file mode 100644
index 0000000..e69de29
diff --git a/src/wok/plugins/sample/ui/js/Makefile.am
b/src/wok/plugins/sample/ui/js/Makefile.am
new file mode 100644
index 0000000..4d536ae
--- /dev/null
+++ b/src/wok/plugins/sample/ui/js/Makefile.am
@@ -0,0 +1,20 @@
+#
+# Kimchi
+#
+# Copyright IBM Corp, 2014
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+EXTRA_DIST = util.js
diff --git a/src/wok/plugins/sample/ui/js/util.js b/src/wok/plugins/sample/ui/js/util.js
new file mode 100644
index 0000000..7689a81
--- /dev/null
+++ b/src/wok/plugins/sample/ui/js/util.js
@@ -0,0 +1,33 @@
+/*
+ * Project Kimchi
+ *
+ * Copyright IBM, Corp. 2014
+ *
+ * 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.
+ */
+
+sample = {};
+
+sample.description = function(suc, err){
+ wok.requestJSON({
+ url : 'plugins/sample/description',
+ type : 'GET',
+ contentType : 'application/json',
+ dataType : 'json',
+ resend : true,
+ success : suc,
+ error : err || function(data) {
+ wok.message.error(data.responseJSON.reason);
+ }
+ });
+};
diff --git a/src/wok/plugins/sample/ui/libs/.gitignore
b/src/wok/plugins/sample/ui/libs/.gitignore
new file mode 100644
index 0000000..e69de29
diff --git a/src/wok/plugins/sample/ui/pages/Makefile.am
b/src/wok/plugins/sample/ui/pages/Makefile.am
new file mode 100644
index 0000000..3da95a2
--- /dev/null
+++ b/src/wok/plugins/sample/ui/pages/Makefile.am
@@ -0,0 +1,20 @@
+#
+# Kimchi
+#
+# Copyright IBM Corp, 2014
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+EXTRA_DIST = i18n.json.tmpl sample-tab1.html.tmpl sample-tab2.html.tmpl
diff --git a/src/wok/plugins/sample/ui/pages/help/en_US/sample-tab1.html
b/src/wok/plugins/sample/ui/pages/help/en_US/sample-tab1.html
new file mode 100644
index 0000000..7122124
--- /dev/null
+++ b/src/wok/plugins/sample/ui/pages/help/en_US/sample-tab1.html
@@ -0,0 +1 @@
+Help page for TAB 1 of Wok's Sample plugin.
diff --git a/src/wok/plugins/sample/ui/pages/help/en_US/sample-tab2.html
b/src/wok/plugins/sample/ui/pages/help/en_US/sample-tab2.html
new file mode 100644
index 0000000..1bfe448
--- /dev/null
+++ b/src/wok/plugins/sample/ui/pages/help/en_US/sample-tab2.html
@@ -0,0 +1 @@
+Help page for TAB 2 of Wok's Sample plugin.
diff --git a/src/wok/plugins/sample/ui/pages/i18n.json.tmpl
b/src/wok/plugins/sample/ui/pages/i18n.json.tmpl
new file mode 100644
index 0000000..737bb39
--- /dev/null
+++ b/src/wok/plugins/sample/ui/pages/i18n.json.tmpl
@@ -0,0 +1,26 @@
+#*
+ * Kimchi
+ *
+ * Copyright IBM, Corp. 2014
+ *
+ * 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.
+ *#
+#unicode UTF-8
+#import gettext
+#from wok.cachebust import href
+#silent t = gettext.translation($lang.domain, $lang.localedir, languages=$lang.lang)
+#silent _ = t.gettext
+#silent _t = t.gettext
+{
+ "SampleTab": "$_("SampleTab")"
+}
diff --git a/src/wok/plugins/sample/ui/pages/sample-tab1.html.tmpl
b/src/wok/plugins/sample/ui/pages/sample-tab1.html.tmpl
new file mode 100644
index 0000000..4354d81
--- /dev/null
+++ b/src/wok/plugins/sample/ui/pages/sample-tab1.html.tmpl
@@ -0,0 +1,30 @@
+#*
+ * Project Kimchi
+ *
+ * Copyright IBM, Corp. 2014
+ *
+ * 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.
+ *#
+#unicode UTF-8
+<!DOCTYPE html>
+<html>
+<script type="text/javascript"
src="plugins/sample/js/util.js"></script>
+<body>
+ <div id="samplebody"/>
+</body>
+<script>
+ sample.description(function(r){
+ \$("#samplebody").html("name: " + r.name + " version:
" + r.version);
+ });
+</script>
+</html>
diff --git a/src/wok/plugins/sample/ui/pages/sample-tab2.html.tmpl
b/src/wok/plugins/sample/ui/pages/sample-tab2.html.tmpl
new file mode 100644
index 0000000..4354d81
--- /dev/null
+++ b/src/wok/plugins/sample/ui/pages/sample-tab2.html.tmpl
@@ -0,0 +1,30 @@
+#*
+ * Project Kimchi
+ *
+ * Copyright IBM, Corp. 2014
+ *
+ * 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.
+ *#
+#unicode UTF-8
+<!DOCTYPE html>
+<html>
+<script type="text/javascript"
src="plugins/sample/js/util.js"></script>
+<body>
+ <div id="samplebody"/>
+</body>
+<script>
+ sample.description(function(r){
+ \$("#samplebody").html("name: " + r.name + " version:
" + r.version);
+ });
+</script>
+</html>
--
2.1.4